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 && (
}
/>
)}
{showDismiss && alert.canDismiss && (
}
/>
)
})
return (
{alertElements}
)
}
AlertsDisplay.propTypes = {
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