main
vue 168 lines 4.82 KB
Raw
1 <template>
2 <n-spin :show="loading" class="flex grow flex-col" content-class="flex grow flex-col">
3 <div class="flex grow flex-col justify-between gap-4">
4 <div class="content-box flex flex-col gap-4 py-3">
5 <div class="flex flex-col gap-4 px-7 sm:flex-row!">
6 <CardKV :color="query.active ? 'success' : undefined" size="lg" class="w-full grow">
7 <template #key>
8 <div class="flex items-center gap-2">
9 <Icon :name="query.active ? EnabledIcon : DisabledIcon" />
10 <span>Status</span>
11 </div>
12 </template>
13 <template #value>
14 <div class="flex">
15 <QueryActiveForm
16 v-slot="{ loading: loadingActive, togglePopup: toggleActivePopup }"
17 :query
18 @updated="updateQuery($event)"
19 >
20 <div
21 class="flex items-center gap-3"
22 :class="{
23 'cursor-not-allowed': loadingActive,
24 'cursor-pointer': !loadingActive
25 }"
26 @click.stop="toggleActivePopup()"
27 >
28 <span>{{ query.active ? "Active" : "Inactive" }}</span>
29 <n-spin
30 :size="14"
31 :show="loadingActive"
32 content-class="flex flex-col justify-center"
33 >
34 <Icon :name="EditIcon" />
35 </n-spin>
36 </div>
37 </QueryActiveForm>
38 </div>
39 </template>
40 </CardKV>
41
42 <CardKV size="lg" class="w-full grow">
43 <template #key>
44 <div class="flex items-center gap-2">
45 <Icon :name="TimeIntervalIcon" />
46 <span>Time Interval</span>
47 </div>
48 </template>
49 <template #value>
50 <div class="flex">
51 <QueryTimeIntervalForm
52 v-slot="{ loading: loadingTimeInterval, togglePopup: toggleTimeIntervalPopup }"
53 :query
54 @updated="updateQuery($event)"
55 >
56 <div
57 class="flex items-center gap-3"
58 :class="{
59 'cursor-not-allowed': loadingTimeInterval,
60 'cursor-pointer': !loadingTimeInterval
61 }"
62 @click.stop="toggleTimeIntervalPopup()"
63 >
64 <span>{{ query.time_interval || "n/d" }}</span>
65 <n-spin
66 :size="14"
67 :show="loadingTimeInterval"
68 content-class="flex flex-col justify-center"
69 >
70 <Icon :name="EditIcon" />
71 </n-spin>
72 </div>
73 </QueryTimeIntervalForm>
74 </div>
75 </template>
76 </CardKV>
77 </div>
78
79 <div class="px-7">
80 <CardKV>
81 <template #key>name</template>
82 <template #value>
83 {{ query.rule_name ?? "-" }}
84 </template>
85 </CardKV>
86 </div>
87
88 <div class="grid-auto-fit-250 grid gap-2 px-7">
89 <CardKV>
90 <template #key>last execution time</template>
91 <template #value>
92 {{
93 query.last_execution_time
94 ? formatDate(query.last_execution_time, dFormats.datetimesec)
95 : "n/d"
96 }}
97 </template>
98 </CardKV>
99
100 <CardKV>
101 <template #key>last updated</template>
102 <template #value>
103 {{ query.last_updated ? formatDate(query.last_updated, dFormats.datetimesec) : "n/d" }}
104 </template>
105 </CardKV>
106 </div>
107 </div>
108
109 <div class="footer-box bg-secondary flex items-center gap-2 px-7 py-4">
110 <div class="grow"></div>
111
112 <QueryDeleteOne
113 v-slot="{ loading: loadingDelete, togglePopup: toggleDeletePopup }"
114 :query
115 @deleted="emit('deleted', query)"
116 >
117 <n-button type="error" secondary :loading="loadingDelete" @click.stop="toggleDeletePopup()">
118 <template #icon>
119 <Icon :name="TrashIcon" />
120 </template>
121 Delete
122 </n-button>
123 </QueryDeleteOne>
124 </div>
125 </div>
126 </n-spin>
127 </template>
128
129 <script setup lang="ts">
130 import type { SigmaQuery } from "@/types/sigma.d"
131 import { NButton, NSpin } from "naive-ui"
132 import { ref, toRefs } from "vue"
133 import CardKV from "@/components/common/cards/CardKV.vue"
134 import Icon from "@/components/common/Icon.vue"
135 import { useSettingsStore } from "@/stores/settings"
136 import { formatDate } from "@/utils/format"
137 import QueryActiveForm from "./actionsProviders/QueryActiveForm.vue"
138 import QueryDeleteOne from "./actionsProviders/QueryDeleteOne.vue"
139 import QueryTimeIntervalForm from "./actionsProviders/QueryTimeIntervalForm.vue"
140
141 const props = defineProps<{ query: SigmaQuery }>()
142
143 const emit = defineEmits<{
144 (e: "deleted", value: SigmaQuery): void
145 (e: "updated", value: SigmaQuery): void
146 }>()
147
148 const { query } = toRefs(props)
149
150 const TrashIcon = "carbon:trash-can"
151 const TimeIntervalIcon = "material-symbols:autoplay"
152 const EditIcon = "uil:edit-alt"
153 const EnabledIcon = "carbon:circle-solid"
154 const DisabledIcon = "carbon:subtract-alt"
155
156 const dFormats = useSettingsStore().dateFormat
157 const loading = ref(false)
158
159 function updateQuery(updatedQuery: SigmaQuery) {
160 emit("updated", updatedQuery)
161 }
162 </script>
163
164 <style lang="scss" scoped>
165 .footer-box {
166 border-top: 1px solid var(--border-color);
167 }
168 </style>