main
vue 185 lines 4.11 KB
Raw
1 <template>
2 <CardEntity class="index-card" :loading :class="[`health-${index.health}`]">
3 <div class="wrapper">
4 <div class="group">
5 <div class="box">
6 <div class="value">
7 {{ index.index }}
8 </div>
9 <div class="label">name</div>
10 </div>
11 <div class="box">
12 <div class="value align-center flex gap-2 uppercase">
13 <IndexIcon :health="index.health" color />
14 {{ index.health }}
15 </div>
16 <div class="label">health</div>
17 </div>
18 </div>
19 <div class="group">
20 <div class="box">
21 <div class="value">
22 {{ index.store_size }}
23 </div>
24 <div class="label">store_size</div>
25 </div>
26 <div class="box">
27 <div class="value">
28 {{ index.docs_count }}
29 </div>
30 <div class="label">docs_count</div>
31 </div>
32 <div class="box">
33 <div class="value">
34 {{ index.replica_count }}
35 </div>
36 <div class="label">replica_count</div>
37 </div>
38 </div>
39 <div v-if="showActions" class="actions group">
40 <div class="box">
41 <!--
42 <el-tooltip content="Rotate" placement="top" :show-arrow="false">
43 <el-button type="primary" :icon="RefreshIcon" circle />
44 </el-tooltip>
45 -->
46 <n-tooltip content="Delete">
47 Delete
48 <template #trigger>
49 <n-button quaternary circle type="error" @click.stop="handleDelete">
50 <template #icon>
51 <Icon :name="DeleteIcon" />
52 </template>
53 </n-button>
54 </template>
55 </n-tooltip>
56 </div>
57 </div>
58 </div>
59 </CardEntity>
60 </template>
61
62 <script setup lang="ts">
63 import type { IndexStats } from "@/types/indices.d"
64 import { NButton, NTooltip, useDialog, useMessage } from "naive-ui"
65 import { h, ref, toRefs } from "vue"
66 import Api from "@/api"
67 import CardEntity from "@/components/common/cards/CardEntity.vue"
68 import Icon from "@/components/common/Icon.vue"
69 import IndexIcon from "@/components/indices/IndexIcon.vue"
70
71 const props = defineProps<{
72 index: IndexStats
73 showActions?: boolean
74 }>()
75
76 const emit = defineEmits<{
77 (e: "delete"): void
78 }>()
79
80 const DeleteIcon = "ph:trash"
81
82 const { index, showActions } = toRefs(props)
83
84 const dialog = useDialog()
85 const message = useMessage()
86 const loading = ref(false)
87
88 function handleDelete() {
89 dialog.warning({
90 title: "Confirm",
91 content: () =>
92 h("div", {
93 innerHTML: `Are you sure you want to delete the index:<br/><strong>${index.value.index}</strong> ?`
94 }),
95 positiveText: "Yes I'm sure",
96 negativeText: "Cancel",
97 onPositiveClick: () => {
98 deleteIndex()
99 },
100 onNegativeClick: () => {
101 message.info("Delete canceled")
102 }
103 })
104 }
105
106 function deleteIndex() {
107 loading.value = true
108
109 Api.graylog
110 .deleteIndex(index.value.index)
111 .then(res => {
112 if (res.data.success) {
113 message.success("Index was successfully deleted.")
114
115 emit("delete")
116 } else {
117 message.error(res.data?.message || "An error occurred. Please try again later.")
118 }
119 })
120 .catch(err => {
121 if (err.response?.status === 401) {
122 message.error(
123 err.response?.data?.message ||
124 "Wazuh-Indexer returned Unauthorized. Please check your connector credentials."
125 )
126 } else if (err.response?.status === 404) {
127 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
128 } else {
129 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
130 }
131 })
132 .finally(() => {
133 loading.value = false
134 })
135 }
136 </script>
137
138 <style lang="scss" scoped>
139 .index-card {
140 .wrapper {
141 display: flex;
142 justify-content: space-between;
143 flex-wrap: wrap;
144 gap: calc(var(--spacing) * 6);
145
146 .group {
147 display: flex;
148 justify-content: space-between;
149 gap: calc(var(--spacing) * 6);
150 flex-grow: 1;
151 flex-wrap: wrap;
152
153 .box {
154 flex-grow: 1;
155
156 .value {
157 font-weight: bold;
158 margin-bottom: 2px;
159 }
160 .label {
161 white-space: nowrap;
162 font-size: var(--text-xs);
163 font-family: var(--font-family-mono);
164 opacity: 0.8;
165 }
166 }
167 &.actions {
168 flex-grow: 0;
169 }
170 }
171 }
172
173 &.health-green {
174 border-color: var(--success-color);
175 }
176
177 &.health-yellow {
178 border-color: var(--warning-color);
179 }
180
181 &.health-red {
182 border-color: var(--error-color);
183 }
184 }
185 </style>