refactor(fe): filtering with saved views

refactor(fe): filtering with saved views
This commit is contained in:
andrewwallacespeckle
2025-09-08 15:51:45 +01:00
committed by GitHub
2 changed files with 58 additions and 0 deletions
@@ -4,6 +4,7 @@ import type {
StringPropertyInfo
} from '@speckle/viewer'
import { difference, uniq, partition } from 'lodash-es'
import { whenever } from '@vueuse/core'
import {
useInjectedViewerState,
type InjectableViewerState
@@ -597,6 +598,15 @@ export function useFilterUtilities(
explodeFactor.value = 0
}
// Store filters that need to be restored once data store is ready
const pendingFiltersToRestore = ref<Array<{
key: string | null
isApplied: boolean
selectedValues: string[]
id: string
condition: 'AND' | 'OR'
}> | null>(null)
/**
* Restores filters from serialized state
*/
@@ -615,6 +625,28 @@ export function useFilterUtilities(
const availableProperties = getPropertyOptionsFromDataStore()
// If data store is ready, restore immediately
if (availableProperties.length > 0) {
applyFiltersFromSerialized(serializedFilters, availableProperties)
} else {
// Store filters to restore later when data store is ready
pendingFiltersToRestore.value = serializedFilters
}
}
/**
* Actually applies the filters once we have the property data
*/
const applyFiltersFromSerialized = (
serializedFilters: Array<{
key: string | null
isApplied: boolean
selectedValues: string[]
id: string
condition: 'AND' | 'OR'
}>,
availableProperties: PropertyInfo[]
) => {
for (const serializedFilter of serializedFilters) {
if (serializedFilter.key) {
const propertyInfo = availableProperties.find(
@@ -731,6 +763,19 @@ export function useFilterUtilities(
}
}
// Watch for data store to become ready and restore pending filters
const shouldRestoreFilters = computed(() => {
return pendingFiltersToRestore.value && getPropertyOptionsFromDataStore().length > 0
})
whenever(shouldRestoreFilters, () => {
if (pendingFiltersToRestore.value) {
const availableProperties = getPropertyOptionsFromDataStore()
applyFiltersFromSerialized(pendingFiltersToRestore.value, availableProperties)
pendingFiltersToRestore.value = null
}
})
return {
isolateObjects,
unIsolateObjects,
@@ -114,6 +114,18 @@ export function useStateSerialization() {
: ('OR' as const)
}))
// Create legacy-compatible propertyFilter from first item in propertyFilters
const propertyFilter =
propertyFilters.length > 0
? {
key: propertyFilters[0].key,
isApplied: propertyFilters[0].isApplied
}
: {
key: null,
isApplied: false
}
return {
isolatedObjectIds: state.ui.filters.isolatedObjectIds.value,
hiddenObjectIds: state.ui.filters.hiddenObjectIds.value,
@@ -121,6 +133,7 @@ export function useStateSerialization() {
ret[obj.id] = obj.applicationId ?? null
return ret
}, {} as Record<string, string | null>),
propertyFilter, // ← Preserve legacy format for backwards compatibility
propertyFilters
}
})(),