main
vue 134 lines 4.06 KB
Raw
1 <template>
2 <div>
3 <CardEntity hoverable clickable @click="openDetails()">
4 <template v-if="alert" #headerMain>#{{ alert.alert_id }} - {{ alert.source }}</template>
5
6 <template v-if="alert?.alert_creation_time" #headerExtra>
7 <div class="flex items-center gap-2">
8 <span>{{ formatDate(alert.alert_creation_time, dFormats.datetime) }}</span>
9 <Icon :name="TimeIcon" :size="16" />
10 </div>
11 </template>
12
13 <template v-if="alert" #default>
14 <div class="flex flex-col gap-2">
15 <div>{{ alert.alert_name }}</div>
16 <div class="flex flex-wrap items-center gap-3">
17 <Badge
18 type="splitted"
19 bright
20 :color="
21 alert.status === 'OPEN'
22 ? 'danger'
23 : alert.status === 'IN_PROGRESS'
24 ? 'warning'
25 : 'success'
26 "
27 >
28 <template #iconLeft>
29 <Icon :name="StatusIcon" :size="14" />
30 </template>
31 <template #label>Status</template>
32 <template #value>{{ alert.status || "n/d" }}</template>
33 </Badge>
34
35 <Badge v-if="alert.report.severity_assessment" type="splitted" bright :color="severityColor">
36 <template #iconLeft>
37 <Icon :name="SeverityIcon" :size="14" />
38 </template>
39 <template #label>Severity</template>
40 <template #value>{{ alert.report.severity_assessment }}</template>
41 </Badge>
42
43 <Badge v-if="alert.assigned_to" type="splitted" bright color="success">
44 <template #iconLeft>
45 <Icon :name="AssigneeIcon" :size="14" />
46 </template>
47 <template #label>Assignee</template>
48 <template #value>{{ alert.assigned_to }}</template>
49 </Badge>
50
51 <Badge type="splitted">
52 <template #label>Customer</template>
53 <template #value>
54 <code class="text-primary leading-none">#{{ alert.customer_code }}</code>
55 </template>
56 </Badge>
57 </div>
58 </div>
59 </template>
60
61 <template v-if="alert" #footerMain>
62 <div class="text-secondary flex items-center gap-1 text-sm">
63 <Icon :name="ReportIcon" :size="14" />
64 <span>Report generated {{ formatDate(alert.report.created_at, dFormats.datetime) }}</span>
65 </div>
66 </template>
67 </CardEntity>
68
69 <n-modal
70 v-model:show="showDetails"
71 :style="{
72 maxWidth: tabActive === 'compare' ? 'min(1650px, 90vw)' : 'min(850px, 90vw)',
73 minHeight: 'min(540px, 90vh)',
74 overflow: 'hidden'
75 }"
76 content-class="p-0!"
77 display-directive="show"
78 preset="card"
79 :title="alertNameTruncated"
80 :bordered="false"
81 segmented
82 >
83 <AlertReportDetails v-if="alert" :alert @tab-change="handleTabChange" />
84 </n-modal>
85 </div>
86 </template>
87
88 <script setup lang="ts">
89 import type { AlertWithReport } from "@/types/aiAnalyst.d"
90 import _truncate from "lodash/truncate"
91 import { NModal } from "naive-ui"
92 import { computed, ref, toRefs } from "vue"
93 import Badge from "@/components/common/Badge.vue"
94 import CardEntity from "@/components/common/cards/CardEntity.vue"
95 import Icon from "@/components/common/Icon.vue"
96 import { useSettingsStore } from "@/stores/settings"
97 import { formatDate } from "@/utils/format"
98 import AlertReportDetails from "./AlertReportDetails.vue"
99
100 const props = defineProps<{
101 alertData: AlertWithReport
102 }>()
103
104 const { alertData } = toRefs(props)
105
106 const TimeIcon = "carbon:time"
107 const StatusIcon = "carbon:circle-dash"
108 const SeverityIcon = "carbon:warning-alt"
109 const AssigneeIcon = "carbon:user"
110 const ReportIcon = "carbon:document"
111
112 const dFormats = useSettingsStore().dateFormat
113 const showDetails = ref(false)
114 const alert = computed(() => alertData.value)
115 const alertNameTruncated = computed(() => _truncate(alert.value?.alert_name, { length: 50 }))
116
117 const tabActive = ref<string | null>(null)
118
119 const severityColor = computed(() => {
120 const severity = alert.value?.report.severity_assessment
121 if (severity === "Critical" || severity === "High") return "danger"
122 if (severity === "Medium") return "warning"
123 if (severity === "Low" || severity === "Informational") return "success"
124 return undefined
125 })
126
127 function openDetails() {
128 showDetails.value = true
129 }
130
131 function handleTabChange(value: string) {
132 tabActive.value = value || null
133 }
134 </script>