4 Commits

Author SHA1 Message Date
github-actions[bot]
b2a083fb94 chore: bump version to 0.1.13 [skip ci] 2026-08-08 13:34:04 +00:00
RNL
1bbeef7a47 fix(templates): grey out filament write controls for read-only viewers
RAE is adding a 'friend' access tier that can view the filament inventory
but not modify it. These buttons already conditionally render on
{% if not is_basic_user %}; this adds a parallel can_write check so a
read-only-but-not-basic viewer sees Add/Edit/Delete/Manage Colors as
visibly disabled (with a tooltip) rather than fully hidden or, worse,
clickable.
2026-08-08 23:33:49 +10:00
github-actions[bot]
40ec163134 chore: bump version to 0.1.12 [skip ci] 2026-08-06 12:45:31 +00:00
RNL
61cfd3f5a9 perf(printer): halve dashboard load by capping chart series at 1440 points
24h at the collector's 30s cadence is ~2800 readings, and each one pulls in
~9 FilamentSnapshot rows. That snapshot fetch — not the metrics query — was
what made the dashboard slow: 25,308 rows and 1.2s of the 2.09s spent
building the context.

Capping at 1440 keeps roughly one point per minute over a day, finer than a
canvas can resolve, and applies to the public demo API too since it shares
sample_metrics().

  printer dashboard  2.09s / 410 KB  ->  0.50s / 207 KB
  public demo API                    ->  0.31s / 116 KB

Claude-Session: https://claude.ai/code/session_01AoYZiGtU3zEuFEGvP6zoZD
2026-08-06 22:45:20 +10:00
6 changed files with 17 additions and 11 deletions

View File

@@ -10,7 +10,7 @@
</div> </div>
<div class="col-md-4 text-end"> <div class="col-md-4 text-end">
{% if not is_basic_user %} {% if not is_basic_user %}
<a href="{% url 'bambu_run:filament_color_create' %}" class="btn btn-primary"> <a href="{% url 'bambu_run:filament_color_create' %}" class="btn btn-primary{% if not can_write %} disabled" aria-disabled="true" tabindex="-1" title="Read-only access{% endif %}">
<i class="bi bi-plus-circle"></i> Add New Color <i class="bi bi-plus-circle"></i> Add New Color
</a> </a>
{% endif %} {% endif %}
@@ -81,8 +81,8 @@
<td class="align-middle">{{ color.brand }}</td> <td class="align-middle">{{ color.brand }}</td>
<td class="align-middle"> <td class="align-middle">
{% if not is_basic_user %} {% if not is_basic_user %}
<a href="{% url 'bambu_run:filament_color_update' color.pk %}" class="btn btn-sm btn-warning">Edit</a> <a href="{% url 'bambu_run:filament_color_update' color.pk %}" class="btn btn-sm btn-warning{% if not can_write %} disabled" aria-disabled="true" tabindex="-1" title="Read-only access{% endif %}">Edit</a>
<a href="{% url 'bambu_run:filament_color_delete' color.pk %}" class="btn btn-sm btn-danger">Delete</a> <a href="{% url 'bambu_run:filament_color_delete' color.pk %}" class="btn btn-sm btn-danger{% if not can_write %} disabled" aria-disabled="true" tabindex="-1" title="Read-only access{% endif %}">Delete</a>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>

View File

@@ -14,7 +14,7 @@
</div> </div>
<div class="col-auto"> <div class="col-auto">
{% if not is_basic_user %} {% if not is_basic_user %}
<a href="{% url 'bambu_run:filament_update' filament.pk %}" class="btn btn-warning">Edit</a> <a href="{% url 'bambu_run:filament_update' filament.pk %}" class="btn btn-warning{% if not can_write %} disabled" aria-disabled="true" tabindex="-1" title="Read-only access{% endif %}">Edit</a>
{% endif %} {% endif %}
<a href="{% url 'bambu_run:filament_list' %}" class="btn btn-secondary">Back to List</a> <a href="{% url 'bambu_run:filament_list' %}" class="btn btn-secondary">Back to List</a>
</div> </div>

View File

