132 lines
3.6 KiB
JavaScript
132 lines
3.6 KiB
JavaScript
import PropTypes from 'prop-types'
|
|
import { Badge, Progress, Flex, Space, Tag, Typography } from 'antd'
|
|
import { green } from '@ant-design/colors'
|
|
import React, { useState, useContext, useEffect } from 'react'
|
|
import { SocketContext } from '../context/SocketContext'
|
|
|
|
const { Text } = Typography
|
|
|
|
const getProgressColor = (percent) => {
|
|
if (percent <= 50) {
|
|
return green[5]
|
|
} else if (percent <= 80) {
|
|
// Interpolate between green and yellow
|
|
const ratio = (percent - 50) / 30
|
|
return `rgb(${Math.round(255 * ratio)}, ${Math.round(255 * (1 - ratio))}, 0)`
|
|
} else {
|
|
// Interpolate between yellow and red
|
|
const ratio = (percent - 80) / 20
|
|
return `rgb(255, ${Math.round(255 * (1 - ratio))}, 0)`
|
|
}
|
|
}
|
|
|
|
const FilamentStockState = ({
|
|
filamentStock,
|
|
showProgress = true,
|
|
showStatus = true
|
|
}) => {
|
|
const { socket } = useContext(SocketContext)
|
|
const [badgeStatus, setBadgeStatus] = useState('unknown')
|
|
const [badgeText, setBadgeText] = useState('Unknown')
|
|
const [currentState, setCurrentState] = useState(
|
|
filamentStock?.state || {
|
|
type: 'unknown',
|
|
progress: 0
|
|
}
|
|
)
|
|
const [initialized, setInitialized] = useState(false)
|
|
|
|
useEffect(() => {
|
|
if (socket && !initialized && filamentStock?._id) {
|
|
setInitialized(true)
|
|
socket.on('notify_filamentstock_update', (statusUpdate) => {
|
|
if (statusUpdate?._id === filamentStock?._id && statusUpdate?.state) {
|
|
setCurrentState(statusUpdate.state)
|
|
}
|
|
})
|
|
}
|
|
return () => {
|
|
if (socket && initialized) {
|
|
socket.off('notify_filamentstock_update')
|
|
}
|
|
}
|
|
}, [socket, initialized, filamentStock?._id])
|
|
|
|
useEffect(() => {
|
|
switch (currentState.type) {
|
|
case 'unconsumed':
|
|
setBadgeStatus('success')
|
|
setBadgeText('Unconsumed')
|
|
break
|
|
case 'partiallyconsumed':
|
|
setBadgeStatus('warning')
|
|
setBadgeText('Partial')
|
|
break
|
|
case 'fullyconsumed':
|
|
setBadgeStatus('error')
|
|
setBadgeText('Consumed')
|
|
break
|
|
case 'error':
|
|
setBadgeStatus('error')
|
|
setBadgeText('Error')
|
|
break
|
|
default:
|
|
setBadgeStatus('default')
|
|
setBadgeText(currentState.type)
|
|
}
|
|
}, [currentState])
|
|
|
|
return (
|
|
<Flex gap='middle' align={'center'}>
|
|
{showStatus && (
|
|
<Space>
|
|
<Tag color={badgeStatus} style={{ marginRight: 0 }}>
|
|
<Flex gap={6}>
|
|
<Badge status={badgeStatus} />
|
|
{badgeText}
|
|
</Flex>
|
|
</Tag>
|
|
</Space>
|
|
)}
|
|
{showProgress && currentState.type === 'partiallyconsumed' ? (
|
|
<Flex style={{ width: '150px' }} gap={'small'}>
|
|
<div style={{ flexGrow: '1' }}>
|
|
<Progress
|
|
percent={Math.round(currentState.percent * 100)}
|
|
style={{ marginBottom: '2px', width: '100%' }}
|
|
strokeColor={getProgressColor(
|
|
Math.round(currentState.percent * 100)
|
|
)}
|
|
showInfo={false}
|
|
/>
|
|
</div>
|
|
<Text style={{ marginTop: '1px' }}>
|
|
{Math.round(currentState.percent * 100) + '%'}
|
|
</Text>
|
|
</Flex>
|
|
) : null}
|
|
</Flex>
|
|
)
|
|
}
|
|
|
|
FilamentStockState.propTypes = {
|
|
filamentStock: PropTypes.shape({
|
|
_id: PropTypes.string,
|
|
name: PropTypes.string,
|
|
state: PropTypes.shape({
|
|
type: PropTypes.oneOf([
|
|
'unconsumed',
|
|
'partiallyconsumed',
|
|
'fullyconsumed',
|
|
'error',
|
|
'unknown'
|
|
]),
|
|
progress: PropTypes.number
|
|
})
|
|
}),
|
|
showProgress: PropTypes.bool,
|
|
showStatus: PropTypes.bool
|
|
}
|
|
|
|
export default FilamentStockState
|