From 49c8d1b47d99852725bbd832c12dce8a90172aa7 Mon Sep 17 00:00:00 2001 From: Kristaps Fabians Geikins Date: Thu, 4 Sep 2025 09:43:48 +0300 Subject: [PATCH] feat(fe2): saved views panel keepalive (#5370) * feat(fe2): saved views panel keepalive * Remove KeepAlive. Add throttle --------- Co-authored-by: andrewwallacespeckle --- .../components/viewer/controls/Left.vue | 17 +++++++----- .../components/viewer/models/Panel.vue | 6 ++--- .../components/viewer/saved-views/Panel.vue | 7 ++++- .../frontend-2/lib/common/composables/dom.ts | 26 ++++++++++++++++++- 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/packages/frontend-2/components/viewer/controls/Left.vue b/packages/frontend-2/components/viewer/controls/Left.vue index b8f8bd498..92147ad3b 100644 --- a/packages/frontend-2/components/viewer/controls/Left.vue +++ b/packages/frontend-2/components/viewer/controls/Left.vue @@ -139,9 +139,10 @@ ]" :style="`width: ${widthClass};`" > - - - + @@ -154,10 +155,12 @@ :summary="summary" /> - + + + diff --git a/packages/frontend-2/components/viewer/models/Panel.vue b/packages/frontend-2/components/viewer/models/Panel.vue index 691f3eba1..d247047db 100644 --- a/packages/frontend-2/components/viewer/models/Panel.vue +++ b/packages/frontend-2/components/viewer/models/Panel.vue @@ -126,7 +126,7 @@ import { useTreeManagement, type UnifiedVirtualItem } from '~~/lib/viewer/composables/tree' -import { useVirtualList, useDebounceFn } from '@vueuse/core' +import { useVirtualList, useDebounceFn, useThrottleFn } from '@vueuse/core' type ModelItem = NonNullable> @@ -373,7 +373,7 @@ const handleSelectionChange = useDebounceFn( ) // Simple scroll tracking - just switch headers -const handleScroll = (e: Event) => { +const handleScroll = useThrottleFn((e: Event) => { const container = e.target as HTMLElement if (!container) return @@ -400,7 +400,7 @@ const handleScroll = (e: Event) => { versionId: currentHeader.versionId } } -} +}, 16) watch(selectedObjects, handleSelectionChange, { deep: true }) diff --git a/packages/frontend-2/components/viewer/saved-views/Panel.vue b/packages/frontend-2/components/viewer/saved-views/Panel.vue index 10574732b..298fafe83 100644 --- a/packages/frontend-2/components/viewer/saved-views/Panel.vue +++ b/packages/frontend-2/components/viewer/saved-views/Panel.vue @@ -78,7 +78,10 @@ -
+
project.value?.permissions.canCreateSavedView diff --git a/packages/frontend-2/lib/common/composables/dom.ts b/packages/frontend-2/lib/common/composables/dom.ts index 60edcc27e..f7c829371 100644 --- a/packages/frontend-2/lib/common/composables/dom.ts +++ b/packages/frontend-2/lib/common/composables/dom.ts @@ -1,6 +1,7 @@ import { TIME_MS, timeoutAt } from '@speckle/shared' -import { until } from '@vueuse/core' +import { until, useScroll } from '@vueuse/core' import DOMPurify from 'dompurify' +import type { ShallowRef } from 'vue' const purify = async (source: string) => { let purify: DOMPurify.DOMPurifyI @@ -55,3 +56,26 @@ export function usePurifiedHtml( purifiedHtml: computed(() => asyncData.data.value || '') } } + +/** + * KeepAlive loses scroll position - use this to cache and restore the position + * upon reactivation + */ +export const useKeepAliveScrollState = (el: ShallowRef) => { + const scrollTracker = useScroll(el, { + throttle: 100 + }) + + const retainedX = ref(scrollTracker.x.value) + const retainedY = ref(scrollTracker.y.value) + + onDeactivated(() => { + retainedX.value = scrollTracker.x.value + retainedY.value = scrollTracker.y.value + }) + + onActivated(() => { + scrollTracker.x.value = retainedX.value + scrollTracker.y.value = retainedY.value + }) +}