import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { Circle, RotateCcw, Palette } from 'lucide-react'; import { getColorName } from '../../utils/colors'; import { canonicalFilamentType } from '../../utils/amsHelpers'; import type { FilamentReqsData } from './types'; interface FilamentOverrideProps { filamentReqs: FilamentReqsData | undefined; availableFilaments: Array<{ type: string; color: string; tray_info_idx: string; tray_sub_brands: string; extruder_id: number | null }>; overrides: Record; onChange: (overrides: Record) => void; /** Per-slot force color match flags. Defaults to false (opt-in) when not provided. */ forceColorMatch?: Record; /** Called when a slot's force color match checkbox is toggled. */ onForceColorMatchChange?: (slotId: number, value: boolean) => void; } /** * Filament override UI for model-based queue assignment. * Allows users to override the 3MF's original filament choices with * filaments available across printers of the selected model. */ export function FilamentOverride({ filamentReqs, availableFilaments, overrides, onChange, forceColorMatch, onForceColorMatchChange, }: FilamentOverrideProps) { const { t } = useTranslation(); // Index available filaments by canonical type for per-slot filtering. // Types in the same equivalence group (e.g. PA-CF / PA12-CF / PAHT-CF) share one bucket. const filamentsByType = useMemo(() => { const map: Record> = {}; for (const f of availableFilaments) { const key = canonicalFilamentType(f.type); if (!map[key]) map[key] = []; map[key].push(f); } return map; }, [availableFilaments]); const filaments = filamentReqs?.filaments; if (!filaments || filaments.length === 0 || availableFilaments.length === 0) { return null; } const handleChange = (slotId: number, value: string) => { if (value === '') { // Reset to original const next = { ...overrides }; delete next[slotId]; onChange(next); } else { // Parse "TYPE|COLOR" value const [type, color] = value.split('|'); onChange({ ...overrides, [slotId]: { type, color } }); } }; return (
{t('printModal.filamentOverride')}

{t('printModal.filamentOverrideHint')}

{filaments.map((req) => { const override = overrides[req.slot_id]; const isOverridden = !!override; // Only show filaments of the same type AND compatible nozzle/extruder const sameType = filamentsByType[canonicalFilamentType(req.type)] || []; // On dual-nozzle printers (H2D), filter to filaments on the correct extruder. // nozzle_id from 3MF maps to extruder_id from AMS. If nozzle_id is undefined // (single-nozzle) or extruder_id is null, no nozzle filtering is needed. const compatible = req.nozzle_id != null ? sameType.filter((f) => f.extruder_id == null || f.extruder_id === req.nozzle_id) : sameType; return (
{/* Original color swatch */} {/* Original type + grams */} {req.type} ({req.used_grams}g) {/* Arrow */} {/* Override dropdown — only compatible (same-type) filaments */} {/* Reset button */} {isOverridden ? ( ) : ( )}
{/* Force Color Match checkbox — shown below each filament row */}
); })}
); }