main
vue 140 lines 3.45 KB
Raw
1 <template>
2 <div class="page">
3 <div class="header flex flex-wrap items-center justify-between gap-4">
4 <div class="info flex items-center gap-3">
5 <n-button size="small" type="primary" secondary :loading @click="getData()">
6 <template #icon>
7 <Icon :name="UpdatedIcon" :size="15" />
8 </template>
9 </n-button>
10 <span>Last check:</span>
11 <strong>{{ lastCheck ? formatDate(lastCheck, dFormats.datetimesec) : "..." }}</strong>
12 </div>
13
14 <div class="toolbar flex items-center gap-3">
15 <n-button v-if="!isRunning" size="small" type="primary" class="w-24!" @click="start()">
16 <template #icon>
17 <Icon :name="StartIcon" />
18 </template>
19 Start
20 </n-button>
21 <n-button v-if="isRunning" size="small" type="error" ghost class="w-24!" @click="stop()">
22 <template #icon>
23 <Icon :name="StopIcon" />
24 </template>
25 Stop
26 </n-button>
27 <n-select v-model:value="intervalSelected" size="small" :options="intervalOptions" class="w-36!" />
28 </div>
29 </div>
30
31 <div class="my-6">
32 <UncommittedEntries :value="uncommittedJournalEntries" />
33 </div>
34
35 <div>
36 <MetricsList :throughput-metrics />
37 </div>
38 </div>
39 </template>
40
41 <script setup lang="ts">
42 import type { ThroughputMetric } from "@/types/graylog/metrics.d"
43 import { useStorage } from "@vueuse/core"
44 import { NButton, NSelect, useMessage } from "naive-ui"
45 import { computed, nextTick, onBeforeMount, onBeforeUnmount, ref, watch } from "vue"
46 import Api from "@/api"
47 import Icon from "@/components/common/Icon.vue"
48 import MetricsList from "@/components/graylog/Metrics/List.vue"
49 import UncommittedEntries from "@/components/graylog/Metrics/UncommittedEntries.vue"
50 import { useSettingsStore } from "@/stores/settings"
51 import { formatDate } from "@/utils/format"
52
53 const UpdatedIcon = "carbon:update-now"
54 const StopIcon = "carbon:stop"
55 const StartIcon = "carbon:play"
56
57 const message = useMessage()
58 const loading = ref(false)
59 const uncommittedJournalEntries = ref(0)
60 const throughputMetrics = ref<ThroughputMetric[]>([])
61 const lastCheck = ref<null | Date>(null)
62 const getDataTimer = ref<NodeJS.Timeout | null>(null)
63 const dFormats = useSettingsStore().dateFormat
64 const intervalOptions = [
65 {
66 label: "1 Second",
67 value: 1000
68 },
69 {
70 label: "5 Seconds",
71 value: 5000
72 },
73 {
74 label: "10 Seconds",
75 value: 10000
76 },
77 {
78 label: "30 Seconds",
79 value: 30000
80 },
81 {
82 label: "1 Minute",
83 value: 60000
84 }
85 ]
86 const intervalSelected = useStorage<number>("metrics-interval", 5000, localStorage)
87
88 const isRunning = computed<boolean>(() => {
89 return !!getDataTimer.value
90 })
91
92 function getData() {
93 loading.value = true
94
95 Api.graylog
96 .getMetrics()
97 .then(res => {
98 if (res.data.success) {
99 throughputMetrics.value = res.data.throughput_metrics || []
100 uncommittedJournalEntries.value = res.data.uncommitted_journal_entries || 0
101 lastCheck.value = new Date()
102 } else {
103 message.warning(res.data?.message || "An error occurred. Please try again later.")
104 }
105 })
106 .catch(err => {
107 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
108 })
109 .finally(() => {
110 loading.value = false
111 })
112 }
113
114 function stop() {
115 if (getDataTimer.value !== null) {
116 clearInterval(getDataTimer.value)
117 getDataTimer.value = null
118 }
119 }
120
121 function start() {
122 getDataTimer.value = setInterval(getData, intervalSelected.value)
123 }
124
125 watch(intervalSelected, () => {
126 stop()
127 nextTick(() => {
128 start()
129 })
130 })
131
132 onBeforeMount(() => {
133 getData()
134 start()
135 })
136
137 onBeforeUnmount(() => {
138 stop()
139 })
140 </script>