import { useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { X } from 'lucide-react';
import type { LoadedSpoolPrinter, LoadedSpoolTray, UnifiedPresetsResponse } from '../api/client';
import { FilamentSwatch } from './FilamentSwatch';
import { formatSlotLabel, getAmsLabel, getEmptySlotKind } from '../utils/amsHelpers';
import {
matchSlotPreset,
presetDisplayName,
savedPresetFor,
trayColourHex,
type FilamentNameIndex,
type SlotMatch,
} from '../utils/sliceLoadedSpools';
import type { PrinterCompatibilityIndex } from '../utils/slicerPrinterMatch';
interface SliceSpoolPickerProps {
/** Connected printers to offer, already narrowed to the selected model. */
printers: LoadedSpoolPrinter[];
data: UnifiedPresetsResponse;
index: FilamentNameIndex;
selectedPrinterName: string | null;
compatIndex: PrinterCompatibilityIndex;
/** The filament row being filled, e.g. "Filament 2 (PLA)". */
slotLabel: string;
onPick: (match: SlotMatch, colour: string | null) => void;
onClose: () => void;
}
/**
* The spools loaded in the connected printers, laid out like the units
* themselves, for filling one filament row of the Slice dialog (#3172).
*
* Regular AMS units keep their four-slot grid, empty slots included, so the
* screen matches the machine. AMS-HT units follow, packed four to a row, then
* the external holders that have a spool in them. A loaded spool with no
* profile for the selected printer stays visible but can't be picked.
*/
export function SliceSpoolPicker({
printers,
data,
index,
selectedPrinterName,
compatIndex,
slotLabel,
onPick,
onClose,
}: SliceSpoolPickerProps) {
const { t } = useTranslation();
useEffect(() => {
const onKey = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
};
window.addEventListener('keydown', onKey);
return () => window.removeEventListener('keydown', onKey);
}, [onClose]);
return (
e.stopPropagation()}
>
{t('slice.loadedSpools.title', 'Loaded spools')}
{slotLabel}
{printers.length === 0 ? (
{t('slice.loadedSpools.none', 'No printer of this model is online.')}