Add queue bulk editing and fix milestone time display

New Features:
- Queue bulk edit: Select multiple pending items and edit printer
  assignment, print options, or cancel them at once (Issue #159)
- Tri-state toggles (unchanged/on/off) for selective field updates

Fixes:
- Progress milestone notifications showed wrong time (e.g., "17m" instead
  of "17h 47m") - fixed by converting remaining_time from minutes to
  seconds (Issue #157)
- File Manager folder names now show full name on hover tooltip (Issue #160)

Backend:
- Added PATCH /queue/bulk endpoint for bulk updates
- Route ordering fixed to prevent /bulk matching as /{item_id}

Frontend:
- Added checkbox selection to pending queue items
- Added bulk action toolbar with Select All, Edit Selected, Cancel Selected
- Created BulkEditModal with tri-state toggles for each setting

Tests:
- Added 7 integration tests for bulk update endpoint

Closes #159
This commit is contained in:
maziggy
2026-01-27 09:35:28 +01:00
parent 60d9505c0d
commit e57fb87a52
9 changed files with 9360 additions and 8731 deletions
+27
View File
@@ -1065,6 +1065,28 @@ export interface PrintQueueItemUpdate {
use_ams?: boolean;
}
export interface PrintQueueBulkUpdate {
item_ids: number[];
printer_id?: number | null;
scheduled_time?: string | null;
require_previous_success?: boolean;
auto_off_after?: boolean;
manual_start?: boolean;
// Print options
bed_levelling?: boolean;
flow_cali?: boolean;
vibration_cali?: boolean;
layer_inspect?: boolean;
timelapse?: boolean;
use_ams?: boolean;
}
export interface PrintQueueBulkUpdateResponse {
updated_count: number;
skipped_count: number;
message: string;
}
// MQTT Logging types
export interface MQTTLogEntry {
timestamp: string;
@@ -2374,6 +2396,11 @@ export const api = {
request<{ message: string }>(`/queue/${id}/stop`, { method: 'POST' }),
startQueueItem: (id: number) =>
request<PrintQueueItem>(`/queue/${id}/start`, { method: 'POST' }),
bulkUpdateQueue: (data: PrintQueueBulkUpdate) =>
request<PrintQueueBulkUpdateResponse>('/queue/bulk', {
method: 'PATCH',
body: JSON.stringify(data),
}),
// K-Profiles
getKProfiles: (printerId: number, nozzleDiameter = '0.4') =>