diff --git a/dashboard/frontend/src/components/Sidebar.svelte b/dashboard/frontend/src/components/Sidebar.svelte index 4a44cd1..d35f29c 100644 --- a/dashboard/frontend/src/components/Sidebar.svelte +++ b/dashboard/frontend/src/components/Sidebar.svelte @@ -44,19 +44,24 @@ { label: "Speedtest", remoteHref: "https://speed.jimmygan.com:8443", icon: "speedtest", external: true }, ]; + const defaultTools2 = []; + function itemKey(item) { return item.id || item.label; } // All items indexed by key for cross-category lookup - const allItems = new Map([...defaultLinks, ...defaultMedia, ...defaultTools].map(i => [itemKey(i), i])); + const allItems = new Map([...defaultLinks, ...defaultMedia, ...defaultTools, ...defaultTools2].map(i => [itemKey(i), i])); // Build category lists from saved order, supporting cross-category moves + const categories = ["main", "media", "tools", "tools2"]; + const categoryDefaults = { main: defaultLinks, media: defaultMedia, tools: defaultTools, tools2: defaultTools2 }; + function buildLists(savedOrder) { - if (!savedOrder) return { main: [...defaultLinks], media: [...defaultMedia], tools: [...defaultTools] }; + if (!savedOrder) return { main: [...defaultLinks], media: [...defaultMedia], tools: [...defaultTools], tools2: [...defaultTools2] }; const used = new Set(); - const result = { main: [], media: [], tools: [] }; + const result = { main: [], media: [], tools: [], tools2: [] }; - for (const cat of ["main", "media", "tools"]) { + for (const cat of categories) { const keys = savedOrder[cat] || []; for (const k of keys) { if (allItems.has(k) && !used.has(k)) { @@ -67,9 +72,8 @@ } // Append any new items not in saved order to their default category - const defaults = { main: defaultLinks, media: defaultMedia, tools: defaultTools }; - for (const cat of ["main", "media", "tools"]) { - for (const item of defaults[cat]) { + for (const cat of categories) { + for (const item of categoryDefaults[cat]) { if (!used.has(itemKey(item))) { result[cat].push(item); used.add(itemKey(item)); @@ -84,6 +88,10 @@ let links = $derived(categoryLists.main); let media = $derived(categoryLists.media); let tools = $derived(categoryLists.tools); + let tools2 = $derived(categoryLists.tools2); + + // Collapsed state for categories (persisted in sidebarOrder) + let collapsed = $state(sidebarOrder?.collapsed ? { ...sidebarOrder.collapsed } : {}); // Drag-and-drop state let dragCategory = $state(null); @@ -116,13 +124,15 @@ e.preventDefault(); if (dragCategory === null) { handleDragEnd(); return; } if (dragCategory === category && dragIndex === index) { handleDragEnd(); return; } - const lists = { main: [...links], media: [...media], tools: [...tools] }; + const lists = { main: [...links], media: [...media], tools: [...tools], tools2: [...tools2] }; const [moved] = lists[dragCategory].splice(dragIndex, 1); lists[category].splice(index, 0, moved); const newOrder = { main: lists.main.map(itemKey), media: lists.media.map(itemKey), tools: lists.tools.map(itemKey), + tools2: lists.tools2.map(itemKey), + collapsed, }; onOrderChange(newOrder); handleDragEnd(); @@ -139,13 +149,15 @@ function handleCategoryDrop(category, e) { e.preventDefault(); if (dragCategory === null) { handleDragEnd(); return; } - const lists = { main: [...links], media: [...media], tools: [...tools] }; + const lists = { main: [...links], media: [...media], tools: [...tools], tools2: [...tools2] }; const [moved] = lists[dragCategory].splice(dragIndex, 1); lists[category].push(moved); const newOrder = { main: lists.main.map(itemKey), media: lists.media.map(itemKey), tools: lists.tools.map(itemKey), + tools2: lists.tools2.map(itemKey), + collapsed, }; onOrderChange(newOrder); handleDragEnd(); @@ -171,6 +183,18 @@ if (dropCategory === category && index === dropIndex) return "border-t-2 border-primary-500"; return ""; } + + function toggleCollapse(cat) { + collapsed[cat] = !collapsed[cat]; + const newOrder = { + main: links.map(itemKey), + media: media.map(itemKey), + tools: tools.map(itemKey), + tools2: tools2.map(itemKey), + collapsed, + }; + onOrderChange(newOrder); + } {#snippet iconSvg(icon)} @@ -232,11 +256,23 @@