@cryptotaxi247 / CoPilot / commits / fbb26f5b

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 +}