Skip to content

Commit 3759fc9

Browse files
committed
refactor: extract catalog and navigation composables from PolicyWorkbench
Extract two new composables to separate concerns: - useCatalogState.ts: Search filter, layout mode (cards/compact), collapse states - settingsFilter, catalogLayout, isCatalogCollapsed, categoryCollapsedState - toggleCatalogLayout(), toggleCatalogCollapsed(), toggleCategoryCollapsed() - Manages persistence via userConfigStore - useNavigation.ts: Scroll tracking, active category, IntersectionObserver - activeCategory, showBackToTop, category chip navigation - scrollToCategory(), attachScrollListener(), reconnectSectionObserver() - Navigation lock to prevent conflicts during smooth scroll - Blur management for focus ring cleanup These will be consumed by Catalog.vue component orchestrator, reducing monolithic component from 4095 to ~300 lines. Signed-off-by: Vitor Mattos <[email protected]>
1 parent 09f0e83 commit 3759fc9

2 files changed

Lines changed: 449 additions & 0 deletions

File tree

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2026 LibreCode coop and LibreCode contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { computed, ref } from 'vue'
7+
import { t } from '@nextcloud/l10n'
8+
import { useUserConfigStore } from '../../../../store/userconfig.js'
9+
import type { RealPolicySettingCategory } from '../settings/realTypes'
10+
11+
const CATALOG_LAYOUT_CONFIG_KEY = 'policy_workbench_catalog_compact_view'
12+
const CATALOG_COLLAPSED_CONFIG_KEY = 'policy_workbench_catalog_collapsed'
13+
const CATEGORY_ORDER: RealPolicySettingCategory[] = [
14+
'who-can-sign',
15+
'how-signing-works',
16+
'signer-experience',
17+
'what-gets-recorded',
18+
'time-and-limits',
19+
'trust-and-verification',
20+
'system-behavior',
21+
]
22+
23+
export function useCatalogState() {
24+
const userConfigStore = useUserConfigStore()
25+
const settingsFilter = ref('')
26+
const isSmallViewport = ref(false)
27+
const catalogLayout = ref<'cards' | 'compact'>('cards')
28+
const isCatalogCollapsed = ref(false)
29+
const categoryCollapsedState = ref<Record<RealPolicySettingCategory, boolean>>({
30+
'who-can-sign': false,
31+
'how-signing-works': false,
32+
'signer-experience': false,
33+
'what-gets-recorded': false,
34+
'time-and-limits': false,
35+
'trust-and-verification': false,
36+
'system-behavior': false,
37+
})
38+
39+
const hasActiveFilter = computed(() => settingsFilter.value.trim().length > 0)
40+
const effectiveCatalogLayout = computed(() => isSmallViewport.value ? 'cards' : catalogLayout.value)
41+
const catalogViewButtonLabel = computed(() => {
42+
return effectiveCatalogLayout.value === 'cards'
43+
? t('libresign', 'Switch to compact view')
44+
: t('libresign', 'Switch to card view')
45+
})
46+
const catalogCollapseButtonLabel = computed(() => {
47+
return isCatalogCollapsed.value
48+
? t('libresign', 'Expand settings categories')
49+
: t('libresign', 'Collapse settings categories')
50+
})
51+
52+
function clearSettingsFilter() {
53+
settingsFilter.value = ''
54+
}
55+
56+
function onSettingsFilterChange(value: string) {
57+
settingsFilter.value = value
58+
}
59+
60+
function toggleCatalogLayout() {
61+
catalogLayout.value = catalogLayout.value === 'cards' ? 'compact' : 'cards'
62+
userConfigStore.update({
63+
[CATALOG_LAYOUT_CONFIG_KEY]: catalogLayout.value === 'compact',
64+
})
65+
}
66+
67+
function toggleCatalogCollapsed() {
68+
isCatalogCollapsed.value = !isCatalogCollapsed.value
69+
userConfigStore.update({
70+
[CATALOG_COLLAPSED_CONFIG_KEY]: isCatalogCollapsed.value,
71+
})
72+
syncCatalogCollapsedFromSections()
73+
}
74+
75+
function toggleCategoryCollapsed(category: RealPolicySettingCategory) {
76+
categoryCollapsedState.value = {
77+
...categoryCollapsedState.value,
78+
[category]: !categoryCollapsedState.value[category],
79+
}
80+
persistCategoryCollapsedState()
81+
syncCatalogCollapsedFromSections()
82+
}
83+
84+
function syncCatalogCollapsedFromSections() {
85+
const allCollapsed = CATEGORY_ORDER.every(cat => categoryCollapsedState.value[cat])
86+
if (allCollapsed !== isCatalogCollapsed.value) {
87+
isCatalogCollapsed.value = allCollapsed
88+
userConfigStore.update({
89+
[CATALOG_COLLAPSED_CONFIG_KEY]: allCollapsed,
90+
})
91+
}
92+
}
93+
94+
function persistCategoryCollapsedState() {
95+
userConfigStore.update({
96+
[CATEGORY_ORDER[0] ? `${CATALOG_SECTION_COLLAPSED_CONFIG_KEY}` : 'temp']: categoryCollapsedState.value,
97+
})
98+
}
99+
100+
function isCategoryExpanded(category: RealPolicySettingCategory): boolean {
101+
return !categoryCollapsedState.value[category]
102+
}
103+
104+
return {
105+
// State
106+
settingsFilter,
107+
isSmallViewport,
108+
catalogLayout,
109+
isCatalogCollapsed,
110+
categoryCollapsedState,
111+
// Computed
112+
hasActiveFilter,
113+
effectiveCatalogLayout,
114+
catalogViewButtonLabel,
115+
catalogCollapseButtonLabel,
116+
// Methods
117+
clearSettingsFilter,
118+
onSettingsFilterChange,
119+
toggleCatalogLayout,
120+
toggleCatalogCollapsed,
121+
toggleCategoryCollapsed,
122+
isCategoryExpanded,
123+
syncCatalogCollapsedFromSections,
124+
persistCategoryCollapsedState,
125+
}
126+
}
127+
128+
const CATALOG_SECTION_COLLAPSED_CONFIG_KEY = 'policy_workbench_category_collapsed_state'

0 commit comments

Comments
 (0)