feat: add shared healthcheck filter state with default 1 day timeframe (#650)
Implemented a composable to synchronize healthcheck time filters across Wazuh and Velociraptor tabs, ensuring filter selections persist when switching between tabs. Set sensible default of 1 day.
oliver-oat committed
Feb 2, 2026 at 19:38 UTC
fbb26f5bca2818c9cc986c36e7725bbd8a0310d2
3 files changed
+45
-6
frontend/src/components/customers/CustomerItem.vue
+8
-1
@@ -211,7 +211,11 @@
211
<n-tab-pane name="Healthcheck Wazuh" tab="Healthcheck Wazuh" display-directive="show:lazy">
212
<n-scrollbar style="max-height: 470px" trigger="none">
213
<div class="p-6 pt-2">
214
- <CustomerHealthcheckList source="wazuh" :customer-code="customer.customer_code" />
214
+ <CustomerHealthcheckList
215
+ source="wazuh"
216
+ :customer-code="customer.customer_code"
217
+ v-model:filters="healthcheckFilters"
218
+ />
219
</div>
220
</n-scrollbar>
221
</n-tab-pane>
@@ -225,6 +229,7 @@
229
<CustomerHealthcheckList
230
source="velociraptor"
231
:customer-code="customer.customer_code"
232
+ v-model:filters="healthcheckFilters"
233
/>
234
</div>
235
</n-scrollbar>
@@ -259,6 +264,7 @@ import Api from "@/api"
264
import Badge from "@/components/common/Badge.vue"
265
import CardEntity from "@/components/common/cards/CardEntity.vue"
266
import Icon from "@/components/common/Icon.vue"
267
+import { useCustomerHealthcheckFilters } from "@/composables/useCustomerHealthcheckFilters"
268
import { hashMD5 } from "@/utils"
269
270
const props = defineProps<{
@@ -301,6 +307,7 @@ const message = useMessage()
307
const customerInfo = ref<Customer | null>(null)
308
const customerMeta = ref<CustomerMeta | null>(null)
309
const customerPortainerStackId = ref<number | null>(null)
310
+const { healthcheckFilters } = useCustomerHealthcheckFilters()
311
312
const loading = computed(() => loadingFull.value || loadingDelete.value)
313
const fallbackAvatar = computed(() => {
frontend/src/components/customers/healthcheck/CustomerHealthcheckList.vue
+25
-5
@@ -3,13 +3,13 @@
3
<div>
4
<n-input-group>
5
<n-select
6
- v-model:value="filters.unit"
6
+ v-model:value="filterUnit"
7
:options="unitOptions"
8
placeholder="Time unit"
9
clearable
10
class="w-28!"
11
/>
12
- <n-input-number v-model:value="filters.time" :min="1" clearable placeholder="Time" class="w-32!" />
12
+ <n-input-number v-model:value="filterTime" :min="1" clearable placeholder="Time" class="w-32!" />
13
</n-input-group>
14
</div>
15
</div>
@@ -58,16 +58,23 @@ import type { CustomerAgentHealth, CustomerHealthcheckSource } from "@/types/cus
58
import { watchDebounced } from "@vueuse/core"
59
import _get from "lodash/get"
60
import { NEmpty, NInputGroup, NInputNumber, NSelect, NSpin, useMessage } from "naive-ui"
61
-import { onBeforeMount, ref, watch } from "vue"
61
+import { computed, onBeforeMount, ref, watch } from "vue"
62
import Api from "@/api"
63
import Icon from "@/components/common/Icon.vue"
64
import CustomerHealthcheckItem from "./CustomerHealthcheckItem.vue"
65
66
-const { source, customerCode } = defineProps<{
66
+const props = defineProps<{
67
source: CustomerHealthcheckSource
68
customerCode: string
69
+ filters: Partial<{ time: number; unit: "minutes" | "hours" | "days" }>
70
}>()
71
72
+const emit = defineEmits<{
73
+ (e: "update:filters", value: Partial<{ time: number; unit: "minutes" | "hours" | "days" }>): void
74
+}>()
75
+
76
+const { source, customerCode } = props
77
+
78
const CheckIcon = "carbon:checkmark-outline"
79
const AlertIcon = "mdi:alert-outline"
80
@@ -82,7 +89,20 @@ const unitOptions = [
89
{ label: "Days", value: "days" }
90
]
91
85
-const filters = ref<Partial<{ time: number; unit: "minutes" | "hours" | "days" }>>({})
92
+const filters = computed({
93
+ get: () => props.filters,
94
+ set: (value) => emit("update:filters", value)
95
+})
96
+
97
+const filterTime = computed({
98
+ get: () => props.filters.time,
99
+ set: (value) => emit("update:filters", { ...props.filters, time: value })
100
+})
101
+
102
+const filterUnit = computed({
103
+ get: () => props.filters.unit,
104
+ set: (value) => emit("update:filters", { ...props.filters, unit: value })
105
+})
106
107
function getList() {
108
loading.value = true
frontend/src/composables/useCustomerHealthcheckFilters.ts
new
+12
@@ -0,0 +1,12 @@
1
+import { ref } from "vue"
2
+
3
+const healthcheckFilters = ref<Partial<{ time: number; unit: "minutes" | "hours" | "days" }>>({
4
+ time: 1,
5
+ unit: "days"
6
+})
7
+
8
+export function useCustomerHealthcheckFilters() {
9
+ return {
10
+ healthcheckFilters
11
+ }
12
+}