diff --git a/packages/frontend-2/components/viewer/controls/Left.vue b/packages/frontend-2/components/viewer/controls/Left.vue index 9cbda8335..a4a46e20e 100644 --- a/packages/frontend-2/components/viewer/controls/Left.vue +++ b/packages/frontend-2/components/viewer/controls/Left.vue @@ -133,7 +133,7 @@ :style="`width: ${widthClass};`" > - + @@ -167,6 +167,7 @@ import { useIntercomEnabled } from '~~/lib/intercom/composables/enabled' import { viewerDocsRoute } from '~~/lib/common/helpers/route' import { useAreSavedViewsEnabled } from '~/lib/viewer/composables/savedViews/general' import { Camera } from 'lucide-vue-next' +import { ModelsSubView } from '~~/lib/viewer/helpers/sceneExplorer' type ActivePanel = | 'none' @@ -237,6 +238,7 @@ const { $intercom } = useNuxtApp() const { hasActiveFilters } = useFilterUtilities() const activePanel = ref('none') +const modelsSubView = ref(ModelsSubView.Main) const hasActivePanel = computed(() => activePanel.value !== 'none') @@ -277,7 +279,28 @@ registerShortcuts({ const toggleActivePanel = (panel: ActivePanel) => { const wasNone = activePanel.value === 'none' - activePanel.value = activePanel.value === panel ? 'none' : panel + + if (panel === 'models') { + if (activePanel.value === 'models') { + if ( + modelsSubView.value === ModelsSubView.Versions || + modelsSubView.value === ModelsSubView.Diff + ) { + // Go back to main models view instead of closing + modelsSubView.value = ModelsSubView.Main + return + } else { + activePanel.value = 'none' + } + } else { + // Open models panel and reset to main view + activePanel.value = 'models' + modelsSubView.value = ModelsSubView.Main + } + } else { + activePanel.value = activePanel.value === panel ? 'none' : panel + modelsSubView.value = ModelsSubView.Main + } // If a panel is being opened (not closed) on mobile, emit event to parent if (wasNone && activePanel.value !== 'none' && isMobile.value) { diff --git a/packages/frontend-2/components/viewer/models/Panel.vue b/packages/frontend-2/components/viewer/models/Panel.vue index 26d7b63ed..f40c714a6 100644 --- a/packages/frontend-2/components/viewer/models/Panel.vue +++ b/packages/frontend-2/components/viewer/models/Panel.vue @@ -1,7 +1,12 @@ @@ -106,7 +111,7 @@ import { useInjectedViewerState } from '~~/lib/viewer/composables/setup' -import type { ExplorerNode } from '~~/lib/viewer/helpers/sceneExplorer' +import { ModelsSubView, type ExplorerNode } from '~~/lib/viewer/helpers/sceneExplorer' import type { ViewerLoadedResourcesQuery } from '~~/lib/common/generated/gql/graphql' import type { Get } from 'type-fest' import { useDiffUtilities, useSelectionUtilities } from '~~/lib/viewer/composables/ui' @@ -118,12 +123,11 @@ import { useVirtualList, useDebounceFn } from '@vueuse/core' type ModelItem = NonNullable> -defineEmits(['close']) - -const showVersions = ref(false) -const showAddModel = ref(false) +const subView = defineModel('subView', { default: ModelsSubView.Main }) const expandedModelId = ref(null) +const showAddModel = ref(false) + const expandedNodes = ref>(new Set()) const expandedModels = ref>(new Set()) const disableScrollOnNextSelection = ref(false) @@ -139,7 +143,8 @@ const { const { resources: { response: { resourceItems: stateResourceItems } - } + }, + ui: { diff: diffState } } = useInjectedViewerState() const { objects: selectedObjects, @@ -147,7 +152,7 @@ const { clearSelection, removeFromSelection } = useSelectionUtilities() -const { diffModelVersions } = useDiffUtilities() +const { diffModelVersions, endDiff } = useDiffUtilities() const { flattenModelTree, getRootNodesForModel, @@ -211,22 +216,31 @@ const modelHeaderPositions = computed(() => { return headers }) +const hasDiffActive = computed(() => { + return !!(diffState.oldVersion.value && diffState.newVersion.value) +}) + const handleShowVersions = (modelId: string) => { expandedModelId.value = modelId - showVersions.value = true + subView.value = ModelsSubView.Versions } const handleShowDiff = async (modelId: string, versionA: string, versionB: string) => { await diffModelVersions(modelId, versionA, versionB) expandedModelId.value = modelId - showVersions.value = true + subView.value = ModelsSubView.Diff } const handleVersionsClose = () => { - showVersions.value = false + subView.value = ModelsSubView.Main expandedModelId.value = null } +const handleDiffClose = async () => { + await endDiff() + subView.value = ModelsSubView.Versions +} + const toggleModelExpansion = (modelId: string) => { if (expandedModels.value.has(modelId)) { expandedModels.value.delete(modelId) @@ -383,6 +397,18 @@ const handleScroll = (e: Event) => { watch(selectedObjects, handleSelectionChange, { deep: true }) +watch(subView, (newSubView) => { + if (newSubView === ModelsSubView.Main) { + expandedModelId.value = null + } +}) + +watch(hasDiffActive, (isActive) => { + if (isActive && subView.value !== ModelsSubView.Diff) { + subView.value = ModelsSubView.Diff + } +}) + // Initialize and update sticky header when models change watch( unifiedVirtualItems, diff --git a/packages/frontend-2/components/viewer/models/versions/Versions.vue b/packages/frontend-2/components/viewer/models/versions/Versions.vue index b3773f815..1f0e1b06f 100644 --- a/packages/frontend-2/components/viewer/models/versions/Versions.vue +++ b/packages/frontend-2/components/viewer/models/versions/Versions.vue @@ -1,58 +1,51 @@