From f64d1272fbf8d98c7787805f74e740d558a2a28e Mon Sep 17 00:00:00 2001 From: Dima K Date: Tue, 17 Feb 2026 12:45:55 -0800 Subject: [PATCH 1/4] feat(ui): wip on grouping filters for examiners --- .../app/components/Table/Header/Select.vue | 35 +++++++++++++++- strr-examiner-web/app/pages/dashboard.vue | 40 +++++++++++-------- 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/strr-examiner-web/app/components/Table/Header/Select.vue b/strr-examiner-web/app/components/Table/Header/Select.vue index 92333ee87..6f8b55b54 100644 --- a/strr-examiner-web/app/components/Table/Header/Select.vue +++ b/strr-examiner-web/app/components/Table/Header/Select.vue @@ -8,6 +8,8 @@ const props = defineProps<{ label: string value: any disabled?: boolean + isChild?: boolean + childValues?: any[] }> sort?: TableSort searchable?: boolean @@ -40,6 +42,37 @@ const clearFilter = () => { filterModel.value = props.default ?? [] } +// Parent-child toggle logic for grouped options +const parentOptions = computed(() => props.options.filter(o => o.childValues?.length)) +const isAdjusting = ref(false) + +watch(filterModel, (newVal, oldVal) => { + if (isAdjusting.value || !parentOptions.value.length) { return } + isAdjusting.value = true + + const prev = new Set(oldVal) + const result = new Set(newVal) + + for (const { value: parentVal, childValues } of parentOptions.value) { + const parentChecked = result.has(parentVal) && !prev.has(parentVal) + const parentUnchecked = !result.has(parentVal) && prev.has(parentVal) + const allChildrenSelected = childValues.every(c => result.has(c)) + + if (parentChecked) { + childValues.forEach(c => result.add(c)) + } else if (parentUnchecked) { + childValues.forEach(c => result.delete(c)) + } else if (allChildrenSelected) { + result.add(parentVal) + } else { + result.delete(parentVal) + } + } + + filterModel.value = [...result] + nextTick(() => { isAdjusting.value = false }) +}) + const filterColumnRef = ref(null) const initialWidth = ref('auto') @@ -82,7 +115,6 @@ onMounted(() => { clear-search-on-close >