From 2314af9825d145ef89326bb9bb21ead89033a203 Mon Sep 17 00:00:00 2001 From: bruno Date: Sat, 11 Jul 2026 09:11:46 -0400 Subject: [PATCH] fix: sidebar workspace tree collapses on navigation Root cause: sectionsOpen did not include workspace:true by default, and toggle state was not persisted. On every page navigation, sectionsOpen.workspace defaulted to undefined (falsy), hiding the workspace tree section. Fixes: - sectionsOpen now defaults with workspace:true - sectionsOpen persisted to localStorage on toggle and before navigation - beforeunload handler auto-saves expandedFolders + sectionsOpen (covers navigation for file clicks too) - navigateToFolder saves both expandedFolders and sectionsOpen --- app/templates/base.html | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/app/templates/base.html b/app/templates/base.html index 3676f31..6cf449a 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -496,8 +496,19 @@ favoriteIds: new Set([{% for p in favorite_pages %}'{{ p.id }}'{% if not loop.last %},{% endif %}{% endfor %}]), // ── Sections collapsible ── - sectionsOpen: { recents: true, private: true, meetings: true, favorites: true, agents: true, shared: true, apps: true }, - toggleSection(key) { this.sectionsOpen[key] = !this.sectionsOpen[key]; this.sectionsOpen = Object.assign({}, this.sectionsOpen); }, + sectionsOpen: (function() { + var def = { recents: true, private: true, meetings: true, favorites: true, agents: true, shared: true, apps: true, workspace: true }; + try { + var saved = JSON.parse(localStorage.getItem('fd_sections') || '{}'); + return Object.assign(def, saved); + } catch(e) { return def; } + })(), + toggleSection(key) { + this.sectionsOpen[key] = !this.sectionsOpen[key]; + this.sectionsOpen = Object.assign({}, this.sectionsOpen); + try { localStorage.setItem('fd_sections', JSON.stringify(this.sectionsOpen)); } + catch(e) {} + }, toggleWorkspaceMenu() { if (window.innerWidth <= 768) { this.mobileSidebarOpen = !this.mobileSidebarOpen; @@ -814,9 +825,11 @@ catch(e) {} }, navigateToFolder(id) { - // Save expansion state before navigating - try { localStorage.setItem('fd_expanded_folders', JSON.stringify(this.expandedFolders)); } - catch(e) {} + // Save expansion + sections state before navigating + try { + localStorage.setItem('fd_expanded_folders', JSON.stringify(this.expandedFolders)); + localStorage.setItem('fd_sections', JSON.stringify(this.sectionsOpen)); + } catch(e) {} window.location = `/local-workspace?folder=${id}`; }, @@ -841,6 +854,18 @@ } }; } + + // Auto-save sidebar state before navigation (covers clicks) + window.addEventListener('beforeunload', function() { + try { + var el = document.querySelector('[x-data]'); + if (el && el.__x) { + var data = el.__x.$data; + if (data.expandedFolders) localStorage.setItem('fd_expanded_folders', JSON.stringify(data.expandedFolders)); + if (data.sectionsOpen) localStorage.setItem('fd_sections', JSON.stringify(data.sectionsOpen)); + } + } catch(e) {} + }); {% block scripts %}{% endblock %}