diff --git a/src/components/Dashboard/Production/GCodeFiles/NewGCodeFile.jsx b/src/components/Dashboard/Production/GCodeFiles/NewGCodeFile.jsx index 69f0988..5f50977 100644 --- a/src/components/Dashboard/Production/GCodeFiles/NewGCodeFile.jsx +++ b/src/components/Dashboard/Production/GCodeFiles/NewGCodeFile.jsx @@ -1,554 +1,89 @@ import PropTypes from 'prop-types' -import { useState, useContext, useEffect } from 'react' -import axios from 'axios' -import { useMediaQuery } from 'react-responsive' -import { - capitalizeFirstLetter, - timeStringToMinutes -} from '../../utils/Utils.js' -import { - Form, - Input, - Button, - message, - Typography, - Flex, - Steps, - Divider, - Upload, - Descriptions, - Checkbox, - Spin, - InputNumber, - Badge -} from 'antd' -import { LoadingOutlined } from '@ant-design/icons' - -import { AuthContext } from '../../context/AuthContext.jsx' - -import GCodeFileIcon from '../../../Icons/GCodeFileIcon' - -import FilamentSelect from '../../common/FilamentSelect' - -import config from '../../../../config.js' - -const { Dragger } = Upload - -const { Title } = Typography - -const initialNewGCodeFileForm = { - gcodeFileInfo: {}, - name: '', - printTimeMins: 0, - cost: 0, - file: null, - filament: null -} - -//const chunkSize = 5000 - -const NewGCodeFile = ({ onOk, reset }) => { - const [messageApi] = message.useMessage() - const isMobile = useMediaQuery({ maxWidth: 768 }) - - const [newGCodeFileLoading, setNewGCodeFileLoading] = useState(false) - const [gcodeParsing, setGcodeParsing] = useState(false) - - const [filamentSelectFilter, setFilamentSelectFilter] = useState(null) - const [useFilamentSelectFilter, setUseFilamentSelectFilter] = useState(true) - - const [currentStep, setCurrentStep] = useState(0) - const [nextEnabled, setNextEnabled] = useState(false) - const [nextLoading, setNextLoading] = useState(false) - - const [newGCodeFileForm] = Form.useForm() - const [newGCodeFileFormValues, setNewGCodeFileFormValues] = useState( - initialNewGCodeFileForm - ) - - const [gcodeFile, setGCodeFile] = useState(null) - - const newGCodeFileFormUpdateValues = Form.useWatch([], newGCodeFileForm) - - const { token, authenticated } = useContext(AuthContext) - // eslint-disable-next-line - const fetchFilamentInfo = async () => { - if (!authenticated) { - return - } - if ( - newGCodeFileFormValues.filament && - newGCodeFileFormValues.gcodeFileInfo - ) { - try { - setNextLoading(true) - const response = await axios.get( - `${config.backendUrl}/filaments/${newGCodeFileFormValues.filament}`, - { - headers: { - Accept: 'application/json' - }, - withCredentials: true // Important for including cookies - } - ) - setNextLoading(false) - - const price = - (response.data.price / 1000) * - newGCodeFileFormValues.gcodeFileInfo.filament_used_g // convert kg to g and multiply - - const printTimeMins = timeStringToMinutes( - newGCodeFileFormValues.gcodeFileInfo - .estimated_printing_time_normal_mode - ) - setNewGCodeFileFormValues({ - ...newGCodeFileFormValues, - price, - printTimeMins - }) - } catch (error) { - if (error.response) { - messageApi.error( - 'Error fetching filament data:', - error.response.status - ) - } else { - messageApi.error( - 'An unexpected error occurred. Please try again later.' - ) - } - } - } - } - - useEffect(() => { - newGCodeFileForm - .validateFields({ - validateOnly: true - }) - .then(() => setNextEnabled(true)) - .catch(() => setNextEnabled(false)) - }, [newGCodeFileForm, newGCodeFileFormUpdateValues]) - - const summaryItems = [ - { - key: 'name', - label: 'Name', - children: newGCodeFileFormValues?.name - }, - { - key: 'filament', - label: 'Filament', - children: - newGCodeFileFormValues?.filament != null ? ( - <> - {newGCodeFileFormValues.filament} - - - ) : ( - 'n/a' - ) - }, - { - key: 'cost', - label: 'Cost', - children: '£' + newGCodeFileFormValues?.cost - }, - { - key: 'sparse_infill_density', - label: 'Infill Density', - children: newGCodeFileFormValues?.gcodeFileInfo?.sparseInfillDensity - }, - { - key: 'sparse_infill_pattern', - label: 'Infill Pattern', - children: capitalizeFirstLetter( - newGCodeFileFormValues?.gcodeFileInfo?.sparseInfillPattern - ) - }, - { - key: 'layer_height', - label: 'Layer Height', - children: newGCodeFileFormValues?.gcodeFileInfo?.layerHeight + 'mm' - }, - { - key: 'filamentType', - label: 'Filament Material', - children: newGCodeFileFormValues?.gcodeFileInfo?.filamentType - }, - { - key: 'filamentUsedG', - label: 'Filament Used (g)', - children: newGCodeFileFormValues?.gcodeFileInfo?.filamentUsedG + 'g' - }, - { - key: 'filamentVendor', - label: 'Filament Brand', - children: newGCodeFileFormValues?.gcodeFileInfo?.filamentVendor - }, - - { - key: 'hotendTemperature', - label: 'Hotend Temperature', - children: newGCodeFileFormValues?.gcodeFileInfo?.nozzleTemperature + '°' - }, - { - key: 'bedTemperature', - label: 'Bed Temperature', - children: newGCodeFileFormValues?.gcodeFileInfo?.hotPlateTemp + '°' - }, - { - key: 'estimated_printing_time_normal_mode', - label: 'Est. Print Time', - children: - newGCodeFileFormValues?.gcodeFileInfo?.estimatedPrintingTimeNormalMode - } - ] - - useEffect(() => { - if (reset) { - setCurrentStep(0) - newGCodeFileForm.resetFields() - } - }, [reset, newGCodeFileForm]) - - useEffect(() => { - const filamentCost = newGCodeFileFormValues?.filament?.cost - const gcodeFilamentUsed = - newGCodeFileFormValues?.gcodeFileInfo?.filamentUsedG - if (filamentCost && gcodeFilamentUsed) { - const cost = (filamentCost / 1000) * gcodeFilamentUsed - setNewGCodeFileFormValues((prev) => ({ ...prev, cost: cost.toFixed(2) })) - newGCodeFileForm.setFieldValue('cost', cost.toFixed(2)) - } - }, [ - newGCodeFileForm, - newGCodeFileFormValues?.filament?.cost, - newGCodeFileFormValues?.gcodeFileInfo?.filamentUsedG - ]) - - const handleNewGCodeFileUpload = async (id) => { - setNewGCodeFileLoading(true) - const formData = new FormData() - formData.append('gcodeFile', gcodeFile) - try { - await axios.post( - `${config.backendUrl}/gcodefiles/${id}/content`, - formData, - { - headers: { - 'Content-Type': 'multipart/form-data', - Authorization: `Bearer ${token}` - } - } - ) - - resetForm() - onOk() - } catch (error) { - messageApi.error('Error creating new gcode file: ' + error.message) - } finally { - setNewGCodeFileLoading(false) - } - } - - const handleNewGCodeFile = async () => { - setNewGCodeFileLoading(true) - try { - const request = await axios.post( - `${config.backendUrl}/gcodefiles`, - newGCodeFileFormValues, - { - headers: { - Authorization: `Bearer ${token}` - } - } - ) - messageApi.info('New G Code file created successfully. Uploading...') - handleNewGCodeFileUpload(request.data._id) - } catch (error) { - messageApi.error('Error creating new gcode file: ' + error.message) - } finally { - setNewGCodeFileLoading(false) - } - } - - const handleGetGCodeFileInfo = async (file) => { - try { - setGcodeParsing(true) - // Create a FormData object to send the file - const formData = new FormData() - formData.append('gcodeFile', file) - - // Call the API to extract and parse the config block - const request = await axios.post( - `${config.backendUrl}/gcodefiles/content`, - formData, - { - withCredentials: true // Important for including cookies - }, - { - headers: { - Accept: 'application/json' - } - } - ) - - // Parse the API response - const parsedConfig = await request.data - - // Update state with the parsed config from API - setNewGCodeFileFormValues({ - ...newGCodeFileFormValues, - gcodeFileInfo: parsedConfig - }) - - // Update filter settings if filament info is available - if (parsedConfig.filament_type && parsedConfig.filament_diameter) { - setFilamentSelectFilter({ - type: parsedConfig.filament_type, - diameter: parsedConfig.filament_diameter - }) - } - const fileName = file.name.replace(/\.[^/.]+$/, '') - newGCodeFileForm.setFieldValue('name', fileName) - setNewGCodeFileFormValues((prev) => ({ - ...prev, - name: fileName - })) - setGCodeFile(file) - setGcodeParsing(false) - setCurrentStep(currentStep + 1) - } catch (error) { - console.error('Error getting G-code file info:', error) - } - } - - const resetForm = () => { - newGCodeFileForm.setFieldsValue(initialNewGCodeFileForm) - setNewGCodeFileFormValues(initialNewGCodeFileForm) - setGCodeFile(null) - setGcodeParsing(false) - setCurrentStep(0) - } - - const steps = [ - { - title: 'Upload', - key: 'upload', - content: ( - <> - (Array.isArray(e) ? e : e && e.fileList)} - > - { - handleGetGCodeFileInfo(file) - setTimeout(() => { - onSuccess('ok') - }, 0) - }} - > - - {gcodeParsing == true ? ( - - } - /> - ) : ( - <> -

