import { useState, useContext, useEffect } from 'react' import { Form, Flex, Descriptions, Alert } from 'antd' import PropTypes from 'prop-types' import PrinterTemperaturePanel from '../../common/PrinterTemperaturePanel' import { LoadingOutlined } from '@ant-design/icons' import ObjectSelect from '../../common/ObjectSelect' import ObjectDisplay from '../../common/ObjectDisplay' import WizardView from '../../common/WizardView' import { ApiServerContext } from '../../context/ApiServerContext' const LoadFilamentStock = ({ onOk, reset, printer = null, filamentStockLoaded = false }) => { const { connected, subscribeToObjectEvent, sendObjectAction } = useContext(ApiServerContext) LoadFilamentStock.propTypes = { onOk: PropTypes.func.isRequired, reset: PropTypes.bool.isRequired, printer: PropTypes.object, filamentStockLoaded: PropTypes.bool } const initialLoadFilamentStockForm = { printer: printer, filamentStock: null } const [loadFilamentStockLoading, setLoadFilamentStockLoading] = useState(false) const [formValid, setFormValid] = useState(false) const [currentTemperature, setCurrentTemperature] = useState(-1) const [targetTemperature, setTargetTemperature] = useState(0) const [filamentSensorDetected, setFilamentSensorDetected] = useState(filamentStockLoaded) const [loadFilamentStockForm] = Form.useForm() const [loadFilamentStockFormValues, setLoadFilamentStockFormValues] = useState(initialLoadFilamentStockForm) const loadFilamentStockFormUpdateValues = Form.useWatch( [], loadFilamentStockForm ) useEffect(() => { if (printer?._id && connected) { const temperatureEventUnsubscribe = subscribeToObjectEvent( printer._id, 'printer', 'temperature', (event) => { if (event.data?.extruder?.current) { setCurrentTemperature(event.data.extruder.current) } if (event.data?.extruder?.target) { setTargetTemperature(event.data.extruder.target) } } ) const filamentStockEventUnsubscribe = subscribeToObjectEvent( printer._id, 'printer', 'filamentSensor', (event) => { console.log('filamentSensor', event.data) setFilamentSensorDetected(event.data.detected) } ) return () => { if (temperatureEventUnsubscribe) temperatureEventUnsubscribe() if (filamentStockEventUnsubscribe) filamentStockEventUnsubscribe() } } }, [printer?._id, connected]) useEffect(() => { // Validate form fields loadFilamentStockForm .validateFields({ validateOnly: true }) .then(() => { const hasPrinter = Boolean(loadFilamentStockFormValues.printer) const hasFilamentStock = Boolean( loadFilamentStockFormValues.filamentStock ) // Step 0 (Preheat): needs printer + filament detected + (temp reached or no temp set) const preheatReady = hasPrinter && filamentSensorDetected && (targetTemperature === 0 || currentTemperature >= targetTemperature) // Step 1+ (Required/Summary): needs filamentStock selected // Form is valid if preheat is ready (for step 0) OR filamentStock is selected (for step 1+) // This allows progression: step 0 can proceed when preheat is ready, // and step 1+ can proceed when filamentStock is selected setFormValid(preheatReady || (hasPrinter && hasFilamentStock)) }) .catch(() => setFormValid(false)) }, [ loadFilamentStockForm, loadFilamentStockFormUpdateValues, loadFilamentStockFormValues, filamentSensorDetected, currentTemperature, targetTemperature ]) const summaryItems = [ { key: 'filamentStock', label: 'Stock', children: loadFilamentStockFormValues.filamentStock ? ( ) : ( 'n/a' ) }, { key: 'printer', label: 'Printer', children: loadFilamentStockFormValues.printer ? ( ) : ( 'n/a' ) } ] useEffect(() => { if (reset) { loadFilamentStockForm.resetFields() } }, [reset, loadFilamentStockForm]) const handleLoadFilamentStock = async () => { setLoadFilamentStockLoading(true) try { // Set the extruder temperature await sendObjectAction( loadFilamentStockFormValues.printer._id, 'printer', { type: 'loadFilamentStock', data: { filamentStock: loadFilamentStockFormValues.filamentStock } } ) onOk() } finally { setLoadFilamentStockLoading(false) } } const steps = [ { title: 'Preheat', key: 'preHeat', content: ( {targetTemperature == 0 ? ( ) : null} {targetTemperature > 0 && currentTemperature < targetTemperature ? ( } /> ) : null} {targetTemperature > 0 && currentTemperature >= targetTemperature && filamentSensorDetected == false ? ( ) : null} {loadFilamentStockFormValues.printer ? ( ) : null} ) }, { title: 'Required', key: 'required', content: ( <> ) }, { title: 'Summary', key: 'summary', content: ( ) } ] return (
setLoadFilamentStockFormValues((prevValues) => ({ ...prevValues, ...changedValues })) } initialValues={initialLoadFilamentStockForm} > loadFilamentStockForm.submit()} formValid={formValid} loading={loadFilamentStockLoading} submitText='Done' /> ) } export default LoadFilamentStock