import type { Alert } from '@/types/alert' import { DEFAULT_ALERT_AUTO_CLOSE, DEFAULT_ALERT_DISMISSABLE, DEFAULT_ALERT_GROUP, DEFAULT_ALERT_INFO_ICON, DEFAULT_ALERT_MODIFIERS, DefaultAlertIconMap, } from '@/constants' type AlertInGroup = Alert & { timestamp: number, group: string } const groups = reactive( new Map>([ [DEFAULT_ALERT_GROUP, new Map()], ]), ) /** * @description Composable to access alert groups, alerts and functions to add, remove and get alerts by group. * @example * const { groups, alerts, addAlert, removeAlert, getAlerts } = useAlert() * addAlert({ * title: 'Success!', * modifiers: 'success', * }) * * `` * * @returns { * alerts: ComputedRef reactive list of alerts default group, * groups: ReactiveRef>>, * addAlert: Function to add alert, * removeAlert: Function to remove alert, * getAlerts: Function to get alerts by group * } the reactive list of alerts, groups, addAlert, removeAlert and getAlerts functions */ export function useAlert() { const addAlert = ( { id = crypto.randomUUID(), group = DEFAULT_ALERT_GROUP, title, icon = DEFAULT_ALERT_INFO_ICON, content, footer, modifiers = DEFAULT_ALERT_MODIFIERS, dismissable = DEFAULT_ALERT_DISMISSABLE, autoClose = DEFAULT_ALERT_AUTO_CLOSE, timestamp = Date.now(), } = {} as Partial, ) => { if (!groups.has(group)) { groups.set(group, new Map()) } const groupMap = groups.get(group) const normalizedModifiers = typeof modifiers === 'string' ? modifiers.split(' ') : modifiers if (!icon) { const alertModifier = normalizedModifiers.find(modifier => DefaultAlertIconMap.has(modifier), ) if (alertModifier) { icon = DefaultAlertIconMap.get(alertModifier) as string } } groupMap?.set(id.toString(), { id, group, title, icon, content, footer, modifiers, dismissable, autoClose, timestamp, }) } const removeAlert = (id: string | number, group = DEFAULT_ALERT_GROUP) => { const groupMap = groups.get(group) groupMap?.delete(id.toString()) } const getAlerts = (group = DEFAULT_ALERT_GROUP) => { return computed(() => { const groupMap = groups.get(group) return groupMap && groupMap instanceof Map ? [...groupMap.values()].toSorted( (a, b) => a.timestamp - b.timestamp, ) : [] }) } return { groups, alerts: getAlerts(), addAlert, removeAlert, getAlerts, } }