main
vue 143 lines 3.57 KB
Raw
1 <template>
2 <div class="page">
3 <div class="section">
4 <IndicesMarquee :indices @click="setIndex" />
5 </div>
6
7 <div class="section">
8 <Details v-model="currentIndex" :indices />
9 </div>
10
11 <div class="section">
12 <div class="columns flex">
13 <div class="col basis-1/2">
14 <ClusterHealth class="stretchy" />
15 </div>
16 <div class="col basis-1/2">
17 <UnhealthyIndices :indices class="stretchy" @click="setIndex" />
18 </div>
19 </div>
20 </div>
21
22 <div class="section">
23 <CustomerIndicesSize @click="setIndex" />
24 </div>
25
26 <n-card class="section overflow-hidden" content-style="padding:0">
27 <div class="columns column-1200 flex gap-0!">
28 <div class="col basis-2/5">
29 <NodeAllocation class="stretchy" style="border-radius: 0" :bordered="false" />
30 </div>
31 <div class="col basis-3/5 overflow-hidden">
32 <TopIndices :indices style="border-radius: 0" :bordered="false" />
33 </div>
34 </div>
35 </n-card>
36 </div>
37 </template>
38
39 <script lang="ts" setup>
40 // TODO-FE: refactor
41 import type { IndexStats } from "@/types/indices.d"
42 import { NCard, useMessage } from "naive-ui"
43 import { defineAsyncComponent, onBeforeMount, ref } from "vue"
44 import { useRoute } from "vue-router"
45 import Api from "@/api"
46 import ClusterHealth from "@/components/indices/ClusterHealth.vue"
47 import CustomerIndicesSize from "@/components/indices/CustomerIndicesSize.vue"
48 import Details from "@/components/indices/Details.vue"
49 import IndicesMarquee from "@/components/indices/Marquee.vue"
50 import NodeAllocation from "@/components/indices/NodeAllocation.vue"
51 import UnhealthyIndices from "@/components/indices/UnhealthyIndices.vue"
52
53 const TopIndices = defineAsyncComponent(() => import("@/components/indices/TopIndices.vue"))
54
55 const message = useMessage()
56 const route = useRoute()
57 const indices = ref<IndexStats[] | null>(null)
58 const loadingIndex = ref(false)
59 const currentIndex = ref<IndexStats | null>(null)
60 const requestedIndex = ref<string | null>(null)
61
62 function setIndex(index: IndexStats | string) {
63 if (typeof index === "string") {
64 const indexStats = indices.value?.find(o => o.index === index) || null
65 indexStats && (currentIndex.value = indexStats)
66 } else {
67 currentIndex.value = index
68 }
69 }
70
71 function getIndices(cb?: () => void) {
72 loadingIndex.value = true
73
74 Api.wazuh.indices
75 .getIndices()
76 .then(res => {
77 if (res.data.success) {
78 indices.value = res.data.indices_stats
79
80 if (cb) cb()
81 } else {
82 message.error(res.data?.message || "An error occurred. Please try again later.")
83 }
84 })
85 .catch(err => {
86 if (err.response?.status === 401) {
87 message.error(
88 err.response?.data?.message ||
89 "Wazuh-Indexer returned Unauthorized. Please check your connector credentials."
90 )
91 } else if (err.response?.status === 404) {
92 message.error(err.response?.data?.message || "No indices were found.")
93 } else {
94 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
95 }
96 })
97 .finally(() => {
98 loadingIndex.value = false
99 })
100 }
101
102 onBeforeMount(() => {
103 if (route.query?.index_name) {
104 requestedIndex.value = route.query.index_name.toString()
105 }
106
107 getIndices(() => {
108 requestedIndex.value && setIndex(requestedIndex.value)
109 })
110 })
111 </script>
112
113 <style lang="scss" scoped>
114 .page {
115 .section {
116 margin-bottom: calc(var(--spacing) * 6);
117
118 .columns {
119 display: flex;
120 gap: calc(var(--spacing) * 6);
121
122 .stretchy {
123 height: 100%;
124 }
125 }
126 }
127
128 @media (max-width: 1000px) {
129 .section {
130 .columns {
131 flex-direction: column;
132 }
133 }
134 }
135 @media (max-width: 1200px) {
136 .section {
137 .columns.column-1200 {
138 flex-direction: column;
139 }
140 }
141 }
142 }
143 </style>