From 92eec3f696f97e2deff9647c1b708807c3fa7d29 Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Tue, 25 Aug 2026 14:44:52 +0200 Subject: [PATCH] fix(datatables): make the database manager tree foldable and compact --- frontend/src/lib/components/DBManager.svelte | 96 ++++++++++++-------- 1 file changed, 58 insertions(+), 38 deletions(-) diff --git a/frontend/src/lib/components/DBManager.svelte b/frontend/src/lib/components/DBManager.svelte index 4c02f02a86..3f9f6c2ed2 100644 --- a/frontend/src/lib/components/DBManager.svelte +++ b/frontend/src/lib/components/DBManager.svelte @@ -212,25 +212,46 @@ ) }) - let expanded = $state>(new Set()) + // Explicit open/closed choices, over a default rule. Storing only the + // overrides is what lets the current data table and selected schema — which + // default to open — actually be folded; a plain "expanded" set could never + // close them, since the default would keep winning. + let expandOverrides = $state>(new Map()) const nodeKey = (dt: string | undefined, schemaKey?: string) => `${dt ?? ''}${schemaKey === undefined ? '' : `/${schemaKey}`}` - function toggle(key: string) { - const next = new Set(expanded) - next.has(key) ? next.delete(key) : next.add(key) - expanded = next - } - - // A node is open when explicitly expanded, when it holds the current selection, - // or when a search is narrowing the tree to what matched. - function isExpanded(dt: string | undefined, schemaKey?: string): boolean { - if (search.trim() !== '') return true - if (expanded.has(nodeKey(dt, schemaKey))) return true + function defaultExpanded(dt: string | undefined, schemaKey?: string): boolean { if (dt !== undefined && dt !== currentDatatable) return false return schemaKey === undefined || schemaKey === selected.schemaKey } + function isExpanded(dt: string | undefined, schemaKey?: string): boolean { + // A search narrows the tree to what matched, so everything left is shown. + if (search.trim() !== '') return true + return expandOverrides.get(nodeKey(dt, schemaKey)) ?? defaultExpanded(dt, schemaKey) + } + + function toggle(dt: string | undefined, schemaKey?: string) { + const key = nodeKey(dt, schemaKey) + const open = expandOverrides.get(key) ?? defaultExpanded(dt, schemaKey) + const next = new Map(expandOverrides) + next.set(key, !open) + expandOverrides = next + } + + /** Every row in the tree reads the same way: what you are looking at now is + * emphasized, everything else recedes. */ + const rowText = (current: boolean) => + current ? 'text-primary font-semibold' : 'text-secondary font-normal' + + /** Reveal a node, dropping a stale "closed" that would hide a new selection. */ + function reveal(dt: string | undefined, schemaKey?: string) { + const next = new Map(expandOverrides) + next.delete(nodeKey(dt)) + next.delete(nodeKey(dt, schemaKey)) + expandOverrides = next + } + function selectTable(dt: string | undefined, schemaKey: string, tableKey: string) { if (dt !== undefined && dt !== currentDatatable) { // Switching data table re-mounts this component against the new one, so @@ -241,6 +262,7 @@ onSelectDatatable?.(dt) return } + reveal(dt, schemaKey) selected = { schemaKey, tableKey } } @@ -534,16 +556,17 @@ {@const dtOpen = isExpanded(root.datatable)} {#if root.datatable !== undefined} {/if} {#if dtOpen} @@ -555,16 +578,21 @@ {@const indent = root.datatable !== undefined ? 'pl-6' : 'pl-2'} {#if dbSupportsSchemas} {/if} {#if schemaOpen || !dbSupportsSchemas} @@ -581,9 +609,11 @@ selected.schemaKey === sc.schemaKey && selected.tableKey === tableKey} - {/if} {#if tableKey && colDefs?.[tableKey]?.length}