- -

-

- Click or drag gcode file here. -

-

- Supported file extentions: .gcode, .gco, .g -

- - )} -
-
-
- - ) - }, - { - title: 'Details', - key: 'details', - content: ( - <> - - - - - - - - - - - { - setUseFilamentSelectFilter(e.target.checked) - }} - > - Filter - - - - - - - - ) - }, - { - title: 'Summary', - key: 'done', - content: ( - <> - - - - - ) - } - ] +import ObjectInfo from '../../common/ObjectInfo' +import NewObjectForm from '../../common/NewObjectForm' +import WizardView from '../../common/WizardView' +const NewGCodeFile = ({ onOk }) => { return ( - - {!isMobile && ( -
- -
- )} - - {!isMobile && } - - - - New G Code File - -
- setNewGCodeFileFormValues((prevValues) => ({ - ...prevValues, - ...changedValues - })) - } - initialValues={initialNewGCodeFileForm} - > -
{steps[currentStep].content}
- - - - {currentStep < steps.length - 1 && ( - - )} - {currentStep === steps.length - 1 && ( - - )} - -
-
-
+ isEditing={false} + objectData={objectData} + /> + ) + } + ] + return ( + { + handleSubmit() + onOk() + }} + /> + ) + }} + ) } NewGCodeFile.propTypes = { - reset: PropTypes.bool.isRequired, - onOk: PropTypes.func.isRequired + onOk: PropTypes.func.isRequired, + reset: PropTypes.bool } export default NewGCodeFile