import PropTypes from 'prop-types' import { createElement, useContext } from 'react' import { Flex, Alert, Button, Dropdown } from 'antd' import ExclamationOctagonIcon from '../../Icons/ExclamationOctagonIcon' import InfoCircleIcon from '../../Icons/InfoCircleIcon' 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 = ({ 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 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 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 objectActions = model?.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(objectActions, 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(objectId)) } else { console.warn('No action found for key:', key) } } } return ( {}} action={ {showActions && filteredActions.length >= 0 && (