main
vue 107 lines 3.69 KB
Raw
1 <template>
2 <n-spin :show="loading" class="flex grow flex-col" content-class="flex grow flex-col">
3 <n-tabs
4 v-model:value="tabActive"
5 type="line"
6 animated
7 :tabs-padding="24"
8 class="grow"
9 pane-wrapper-class="flex grow flex-col"
10 >
11 <n-tab-pane name="summary" tab="Summary" display-directive="show:lazy" class="flex grow flex-col">
12 <div class="p-6 pt-3">
13 <div class="flex flex-col gap-4">
14 <div v-if="report?.severity_assessment" class="flex items-center gap-2">
15 <Badge type="splitted" bright :color="severityColor">
16 <template #label>Severity</template>
17 <template #value>{{ report.severity_assessment }}</template>
18 </Badge>
19 </div>
20 <CardKV v-if="report?.summary">
21 <template #key>Summary</template>
22 <template #value>{{ report.summary }}</template>
23 </CardKV>
24 <CardKV v-if="report?.recommended_actions">
25 <template #key>Recommended Actions</template>
26 <template #value>{{ report.recommended_actions }}</template>
27 </CardKV>
28 <div v-if="!report?.summary && !report?.recommended_actions">
29 <n-empty description="No summary available" class="h-40" />
30 </div>
31 </div>
32 </div>
33 </n-tab-pane>
34 <n-tab-pane name="report" tab="Full Report" display-directive="show:lazy">
35 <div class="p-6 pt-3">
36 <Markdown v-if="report?.report_markdown" :source="report.report_markdown" breaks />
37 <n-empty v-else description="No report content available" class="h-40" />
38 </div>
39 </n-tab-pane>
40 <n-tab-pane name="iocs" tab="IOCs" display-directive="show:lazy">
41 <div class="p-6 pt-3">
42 <AlertReportIocsList :alert-id="alert.alert_id" />
43 </div>
44 </n-tab-pane>
45 <n-tab-pane name="jobs" tab="Jobs" display-directive="show:lazy">
46 <div class="p-6 pt-3">
47 <AlertReportJobsList :alert-id="alert.alert_id" />
48 </div>
49 </n-tab-pane>
50 <n-tab-pane name="review" tab="Review" display-directive="show:lazy">
51 <div class="p-6 pt-3">
52 <AlertReportReviewPanel :report />
53 </div>
54 </n-tab-pane>
55 <n-tab-pane name="compare" tab="Compare" display-directive="show:lazy">
56 <div class="p-6 pt-3">
57 <AlertReportCompare :alert-id="alert.alert_id" :current-report-id="report.id" />
58 </div>
59 </n-tab-pane>
60 </n-tabs>
61 </n-spin>
62 </template>
63
64 <script setup lang="ts">
65 import type { AlertWithReport } from "@/types/aiAnalyst.d"
66 import { NEmpty, NSpin, NTabPane, NTabs } from "naive-ui"
67 import { computed, defineAsyncComponent, ref, toRefs, watch } from "vue"
68 import Badge from "@/components/common/Badge.vue"
69 import CardKV from "@/components/common/cards/CardKV.vue"
70 import Markdown from "@/components/common/Markdown.vue"
71
72 const props = defineProps<{
73 alert: AlertWithReport
74 }>()
75
76 const emit = defineEmits<{
77 (e: "tab-change", value: string): void
78 }>()
79
80 const { alert } = toRefs(props)
81
82 const AlertReportIocsList = defineAsyncComponent(() => import("./AlertReportIocsList.vue"))
83 const AlertReportJobsList = defineAsyncComponent(() => import("./AlertReportJobsList.vue"))
84 const AlertReportReviewPanel = defineAsyncComponent(() => import("./AlertReportReviewPanel/AlertReportReviewPanel.vue"))
85 const AlertReportCompare = defineAsyncComponent(() => import("./AlertReportCompare/AlertReportCompare.vue"))
86
87 const tabActive = ref("summary")
88
89 const loading = ref(false)
90 const report = computed(() => alert.value.report)
91
92 const severityColor = computed(() => {
93 const severity = report.value?.severity_assessment
94 if (severity === "Critical" || severity === "High") return "danger"
95 if (severity === "Medium") return "warning"
96 if (severity === "Low" || severity === "Informational") return "success"
97 return undefined
98 })
99
100 watch(
101 tabActive,
102 value => {
103 emit("tab-change", value)
104 },
105 { immediate: true }
106 )
107 </script>