Show the Print Log's per-run cost and energy, and let users pick columns (#2636)

The list and update endpoints serialised field by field and never named
cost / energy_kwh / energy_cost, so values Bambuddy had been recording
all along went out as nulls. Both now validate from the ORM row, which
removes the chance to omit a field rather than patching the three that
were missing.

Adds a Filament Used column plus a Columns picker for Cost, Energy,
Energy Cost and Finished, persisted per browser.

Also fixes the log view being unreachable with zero archives: the empty
state ran before the view check, hiding a log that outlives the archives
it refers to.

---

Sort the Print Log by any column (#2636)

Adds sort_by / sort_dir to the print-log endpoint, driven by clickable
column headers. Server-side because paging is: ordering the rows the
client holds would sort one page rather than the log.

Empty values are held last in both directions — Postgres sorts NULLs
high and SQLite low, so the same click would otherwise open on blanks
on one backend and values on the other. id DESC breaks ties so paging
through a low-cardinality sort can't repeat or skip a row.
This commit is contained in:
maziggy
2026-08-03 14:53:21 +02:00
parent e95c42c021
commit a08d3e62f3
23 changed files with 1203 additions and 282 deletions
+6
View File
@@ -4836,6 +4836,10 @@ export const api = {
dateTo?: string;
limit?: number;
offset?: number;
// Sorting is server-side because paging is: ordering only the rows the
// client holds would sort one page, not the log (#2636).
sortBy?: string;
sortDir?: 'asc' | 'desc';
}) => {
const searchParams = new URLSearchParams();
if (params?.search) searchParams.set('search', params.search);
@@ -4846,6 +4850,8 @@ export const api = {
if (params?.dateTo) searchParams.set('date_to', params.dateTo);
if (params?.limit) searchParams.set('limit', String(params.limit));
if (params?.offset !== undefined) searchParams.set('offset', String(params.offset));
if (params?.sortBy) searchParams.set('sort_by', params.sortBy);
if (params?.sortDir) searchParams.set('sort_dir', params.sortDir);
return request<PrintLogResponse>(`/print-log/?${searchParams}`);
},
getPrintLogThumbnail: (id: number) => withStreamToken(`${API_BASE}/print-log/${id}/thumbnail`),