main
vue 114 lines 3.11 KB
Raw
1 <template>
2 <div>
3 <CardEntity :status="statusType">
4 <template #headerMain>
5 <div class="flex items-center gap-2">
6 <span>{{ alert.check_name }}</span>
7 <n-tag
8 v-if="alert.status === InfluxDBAlertStatus.Active"
9 type="error"
10 size="small"
11 :bordered="false"
12 >
13 Active
14 </n-tag>
15 <n-tag v-else type="success" size="small" :bordered="false">Cleared</n-tag>
16 </div>
17 </template>
18 <template #headerExtra>
19 <div class="flex items-center gap-2">
20 <n-tag v-if="alert.severity" :type="severityTagType" size="small" :bordered="false">
21 {{ alert.severity.toUpperCase() }}
22 </n-tag>
23 <span>{{ formatDate(alert.time) }}</span>
24 </div>
25 </template>
26 <template #default>
27 <div class="flex items-center gap-3">
28 <div class="mt-1">
29 <Icon :name="severityIcon" :size="20" :class="severityIconClass" />
30 </div>
31 <div class="grow">
32 <div class="font-mono text-sm" v-html="formattedMessage"></div>
33 <div v-if="alert.sensor_type" class="mt-1 text-xs opacity-50">
34 Sensor: {{ alert.sensor_type }}
35 </div>
36 </div>
37 </div>
38 </template>
39 </CardEntity>
40 </div>
41 </template>
42
43 <script setup lang="ts">
44 import type { InfluxDBAlert } from "@/types/healthchecks.d"
45 import { NTag } from "naive-ui"
46 import { computed } from "vue"
47 import CardEntity from "@/components/common/cards/CardEntity.vue"
48 import Icon from "@/components/common/Icon.vue"
49 import { useSettingsStore } from "@/stores/settings"
50 import { InfluxDBAlertSeverity, InfluxDBAlertStatus } from "@/types/healthchecks.d"
51 import dayjs from "@/utils/dayjs"
52
53 const { alert } = defineProps<{ alert: InfluxDBAlert }>()
54
55 const NEWLINE_REGEX = /\r?\n/g
56
57 const formattedMessage = computed(() => {
58 return alert.message.replace(NEWLINE_REGEX, " <span class='mx-1'>•</span> ")
59 })
60
61 const statusType = computed(() => {
62 if (alert.severity === InfluxDBAlertSeverity.Critical) {
63 return "error"
64 } else if (alert.severity === InfluxDBAlertSeverity.Warning) {
65 return "warning"
66 }
67 return undefined
68 })
69
70 const severityTagType = computed(() => {
71 switch (alert.severity) {
72 case InfluxDBAlertSeverity.Critical:
73 return "error"
74 case InfluxDBAlertSeverity.Warning:
75 return "warning"
76 case InfluxDBAlertSeverity.Info:
77 return "info"
78 default:
79 return "success"
80 }
81 })
82
83 const severityIcon = computed(() => {
84 switch (alert.severity) {
85 case InfluxDBAlertSeverity.Critical:
86 return "carbon:warning-alt-filled"
87 case InfluxDBAlertSeverity.Warning:
88 return "carbon:warning"
89 case InfluxDBAlertSeverity.Info:
90 return "carbon:information-filled"
91 default:
92 return "carbon:checkmark-filled"
93 }
94 })
95
96 const severityIconClass = computed(() => {
97 switch (alert.severity) {
98 case InfluxDBAlertSeverity.Critical:
99 return "text-error-500"
100 case InfluxDBAlertSeverity.Warning:
101 return "text-warning-500"
102 case InfluxDBAlertSeverity.Info:
103 return "text-info-500"
104 default:
105 return "text-success-500"
106 }
107 })
108
109 const dFormats = useSettingsStore().dateFormat
110
111 function formatDate(timestamp: string | number | Date, utc: boolean = true): string {
112 return dayjs(timestamp).utc(utc).format(dFormats.datetime)
113 }
114 </script>