diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 7d45903..a18b807 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -19,7 +19,7 @@ checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "agx" -version = "0.3.0" +version = "0.3.1" dependencies = [ "bindgen", "serde_json", diff --git a/src/lib/components/Datasets/Datasets.svelte b/src/lib/components/Datasets/Datasets.svelte index 6c70ae1..d370b6c 100644 --- a/src/lib/components/Datasets/Datasets.svelte +++ b/src/lib/components/Datasets/Datasets.svelte @@ -2,6 +2,8 @@ import type { Table } from '$lib/olap-engine'; import SearchBar from '$lib/components/SearchBar.svelte'; + import CollapseAll from '$lib/icons/CollapseAll.svelte'; + import { collapseAll, expandAll } from './emitter'; import Tree from './Tree.svelte'; import { buildTree, filter } from './utils'; @@ -14,19 +16,77 @@ let search = $state(''); const filtered = $derived(filter(tables, search)); const tree = $derived(buildTree(filtered)); + + $effect(() => { + if (search) expandAll(); + else collapseAll(); + }); -
+
+
+ +
{#each tree as node} - + {/each}
diff --git a/src/lib/components/Datasets/Tree.svelte b/src/lib/components/Datasets/Tree.svelte index ba24d80..a7954e4 100644 --- a/src/lib/components/Datasets/Tree.svelte +++ b/src/lib/components/Datasets/Tree.svelte @@ -2,35 +2,45 @@ import Folder from '$lib/icons/Folder.svelte'; import FolderOpen from '$lib/icons/FolderOpen.svelte'; import Table from '$lib/icons/Table.svelte'; + import { tick } from 'svelte'; import Columns from './Columns.svelte'; - import { onExpand } from './emitter'; + import { onCollapseAll, onExpand, onExpandAll } from './emitter'; import Tree from './Tree.svelte'; import { findNodeInTree, type TreeNode } from './utils'; interface Props { node: TreeNode; level?: number; - expanded?: boolean; } - let { node, level = 0, expanded: forceExpanded }: Props = $props(); + let { node, level = 0 }: Props = $props(); let expanded = $state(false); - $effect(() => { - if (typeof forceExpanded === 'boolean') expanded = forceExpanded; - }); + $effect(() => onCollapseAll(() => (expanded = false))); + $effect(() => onExpandAll(() => (expanded = true))); function toggleExpanded() { expanded = !expanded; } $effect(() => - onExpand((value) => { - if (node.type === 'dataset' && node.value === value) expanded = true; - else if (node.type === 'group' && findNodeInTree(node.children, value)) expanded = true; + onExpand(async (value) => { + if (node.type === 'dataset' && node.value === value) { + expanded = true; + await tick(); + animateExpand(value); + } else if (node.type === 'group' && findNodeInTree(node.children, value)) expanded = true; }) ); + + function animateExpand(id: string) { + const element = document.getElementById(id); + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'start' }); + element.style.backgroundColor = 'hsl(60 40% 34% / 1)'; + } + }
@@ -53,7 +63,11 @@ {/if} {#if node.type == 'dataset'} - + (e.currentTarget.style.backgroundColor = '')} + > {node.name} @@ -62,7 +76,7 @@ {#if node.type === 'group'}
{#each node.children as child} - + {/each}
{/if} @@ -94,6 +108,9 @@ display: flex; align-items: center; margin-top: 3px; + + transition: background-color linear 0.25s; + scroll-margin-top: 30px; } .name span { diff --git a/src/lib/components/Datasets/emitter.ts b/src/lib/components/Datasets/emitter.ts index 28a8c78..90a6338 100644 --- a/src/lib/components/Datasets/emitter.ts +++ b/src/lib/components/Datasets/emitter.ts @@ -3,6 +3,8 @@ import mitt from 'mitt'; type Events = { expand: Table['name']; + 'expand-all': void; + 'collapse-all': void; }; const emitter = mitt(); @@ -16,3 +18,23 @@ export function onExpand(handler: (tableName: string) => void) { return () => emitter.off('expand', handler); } + +export function expandAll() { + emitter.emit('expand-all'); +} + +export function onExpandAll(handler: () => void) { + emitter.on('expand-all', handler); + + return () => emitter.off('expand-all', handler); +} + +export function collapseAll() { + emitter.emit('collapse-all'); +} + +export function onCollapseAll(handler: () => void) { + emitter.on('collapse-all', handler); + + return () => emitter.off('collapse-all', handler); +} diff --git a/src/lib/icons/CollapseAll.svelte b/src/lib/icons/CollapseAll.svelte new file mode 100644 index 0000000..c3d615a --- /dev/null +++ b/src/lib/icons/CollapseAll.svelte @@ -0,0 +1,18 @@ + + + + + +