separate counts
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { FilteringExtension, type PropertyInfo, ViewerEvent } from '@speckle/viewer'
|
||||
import type { PropertyInfo } from '@speckle/viewer'
|
||||
import { useInjectedViewerState } from '~~/lib/viewer/composables/setup'
|
||||
import {
|
||||
ExistenceFilterCondition,
|
||||
@@ -6,66 +6,15 @@ import {
|
||||
} from '~/lib/viewer/helpers/filters/types'
|
||||
|
||||
/**
|
||||
* Get count of filtered objects directly from the viewer
|
||||
* Uses viewer events to stay in sync with the viewer's internal state
|
||||
* Get count of filtered objects from the viewer state.
|
||||
*/
|
||||
export function useFilteredObjectsCount() {
|
||||
const {
|
||||
viewer,
|
||||
ui: { filters }
|
||||
} = useInjectedViewerState()
|
||||
const filteredObjectsCount = ref(0)
|
||||
|
||||
const updateCount = () => {
|
||||
const filteringExtension = viewer.instance.getExtension(FilteringExtension)
|
||||
if (!filteringExtension) return
|
||||
|
||||
const isolatedObjects = filteringExtension.filteringState.isolatedObjects
|
||||
|
||||
const hasAppliedFilters = filters.propertyFilters.value.some(
|
||||
(f) =>
|
||||
f.isApplied &&
|
||||
(f.selectedValues.length > 0 ||
|
||||
('isDefaultAllSelected' in f && f.isDefaultAllSelected))
|
||||
)
|
||||
|
||||
if (!hasAppliedFilters) {
|
||||
filteredObjectsCount.value = 0
|
||||
return
|
||||
}
|
||||
|
||||
const rawCount = isolatedObjects?.length || 0
|
||||
|
||||
// Ghost object that is used to represent objects that don't match the filter
|
||||
const isGhostOnly = rawCount === 1 && isolatedObjects?.[0] === 'no-match-ghost-all'
|
||||
|
||||
if (isGhostOnly) {
|
||||
filteredObjectsCount.value = 0
|
||||
return
|
||||
}
|
||||
|
||||
const realObjectCount =
|
||||
isolatedObjects?.filter((id) => id !== 'no-match-ghost-all').length || 0
|
||||
filteredObjectsCount.value = realObjectCount
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const filteringExtension = viewer.instance.getExtension(FilteringExtension)
|
||||
|
||||
filteringExtension.on(ViewerEvent.FilteringStateSet, updateCount)
|
||||
|
||||
updateCount()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
const filteringExtension = viewer.instance?.getExtension(FilteringExtension)
|
||||
if (filteringExtension) {
|
||||
filteringExtension.removeListener(ViewerEvent.FilteringStateSet, updateCount)
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
filteredObjectsCount: readonly(filteredObjectsCount)
|
||||
filteredObjectsCount: readonly(filters.filteredObjectsCount)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -321,6 +321,7 @@ export type InjectableViewerState = Readonly<{
|
||||
|
||||
// Multi-filter system
|
||||
propertyFilters: Ref<FilterData[]>
|
||||
filteredObjectsCount: Ref<number>
|
||||
hasAnyFiltersApplied: ComputedRef<boolean>
|
||||
activeColorFilterId: Ref<string | null>
|
||||
}
|
||||
@@ -1131,6 +1132,7 @@ function setupInterfaceState(
|
||||
const selectedObjects = shallowRef<Raw<SpeckleObject>[]>([])
|
||||
|
||||
const propertyFilters = ref<FilterData[]>([])
|
||||
const filteredObjectsCount = ref(0)
|
||||
|
||||
// Track which filter is currently applying colors (only one at a time)
|
||||
const activeColorFilterId = ref<string | null>(null)
|
||||
@@ -1238,6 +1240,7 @@ function setupInterfaceState(
|
||||
selectedObjectIds,
|
||||
isolatedObjectsSet,
|
||||
propertyFilters,
|
||||
filteredObjectsCount,
|
||||
hasAnyFiltersApplied,
|
||||
activeColorFilterId
|
||||
},
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { FilteringExtension, ViewerEvent } from '@speckle/viewer'
|
||||
import { useInjectedViewerState } from '~/lib/viewer/composables/setup'
|
||||
import { useOnViewerLoadComplete } from '~/lib/viewer/composables/viewer'
|
||||
|
||||
/**
|
||||
* Integration composable that manages filteredObjectsCount in the viewer state.
|
||||
*/
|
||||
export const useFilteredObjectsCountPostSetup = () => {
|
||||
const {
|
||||
ui: { filters },
|
||||
viewer: { instance }
|
||||
} = useInjectedViewerState()
|
||||
|
||||
const updateCount = () => {
|
||||
const filteringExtension = instance.getExtension(FilteringExtension)
|
||||
if (!filteringExtension) return
|
||||
|
||||
const isolatedObjects = filteringExtension.filteringState.isolatedObjects
|
||||
|
||||
const hasAppliedFilters = filters.propertyFilters.value.some(
|
||||
(f) =>
|
||||
f.isApplied &&
|
||||
(f.selectedValues.length > 0 ||
|
||||
('isDefaultAllSelected' in f && f.isDefaultAllSelected))
|
||||
)
|
||||
|
||||
if (!hasAppliedFilters) {
|
||||
filters.filteredObjectsCount.value = 0
|
||||
return
|
||||
}
|
||||
|
||||
const rawCount = isolatedObjects?.length || 0
|
||||
|
||||
// Ghost object that is used to represent objects that don't match the filter
|
||||
const isGhostOnly = rawCount === 1 && isolatedObjects?.[0] === 'no-match-ghost-all'
|
||||
|
||||
if (isGhostOnly) {
|
||||
filters.filteredObjectsCount.value = 0
|
||||
return
|
||||
}
|
||||
|
||||
const realObjectCount =
|
||||
isolatedObjects?.filter((id) => id !== 'no-match-ghost-all').length || 0
|
||||
filters.filteredObjectsCount.value = realObjectCount
|
||||
}
|
||||
|
||||
useOnViewerLoadComplete(() => {
|
||||
const filteringExtension = instance.getExtension(FilteringExtension)
|
||||
|
||||
filteringExtension.on(ViewerEvent.FilteringStateSet, updateCount)
|
||||
updateCount()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
const filteringExtension = instance?.getExtension(FilteringExtension)
|
||||
if (filteringExtension) {
|
||||
filteringExtension.removeListener(ViewerEvent.FilteringStateSet, updateCount)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -59,6 +59,7 @@ import { useMeasurementsPostSetup } from '~/lib/viewer/composables/setup/measure
|
||||
import { useFilterColoringPostSetup } from '~/lib/viewer/composables/setup/coloring'
|
||||
import { usePropertyFilteringPostSetup } from '~/lib/viewer/composables/setup/propertyFiltering'
|
||||
import { useManualFilteringPostSetup } from '~/lib/viewer/composables/setup/manualFiltering'
|
||||
import { useFilteredObjectsCountPostSetup } from '~/lib/viewer/composables/setup/filteredObjectsCount'
|
||||
import { useFilterUtilities } from '~/lib/viewer/composables/filtering/filtering'
|
||||
import { cleanupFilteringDataStore } from '~/lib/viewer/composables/filtering/dataStore'
|
||||
import { cleanupValueGroupCountCache } from '~/lib/viewer/composables/filtering/counts'
|
||||
@@ -863,6 +864,7 @@ export function useViewerPostSetup() {
|
||||
useFilterColoringPostSetup()
|
||||
usePropertyFilteringPostSetup()
|
||||
useManualFilteringPostSetup()
|
||||
useFilteredObjectsCountPostSetup()
|
||||
useDisableZoomOnEmbed()
|
||||
useViewerCursorIntegration()
|
||||
useViewerTreeIntegration()
|
||||
|
||||
Reference in New Issue
Block a user