diff --git a/dashboard/frontend/src/components/Sidebar.svelte b/dashboard/frontend/src/components/Sidebar.svelte index e932b35..17d51b3 100644 --- a/dashboard/frontend/src/components/Sidebar.svelte +++ b/dashboard/frontend/src/components/Sidebar.svelte @@ -44,27 +44,44 @@ { label: "Speedtest", remoteHref: "https://speed.jimmygan.com:8443", icon: "speedtest", external: true }, ]; - // Item key: use id if present, otherwise label - 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])); - // Apply saved order: saved items first (in order), then new items appended - function applyOrder(items, savedKeys) { - if (!savedKeys || !savedKeys.length) return [...items]; - const byKey = new Map(items.map(i => [itemKey(i), i])); - const ordered = []; - for (const k of savedKeys) { - if (byKey.has(k)) { ordered.push(byKey.get(k)); byKey.delete(k); } + // Build category lists from saved order, supporting cross-category moves + function buildLists(savedOrder) { + if (!savedOrder) return { main: [...defaultLinks], media: [...defaultMedia], tools: [...defaultTools] }; + + const used = new Set(); + const result = { main: [], media: [], tools: [] }; + + for (const cat of ["main", "media", "tools"]) { + const keys = savedOrder[cat] || []; + for (const k of keys) { + if (allItems.has(k) && !used.has(k)) { + result[cat].push(allItems.get(k)); + used.add(k); + } + } } - // Append items not in saved order - for (const i of items) { - if (byKey.has(itemKey(i))) ordered.push(i); + + // 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]) { + if (!used.has(itemKey(item))) { + result[cat].push(item); + used.add(itemKey(item)); + } + } } - return ordered; + + return result; } - let links = $derived(applyOrder(defaultLinks, sidebarOrder?.main)); - let media = $derived(applyOrder(defaultMedia, sidebarOrder?.media)); - let tools = $derived(applyOrder(defaultTools, sidebarOrder?.tools)); + let categoryLists = $derived(buildLists(sidebarOrder)); + let links = $derived(categoryLists.main); + let media = $derived(categoryLists.media); + let tools = $derived(categoryLists.tools); // Drag-and-drop state let dragCategory = $state(null); @@ -154,166 +171,118 @@ } +{#snippet iconSvg(icon)} + + {#if icon === "grid"} + + {:else if icon === "box"} + + {:else if icon === "folder"} + + {:else if icon === "terminal"} + + {:else if icon === "shield"} + + {:else if icon === "music"} + + {:else if icon === "play"} + + {:else if icon === "headphones"} + + {:else if icon === "image"} + + {:else if icon === "openclaw"} + + {:else if icon === "chat"} + + {:else if icon === "git"} + + {:else if icon === "pdf"} + + {:else if icon === "lock"} + + {:else if icon === "speedtest"} + + {:else if icon === "users"} + + {:else if icon === "n8n"} + + {/if} + +{/snippet} + {#if sidebarOpen} {/if} -