diff --git a/frontend/src/app.html b/frontend/src/app.html index 6769ed5..ca08e96 100644 --- a/frontend/src/app.html +++ b/frontend/src/app.html @@ -2,7 +2,8 @@
- + + %sveltekit.head% diff --git a/frontend/src/lib/components/layout/Breadcrumbs.svelte b/frontend/src/lib/components/layout/Breadcrumbs.svelte index c224c48..79eb7e2 100644 --- a/frontend/src/lib/components/layout/Breadcrumbs.svelte +++ b/frontend/src/lib/components/layout/Breadcrumbs.svelte @@ -14,6 +14,7 @@ import { page } from "$app/stores"; import { t, _ } from "$lib/i18n"; + import Icon from "$lib/ui/Icon.svelte"; let { maxVisible = 3 } = $props(); @@ -82,30 +83,103 @@ .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) .join(" "); } + + function getCrumbMeta(item) { + if (item.path === "/") { + return { + icon: "home", + tone: "from-sky-100 to-cyan-100 text-sky-700 ring-sky-200", + }; + } + + const segment = item.path.split("/").filter(Boolean).at(-1) || ""; + + const map = { + dashboards: { + icon: "dashboard", + tone: "from-sky-100 to-sky-200 text-sky-700 ring-sky-200", + }, + datasets: { + icon: "database", + tone: "from-emerald-100 to-emerald-200 text-emerald-700 ring-emerald-200", + }, + storage: { + icon: "storage", + tone: "from-amber-100 to-amber-200 text-amber-800 ring-amber-200", + }, + reports: { + icon: "reports", + tone: "from-violet-100 to-fuchsia-100 text-violet-700 ring-violet-200", + }, + admin: { + icon: "admin", + tone: "from-rose-100 to-rose-200 text-rose-700 ring-rose-200", + }, + settings: { + icon: "settings", + tone: "from-slate-100 to-slate-200 text-slate-700 ring-slate-200", + }, + git: { + icon: "storage", + tone: "from-orange-100 to-orange-200 text-orange-700 ring-orange-200", + }, + }; + + return ( + map[segment] || { + icon: "layers", + tone: "from-slate-100 to-slate-200 text-slate-600 ring-slate-200", + } + ); + } diff --git a/frontend/src/lib/components/layout/Sidebar.svelte b/frontend/src/lib/components/layout/Sidebar.svelte index 6efab49..e2e27eb 100644 --- a/frontend/src/lib/components/layout/Sidebar.svelte +++ b/frontend/src/lib/components/layout/Sidebar.svelte @@ -24,59 +24,68 @@ } from "$lib/stores/sidebar.js"; import { t } from "$lib/i18n"; import { browser } from "$app/environment"; + import Icon from "$lib/ui/Icon.svelte"; - // Sidebar categories with sub-items matching Superset-style navigation - let categories = [ - { - id: "dashboards", - label: $t.nav?.dashboards || "DASHBOARDS", - icon: "M3 3h18v18H3V3zm16 16V5H5v14h14z", - path: "/dashboards", - subItems: [ - { label: $t.nav?.overview || "Overview", path: "/dashboards" }, - ], - }, - { - id: "datasets", - label: $t.nav?.datasets || "DATASETS", - icon: "M3 3h18v18H3V3zm2 2v14h14V5H5zm2 2h10v2H7V7zm0 4h10v2H7v-2zm0 4h6v2H7v-2z", - path: "/datasets", - subItems: [ - { label: $t.nav?.all_datasets || "All Datasets", path: "/datasets" }, - ], - }, - { - id: "storage", - label: $t.nav?.storage || "STORAGE", - icon: "M4 4h16v16H4V4zm2 2v12h12V6H6zm2 2h8v2H8V8zm0 4h8v2H8v-2zm0 4h5v2H8v-2z", - path: "/storage", - subItems: [ - { label: $t.nav?.backups || "Backups", path: "/storage/backups" }, - { - label: $t.nav?.repositories || "Repositories", - path: "/storage/repos", - }, - ], - }, - { - id: "reports", - label: $t.nav?.reports || "REPORTS", - icon: "M4 5h16M4 12h16M4 19h10", - path: "/reports", - subItems: [{ label: $t.nav?.reports || "Reports", path: "/reports" }], - }, - { - id: "admin", - label: $t.nav?.admin || "ADMIN", - icon: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z", - path: "/admin", - subItems: [ - { label: $t.nav?.admin_users || "Users", path: "/admin/users" }, - { label: $t.nav?.admin_roles || "Roles", path: "/admin/roles" }, - { label: $t.nav?.settings || "Settings", path: "/settings" }, - ], - }, - ]; + function buildCategories() { + return [ + { + id: "dashboards", + label: $t.nav?.dashboards || "DASHBOARDS", + icon: "dashboard", + tone: "from-sky-100 to-sky-200 text-sky-700 ring-sky-200", + path: "/dashboards", + subItems: [ + { label: $t.nav?.overview || "Overview", path: "/dashboards" }, + ], + }, + { + id: "datasets", + label: $t.nav?.datasets || "DATASETS", + icon: "database", + tone: "from-emerald-100 to-emerald-200 text-emerald-700 ring-emerald-200", + path: "/datasets", + subItems: [ + { label: $t.nav?.all_datasets || "All Datasets", path: "/datasets" }, + ], + }, + { + id: "storage", + label: $t.nav?.storage || "STORAGE", + icon: "storage", + tone: "from-amber-100 to-amber-200 text-amber-800 ring-amber-200", + path: "/storage", + subItems: [ + { label: $t.nav?.backups || "Backups", path: "/storage/backups" }, + { + label: $t.nav?.repositories || "Repositories", + path: "/storage/repos", + }, + ], + }, + { + id: "reports", + label: $t.nav?.reports || "REPORTS", + icon: "reports", + tone: "from-violet-100 to-fuchsia-100 text-violet-700 ring-violet-200", + path: "/reports", + subItems: [{ label: $t.nav?.reports || "Reports", path: "/reports" }], + }, + { + id: "admin", + label: $t.nav?.admin || "ADMIN", + icon: "admin", + tone: "from-rose-100 to-rose-200 text-rose-700 ring-rose-200", + path: "/admin", + subItems: [ + { label: $t.nav?.admin_users || "Users", path: "/admin/users" }, + { label: $t.nav?.admin_roles || "Roles", path: "/admin/roles" }, + { label: $t.nav?.settings || "Settings", path: "/settings" }, + ], + }, + ]; + } + + let categories = buildCategories(); let isExpanded = true; let activeCategory = "dashboards"; @@ -93,57 +102,7 @@ } // Reactive categories to update translations - $: categories = [ - { - id: "dashboards", - label: $t.nav?.dashboards || "DASHBOARDS", - icon: "M3 3h18v18H3V3zm16 16V5H5v14h14z", - path: "/dashboards", - subItems: [ - { label: $t.nav?.overview || "Overview", path: "/dashboards" }, - ], - }, - { - id: "datasets", - label: $t.nav?.datasets || "DATASETS", - icon: "M3 3h18v18H3V3zm2 2v14h14V5H5zm2 2h10v2H7V7zm0 4h10v2H7v-2zm0 4h6v2H7v-2z", - path: "/datasets", - subItems: [ - { label: $t.nav?.all_datasets || "All Datasets", path: "/datasets" }, - ], - }, - { - id: "storage", - label: $t.nav?.storage || "STORAGE", - icon: "M4 4h16v16H4V4zm2 2v12h12V6H6zm2 2h8v2H8V8zm0 4h8v2H8v-2zm0 4h5v2H8v-2z", - path: "/storage", - subItems: [ - { label: $t.nav?.backups || "Backups", path: "/storage/backups" }, - { - label: $t.nav?.repositories || "Repositories", - path: "/storage/repos", - }, - ], - }, - { - id: "reports", - label: $t.nav?.reports || "REPORTS", - icon: "M4 5h16M4 12h16M4 19h10", - path: "/reports", - subItems: [{ label: $t.nav?.reports || "Reports", path: "/reports" }], - }, - { - id: "admin", - label: $t.nav?.admin || "ADMIN", - icon: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z", - path: "/admin", - subItems: [ - { label: $t.nav?.admin_users || "Users", path: "/admin/users" }, - { label: $t.nav?.admin_roles || "Roles", path: "/admin/roles" }, - { label: $t.nav?.settings || "Settings", path: "/settings" }, - ], - }, - ]; + $: categories = buildCategories(); // Update active item when page changes $: if ($page && $page.url.pathname !== activeItem) { @@ -238,7 +197,12 @@ : 'justify-center'}" > {#if isExpanded} - Menu + + +{$t.tasks?.select_task || 'No recent tasks'}