Overhaul printer control 1.
This commit is contained in:
parent
23b5300a2c
commit
4d01a6a04f
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,8 @@ const breadcrumbNameMap = {
|
|||||||
developer: 'Developer',
|
developer: 'Developer',
|
||||||
overview: 'Overview',
|
overview: 'Overview',
|
||||||
info: 'Info',
|
info: 'Info',
|
||||||
design: 'Design'
|
design: 'Design',
|
||||||
|
control: 'Control'
|
||||||
}
|
}
|
||||||
|
|
||||||
const mainSections = ['production', 'inventory', 'management', 'developer']
|
const mainSections = ['production', 'inventory', 'management', 'developer']
|
||||||
|
|||||||
@ -8,11 +8,21 @@ const ObjectInfo = ({
|
|||||||
loading = false,
|
loading = false,
|
||||||
isEditing = false,
|
isEditing = false,
|
||||||
type = 'unknown',
|
type = 'unknown',
|
||||||
|
showHyperlink,
|
||||||
|
showLabels = true,
|
||||||
objectData = null,
|
objectData = null,
|
||||||
properties = [],
|
properties = [],
|
||||||
required = undefined,
|
required = undefined,
|
||||||
visibleProperties = {},
|
visibleProperties = {},
|
||||||
objectPropertyProps = {},
|
objectPropertyProps = {},
|
||||||
|
column = {
|
||||||
|
xs: 1,
|
||||||
|
sm: 1,
|
||||||
|
md: 1,
|
||||||
|
lg: 2,
|
||||||
|
xl: 2,
|
||||||
|
xxl: 2
|
||||||
|
},
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => {
|
||||||
const allItems = getModelProperties(type)
|
const allItems = getModelProperties(type)
|
||||||
@ -47,33 +57,29 @@ const ObjectInfo = ({
|
|||||||
const key = item.name || item.label || idx
|
const key = item.name || item.label || idx
|
||||||
return {
|
return {
|
||||||
key,
|
key,
|
||||||
label: (
|
label:
|
||||||
<Flex vertical style={{ height: '100%' }} justify='center'>
|
showLabels == true ? (
|
||||||
{item.label}
|
<Flex vertical style={{ height: '100%' }} justify='center'>
|
||||||
</Flex>
|
{item.label}
|
||||||
),
|
</Flex>
|
||||||
|
) : null,
|
||||||
children: (
|
children: (
|
||||||
<ObjectProperty
|
<ObjectProperty
|
||||||
{...item}
|
{...item}
|
||||||
{...objectPropertyProps}
|
{...objectPropertyProps}
|
||||||
|
showHyperlink={showHyperlink}
|
||||||
isEditing={isEditing}
|
isEditing={isEditing}
|
||||||
objectData={objectData}
|
objectData={objectData}
|
||||||
/>
|
/>
|
||||||
)
|
),
|
||||||
|
span: item?.span || undefined
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Spin spinning={loading} indicator={<LoadingOutlined />}>
|
<Spin spinning={loading} indicator={<LoadingOutlined />}>
|
||||||
<Descriptions
|
<Descriptions
|
||||||
column={{
|
column={column}
|
||||||
xs: 1,
|
|
||||||
sm: 1,
|
|
||||||
md: 1,
|
|
||||||
lg: 2,
|
|
||||||
xl: 2,
|
|
||||||
xxl: 2
|
|
||||||
}}
|
|
||||||
bordered={true}
|
bordered={true}
|
||||||
{...rest}
|
{...rest}
|
||||||
items={descriptionItems}
|
items={descriptionItems}
|
||||||
@ -84,6 +90,9 @@ const ObjectInfo = ({
|
|||||||
|
|
||||||
ObjectInfo.propTypes = {
|
ObjectInfo.propTypes = {
|
||||||
loading: PropTypes.bool,
|
loading: PropTypes.bool,
|
||||||
|
column: PropTypes.object,
|
||||||
|
showHyperlink: PropTypes.bool,
|
||||||
|
showLabels: PropTypes.bool,
|
||||||
indicator: PropTypes.node,
|
indicator: PropTypes.node,
|
||||||
properties: PropTypes.array,
|
properties: PropTypes.array,
|
||||||
bordered: PropTypes.bool,
|
bordered: PropTypes.bool,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
// PrinterTemperaturePanel.js
|
// PrinterTemperaturePanel.js
|
||||||
import { useContext, useState, useEffect, useCallback } from 'react'
|
import { useContext, useState, useEffect } from 'react'
|
||||||
import {
|
import {
|
||||||
Progress,
|
Progress,
|
||||||
Typography,
|
Typography,
|
||||||
@ -11,9 +11,10 @@ import {
|
|||||||
Button
|
Button
|
||||||
} from 'antd'
|
} from 'antd'
|
||||||
import { LoadingOutlined, CaretLeftOutlined } from '@ant-design/icons'
|
import { LoadingOutlined, CaretLeftOutlined } from '@ant-design/icons'
|
||||||
import { PrintServerContext } from '../context/PrintServerContext'
|
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
import { ApiServerContext } from '../context/ApiServerContext'
|
||||||
|
import merge from 'lodash/merge'
|
||||||
|
|
||||||
const { Text } = Typography
|
const { Text } = Typography
|
||||||
const { Panel } = Collapse
|
const { Panel } = Collapse
|
||||||
@ -30,90 +31,69 @@ const CustomCollapse = styled(Collapse)`
|
|||||||
`
|
`
|
||||||
|
|
||||||
const PrinterTemperaturePanel = ({
|
const PrinterTemperaturePanel = ({
|
||||||
printerId,
|
id,
|
||||||
showHotEndControls = true,
|
showExtruderControls = true,
|
||||||
showHeatedBedControls = true,
|
showBedControls = true,
|
||||||
showHotEnd = true,
|
showExtruder = true,
|
||||||
showHeatedBed = true,
|
showBed = true,
|
||||||
showMoreInfo = true,
|
showMoreInfo = true
|
||||||
shouldUnsubscribe = true
|
|
||||||
}) => {
|
}) => {
|
||||||
const [temperatureData, setTemperatureData] = useState({
|
const [temperatureData, setTemperatureData] = useState({
|
||||||
hotEnd: {},
|
extruder: {
|
||||||
heatedBed: {}
|
current: 0,
|
||||||
|
target: 0,
|
||||||
|
power: 0
|
||||||
|
},
|
||||||
|
bed: {
|
||||||
|
current: 0,
|
||||||
|
target: 0,
|
||||||
|
power: 0
|
||||||
|
},
|
||||||
|
pinda: 0,
|
||||||
|
ambiant: 0
|
||||||
})
|
})
|
||||||
|
|
||||||
const [hotEndTemperature, setHotEndTemperature] = useState(
|
const { subscribeToObjectEvent, connected } = useContext(ApiServerContext)
|
||||||
temperatureData?.hotEnd?.target || 0
|
|
||||||
)
|
|
||||||
const [heatedBedTemperature, setHeatedBedTemperature] = useState(
|
|
||||||
temperatureData?.heatedBed?.target || 0
|
|
||||||
)
|
|
||||||
const { printServer } = useContext(PrintServerContext)
|
|
||||||
|
|
||||||
const notifyTemperatureStatusUpdate = useCallback((statusUpdate) => {
|
// Sync input values with actual temperature targets
|
||||||
setTemperatureData((prev) => {
|
useEffect(() => {
|
||||||
const temperatureObject = {
|
if (temperatureData.extruder?.target !== undefined) {
|
||||||
...prev
|
setExtruderTarget(temperatureData.extruder.target)
|
||||||
}
|
}
|
||||||
if (statusUpdate?.extruder?.temperature !== undefined) {
|
}, [temperatureData.extruder?.target])
|
||||||
temperatureObject.hotEnd.current = statusUpdate?.extruder?.temperature
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusUpdate?.heater_bed?.temperature !== undefined) {
|
|
||||||
temperatureObject.heatedBed.current =
|
|
||||||
statusUpdate?.heater_bed?.temperature
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusUpdate?.extruder?.target !== undefined) {
|
|
||||||
temperatureObject.hotEnd.target = statusUpdate?.extruder?.target
|
|
||||||
setHotEndTemperature(statusUpdate?.extruder?.target)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusUpdate?.heater_bed?.target !== undefined) {
|
|
||||||
temperatureObject.heatedBed.target = statusUpdate?.heater_bed?.target
|
|
||||||
setHeatedBedTemperature(statusUpdate?.heater_bed?.target)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusUpdate?.extruder?.power !== undefined) {
|
|
||||||
temperatureObject.hotEnd.power = statusUpdate?.extruder?.power
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusUpdate?.heater_bed?.power !== undefined) {
|
|
||||||
temperatureObject.heatedBed.power = statusUpdate?.heater_bed?.power
|
|
||||||
}
|
|
||||||
|
|
||||||
return temperatureObject
|
|
||||||
})
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const params = {
|
if (temperatureData.bed?.target !== undefined) {
|
||||||
printerId,
|
setBedTarget(temperatureData.bed.target)
|
||||||
objects: {
|
|
||||||
extruder: null,
|
|
||||||
heater_bed: null // eslint-disable-line
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (printServer?.connected == true) {
|
}, [temperatureData.bed?.target])
|
||||||
printServer.emit('printer.objects.subscribe', params)
|
|
||||||
printServer.emit('printer.objects.query', params)
|
|
||||||
printServer.on('notify_status_update', notifyTemperatureStatusUpdate)
|
|
||||||
}
|
|
||||||
return () => {
|
|
||||||
if (printServer && shouldUnsubscribe == true) {
|
|
||||||
printServer.off('notify_status_update', notifyTemperatureStatusUpdate)
|
|
||||||
printServer.emit('printer.objects.unsubscribe', params)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [printServer, printerId, notifyTemperatureStatusUpdate, shouldUnsubscribe])
|
|
||||||
|
|
||||||
const handleSetTemperatureClick = (target, value) => {
|
useEffect(() => {
|
||||||
if (printServer) {
|
if (id && connected) {
|
||||||
printServer.emit('printer.gcode.script', {
|
const temperatureEventUnsubscribe = subscribeToObjectEvent(
|
||||||
printerId,
|
id,
|
||||||
script: `SET_HEATER_TEMPERATURE HEATER=${target} TARGET=${value}`
|
'printer',
|
||||||
})
|
'temperature',
|
||||||
|
(event) => {
|
||||||
|
setTemperatureData((prev) => {
|
||||||
|
const merged = merge({}, prev, event.data)
|
||||||
|
return merged
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return () => {
|
||||||
|
if (temperatureEventUnsubscribe) temperatureEventUnsubscribe()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [id, connected])
|
||||||
|
|
||||||
|
const [extruderTarget, setExtruderTarget] = useState(0)
|
||||||
|
const [bedTarget, setBedTarget] = useState(0)
|
||||||
|
|
||||||
|
const handleSetTemperature = (data) => {
|
||||||
|
if (id && connected == true) {
|
||||||
|
console.log(data)
|
||||||
|
//sendObjectAction(id, 'printer', { type: 'setTemperature', data })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,33 +106,32 @@ const PrinterTemperaturePanel = ({
|
|||||||
<Flex vertical gap={0}>
|
<Flex vertical gap={0}>
|
||||||
<Text>
|
<Text>
|
||||||
Hot End Power:{' '}
|
Hot End Power:{' '}
|
||||||
{Math.round((temperatureData.hotEnd.power || 0) * 100)}%
|
{Math.round((temperatureData.extruder.power || 0) * 100)}%
|
||||||
</Text>
|
</Text>
|
||||||
<Progress
|
<Progress
|
||||||
percent={(temperatureData.hotEnd.power || 0) * 100}
|
percent={(temperatureData.extruder.power || 0) * 100}
|
||||||
showInfo={false}
|
showInfo={false}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical gap={0}>
|
<Flex vertical gap={0}>
|
||||||
<Text>
|
<Text>
|
||||||
Bed Power:{' '}
|
Bed Power: {Math.round((temperatureData.bed.power || 0) * 100)}%
|
||||||
{Math.round((temperatureData.heatedBed.power || 0) * 100)}%
|
|
||||||
</Text>
|
</Text>
|
||||||
<Progress
|
<Progress
|
||||||
percent={(temperatureData.heatedBed.power || 0) * 100}
|
percent={(temperatureData.bed.power || 0) * 100}
|
||||||
showInfo={false}
|
showInfo={false}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Panel>
|
<Panel>
|
||||||
{typeof temperatureData.pindaTemp !== 'undefined' && (
|
{typeof temperatureData.pinda !== 'undefined' && (
|
||||||
<Flex vertical gap={0}>
|
<Flex vertical gap={0}>
|
||||||
<Text>Pinda Temp: {temperatureData.pindaTemp}°C</Text>
|
<Text>Pinda Temp: {temperatureData.pindaTemp}°C</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{typeof temperatureData.ambiantActual !== 'undefined' && (
|
{typeof temperatureData.ambiant !== 'undefined' && (
|
||||||
<Flex vertical gap={0}>
|
<Flex vertical gap={0}>
|
||||||
<Text>Ambient Actual: {temperatureData.ambiantActual}°C</Text>
|
<Text>Ambient Actual: {temperatureData.ambiant}°C</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
</Panel>
|
</Panel>
|
||||||
@ -165,41 +144,41 @@ const PrinterTemperaturePanel = ({
|
|||||||
<div style={{ minWidth: 190 }}>
|
<div style={{ minWidth: 190 }}>
|
||||||
{temperatureData ? (
|
{temperatureData ? (
|
||||||
<Flex vertical gap='middle'>
|
<Flex vertical gap='middle'>
|
||||||
{temperatureData.hotEnd && showHotEnd && (
|
{temperatureData.extruder && showExtruder && (
|
||||||
<Flex vertical gap={0}>
|
<Flex vertical gap={0}>
|
||||||
<Text>
|
<Text>
|
||||||
Hot End: {temperatureData.hotEnd.current}°C /{' '}
|
Hot End: {temperatureData.extruder.current}°C /{' '}
|
||||||
{temperatureData.hotEnd.target}°C
|
{temperatureData.extruder.target}°C
|
||||||
</Text>
|
</Text>
|
||||||
<Progress
|
<Progress
|
||||||
percent={(temperatureData.hotEnd.target / 300) * 100}
|
percent={(temperatureData.extruder.target / 300) * 100}
|
||||||
strokeColor='#FF392F1D'
|
strokeColor='#FF392F1D'
|
||||||
success={{
|
success={{
|
||||||
percent: (temperatureData.hotEnd.current / 300) * 100,
|
percent: (temperatureData.extruder.current / 300) * 100,
|
||||||
strokeColor: '#FF3B2F'
|
strokeColor: '#FF3B2F'
|
||||||
}}
|
}}
|
||||||
showInfo={false}
|
showInfo={false}
|
||||||
/>
|
/>
|
||||||
{showHotEndControls && (
|
{showExtruderControls && (
|
||||||
<Space direction='horizontal' style={{ marginTop: 5 }}>
|
<Space direction='horizontal' style={{ marginTop: 5 }}>
|
||||||
<Space.Compact block size='small'>
|
<Space.Compact block size='small'>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
value={hotEndTemperature}
|
value={extruderTarget}
|
||||||
min={0}
|
min={0}
|
||||||
max={300}
|
max={300}
|
||||||
style={{ width: '120px' }}
|
style={{ width: '120px' }}
|
||||||
addonAfter='°C'
|
addonAfter='°C'
|
||||||
onChange={(value) => setHotEndTemperature(value)}
|
onChange={(value) => setExtruderTarget(value || 0)}
|
||||||
onPressEnter={() =>
|
onPressEnter={handleSetTemperature({
|
||||||
handleSetTemperatureClick('extruder', hotEndTemperature)
|
extruder: { target: extruderTarget }
|
||||||
}
|
})}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
type='default'
|
type='default'
|
||||||
style={{ width: 40 }}
|
style={{ width: 40 }}
|
||||||
onClick={() =>
|
onClick={handleSetTemperature({
|
||||||
handleSetTemperatureClick('extruder', hotEndTemperature)
|
extruder: { target: extruderTarget }
|
||||||
}
|
})}
|
||||||
>
|
>
|
||||||
Set
|
Set
|
||||||
</Button>
|
</Button>
|
||||||
@ -208,7 +187,9 @@ const PrinterTemperaturePanel = ({
|
|||||||
type='default'
|
type='default'
|
||||||
size='small'
|
size='small'
|
||||||
style={{ width: 40 }}
|
style={{ width: 40 }}
|
||||||
onClick={() => handleSetTemperatureClick('extruder', 0)}
|
onClick={() =>
|
||||||
|
handleSetTemperature({ extruder: { target: 0 } })
|
||||||
|
}
|
||||||
>
|
>
|
||||||
Off
|
Off
|
||||||
</Button>
|
</Button>
|
||||||
@ -217,50 +198,44 @@ const PrinterTemperaturePanel = ({
|
|||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{temperatureData.heatedBed && showHeatedBed && (
|
{temperatureData.bed && showBed && (
|
||||||
<Flex vertical gap={0}>
|
<Flex vertical gap={0}>
|
||||||
<Text>
|
<Text>
|
||||||
Heated Bed: {temperatureData.heatedBed.current}°C /{' '}
|
Heated Bed: {temperatureData.bed.current}°C /{' '}
|
||||||
{temperatureData.heatedBed.target}°C
|
{temperatureData.bed.target}°C
|
||||||
</Text>
|
</Text>
|
||||||
<Progress
|
<Progress
|
||||||
percent={(temperatureData.heatedBed.target / 300) * 100}
|
percent={(temperatureData.bed.target / 300) * 100}
|
||||||
strokeColor='#FF392F1D'
|
strokeColor='#FF392F1D'
|
||||||
success={{
|
success={{
|
||||||
percent: (temperatureData.heatedBed.current / 300) * 100,
|
percent: (temperatureData.bed.current / 300) * 100,
|
||||||
strokeColor: '#FF3B2F'
|
strokeColor: '#FF3B2F'
|
||||||
}}
|
}}
|
||||||
showInfo={false}
|
showInfo={false}
|
||||||
/>
|
/>
|
||||||
{showHeatedBedControls && (
|
{showBedControls && (
|
||||||
<Space
|
<Space
|
||||||
direction='horizontal'
|
direction='horizontal'
|
||||||
style={{ marginTop: 5, height: '21px' }}
|
style={{ marginTop: 5, height: '21px' }}
|
||||||
>
|
>
|
||||||
<Space.Compact block size='small'>
|
<Space.Compact block size='small'>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
value={heatedBedTemperature}
|
value={bedTarget}
|
||||||
min={0}
|
min={0}
|
||||||
max={300}
|
max={300}
|
||||||
style={{ width: '120px' }}
|
style={{ width: '120px' }}
|
||||||
addonAfter='°C'
|
addonAfter='°C'
|
||||||
onChange={(value) => setHeatedBedTemperature(value)}
|
onChange={(value) => setBedTarget(value || 0)}
|
||||||
onPressEnter={() =>
|
onPressEnter={handleSetTemperature({
|
||||||
handleSetTemperatureClick(
|
bed: { target: bedTarget }
|
||||||
'heater_bed',
|
})}
|
||||||
heatedBedTemperature
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
type='default'
|
type='default'
|
||||||
style={{ width: 40 }}
|
style={{ width: 40 }}
|
||||||
onClick={() =>
|
onClick={handleSetTemperature({
|
||||||
handleSetTemperatureClick(
|
bed: { target: bedTarget }
|
||||||
'heater_bed',
|
})}
|
||||||
heatedBedTemperature
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Set
|
Set
|
||||||
</Button>
|
</Button>
|
||||||
@ -269,7 +244,11 @@ const PrinterTemperaturePanel = ({
|
|||||||
type='default'
|
type='default'
|
||||||
size='small'
|
size='small'
|
||||||
style={{ width: 40 }}
|
style={{ width: 40 }}
|
||||||
onClick={() => handleSetTemperatureClick('heater_bed', 0)}
|
onClick={() =>
|
||||||
|
handleSetTemperature({
|
||||||
|
bed: { target: 0 }
|
||||||
|
})
|
||||||
|
}
|
||||||
>
|
>
|
||||||
Off
|
Off
|
||||||
</Button>
|
</Button>
|
||||||
@ -298,11 +277,11 @@ const PrinterTemperaturePanel = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
PrinterTemperaturePanel.propTypes = {
|
PrinterTemperaturePanel.propTypes = {
|
||||||
printerId: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
showHotEndControls: PropTypes.bool,
|
showExtruderControls: PropTypes.bool,
|
||||||
showHeatedBedControls: PropTypes.bool,
|
showBedControls: PropTypes.bool,
|
||||||
showHotEnd: PropTypes.bool,
|
showExtruder: PropTypes.bool,
|
||||||
showHeatedBed: PropTypes.bool,
|
showBed: PropTypes.bool,
|
||||||
showMoreInfo: PropTypes.bool,
|
showMoreInfo: PropTypes.bool,
|
||||||
shouldUnsubscribe: PropTypes.bool
|
shouldUnsubscribe: PropTypes.bool
|
||||||
}
|
}
|
||||||
|
|||||||
@ -93,7 +93,9 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
newSocket.on('objectUpdate', handleObjectUpdate)
|
newSocket.on('objectUpdate', handleObjectUpdate)
|
||||||
|
newSocket.on('objectEvent', handleObjectEvent)
|
||||||
newSocket.on('objectNew', handleObjectNew)
|
newSocket.on('objectNew', handleObjectNew)
|
||||||
|
newSocket.on('objectDelete', handleObjectDelete)
|
||||||
newSocket.on('lockUpdate', handleLockUpdate)
|
newSocket.on('lockUpdate', handleLockUpdate)
|
||||||
|
|
||||||
newSocket.on('disconnect', () => {
|
newSocket.on('disconnect', () => {
|
||||||
@ -216,6 +218,37 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleObjectEvent = async (data) => {
|
||||||
|
const id = data._id
|
||||||
|
const objectType = data.objectType
|
||||||
|
|
||||||
|
const callbacksRefKey = `${objectType}:${id}:events:${data.event.type}`
|
||||||
|
logger.debug('Notifying object event:', data)
|
||||||
|
if (
|
||||||
|
id &&
|
||||||
|
objectType &&
|
||||||
|
subscribedCallbacksRef.current.has(callbacksRefKey)
|
||||||
|
) {
|
||||||
|
const callbacks = subscribedCallbacksRef.current.get(callbacksRefKey)
|
||||||
|
logger.debug(
|
||||||
|
`Calling ${callbacks.length} callbacks for object:`,
|
||||||
|
callbacksRefKey
|
||||||
|
)
|
||||||
|
callbacks.forEach((callback) => {
|
||||||
|
try {
|
||||||
|
callback(data.event)
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Error in object event callback:', error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
logger.debug(
|
||||||
|
`No callbacks found for object: ${callbacksRefKey}, subscribed callbacks:`,
|
||||||
|
Array.from(subscribedCallbacksRef.current.keys())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleObjectNew = async (data) => {
|
const handleObjectNew = async (data) => {
|
||||||
logger.debug('Notifying object new:', data)
|
logger.debug('Notifying object new:', data)
|
||||||
const objectType = data.objectType || 'unknown'
|
const objectType = data.objectType || 'unknown'
|
||||||
@ -241,6 +274,31 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleObjectDelete = async (data) => {
|
||||||
|
logger.debug('Notifying object delete:', data)
|
||||||
|
const objectType = data.objectType || 'unknown'
|
||||||
|
|
||||||
|
if (objectType && subscribedCallbacksRef.current.has(objectType)) {
|
||||||
|
const callbacks = subscribedCallbacksRef.current.get(objectType)
|
||||||
|
logger.debug(
|
||||||
|
`Calling ${callbacks.length} callbacks for type:`,
|
||||||
|
objectType
|
||||||
|
)
|
||||||
|
callbacks.forEach((callback) => {
|
||||||
|
try {
|
||||||
|
callback(data.object)
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Error in object new callback:', error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
logger.debug(
|
||||||
|
`No callbacks found for object: ${objectType}, subscribed callbacks:`,
|
||||||
|
Array.from(subscribedCallbacksRef.current.keys())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const offObjectUpdatesEvent = useCallback((id, objectType, callback) => {
|
const offObjectUpdatesEvent = useCallback((id, objectType, callback) => {
|
||||||
if (socketRef.current && socketRef.current.connected == true) {
|
if (socketRef.current && socketRef.current.connected == true) {
|
||||||
const callbacksRefKey = `${objectType}:${id}`
|
const callbacksRefKey = `${objectType}:${id}`
|
||||||
@ -251,7 +309,10 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
.filter((cb) => cb !== callback)
|
.filter((cb) => cb !== callback)
|
||||||
if (callbacks.length === 0) {
|
if (callbacks.length === 0) {
|
||||||
subscribedCallbacksRef.current.delete(callbacksRefKey)
|
subscribedCallbacksRef.current.delete(callbacksRefKey)
|
||||||
socketRef.current.emit('unsubscribe', { id: id, type: objectType })
|
socketRef.current.emit('unsubscribeObjectUpdate', {
|
||||||
|
id: id,
|
||||||
|
objectType: objectType
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
subscribedCallbacksRef.current.set(callbacksRefKey, callbacks)
|
subscribedCallbacksRef.current.set(callbacksRefKey, callbacks)
|
||||||
}
|
}
|
||||||
@ -262,14 +323,22 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
const offObjectTypeUpdatesEvent = useCallback((objectType, callback) => {
|
const offObjectTypeUpdatesEvent = useCallback((objectType, callback) => {
|
||||||
if (socketRef.current && socketRef.current.connected == true) {
|
if (socketRef.current && socketRef.current.connected == true) {
|
||||||
// Remove callback from the subscribed callbacks map
|
// Remove callback from the subscribed callbacks map
|
||||||
console.log('Unsubscribing from type')
|
console.log(
|
||||||
|
'Unsubscribing from type',
|
||||||
|
objectType,
|
||||||
|
subscribedCallbacksRef.current.has(objectType)
|
||||||
|
)
|
||||||
if (subscribedCallbacksRef.current.has(objectType)) {
|
if (subscribedCallbacksRef.current.has(objectType)) {
|
||||||
const callbacks = subscribedCallbacksRef.current
|
const callbacks = subscribedCallbacksRef.current
|
||||||
.get(objectType)
|
.get(objectType)
|
||||||
.filter((cb) => cb !== callback)
|
.filter((cb) => cb !== callback)
|
||||||
|
console.log('API: CALLBACKS', callbacks)
|
||||||
|
|
||||||
if (callbacks.length === 0) {
|
if (callbacks.length === 0) {
|
||||||
subscribedCallbacksRef.current.delete(objectType)
|
subscribedCallbacksRef.current.delete(objectType)
|
||||||
socketRef.current.emit('unsubscribe', { objectType: objectType })
|
socketRef.current.emit('unsubscribeObjectTypeUpdate', {
|
||||||
|
objectType: objectType
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
subscribedCallbacksRef.current.set(objectType, callbacks)
|
subscribedCallbacksRef.current.set(objectType, callbacks)
|
||||||
}
|
}
|
||||||
@ -342,7 +411,7 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
logger.debug('Registered update event listener for object:', objectType)
|
logger.debug('Registered type event listener for object:', objectType)
|
||||||
|
|
||||||
// Return cleanup function
|
// Return cleanup function
|
||||||
return () => offObjectTypeUpdatesEvent(objectType, callback)
|
return () => offObjectTypeUpdatesEvent(objectType, callback)
|
||||||
@ -369,6 +438,84 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const offObjectEventEvent = useCallback(
|
||||||
|
(id, objectType, eventType, callback) => {
|
||||||
|
if (socketRef.current && socketRef.current.connected == true) {
|
||||||
|
const callbacksRefKey = `${objectType}:${id}:events:${eventType}`
|
||||||
|
// Remove callback from the subscribed callbacks map
|
||||||
|
if (subscribedCallbacksRef.current.has(callbacksRefKey)) {
|
||||||
|
const callbacks = subscribedCallbacksRef.current
|
||||||
|
.get(callbacksRefKey)
|
||||||
|
.filter((cb) => cb !== callback)
|
||||||
|
if (callbacks.length === 0) {
|
||||||
|
subscribedCallbacksRef.current.delete(callbacksRefKey)
|
||||||
|
socketRef.current.emit('unsubscribeObjectEvent', {
|
||||||
|
_id: id,
|
||||||
|
objectType,
|
||||||
|
eventType
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
subscribedCallbacksRef.current.set(callbacksRefKey, callbacks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
|
const subscribeToObjectEvent = useCallback(
|
||||||
|
(id, objectType, eventType, callback) => {
|
||||||
|
if (socketRef.current && socketRef.current.connected == true) {
|
||||||
|
const callbacksRefKey = `${objectType}:${id}:events:${eventType}`
|
||||||
|
// Add callback to the subscribed callbacks map immediately
|
||||||
|
if (!subscribedCallbacksRef.current.has(callbacksRefKey)) {
|
||||||
|
subscribedCallbacksRef.current.set(callbacksRefKey, [])
|
||||||
|
}
|
||||||
|
|
||||||
|
const callbacksLength =
|
||||||
|
subscribedCallbacksRef.current.get(callbacksRefKey).length
|
||||||
|
|
||||||
|
if (callbacksLength <= 0) {
|
||||||
|
socketRef.current.emit(
|
||||||
|
'subscribeToObjectEvent',
|
||||||
|
{
|
||||||
|
_id: id,
|
||||||
|
objectType: objectType,
|
||||||
|
eventType: eventType
|
||||||
|
},
|
||||||
|
(result) => {
|
||||||
|
if (result.success) {
|
||||||
|
logger.info(
|
||||||
|
'Subscribed to event id:',
|
||||||
|
id,
|
||||||
|
'objectType:',
|
||||||
|
objectType,
|
||||||
|
'eventType:',
|
||||||
|
eventType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
logger.info(
|
||||||
|
'Adding event callback id:',
|
||||||
|
id,
|
||||||
|
'objectType:',
|
||||||
|
objectType,
|
||||||
|
'eventType:',
|
||||||
|
eventType,
|
||||||
|
'callbacks length:',
|
||||||
|
callbacksLength + 1
|
||||||
|
)
|
||||||
|
subscribedCallbacksRef.current.get(callbacksRefKey).push(callback)
|
||||||
|
|
||||||
|
// Return cleanup function
|
||||||
|
return () => offObjectEventEvent(id, objectType, eventType, callback)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[offObjectUpdatesEvent]
|
||||||
|
)
|
||||||
|
|
||||||
const subscribeToObjectLock = useCallback(
|
const subscribeToObjectLock = useCallback(
|
||||||
(id, type, callback) => {
|
(id, type, callback) => {
|
||||||
logger.debug('Subscribing to lock for object:', id, 'type:', type)
|
logger.debug('Subscribing to lock for object:', id, 'type:', type)
|
||||||
@ -548,13 +695,6 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
logger.debug('Object updated successfully')
|
logger.debug('Object updated successfully')
|
||||||
if (socketRef.current && socketRef.current.connected == true) {
|
|
||||||
await socketRef.current.emit('update', {
|
|
||||||
_id: id,
|
|
||||||
type: type,
|
|
||||||
updatedAt: response.data.updatedAt
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return response.data
|
return response.data
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
@ -577,13 +717,6 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
logger.debug('Object deleted successfully')
|
logger.debug('Object deleted successfully')
|
||||||
if (socketRef.current && socketRef.current.connected == true) {
|
|
||||||
await socketRef.current.emit('update', {
|
|
||||||
_id: id,
|
|
||||||
type: type,
|
|
||||||
updatedAt: response.data.updatedAt
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return response.data
|
return response.data
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
@ -649,7 +782,7 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
try {
|
try {
|
||||||
const response = await axios.get(`${config.backendUrl}/notes`, {
|
const response = await axios.get(`${config.backendUrl}/notes`, {
|
||||||
params: {
|
params: {
|
||||||
parent: parentId,
|
'parent._id': parentId,
|
||||||
sort: 'createdAt',
|
sort: 'createdAt',
|
||||||
order: 'ascend'
|
order: 'ascend'
|
||||||
},
|
},
|
||||||
@ -755,6 +888,7 @@ const ApiServerProvider = ({ children }) => {
|
|||||||
createObject,
|
createObject,
|
||||||
deleteObject,
|
deleteObject,
|
||||||
subscribeToObjectUpdates,
|
subscribeToObjectUpdates,
|
||||||
|
subscribeToObjectEvent,
|
||||||
subscribeToObjectTypeUpdates,
|
subscribeToObjectTypeUpdates,
|
||||||
subscribeToObjectLock,
|
subscribeToObjectLock,
|
||||||
fetchObject,
|
fetchObject,
|
||||||
|
|||||||
@ -143,6 +143,21 @@ export const Printer = {
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
required: false,
|
required: false,
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'currentFilamentStock',
|
||||||
|
label: 'Filament Stock',
|
||||||
|
type: 'object',
|
||||||
|
objectType: 'filamentStock',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'currentFilamentStock._id',
|
||||||
|
label: 'Filament Stock ID',
|
||||||
|
type: 'id',
|
||||||
|
objectType: 'filamentStock',
|
||||||
|
showHyperlink: true,
|
||||||
|
readOnly: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user