- Wrapped the ObjectProperty component in a div with defined width properties to improve layout consistency and responsiveness within the SlicerIntegration component. - Ensured that the display adapts better to varying screen sizes, enhancing user experience.
234 lines
7.1 KiB
JavaScript
234 lines
7.1 KiB
JavaScript
import { useContext, useEffect, useState } from 'react'
|
|
import { Divider, Flex, Layout, Typography, Button, Badge, Modal } from 'antd'
|
|
import { LoadingOutlined } from '@ant-design/icons'
|
|
import { useLocation } from 'react-router-dom'
|
|
import ControlPrinter from './ControlPrinter.jsx'
|
|
import SlicerUploadFlow from './SlicerUploadFlow.jsx'
|
|
import PrinterIcon from '../../../Icons/PrinterIcon.jsx'
|
|
import ObjectForm from '../../common/ObjectForm.jsx'
|
|
import FileIcon from '../../../Icons/FileIcon.jsx'
|
|
import ObjectProperty from '../../common/ObjectProperty.jsx'
|
|
import { getModelProperty } from '../../../../database/ObjectModels.js'
|
|
import { ApiServerContext } from '../../context/ApiServerContext.jsx'
|
|
import { useThemeContext } from '../../context/ThemeContext.jsx'
|
|
|
|
const { Content } = Layout
|
|
const { Title } = Typography
|
|
|
|
const SlicerIntegration = () => {
|
|
const location = useLocation()
|
|
const printerId = new URLSearchParams(location.search).get('printerId')
|
|
const { updateObject } = useContext(ApiServerContext)
|
|
|
|
const [pendingSlicerUploads, setPendingSlicerUploads] = useState([])
|
|
const [currentPendingSlicerUpload, setCurrentPendingSlicerUpload] =
|
|
useState(null)
|
|
|
|
const { setPrimaryColorOverride } = useThemeContext()
|
|
|
|
useEffect(() => {
|
|
setPrimaryColorOverride('#00baa8')
|
|
}, [setPrimaryColorOverride])
|
|
|
|
const [objectFormState, setEditFormState] = useState({
|
|
isEditing: false,
|
|
editLoading: false,
|
|
formValid: false,
|
|
activities: [],
|
|
loading: false,
|
|
objectData: {
|
|
pendingSlicerUploads: []
|
|
}
|
|
})
|
|
const [showSlicerUploadFlow, setShowSlicerUploadFlow] = useState(false)
|
|
|
|
useEffect(() => {
|
|
setPendingSlicerUploads(
|
|
objectFormState.objectData?.pendingSlicerUploads || []
|
|
)
|
|
}, [objectFormState.objectData?.pendingSlicerUploads])
|
|
|
|
useEffect(() => {
|
|
const nextUpload = pendingSlicerUploads.find(
|
|
(upload) => upload.new === true
|
|
)
|
|
|
|
if (nextUpload) {
|
|
setCurrentPendingSlicerUpload(nextUpload)
|
|
setShowSlicerUploadFlow(true)
|
|
} else {
|
|
setCurrentPendingSlicerUpload(null)
|
|
setShowSlicerUploadFlow(false)
|
|
}
|
|
}, [pendingSlicerUploads])
|
|
|
|
const showPendingSlicerUpload = () => {
|
|
const upload =
|
|
pendingSlicerUploads.find(
|
|
(pendingUpload) => pendingUpload.new === true
|
|
) || pendingSlicerUploads[0]
|
|
|
|
if (upload) {
|
|
setCurrentPendingSlicerUpload(upload)
|
|
setShowSlicerUploadFlow(true)
|
|
}
|
|
}
|
|
|
|
const handleGCodeFileCreated = async (gcodeFile) => {
|
|
const updatedUploads = pendingSlicerUploads.map((upload) =>
|
|
upload._id === currentPendingSlicerUpload?._id
|
|
? { ...upload, gcodeFile: gcodeFile }
|
|
: upload
|
|
)
|
|
|
|
setPendingSlicerUploads(updatedUploads)
|
|
setCurrentPendingSlicerUpload((previous) => ({
|
|
...previous,
|
|
gcodeFile
|
|
}))
|
|
await updateObject(printerId, 'printer', {
|
|
...objectFormState.objectData,
|
|
pendingSlicerUploads: updatedUploads
|
|
})
|
|
}
|
|
|
|
const handleJobCreated = async (job) => {
|
|
const updatedUploads = pendingSlicerUploads.map((upload) =>
|
|
upload._id === currentPendingSlicerUpload?._id
|
|
? { ...upload, job }
|
|
: upload
|
|
)
|
|
|
|
setPendingSlicerUploads(updatedUploads)
|
|
setCurrentPendingSlicerUpload((previous) => ({
|
|
...previous,
|
|
job
|
|
}))
|
|
await updateObject(printerId, 'printer', {
|
|
...objectFormState.objectData,
|
|
pendingSlicerUploads: updatedUploads
|
|
})
|
|
}
|
|
|
|
const handleSlicerUploadComplete = async () => {
|
|
const updatedUploads = pendingSlicerUploads.filter(
|
|
(upload) => upload._id !== currentPendingSlicerUpload?._id
|
|
)
|
|
|
|
setPendingSlicerUploads(updatedUploads)
|
|
await updateObject(printerId, 'printer', {
|
|
...objectFormState.objectData,
|
|
pendingSlicerUploads: updatedUploads
|
|
})
|
|
}
|
|
|
|
const handleSlicerUploadFlowClosed = async () => {
|
|
const updatedUploads = pendingSlicerUploads.map((upload) =>
|
|
upload._id === currentPendingSlicerUpload?._id
|
|
? { ...upload, new: false }
|
|
: upload
|
|
)
|
|
|
|
setPendingSlicerUploads(updatedUploads)
|
|
await updateObject(printerId, 'printer', {
|
|
...objectFormState.objectData,
|
|
pendingSlicerUploads: updatedUploads
|
|
})
|
|
}
|
|
|
|
const slicerUploadsButton = () => {
|
|
if (pendingSlicerUploads.length > 0) {
|
|
return (
|
|
<Badge
|
|
count={pendingSlicerUploads.length}
|
|
style={{ marginTop: '8px' }}
|
|
size='small'
|
|
>
|
|
<Button
|
|
type='text'
|
|
icon={<FileIcon />}
|
|
onClick={showPendingSlicerUpload}
|
|
/>
|
|
</Badge>
|
|
)
|
|
}
|
|
return null
|
|
}
|
|
|
|
return (
|
|
<Layout style={{ height: 'var(--unit-100vh)' }}>
|
|
<Layout style={{ padding: '24px' }}>
|
|
<Content>
|
|
<Flex vertical style={{ height: '100%' }} gap='20px'>
|
|
<ObjectForm
|
|
id={printerId}
|
|
type='printer'
|
|
onStateChange={(state) =>
|
|
setEditFormState((previousState) => ({
|
|
...previousState,
|
|
...state
|
|
}))
|
|
}
|
|
>
|
|
{({ loading, objectData }) => (
|
|
<Flex justify='space-between' align='center'>
|
|
<Flex align='center' gap='middle'>
|
|
{loading ? (
|
|
<LoadingOutlined spin style={{ fontSize: '26px' }} />
|
|
) : (
|
|
<PrinterIcon style={{ fontSize: '26px' }} />
|
|
)}
|
|
<Title level={3} style={{ margin: 0 }}>
|
|
{loading
|
|
? 'Loading...'
|
|
: objectData?.name || 'Slicer Integration'}
|
|
</Title>
|
|
{!loading && (
|
|
<div
|
|
style={{
|
|
maxWidth: '400px',
|
|
width: '400px',
|
|
minWidth: '100px'
|
|
}}
|
|
>
|
|
<ObjectProperty
|
|
objectData={objectData}
|
|
{...getModelProperty('printer', 'state')}
|
|
/>
|
|
</div>
|
|
)}
|
|
</Flex>
|
|
{slicerUploadsButton()}
|
|
</Flex>
|
|
)}
|
|
</ObjectForm>
|
|
<Divider style={{ margin: '0' }} />
|
|
<ControlPrinter slicerIntegration={true} />
|
|
</Flex>
|
|
</Content>
|
|
<Modal
|
|
open={showSlicerUploadFlow}
|
|
onCancel={() => setShowSlicerUploadFlow(false)}
|
|
afterClose={handleSlicerUploadFlowClosed}
|
|
footer={null}
|
|
width={740}
|
|
destroyOnHidden={true}
|
|
>
|
|
{currentPendingSlicerUpload && (
|
|
<SlicerUploadFlow
|
|
key={currentPendingSlicerUpload._id}
|
|
currentPendingSlicerUpload={currentPendingSlicerUpload}
|
|
printer={objectFormState.objectData}
|
|
onGCodeFileCreated={handleGCodeFileCreated}
|
|
onJobCreated={handleJobCreated}
|
|
onComplete={handleSlicerUploadComplete}
|
|
/>
|
|
)}
|
|
</Modal>
|
|
</Layout>
|
|
</Layout>
|
|
)
|
|
}
|
|
|
|
export default SlicerIntegration
|