import { useState } from 'react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { Loader2, Sparkles, Trash2, Wand2 } from 'lucide-react'; import { api } from '../api/client'; import type { ProfileDefault } from '../api/client'; import { useToast } from '../contexts/ToastContext'; import { Button } from './Button'; import { Card, CardContent, CardHeader } from './Card'; import { ConfirmModal } from './ConfirmModal'; /** * Settings > Filament > Profile defaults (#1326): what new spools of each * product start with. A default is saved from a spool's Printers tab ("Save as * default"), which is also how one is changed: this card lists them, applies * one to the spools already in stock, and deletes one. */ export function ProfileDefaultsSettings() { const { t } = useTranslation(); const { showToast } = useToast(); const queryClient = useQueryClient(); const [deleting, setDeleting] = useState(null); const { data: defaults = [], isLoading } = useQuery({ queryKey: ['profile-defaults'], queryFn: api.getProfileDefaults, }); const { data: printers = [] } = useQuery({ queryKey: ['printers'], queryFn: api.getPrinters }); // Applying writes to the spools of the inventory in use. const { data: spoolmanSettings } = useQuery({ queryKey: ['spoolman-settings'], queryFn: api.getSpoolmanSettings, staleTime: 5 * 60 * 1000, }); const spoolmanMode = spoolmanSettings?.spoolman_enabled === 'true' && !!spoolmanSettings?.spoolman_url; const printerName = (id: number) => printers.find((p) => p.id === id)?.name ?? `#${id}`; const applyMutation = useMutation({ mutationFn: (row: ProfileDefault) => api.applyProfileDefault(row.id, spoolmanMode), onSuccess: async ({ updated }) => { showToast(t('inventory.profileDefaults.applied', { count: updated }), 'success'); await queryClient.invalidateQueries({ queryKey: ['inventory-spools'] }); await queryClient.invalidateQueries({ queryKey: ['spoolman-inventory-spools'] }); }, onError: () => showToast(t('inventory.profileDefaults.applyFailed'), 'error'), }); const deleteMutation = useMutation({ mutationFn: (row: ProfileDefault) => api.deleteProfileDefault(row.id), onSuccess: async () => { setDeleting(null); await queryClient.invalidateQueries({ queryKey: ['profile-defaults'] }); }, onError: () => { setDeleting(null); showToast(t('inventory.profileDefaults.deleteFailed'), 'error'); }, }); const productOf = (row: ProfileDefault) => [row.brand, row.material, row.subtype].filter((part) => part.trim()).join(' '); return (

{t('inventory.profileDefaults.title')}

{t('inventory.profileDefaults.description')}

{isLoading ? (
) : defaults.length === 0 ? (

{t('inventory.profileDefaults.empty')}

) : (
    {defaults.map((row) => (
  • {productOf(row)} {row.color_name || t('inventory.profileDefaults.allColours')}

      {row.slicer_filament && (
    • {t('inventory.filamentPreset')}: {row.slicer_filament_name || row.slicer_filament}
    • )} {row.presets.map((p) => (
    • {p.printer_model} {p.nozzle_diameter ? ` ${p.nozzle_diameter} mm` : ''}: {p.slicer_filament_name || p.slicer_filament}
    • ))} {row.k_profiles.map((k) => (
    • {`${printerName(k.printer_id)} ${k.nozzle_diameter ?? '0.4'} mm: ${k.name || '-'} K=${k.k_value.toFixed(3)}`} {(k.extruder ?? 0) > 0 ? ` (${t('inventory.leftNozzle')})` : ''}
    • ))}
  • ))}
)}
{deleting && ( deleteMutation.mutate(deleting)} onCancel={() => setDeleting(null)} /> )}
); }