main
vue 90 lines 2.45 KB
Raw
1 <template>
2 <n-drawer v-model:show="showDrawer" :width="600" class="max-w-[90vw]" :trap-focus="false">
3 <n-drawer-content title="Event Details" closable :native-scrollbar="false">
4 <div class="divide-border divide-y">
5 <div
6 v-for="[key, value] in sortedEventFields"
7 :key
8 class="group flex items-start justify-between gap-5 py-3"
9 >
10 <div class="shrink-0 font-mono text-xs font-semibold">
11 {{ key }}
12 </div>
13 <div class="flex items-start justify-end gap-2">
14 <div class="flex-1 text-right text-sm break-all">
15 {{ formatValue(value) }}
16 </div>
17 <div
18 class="flex shrink-0 items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100"
19 >
20 <n-button title="Filter for this value" text @click="addFilter(key, String(value))">
21 <template #icon>
22 <Icon name="carbon:add" />
23 </template>
24 </n-button>
25 <n-button title="Exclude this value" text @click="excludeFilter(key, String(value))">
26 <template #icon>
27 <Icon name="carbon:subtract" />
28 </template>
29 </n-button>
30 </div>
31 </div>
32 </div>
33 </div>
34 </n-drawer-content>
35 </n-drawer>
36 </template>
37
38 <script setup lang="tsx">
39 import type { EventSearchResult } from "@/types/siem"
40 import { NButton, NDrawer, NDrawerContent } from "naive-ui"
41 import { computed, ref, toRefs, watch } from "vue"
42 import Icon from "@/components/common/Icon.vue"
43
44 const props = defineProps<{
45 event: EventSearchResult | null
46 }>()
47
48 const emit = defineEmits<{
49 (e: "filter-add", field: string, value: string): void
50 (e: "filter-exclude", field: string, value: string): void
51 (e: "close"): void
52 }>()
53
54 const { event: selectedEvent } = toRefs(props)
55
56 const showDrawer = ref<boolean>(false)
57
58 const sortedEventFields = computed(() => {
59 if (!selectedEvent.value) return []
60 return Object.entries(selectedEvent.value)
61 .filter(([key]) => !key.startsWith("_"))
62 .sort(([a], [b]) => a.localeCompare(b))
63 })
64
65 function addFilter(field: string, value: string) {
66 emit("filter-add", field, value)
67 }
68
69 function excludeFilter(field: string, value: string) {
70 emit("filter-exclude", field, value)
71 }
72
73 function formatValue(value: unknown): string {
74 if (value === null || value === undefined) return "-"
75 if (typeof value === "object") return JSON.stringify(value)
76 return String(value)
77 }
78
79 watch(selectedEvent, newVal => {
80 if (newVal) {
81 showDrawer.value = true
82 }
83 })
84
85 watch(showDrawer, newVal => {
86 if (!newVal) {
87 emit("close")
88 }
89 })
90 </script>