// PrinterSelect.js import PropTypes from 'prop-types' import { Tree, Card, Spin, Space, Button, message } from 'antd' import { LoadingOutlined, ReloadOutlined } from '@ant-design/icons' import React, { useState, useEffect, useContext, useCallback } from 'react' import PrinterState from './PrinterState' import axios from 'axios' import { SocketContext } from '../context/SocketContext' import SubJobState from './SubJobState' const SubJobsTree = ({ printJobData }) => { const [treeData, setTreeData] = useState([]) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const { socket } = useContext(SocketContext) const [messageApi] = message.useMessage() const [expandedKeys, setExpandedKeys] = useState([]) const [currentPrintJobData, setCurrentPrintJobData] = useState(null) const buildTreeData = useCallback( (jobData) => { if (!jobData?.subJobs?.length) { setTreeData([]) setExpandedKeys([]) return } // Create tree nodes for each printer const printerNodes = jobData.printers.map((printerData) => { // Find subjobs for this printer const printerSubJobs = jobData.subJobs.filter( (subJob) => subJob.printer === printerData.id ) setExpandedKeys((prev) => [...prev, `printer-${printerData.id}`]) return { title: printerData.state ? ( ) : ( } /> ), key: `printer-${printerData.id}`, children: printerSubJobs.map((subJob) => { return { title: ( ), key: `subjob-${subJob._id}`, isLeaf: true } }) } }) setTreeData(printerNodes) }, [expandedKeys] ) useEffect(() => { buildTreeData(currentPrintJobData) }, [currentPrintJobData]) useEffect(() => { const initializeData = async () => { if (!printJobData) { try { setLoading(true) const response = await axios.get('http://localhost:8080/printjobs', { headers: { Accept: 'application/json' }, withCredentials: true }) if (response.data) { setCurrentPrintJobData(response.data) } } catch (err) { setError('Failed to fetch print job details') messageApi.error('Failed to fetch print job details') } finally { setLoading(false) } } else { setCurrentPrintJobData(printJobData) } } initializeData() // Add socket.io event listener for deployment updates if (socket) { socket.on('notify_deployment_update', (updateData) => { console.log('Received deployment update:', updateData) setCurrentPrintJobData((prevData) => { if (!prevData) return prevData // Handle printer updates if (updateData.printerId) { return { ...prevData, printers: prevData.printers.map((printer) => { if ( printer.id === updateData.printerId && updateData.state == 'deploying' ) { return { ...printer, deploymentProgress: updateData.progress } } else if ( printer.id === updateData.printerId && updateData.state == 'complete' ) { return { ...printer, deploymentProgress: undefined } } return printer }) } } return prevData }) }) socket.on('notify_subjob_update', (updateData) => { // Handle sub-job updates if (updateData.subJobId) { console.log('Received subjob update:', updateData) setCurrentPrintJobData((prevData) => { if (!prevData) return prevData return { ...prevData, // eslint-disable-next-line camelcase subJobs: prevData.subJobs.map((subJob) => { if (subJob._id === updateData.id) { return { ...subJob, state: updateData.state, subJobId: updateData.subJobId } } return subJob }) } }) } }) } return () => { if (socket) { socket.off('notify_deployment_update') } } }, [printJobData, socket]) if (loading) { return (
} />
) } if (error) { return (

{error}

) } return ( ) } SubJobsTree.propTypes = { printJobData: PropTypes.object.isRequired } export default SubJobsTree