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}
-