mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-22 03:49:18 +02:00
Selecting several sliced files and pressing Print now creates one queue item carrying all of them, instead of hiding the Print button the moment a second file is selected. The printer picker is replaced by the ordered candidate list, since choosing these files is already the answer to "which printer" and the only question left is which is preferred. Per-candidate configuration is the plate only. Model-based assignment sends no AMS mapping — the printer is unknown until dispatch, where the scheduler derives it — so a per-candidate mapping editor would collect choices it then discards. Filament overrides stay shared: "this job needs PETG" holds for every slice of the same job. Adds Group as versions for durable grouping, a versions badge counting the whole group rather than the rows on screen, and a queue card label naming every model a pending item is waiting on.
This commit is contained in:
@@ -2203,6 +2203,15 @@ export interface PrintQueueItem {
|
||||
target_location: string | null; // Target location filter for model-based assignment
|
||||
required_filament_types: string[] | null; // Required filament types for model-based assignment
|
||||
waiting_reason: string | null; // Why a model-based job hasn't started yet
|
||||
// Cross-model alternatives (#671), in priority order. Empty for ordinary
|
||||
// items. Present until dispatch resolves one, after which library_file_id and
|
||||
// target_model name the candidate that actually ran.
|
||||
variants?: Array<{
|
||||
library_file_id: number;
|
||||
filename: string;
|
||||
target_model: string;
|
||||
position: number;
|
||||
}>;
|
||||
// Either archive_id OR library_file_id must be set (archive created at print start)
|
||||
archive_id: number | null;
|
||||
library_file_id: number | null;
|
||||
@@ -2324,6 +2333,22 @@ export interface PrintQueueItemCreate {
|
||||
project_id?: number;
|
||||
// Delete transient uploaded library file after scheduler creates the archive
|
||||
cleanup_library_after_dispatch?: boolean;
|
||||
// Cross-model alternatives (#671): several sliced files, one job, whichever
|
||||
// printer frees up first. Mutually exclusive with printer_id (a named printer
|
||||
// defeats the point) and with archive_id/library_file_id (these ARE the files).
|
||||
// Order is priority — index 0 wins when several printers are idle at once.
|
||||
variants?: QueueVariantCreate[];
|
||||
}
|
||||
|
||||
/** One candidate file for a cross-model queue item (#671). */
|
||||
export interface QueueVariantCreate {
|
||||
library_file_id: number;
|
||||
/** Read from the file's own sliced_for_model unless it declares none. */
|
||||
target_model?: string | null;
|
||||
plate_id?: number | null;
|
||||
ams_mapping?: number[] | null;
|
||||
nozzle_mapping?: number[] | null;
|
||||
filament_overrides?: Array<{ slot_id: number; type: string; color: string; color_name?: string; force_color_match?: boolean }> | null;
|
||||
}
|
||||
|
||||
export interface PrintBatchCreate {
|
||||
@@ -6289,6 +6314,50 @@ export const api = {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ file_ids: fileIds, tag_ids: tagIds, action }),
|
||||
}),
|
||||
// ============ Variant groups (#671 / #2570) ============
|
||||
// "These files are the same job sliced for different printers." Consumed from
|
||||
// both ends: the queue picks a printer and needs the matching file, the File
|
||||
// Manager's print action has the printer and needs the same match.
|
||||
createVariantGroup: (
|
||||
members: { library_file_id: number; target_model?: string }[],
|
||||
name?: string,
|
||||
) =>
|
||||
request<VariantGroup>('/library/variant-groups', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ members, ...(name ? { name } : {}) }),
|
||||
}),
|
||||
getVariantGroup: (groupId: number) =>
|
||||
request<VariantGroup>(`/library/variant-groups/${groupId}`),
|
||||
/** Returns null when the file is not grouped, rather than throwing on the 404. */
|
||||
getVariantGroupForFile: async (fileId: number): Promise<VariantGroup | null> => {
|
||||
try {
|
||||
return await request<VariantGroup>(`/library/variant-groups/by-file/${fileId}`);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
updateVariantGroup: (groupId: number, body: { name?: string; member_file_ids?: number[] }) =>
|
||||
request<VariantGroup>(`/library/variant-groups/${groupId}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(body),
|
||||
}),
|
||||
addVariantGroupMember: (
|
||||
groupId: number,
|
||||
libraryFileId: number,
|
||||
targetModel?: string,
|
||||
) =>
|
||||
request<VariantGroup>(`/library/variant-groups/${groupId}/members`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
library_file_id: libraryFileId,
|
||||
...(targetModel ? { target_model: targetModel } : {}),
|
||||
}),
|
||||
}),
|
||||
removeVariantGroupMember: (groupId: number, fileId: number) =>
|
||||
request<void>(`/library/variant-groups/${groupId}/members/${fileId}`, { method: 'DELETE' }),
|
||||
deleteVariantGroup: (groupId: number) =>
|
||||
request<void>(`/library/variant-groups/${groupId}`, { method: 'DELETE' }),
|
||||
|
||||
getLibraryFile: (id: number) => request<LibraryFile>(`/library/files/${id}`),
|
||||
uploadLibraryFile: async (
|
||||
file: File,
|
||||
@@ -6988,6 +7057,26 @@ export interface LibraryFileListItem {
|
||||
// legacy code path (or mock) that constructs a LibraryFileListItem without
|
||||
// it doesn't crash the renderer. Read sites use `file.tags ?? []`.
|
||||
tags?: LibraryTagSummary[];
|
||||
// Variant grouping (#671 / #2570). `variant_count` is the size of the whole
|
||||
// group, which may include files in other folders — never the number of
|
||||
// matching rows on screen. 0 when the file is not grouped.
|
||||
variant_group_id?: number | null;
|
||||
variant_count?: number;
|
||||
}
|
||||
|
||||
// Variant groups (#671 / #2570): the same job sliced for different printers.
|
||||
export interface VariantGroupMember {
|
||||
library_file_id: number;
|
||||
filename: string;
|
||||
target_model: string;
|
||||
position: number;
|
||||
}
|
||||
|
||||
export interface VariantGroup {
|
||||
id: number;
|
||||
name: string;
|
||||
/** In priority order — index 0 wins when several printers are free at once. */
|
||||
members: VariantGroupMember[];
|
||||
}
|
||||
|
||||
// Library tag catalog (#1268)
|
||||
|
||||
Reference in New Issue
Block a user