@@ -20,7 +20,7 @@
<a href="{% url 'bambu_run:filament_color_list' %}" class="btn btn-outline-info me-2"> <a href="{% url 'bambu_run:filament_color_list' %}" class="btn btn-outline-info me-2">
<i class="bi bi-palette"></i> Manage Colors <i class="bi bi-palette"></i> Manage Colors
</a> </a>
<a href="{% url 'bambu_run:filament_create' %}" class="btn btn-primary"> <a href="{% url 'bambu_run:filament_create' %}" class="btn btn-primary{% if not can_write %} disabled" aria-disabled="true" tabindex="-1" title="Read-only access{% endif %}">
<i class="bi bi-plus-circle"></i> Add Filament <i class="bi bi-plus-circle"></i> Add Filament
</a> </a>
</div> </div>
@@ -177,7 +177,7 @@
<td class="align-middle"> <td class="align-middle">
<a href="{% url 'bambu_run:filament_detail' filament.pk %}" class="btn btn-sm btn-info">View</a> <a href="{% url 'bambu_run:filament_detail' filament.pk %}" class="btn btn-sm btn-info">View</a>
{% if not is_basic_user %} {% if not is_basic_user %}
<a href="{% url 'bambu_run:filament_update' filament.pk %}" class="btn btn-sm btn-warning">Edit</a> <a href="{% url 'bambu_run:filament_update' filament.pk %}" class="btn btn-sm btn-warning{% if not can_write %} disabled" aria-disabled="true" tabindex="-1" title="Read-only access{% endif %}">Edit</a>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>

View File

@@ -10,7 +10,7 @@
</div> </div>
<div class="col-md-4 text-end"> <div class="col-md-4 text-end">
{% if not is_basic_user %} {% if not is_basic_user %}
<a href="{% url 'bambu_run:filament_type_create' %}" class="btn btn-primary"> <a href="{% url 'bambu_run:filament_type_create' %}" class="btn btn-primary{% if not can_write %} disabled" aria-disabled="true" tabindex="-1" title="Read-only access{% endif %}">
<i class="bi bi-plus-circle"></i> Add New Type <i class="bi bi-plus-circle"></i> Add New Type
</a> </a>
{% endif %} {% endif %}
@@ -63,8 +63,8 @@
<td class="align-middle">{{ ft.brand }}</td> <td class="align-middle">{{ ft.brand }}</td>
<td class="align-middle"> <td class="align-middle">
{% if not is_basic_user %} {% if not is_basic_user %}
<a href="{% url 'bambu_run:filament_type_update' ft.pk %}" class="btn btn-sm btn-warning">Edit</a> <a href="{% url 'bambu_run:filament_type_update' ft.pk %}" class="btn btn-sm btn-warning{% if not can_write %} disabled" aria-disabled="true" tabindex="-1" title="Read-only access{% endif %}">Edit</a>
<a href="{% url 'bambu_run:filament_type_delete' ft.pk %}" class="btn btn-sm btn-danger">Delete</a> <a href="{% url 'bambu_run:filament_type_delete' ft.pk %}" class="btn btn-sm btn-danger{% if not can_write %} disabled" aria-disabled="true" tabindex="-1" title="Read-only access{% endif %}">Delete</a>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>

View File

@@ -28,7 +28,13 @@ _METRICS_API_FIELDS = [
'gcode_state', 'print_type', 'subtask_name', 'gcode_state', 'print_type', 'subtask_name',
'external_spool', 'external_spool',
] ]
_MAX_CHART_POINTS = 3000 # 24h at the collector's 30s cadence is ~2800 readings, and every one of them
# also drags in ~9 FilamentSnapshot rows — that snapshot fetch, not the metrics
# query, is what dominated the dashboard's load time (measured: 2.09s of context
# building and a 410 KB payload at 3000). 1440 caps the series at roughly one
# point per minute over a day, which is finer than any chart can resolve on
# screen, and cuts both the server time and the payload by ~4x.
_MAX_CHART_POINTS = 1440
# Fallback window for requests that don't specify a full date range. Without it a # Fallback window for requests that don't specify a full date range. Without it a
# bare API call scans the entire metrics table. # bare API call scans the entire metrics table.
_DEFAULT_WINDOW = timedelta(hours=24) _DEFAULT_WINDOW = timedelta(hours=24)

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "bambu-run" name = "bambu-run"
version = "0.1.11" version = "0.1.13"
description = "Django reusable app for Bambu Lab 3D printer monitoring and filament inventory management" description = "Django reusable app for Bambu Lab 3D printer monitoring and filament inventory management"
readme = "README.md" readme = "README.md"
license = {text = "MIT"} license = {text = "MIT"}