mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-21 10:15:04 +02:00
feat(queue): show build plate type on queue items + print modal (#1281)
Reporter on a multi-printer farm with 40+-plate runs needed to walk to
the printer with the right physical plate, but the queue and the
scheduling modal didn't surface curr_bed_type the way the archive card
already did.
New utils/threemf_tools.extract_bed_type_from_3mf helper (per-plate) so
both the queue API and the /plates endpoint can return per-plate values.
PrintQueueItemResponse.bed_type populated from archive.bed_type /
library_file.file_metadata['bed_type'] as the default, then overridden
per-plate via the helper when item.plate_id is set. /archives/{id}/plates
(and library equivalent) include bed_type in each plate object.
Per-plate accuracy matters because archive.bed_type is captured at
ingest as only the first plate's value (services/archive.py:235) -
a 40-plate 3MF mixing PEI + Engineering returns PEI at the archive
level for every plate. The helper re-reads the 3MF and returns the
truth.
Frontend: queue card meta row + PlateSelector per-plate row + PrintModal
header all render bed icon + canonical label via the existing
getBedTypeInfo() helper, same as the archive card.
This commit is contained in:
@@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import type { PlateSelectorProps } from './types';
|
||||
import { formatDuration } from '../../utils/date';
|
||||
import { withStreamToken } from '../../api/client';
|
||||
import { getBedTypeInfo } from '../../utils/bedType';
|
||||
|
||||
/**
|
||||
* Plate selection grid for multi-plate 3MF files.
|
||||
@@ -96,6 +97,18 @@ export function PlateSelector({
|
||||
: `${plate.filaments.length} filament${plate.filaments.length !== 1 ? 's' : ''}`}
|
||||
{plate.print_time_seconds != null ? ` • ${formatDuration(plate.print_time_seconds)}` : ''}
|
||||
</p>
|
||||
{(() => {
|
||||
// Per-plate bed-type badge so multi-plate prints make the
|
||||
// required plate explicit at scheduling time (#1281).
|
||||
const bed = getBedTypeInfo(plate.bed_type);
|
||||
if (!bed) return null;
|
||||
return (
|
||||
<p className="text-xs text-bambu-gray flex items-center gap-1 mt-0.5 truncate" title={bed.label}>
|
||||
<img src={bed.icon} alt="" className="w-3.5 h-3.5 object-contain flex-shrink-0" />
|
||||
<span className="truncate">{bed.label}</span>
|
||||
</p>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
{!multiSelect && isSelected && (
|
||||
<Check className="w-4 h-4 text-bambu-green flex-shrink-0" />
|
||||
|
||||
@@ -13,6 +13,7 @@ import { buildLoadedFilaments, useFilamentMapping } from '../../hooks/useFilamen
|
||||
import { useMultiPrinterFilamentMapping, type PerPrinterConfig } from '../../hooks/useMultiPrinterFilamentMapping';
|
||||
import { getColorName } from '../../utils/colors';
|
||||
import { getCurrencySymbol } from '../../utils/currency';
|
||||
import { getBedTypeInfo } from '../../utils/bedType';
|
||||
import { toDateTimeLocalValue, parseUTCDate } from '../../utils/date';
|
||||
import { getGlobalTrayId, isPlaceholderDate } from '../../utils/amsHelpers';
|
||||
import { FilamentMapping } from './FilamentMapping';
|
||||
@@ -979,6 +980,26 @@ export function PrintModal({
|
||||
)}
|
||||
</p>
|
||||
|
||||
{/* Build-plate badge for the selected (or sole) plate — surfaced
|
||||
early so the user knows which plate to mount before scheduling
|
||||
(#1281). PlateSelector renders its own per-plate badges for
|
||||
multi-plate files; this badge covers the single-plate case and
|
||||
the multi-plate case where exactly one plate is selected. */}
|
||||
{(() => {
|
||||
if (!plates.length) return null;
|
||||
const target = selectedPlate != null
|
||||
? plates.find(p => p.index === selectedPlate)
|
||||
: plates[0];
|
||||
const bed = getBedTypeInfo(target?.bed_type);
|
||||
if (!bed) return null;
|
||||
return (
|
||||
<p className="flex items-center gap-1.5 text-xs text-bambu-gray -mt-2" title={bed.label}>
|
||||
<img src={bed.icon} alt="" className="w-4 h-4 object-contain flex-shrink-0" />
|
||||
<span className="truncate">{bed.label}</span>
|
||||
</p>
|
||||
);
|
||||
})()}
|
||||
|
||||
{/* Plate selection - first so users know filament requirements before selecting printers */}
|
||||
<PlateSelector
|
||||
plates={plates}
|
||||
|
||||
@@ -111,6 +111,7 @@ export interface PlateInfo {
|
||||
}>;
|
||||
print_time_seconds: number | null;
|
||||
filament_used_grams: number | null;
|
||||
bed_type?: string | null; // Build plate type for this plate, e.g. "Textured PEI Plate" (#1281)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user