main
vue 171 lines 4.38 KB
Raw
1 <template>
2 <div class="monitoring-alert-list">
3 <div class="header flex items-center justify-end gap-2">
4 <div class="info flex grow gap-2">
5 <n-popover overlap placement="bottom-start">
6 <template #trigger>
7 <div class="bg-default rounded-lg">
8 <n-button size="small" class="cursor-help!">
9 <template #icon>
10 <Icon :name="InfoIcon" />
11 </template>
12 </n-button>
13 </div>
14 </template>
15 <div class="flex flex-col gap-2">
16 <div class="box">
17 Total :
18 <code>{{ total }}</code>
19 </div>
20 <div class="box text-success">
21 Enabled :
22 <code>{{ enabledTotal }}</code>
23 </div>
24 </div>
25 </n-popover>
26 <CustomAlertButton />
27 </div>
28 <n-pagination
29 v-model:page="currentPage"
30 v-model:page-size="pageSize"
31 :page-slot
32 :show-size-picker
33 :page-sizes
34 :item-count="total"
35 :simple="simpleMode"
36 />
37 </div>
38 <n-spin :show="loading">
39 <div class="my-3 flex min-h-52 flex-col gap-2">
40 <template v-if="alerts.length">
41 <MonitoringAlert
42 v-for="alert of itemsPaginated"
43 :key="alert.name"
44 :alert
45 :is-enabled="isEnabled(alert)"
46 @provisioned="getData()"
47 />
48 </template>
49 <template v-else>
50 <n-empty v-if="!loading" description="No items found" class="h-48 justify-center" />
51 </template>
52 </div>
53 </n-spin>
54 <div class="footer flex justify-end">
55 <n-pagination
56 v-if="itemsPaginated.length > 3"
57 v-model:page="currentPage"
58 :page-size
59 :item-count="total"
60 :page-slot="6"
61 />
62 </div>
63 </div>
64 </template>
65
66 <script setup lang="ts">
67 // TODO-FE: refactor
68 import type { EventDefinition } from "@/types/graylog/event-definition.d"
69 import type { AvailableMonitoringAlert } from "@/types/monitoringAlerts.d"
70 import { NButton, NEmpty, NPagination, NPopover, NSpin, useMessage } from "naive-ui"
71 import { computed, onBeforeMount, ref } from "vue"
72 import Api from "@/api"
73 import Icon from "@/components/common/Icon.vue"
74 import CustomAlertButton from "./CustomAlertButton.vue"
75 import MonitoringAlert from "./Item.vue"
76
77 const { eventsList } = defineProps<{ eventsList: EventDefinition[] }>()
78
79 const message = useMessage()
80 const loadingEvents = ref(false)
81 const loadingAlerts = ref(false)
82 const alerts = ref<AvailableMonitoringAlert[]>([])
83 const events = ref<EventDefinition[]>([])
84
85 const loading = computed(() => loadingAlerts.value || loadingEvents.value)
86
87 const pageSize = ref(25)
88 const currentPage = ref(1)
89 const simpleMode = ref(false)
90 const showSizePicker = ref(true)
91 const pageSizes = [10, 25, 50, 100]
92 const pageSlot = ref(8)
93
94 const InfoIcon = "carbon:information"
95
96 const total = computed<number>(() => {
97 return alerts.value.length || 0
98 })
99
100 const enabledList = computed<AvailableMonitoringAlert[]>(() => {
101 return alerts.value.filter(alert => {
102 const eventIndex = events.value.findIndex(event => event.title === alert.name)
103 return eventIndex !== -1
104 })
105 })
106
107 const enabledTotal = computed<number>(() => {
108 return enabledList.value.length || 0
109 })
110
111 const itemsPaginated = computed(() => {
112 const from = (currentPage.value - 1) * pageSize.value
113 const to = currentPage.value * pageSize.value
114
115 return alerts.value.slice(from, to)
116 })
117
118 function isEnabled(alert: AvailableMonitoringAlert): boolean {
119 return enabledList.value.findIndex(o => o.name === alert.name) !== -1
120 }
121
122 function getData() {
123 loadingAlerts.value = true
124
125 Api.monitoringAlerts
126 .getAvailableMonitoringAlerts()
127 .then(res => {
128 if (res.data.success) {
129 alerts.value = res.data.available_monitoring_alerts || []
130 } else {
131 message.warning(res.data?.message || "An error occurred. Please try again later.")
132 }
133 })
134 .catch(err => {
135 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
136 })
137 .finally(() => {
138 loadingAlerts.value = false
139 })
140 }
141
142 function getEvents() {
143 loadingEvents.value = true
144
145 Api.graylog
146 .getEventDefinitions()
147 .then(res => {
148 if (res.data.success) {
149 events.value = res.data.event_definitions || []
150 } else {
151 message.warning(res.data?.message || "An error occurred. Please try again later.")
152 }
153 })
154 .catch(err => {
155 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
156 })
157 .finally(() => {
158 loadingEvents.value = false
159 })
160 }
161
162 onBeforeMount(() => {
163 getData()
164
165 if (eventsList.length && !events.value.length) {
166 events.value = eventsList
167 } else {
168 getEvents()
169 }
170 })
171 </script>