import PropTypes from 'prop-types' import { createElement } from 'react' import { Flex, Alert, Button, Dropdown, Popover } from 'antd' import ExclamationOctagonIcon from '../../Icons/ExclamationOctagonIcon' import InfoCircleIcon from '../../Icons/InfoCircleIcon' import { CaretDownOutlined } from '@ant-design/icons' import { useMediaQuery } from 'react-responsive' import { getModelByName } from '../../../database/ObjectModels' import { useNavigate } from 'react-router-dom' const AlertsDisplay = ({ alerts = [], printerId, showDismiss = true, showActions = true }) => { const isMobile = useMediaQuery({ maxWidth: 768 }) 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 navigate = useNavigate() const getAlertIcon = (type, priority) => { if (type === 'error' || priority === '9') return if (type === 'warning' || priority === '8') return return } // Recursively filter the printer model actions by a set of allowed action keys const filterActionsByKeys = (actions, allowedKeys) => { if (!Array.isArray(actions)) return [] const filtered = actions .map((action) => { if (action.type === 'divider') { return { type: 'divider' } } const actionKey = action.key || action.name let children = [] if (Array.isArray(action.children)) { children = filterActionsByKeys(action.children, allowedKeys) } const isAllowed = actionKey && allowedKeys.has(actionKey) if (!isAllowed && children.length === 0) { return null } return { ...action, children } }) .filter((action) => action !== null) // Clean up dividers: remove leading/trailing and consecutive dividers const cleaned = [] for (const action of filtered) { if (action.type === 'divider') { if (cleaned.length === 0) continue if (cleaned[cleaned.length - 1].type === 'divider') continue } cleaned.push(action) } if (cleaned[cleaned.length - 1]?.type === 'divider') { cleaned.pop() } return cleaned } // Map filtered printer actions to AntD Dropdown menu items (including children) const mapActionsToMenuItems = (actions) => { if (!Array.isArray(actions)) return [] return actions.map((action) => { if (action.type === 'divider') { return { type: 'divider' } } const item = { key: action.key || action.name, label: action.label, icon: action.icon ? createElement(action.icon) : undefined } if (Array.isArray(action.children) && action.children.length > 0) { item.children = mapActionsToMenuItems(action.children) } return item }) } if (alerts.length == 0) { return null } const alertElements = alerts.map((alert, index) => { const printerActions = printerModel?.actions || [] const alertActionKeys = Array.isArray(alert?.actions) ? alert.actions .map((action) => typeof action === 'string' ? action : action?.key || action?.name || null ) .filter((key) => key != null) : [] const allowedKeys = new Set(alertActionKeys) const filteredActions = filterActionsByKeys(printerActions, allowedKeys) const findActionByKey = (actions, key) => { if (!Array.isArray(actions)) return null for (const action of actions) { if (action.type === 'divider') continue const actionKey = action.key || action.name if (actionKey === key) { return action } if (Array.isArray(action.children) && action.children.length > 0) { const found = findActionByKey(action.children, key) if (found) return found } } return null } const menu = { items: mapActionsToMenuItems(filteredActions), onClick: ({ key }) => { const action = findActionByKey(filteredActions, key) if (action?.url) { navigate(action.url(printerId)) } else { console.warn('No action found for key:', key) } } } return ( { console.log('Closing alert:', alert._id) }} action={ showActions ? ( ) : null } /> ) }) if (isMobile) { return ( ) } return {alertElements} } 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 } export default AlertsDisplay