mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-18 21:47:39 +02:00
Keep the printer's name on statistics after it is deleted (issue #2873)
Every per-printer breakdown resolved the name against the printers that exist now, so deleting a printer and choosing to keep its prints turned "Ultron" into "Printer 1" in Prints by Printer, the success-rate and time-accuracy lists, and Failures by Printer. Archives lose their printer on that delete as well, so nothing was left to read a name from. The runs themselves recorded the name they printed on. /archives/stats now reports the last name each id was known by - taken from the newest run that has one, so a later name-less row cannot blank it - and failure analysis falls back to the same thing for ids with no printer left. The client keeps preferring a live printer's own record, so a rename still shows up straight away rather than after the next print.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* Tests for the StatsPage component.
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { render } from '../utils';
|
||||
import { StatsPage } from '../../pages/StatsPage';
|
||||
@@ -621,4 +621,46 @@ describe('StatsPage', () => {
|
||||
expect(printTime?.querySelector('svg[aria-label]')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleted printers (#2873)', () => {
|
||||
// The per-printer breakdown only renders at half width, and the dashboard
|
||||
// reads its sizes back from localStorage.
|
||||
const halfWidthSuccessRate = JSON.stringify({
|
||||
order: ['success-rate'],
|
||||
hidden: [],
|
||||
sizes: { 'success-rate': 2 },
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.mocked(localStorage.getItem).mockReset();
|
||||
});
|
||||
|
||||
it('labels history from a deleted printer with the name it ran under', async () => {
|
||||
vi.mocked(localStorage.getItem).mockImplementation((key: string) =>
|
||||
key === 'bambusy-dashboard-layout-v2' ? halfWidthSuccessRate : null
|
||||
);
|
||||
server.use(
|
||||
http.get('/api/v1/archives/stats', () =>
|
||||
HttpResponse.json({
|
||||
...mockStats,
|
||||
// Printer 7 was deleted with its prints kept, so it is missing from
|
||||
// /printers and used to show as "Printer 7".
|
||||
prints_by_printer: { '1': 100, '7': 12 },
|
||||
printer_names: { '1': 'Name At The Time', '7': 'Ultron' },
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
render(<StatsPage />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Ultron')).toBeInTheDocument();
|
||||
});
|
||||
expect(screen.queryByText('Printer 7')).not.toBeInTheDocument();
|
||||
// A printer that still exists is named from the live record instead, so a
|
||||
// rename shows up without waiting for the next print.
|
||||
expect(screen.getAllByText('X1 Carbon').length).toBeGreaterThan(0);
|
||||
expect(screen.queryByText('Name At The Time')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -813,6 +813,9 @@ export interface ArchiveStats {
|
||||
total_cost: number;
|
||||
prints_by_filament_type: Record<string, number>;
|
||||
prints_by_printer: Record<string, number>;
|
||||
// Name each printer id was last recorded under in the print log, so history
|
||||
// belonging to a deleted printer keeps its label.
|
||||
printer_names?: Record<string, string>;
|
||||
average_time_accuracy: number | null;
|
||||
time_accuracy_by_printer: Record<string, number> | null;
|
||||
total_energy_kwh: number;
|
||||
|
||||
@@ -1103,7 +1103,18 @@ export function StatsPage() {
|
||||
const isRefetching = (isStatsFetching || isArchivesFetching) && !isLoading;
|
||||
|
||||
const currency = getCurrencySymbol(settings?.currency || 'USD');
|
||||
const printerMap = new Map(printers?.map((p) => [String(p.id), p.name]) || []);
|
||||
// History outlives the printer that made it: a deleted printer is gone from
|
||||
// `printers`, so its rows fell back to "Printer 1" (#2873). The stats response
|
||||
// carries the name each id was last recorded under; a printer that still
|
||||
// exists overrides it, so a rename shows up straight away.
|
||||
const printerMap = useMemo(
|
||||
() =>
|
||||
new Map<string, string>([
|
||||
...Object.entries(stats?.printer_names || {}),
|
||||
...(printers?.map((p) => [String(p.id), p.name] as [string, string]) || []),
|
||||
]),
|
||||
[stats?.printer_names, printers],
|
||||
);
|
||||
const printDates = useMemo(() => archives?.map((a) => a.created_at) || [], [archives]);
|
||||
|
||||
if (isLoading) {
|
||||
|
||||
Reference in New Issue
Block a user