Files
vigilcare-clinical/vigilcare-dashboard/src/stores/alerts.js
T

122 lines
3.3 KiB
JavaScript

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import * as alertsApi from '@/api/alerts'
import { detectNewCriticalAlerts } from '@/composables/criticalAlertDetect'
export const useAlertStore = defineStore('alerts', () => {
const alerts = ref([])
const loading = ref(false)
const statusFilter = ref(null)
const lastSeenAlertIds = ref([])
const bannerAlerts = ref([])
const pollSeeded = ref(false)
const openAlerts = computed(() => alerts.value.filter(a => a.status === 'OPEN'))
const criticalAlerts = computed(() => alerts.value.filter(a => a.severity === 'CRITICAL'))
function mergeBannerAlerts(newAlerts) {
const existingIds = new Set(bannerAlerts.value.map(alert => alert.id))
const merged = [...bannerAlerts.value]
for (const alert of newAlerts) {
if (!existingIds.has(alert.id)) merged.push(alert)
}
bannerAlerts.value = merged
}
function applyPollResults(items) {
const { newAlerts, nextSeenIds, seeded } = detectNewCriticalAlerts(
items,
lastSeenAlertIds.value,
pollSeeded.value,
)
lastSeenAlertIds.value = nextSeenIds
pollSeeded.value = seeded
if (newAlerts.length > 0) {
mergeBannerAlerts(newAlerts)
}
return newAlerts
}
async function loadAlerts(encounterId, status) {
loading.value = true
try {
const filter = status ?? statusFilter.value
const data = await alertsApi.fetchAlerts(encounterId, filter)
alerts.value = data.items
} catch (e) {
console.error('Failed to load alerts', e)
} finally {
loading.value = false
}
}
async function loadGlobalAlerts(status = 'OPEN') {
loading.value = true
try {
const data = await alertsApi.fetchAllAlerts(status)
alerts.value = data.items
} catch (e) {
console.error('Failed to load alerts', e)
} finally {
loading.value = false
}
}
async function pollOpenAlerts() {
try {
const items = await alertsApi.fetchAllOpenAlerts()
alerts.value = items
return applyPollResults(items)
} catch (e) {
console.error('Failed to poll alerts', e)
return []
}
}
function dismissBannerAlert(alertId) {
bannerAlerts.value = bannerAlerts.value.filter(alert => alert.id !== alertId)
}
function dismissAllBannerAlerts() {
bannerAlerts.value = []
}
async function acknowledge(alertId, note) {
const updated = await alertsApi.acknowledgeAlert(alertId, note || undefined)
const alert = alerts.value.find(a => a.id === alertId)
if (alert) {
alert.status = updated.status ?? 'ACKNOWLEDGED'
alert.acknowledgedBy = updated.acknowledgedBy ?? alert.acknowledgedBy
alert.acknowledgedAt = updated.acknowledgedAt ?? alert.acknowledgedAt
}
dismissBannerAlert(alertId)
return updated
}
async function resolve(alertId) {
await alertsApi.resolveAlert(alertId)
const alert = alerts.value.find(a => a.id === alertId)
if (alert) alert.status = 'RESOLVED'
dismissBannerAlert(alertId)
}
return {
alerts,
loading,
statusFilter,
lastSeenAlertIds,
bannerAlerts,
pollSeeded,
openAlerts,
criticalAlerts,
loadAlerts,
loadGlobalAlerts,
pollOpenAlerts,
dismissBannerAlert,
dismissAllBannerAlerts,
acknowledge,
resolve,
applyPollResults,
}
})