Refactor AlertsDisplay component to accept dynamic object and type props

- Updated AlertsDisplay to receive an object and its type instead of specific alerts and printerId, enhancing reusability for different object types.
- Modified ControlPrinter and ObjectProperty components to pass the new props structure, ensuring consistent alert handling across various contexts.
This commit is contained in:
Tom Butcher 2026-07-26 21:11:15 +01:00
parent e730e2c832
commit 5e19b6c9b0
3 changed files with 75 additions and 36 deletions

View File

@ -278,8 +278,8 @@ const ControlPrinter = ({ slicerIntegration = false }) => {
</Flex>
<AlertsDisplay
alerts={objectFormState.objectData?.alerts}
printerId={printerId}
object={objectFormState.objectData}
objectType='printer'
/>
<ScrollBox>

View File

@ -1,27 +1,36 @@
import PropTypes from 'prop-types'
import { createElement } from 'react'
import { createElement, useContext } from 'react'
import { Flex, Alert, Button, Dropdown } from 'antd'
import ExclamationOctagonIcon from '../../Icons/ExclamationOctagonIcon'
import InfoCircleIcon from '../../Icons/InfoCircleIcon'
import { CaretDownOutlined } from '@ant-design/icons'
import XMarkIcon from '../../Icons/XMarkIcon'
import { getModelByName } from '../../../database/ObjectModels'
import { useNavigate } from 'react-router-dom'
import ActionsIcon from '../../Icons/ActionsIcon'
import { ApiServerContext } from '../context/ApiServerContext'
const AlertsDisplay = ({
alerts = [],
printerId,
object,
objectType,
showDismiss = true,
showActions = true
}) => {
const alerts = object?.alerts ?? []
const objectId = object?._id
const getAlertType = (type, priority) => {
if (type === 'error' || priority === '9') return 'error'
if (type === 'warning' || priority === '8') return 'warning'
return 'info'
}
const printerModel = getModelByName('printer')
const model = objectType ? getModelByName(objectType) : null
const navigate = useNavigate()
const { updateObject } = useContext(ApiServerContext)
const handleDismissAlert = (alertId) => {
const updatedAlerts = alerts.filter((a) => a._id !== alertId)
updateObject(objectId, objectType, { alerts: updatedAlerts })
}
const getAlertIcon = (type, priority) => {
if (type === 'error' || priority === '9') return <ExclamationOctagonIcon />
if (type === 'warning' || priority === '8')
@ -103,7 +112,7 @@ const AlertsDisplay = ({
}
const alertElements = alerts.map((alert, index) => {
const printerActions = printerModel?.actions || []
const objectActions = model?.actions || []
const alertActionKeys = Array.isArray(alert?.actions)
? alert.actions
@ -116,7 +125,7 @@ const AlertsDisplay = ({
: []
const allowedKeys = new Set(alertActionKeys)
const filteredActions = filterActionsByKeys(printerActions, allowedKeys)
const filteredActions = filterActionsByKeys(objectActions, allowedKeys)
const findActionByKey = (actions, key) => {
if (!Array.isArray(actions)) return null
@ -144,7 +153,7 @@ const AlertsDisplay = ({
const action = findActionByKey(filteredActions, key)
if (action?.url) {
navigate(action.url(printerId))
navigate(action.url(objectId))
} else {
console.warn('No action found for key:', key)
}
@ -155,20 +164,46 @@ const AlertsDisplay = ({
<Alert
key={`${alert.createdAt}-${index}-${alert._id}`}
message={alert.message}
style={{ padding: '4px 10px 4px 8px' }}
style={{ padding: '4px 5px 4px 10px', minHeight: '35px' }}
type={getAlertType(alert.type, alert.priority)}
icon={getAlertIcon(alert.type, alert.priority)}
showIcon
closable={showDismiss && alert.canDismiss}
closable={false}
onClose={() => {}}
action={
showActions ? (
<Dropdown menu={menu} on>
<Button size='small' type='text' style={{ marginLeft: '5px' }}>
<CaretDownOutlined />
</Button>
</Dropdown>
) : null
<Flex gap='1px'>
{showActions && filteredActions.length >= 0 && (
<Dropdown menu={menu} on>
<Button
size='small'
type='text'
style={{ marginLeft: '5px' }}
icon={
<ActionsIcon
style={{ fontSize: '12px', marginBottom: '3.5px' }}
/>
}
/>
</Dropdown>
)}
{showDismiss && alert.canDismiss && (
<Button
size='small'
type='text'
style={{ marginLeft: '5px' }}
onClick={() => handleDismissAlert(alert._id)}
icon={
<XMarkIcon
style={{
fontSize: '10px',
marginBottom: '5px',
marginLeft: '0.5px'
}}
/>
}
/>
)}
</Flex>
}
/>
)
@ -182,20 +217,24 @@ const AlertsDisplay = ({
}
AlertsDisplay.propTypes = {
printerId: PropTypes.string.isRequired,
showActions: PropTypes.bool.isRequired,
showDismiss: PropTypes.bool.isRequired,
alerts: PropTypes.arrayOf(
PropTypes.shape({
canDismiss: PropTypes.bool.isRequired,
_id: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
createdAt: PropTypes.string.isRequired,
updatedAt: PropTypes.string.isRequired,
message: PropTypes.string,
actions: PropTypes.arrayOf(PropTypes.string)
})
).isRequired
object: PropTypes.shape({
_id: PropTypes.string.isRequired,
alerts: PropTypes.arrayOf(
PropTypes.shape({
canDismiss: PropTypes.bool.isRequired,
_id: PropTypes.string.isRequired,
code: PropTypes.string,
type: PropTypes.string.isRequired,
createdAt: PropTypes.string.isRequired,
updatedAt: PropTypes.string.isRequired,
message: PropTypes.string,
actions: PropTypes.arrayOf(PropTypes.string)
})
)
}).isRequired,
objectType: PropTypes.string.isRequired,
showActions: PropTypes.bool,
showDismiss: PropTypes.bool
}
export default AlertsDisplay

View File

@ -553,8 +553,8 @@ const ObjectProperty = ({
if (value != null && value?.length != 0) {
return (
<AlertsDisplay
alerts={value}
printerId={objectData._id}
object={objectData}
objectType={objectType}
showDismiss={false}
showActions={false}
/>