Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 0 additions & 68 deletions internal/admin/dashboard/static/dist/assets/index-DzO__mgM.js

This file was deleted.

68 changes: 68 additions & 0 deletions internal/admin/dashboard/static/dist/assets/index-G3uz-AWc.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion internal/admin/dashboard/static/dist/index.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions web/dashboard/src/lib/components/atoms/CopyButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// (from createCopyState) and performs the copy in `onclick`, so the same
// button works for page-local state and store-held state.
import Icon from "$lib/components/atoms/Icon.svelte";
import { CircleCheck, Copy } from "lucide";

let {
state,
Expand Down Expand Up @@ -30,9 +31,9 @@
}}
>
{#if state.copied}
<Icon name="circle-check" width="14" height="14" stroke-width="2.5" />
<Icon icon={CircleCheck} width="14" height="14" stroke-width="2.5" />
{:else}
<Icon name="copy" width="14" height="14" />
<Icon icon={Copy} width="14" height="14" />
{/if}
<span aria-live="polite" aria-atomic="true">{text}</span>
</button>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// `iconClass` defaults to the 14px table icon size used by the editors;
// the auth-style dialogs pass "" to keep their larger X.
import Icon from "./Icon.svelte";
import { X } from "lucide";

let {
label = "Close",
Expand All @@ -22,7 +23,7 @@
{onclick}
bind:this={el}
>
<Icon name="x" class={iconClass} />
<Icon icon={X} class={iconClass} />
</button>

<style>
Expand Down
6 changes: 4 additions & 2 deletions web/dashboard/src/lib/components/atoms/EmptyState.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<script>
// Empty-table / empty-list placeholder.
let { icon = "inbox", title = "No data", hint = "", children } = $props();
import Icon from "./Icon.svelte";
import { Inbox } from "lucide";

let { icon = Inbox, title = "No data", hint = "", children } = $props();
</script>

<div class="empty-state">
<Icon name={icon} class="empty-state-icon" />
<Icon {icon} class="empty-state-icon" />
<p class="empty-state-title">{title}</p>
{#if hint}
<p class="empty-state-hint">{hint}</p>
Expand Down
23 changes: 11 additions & 12 deletions web/dashboard/src/lib/components/atoms/Icon.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<script>
// Lucide icon by kebab-case name. Renders the SVG inline so CSS classes
// style it directly. Icons come from the curated registry in icons.js —
// add new names there.
import { iconRegistry } from "./icons.js";

let { name = "", class: className = "", ...rest } = $props();

const nodes = $derived(iconRegistry[name] || []);
// Renders a lucide icon inline as SVG so CSS classes style it directly.
// `icon` is the icon itself, imported from "lucide" by the caller
// (`import { Pencil } from "lucide"` → `<Icon icon={Pencil} />`), not a
// name string: an unknown icon is then a build error rather than a
// silently blank SVG. Lucide icons are plain [tag, attrs, children?]
// arrays, so they are safe to pass around and store as data.
let { icon = [], class: className = "", ...rest } = $props();
</script>

<svg
Expand All @@ -24,14 +23,14 @@
focusable="false"
{...rest}
>
{#snippet iconNodes(children)}
{#each children as [tag, attrs, kids], i (i)}
{#snippet iconNodes(nodes)}
{#each nodes as [tag, attrs, children], i (i)}
<!-- xmlns tells the compiler to create these in the SVG namespace;
snippet bodies don't inherit it from the surrounding <svg>. -->
<svelte:element this={tag} xmlns="http://www.w3.org/2000/svg" {...attrs}>
{#if Array.isArray(kids)}{@render iconNodes(kids)}{/if}
{#if Array.isArray(children)}{@render iconNodes(children)}{/if}
</svelte:element>
{/each}
{/snippet}
{@render iconNodes(nodes)}
{@render iconNodes(icon)}
</svg>
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<script>
import { Pencil } from "lucide";
// Small action button used in table rows, cards, and editors
// (.table-action-btn styles). `label` fills both title and aria-label.
// Children supply the icon (and optional text span), e.g.
// <TableActionButton label="Edit budget" class="budget-action-btn" onclick={...}>
// <Icon name="pencil" class="budget-action-icon" />
// <Icon icon={Pencil} class="budget-action-icon" />
// <span class="budget-action-label">Edit</span>
// </TableActionButton>
let {
Expand Down
123 changes: 0 additions & 123 deletions web/dashboard/src/lib/components/atoms/icons.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Standard toolbar search field: magnifier icon inside a text input.
// `label` fills aria-label; `class` adds modifiers to the wrapper.
import Icon from "$lib/components/atoms/Icon.svelte";
import { Search } from "lucide";

let {
value = $bindable(""),
Expand All @@ -14,7 +15,7 @@
</script>

<div class={["filter-input-wrap", className]}>
<Icon name="search" class="filter-input-icon" />
<Icon icon={Search} class="filter-input-icon" />
<input
type="text"
class="filter-input"
Expand Down
5 changes: 3 additions & 2 deletions web/dashboard/src/lib/components/organisms/AuthDialog.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import Modal from "$lib/components/atoms/Modal.svelte";
import Icon from "$lib/components/atoms/Icon.svelte";
import { auth } from "$lib/stores/auth.svelte.js";
import { Check, LockKeyhole } from "lucide";
</script>

<Modal
Expand Down Expand Up @@ -37,7 +38,7 @@
}}
>
<div class="auth-dialog-input-shell">
<Icon name="lock-keyhole" class="auth-dialog-input-icon" />
<Icon icon={LockKeyhole} class="auth-dialog-input-icon" />
<input
id="authDialogApiKey"
class="auth-dialog-input"
Expand All @@ -62,7 +63,7 @@
type="submit"
class="btn btn-primary btn-with-icon auth-dialog-submit-btn"
>
<Icon name="check" class="auth-dialog-submit-icon" />
<Icon icon={Check} class="auth-dialog-submit-icon" />
<span>{auth.needsAuth ? "Unlock dashboard" : "Save API key"}</span>
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import DialogCloseButton from "$lib/components/atoms/DialogCloseButton.svelte";
import Icon from "$lib/components/atoms/Icon.svelte";
import { auth } from "$lib/stores/auth.svelte.js";
import { Save } from "lucide";

let {
open = false,
Expand All @@ -42,7 +43,7 @@
submitDisabled = false,
submitLabel = "Save",
submittingLabel = "Saving...",
submitIcon = "save",
submitIcon = Save,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 6 '<EditorDialog\b|submitIcon\s*=' \
  web/dashboard/src --glob '*.svelte' --glob '*.js'

Repository: ENTERPILOT/GoModel

Length of output: 17093


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== EditorDialog relevant source =="
sed -n '1,180p' web/dashboard/src/lib/components/organisms/EditorDialog.svelte

echo
echo "== Icon component definitions/usages =="
fd -i 'Icon\.svelte$|Icon.*\.svelte' web/dashboard/src --exec sh -c 'echo "--- $1"; sed -n "1,220p" "$1"' sh {}

Repository: ENTERPILOT/GoModel

Length of output: 5589


Update the remaining submitIcon callers to use Lucide icon data.

Icon.svelte expects Lucide icon data ([tag, attrs, children]), so callers currently passing "plus", "save", "check", or "delete" render an empty SVG node. Import the matching Lucide icons and pass them to EditorDialog on these call sites:
web/dashboard/src/pages/auth-keys/AuthKeyEditor.svelte:20,
web/dashboard/src/pages/models/VirtualModelEditor.svelte:34,
web/dashboard/src/pages/workflows/WorkflowEditor.svelte:21, and the AuthKeyLabelsEditor/MCP/Tenant/Rate-limit/Policy editors where they may also use string icons.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/dashboard/src/lib/components/organisms/EditorDialog.svelte` at line 46,
Update all remaining callers of EditorDialog's submitIcon prop to pass Lucide
icon data instead of strings. In AuthKeyEditor.svelte,
VirtualModelEditor.svelte, WorkflowEditor.svelte, and other editor components
(AuthKeyLabelsEditor, MCP, Tenant, Rate-limit, Policy editors), replace the
string values "plus", "save", "check", and "delete" with their corresponding
imported Lucide icons (Plus, Save, Check, Trash respectively). Import each
needed Lucide icon at the top of each file and update the submitIcon assignments
to use the imported icon data in the same format that Save is now used in
EditorDialog.svelte.

cancel = true,
dialogClass = "",
novalidate = false,
Expand Down Expand Up @@ -113,7 +114,7 @@
class="btn btn-primary btn-with-icon"
disabled={submitting || submitDisabled}
>
<Icon name={submitIcon} class="form-action-icon" />
<Icon icon={submitIcon} class="form-action-icon" />
<span>{submitting ? submittingLabel : submitLabel}</span>
</button>
</div>
Expand Down
5 changes: 3 additions & 2 deletions web/dashboard/src/lib/components/organisms/Sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { auth } from "$lib/stores/auth.svelte.js";
import { gomodelPath } from "$lib/api/paths.js";
import { NAV_ITEMS } from "./navigation.js";
import { LockKeyhole } from "lucide";

// Visibility gates read the runtimeConfig store, so this re-filters when
// the flags load.
Expand Down Expand Up @@ -35,7 +36,7 @@
router.navigate(item.page);
}}
>
<Icon name={item.icon} class="nav-icon" />
<Icon icon={item.icon} class="nav-icon" />
<span>{item.label}</span>
</a>
{/each}
Expand All @@ -50,7 +51,7 @@
onclick={() => auth.openDialog()}
aria-label={auth.needsAuth ? "Enter API key" : "Change API key"}
>
<Icon name="lock-keyhole" class="api-key-open-icon" />
<Icon icon={LockKeyhole} class="api-key-open-icon" />
<span>{auth.needsAuth ? "Enter API key" : "Change API key"}</span>
</button>
</div>
Expand Down
11 changes: 6 additions & 5 deletions web/dashboard/src/lib/components/organisms/ThemeToggle.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
// sidebar); below 768px it is used regardless.
import Icon from "$lib/components/atoms/Icon.svelte";
import { themeStore } from "$lib/stores/ui.svelte.js";
import { Monitor, Moon, Sun } from "lucide";

let { compact = false } = $props();

const themes = [
{ value: "light", icon: "sun", label: "Light theme" },
{ value: "system", icon: "monitor", label: "System theme" },
{ value: "dark", icon: "moon", label: "Dark theme" },
{ value: "light", icon: Sun, label: "Light theme" },
{ value: "system", icon: Monitor, label: "System theme" },
{ value: "dark", icon: Moon, label: "Dark theme" },
];
const activeTheme = $derived(
themes.find((t) => t.value === themeStore.theme) || themes[1],
Expand All @@ -31,7 +32,7 @@
title={theme.label}
aria-label={theme.label}
>
<Icon name={theme.icon} class="theme-icon" />
<Icon icon={theme.icon} class="theme-icon" />
</button>
{/each}
</div>
Expand All @@ -42,7 +43,7 @@
title={cycleLabel}
aria-label={cycleLabel}
>
<Icon name={activeTheme.icon} class="theme-icon" />
<Icon icon={activeTheme.icon} class="theme-icon" />
</button>

<style>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
class="btn btn-danger btn-with-icon"
disabled={dialog.loading || !confirmDialog.ready()}
>
<Icon name={dialog.icon} class="form-action-icon" />
<Icon icon={dialog.icon} class="form-action-icon" />
<span>{dialog.confirmLabel}</span>
</button>
</div>
Expand Down
Loading
Loading