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-DwpOmyPo.js

This file was deleted.

68 changes: 68 additions & 0 deletions internal/admin/dashboard/static/dist/assets/index-DzO__mgM.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.

2 changes: 1 addition & 1 deletion web/dashboard/src/lib/components/atoms/CopyButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

<button
type="button"
class="copy-feedback-btn {className}"
class={["copy-feedback-btn", className]}
class:copy-feedback-btn-copied={state.copied}
onclick={(event) => {
event.preventDefault();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

<button
type="button"
class="dialog-close-btn {className}"
class={["dialog-close-btn", className]}
aria-label={label}
{disabled}
{onclick}
Expand Down
43 changes: 14 additions & 29 deletions web/dashboard/src/lib/components/atoms/Icon.svelte
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
<script>
// Lucide icon by kebab-case name. Renders the SVG inline so CSS classes
// style it directly.
import { icons } from "lucide";
// 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();

function pascalCase(kebab) {
return String(kebab || "")
.split("-")
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
.join("");
}

function attrsToString(attrs) {
return Object.entries(attrs)
.map(([key, value]) => `${key}="${String(value)}"`)
.join(" ");
}

function renderNode([tag, attrs, children]) {
const inner = Array.isArray(children)
? children.map(renderNode).join("")
: "";
return `<${tag} ${attrsToString(attrs || {})}>${inner}</${tag}>`;
}

const svg = $derived.by(() => {
const icon = icons[pascalCase(name)];
if (!icon) return "";
return icon.map(renderNode).join("");
});
const nodes = $derived(iconRegistry[name] || []);
</script>

<svg
Expand All @@ -47,6 +24,14 @@
focusable="false"
{...rest}
>
<!-- eslint-disable-next-line svelte/no-at-html-tags -- trusted static icon data -->
{@html svg}
{#snippet iconNodes(children)}
{#each children as [tag, attrs, kids], 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}
</svelte:element>
{/each}
{/snippet}
{@render iconNodes(nodes)}
</svg>
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
} = $props();
</script>

<div class="segmented-control {className}" role="group" aria-label={ariaLabel}>
<div class={["segmented-control", className]} role="group" aria-label={ariaLabel}>
{#each options as option (option.value)}
<button
type="button"
Expand Down
2 changes: 1 addition & 1 deletion web/dashboard/src/lib/components/atoms/Spinner.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</script>

<span
class="spinner {className}"
class={["spinner", className]}
style="--spinner-size: {size}px"
role="status"
aria-label={label}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

<button
type="button"
class="table-action-btn {className}"
class={["table-action-btn", className]}
aria-label={label}
title={label}
{disabled}
Expand Down
123 changes: 123 additions & 0 deletions web/dashboard/src/lib/components/atoms/icons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Curated lucide icon registry. Importing named icons (instead of the whole
// `icons` map) keeps the unused ~1,500 icons out of the bundle; dynamic
// name lookups go through this map. When using a new icon in a component,
// add its kebab-case name here.
import {
Activity,
ArrowLeft,
ArrowRight,
Box,
Calculator,
Calendar,
CalendarDays,
ChartColumn,
ChartColumnIncreasing,
Check,
ChevronDown,
ChevronRight,
CircleCheck,
CircleCheckBig,
CircleDollarSign,
Clock,
Copy,
Database,
DatabaseZap,
FileText,
Gauge,
History,
Inbox,
Info,
KeyRound,
LayoutDashboard,
List,
LockKeyhole,
Maximize2,
Monitor,
Moon,
Pencil,
Plug,
Plus,
Power,
RefreshCw,
RotateCcw,
Save,
Search,
Server,
ServerCog,
Settings,
Settings2,
Shield,
ShieldCheck,
ShieldOff,
Shuffle,
Sun,
Tag,
Timer,
Trash2,
TriangleAlert,
User,
Wallet,
WandSparkles,
Workflow,
X,
} from "lucide";

export const iconRegistry = {
activity: Activity,
"arrow-left": ArrowLeft,
"arrow-right": ArrowRight,
box: Box,
calculator: Calculator,
calendar: Calendar,
"calendar-days": CalendarDays,
"chart-column": ChartColumn,
"chart-column-increasing": ChartColumnIncreasing,
check: Check,
"chevron-down": ChevronDown,
"chevron-right": ChevronRight,
"circle-check": CircleCheck,
"circle-check-big": CircleCheckBig,
"circle-dollar-sign": CircleDollarSign,
clock: Clock,
copy: Copy,
database: Database,
"database-zap": DatabaseZap,
"file-text": FileText,
gauge: Gauge,
history: History,
inbox: Inbox,
info: Info,
"key-round": KeyRound,
"layout-dashboard": LayoutDashboard,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
list: List,
"lock-keyhole": LockKeyhole,
"maximize-2": Maximize2,
monitor: Monitor,
moon: Moon,
pencil: Pencil,
plug: Plug,
plus: Plus,
power: Power,
"refresh-cw": RefreshCw,
"rotate-ccw": RotateCcw,
save: Save,
search: Search,
server: Server,
"server-cog": ServerCog,
settings: Settings,
"settings-2": Settings2,
shield: Shield,
"shield-check": ShieldCheck,
"shield-off": ShieldOff,
shuffle: Shuffle,
sun: Sun,
tag: Tag,
timer: Timer,
"trash-2": Trash2,
"triangle-alert": TriangleAlert,
user: User,
wallet: Wallet,
"wand-sparkles": WandSparkles,
workflow: Workflow,
x: X,
};
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,17 @@
<div class="dp-days">
{#each days as day (day.key)}
<button
class="dp-day"
class:other-month={!day.current}
class:today={isToday(day)}
class:range-start={boundary(day, "start")}
class:range-end={boundary(day, "end")}
class:in-range={inRange(day)}
class:disabled={isFuture(day)}
class={[
"dp-day",
{
"other-month": !day.current,
today: isToday(day),
"range-start": boundary(day, "start"),
"range-end": boundary(day, "end"),
"in-range": inRange(day),
disabled: isFuture(day),
},
]}
disabled={isFuture(day) || !day.current}
onclick={() => onselect?.(day)}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
} = $props();
</script>

<div class="filter-input-wrap {className}">
<div class={["filter-input-wrap", className]}>
<Icon name="search" class="filter-input-icon" />
<input
type="text"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
let { label = "Loading...", class: className = "" } = $props();
</script>

<div class="loading-state {className}" role="status" aria-live="polite">
<div class={["loading-state", className]} role="status" aria-live="polite">
<span class="loading-spinner" aria-hidden="true"></span>
<span>{label}</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@

<Modal {open} variant="editor" onclose={onModalClose}>
<div
class={"model-editor" + (dialogClass ? " " + dialogClass : "")}
class={["model-editor", dialogClass]}
role="dialog"
aria-modal="true"
aria-label={ariaLabel || title}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<span class="audit-entry-metadata-label">Metadata:</span>
<div class="audit-entry-context">
{#each badges as badge (badge.key)}
<span class="provider-badge {badge.class || ''}" class:mono={badge.mono}
<span class={["provider-badge", badge.class, { mono: badge.mono }]}
>{badge.text}</span
>
{/each}
Expand Down
4 changes: 2 additions & 2 deletions web/dashboard/src/pages/audit-logs/AuditPaneTabs.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
onclick={() => (activeTab = p.id)}
>
<span
class="audit-pane-icon audit-pane-icon-{p.pane.direction || ''}"
class={["audit-pane-icon", p.pane.direction && `audit-pane-icon-${p.pane.direction}`]}
aria-hidden="true"
>
{#if p.pane.direction === "request"}
Expand All @@ -57,7 +57,7 @@
<span class="audit-pane-seq mono">#{p.pane.seq}</span>
{/if}
{#if p.pane.kind}
<span class="provider-badge audit-pane-kind audit-pane-kind-{p.pane.kind || ''}"
<span class="provider-badge audit-pane-kind audit-pane-kind-{p.pane.kind}"
>{p.pane.kind}</span
>
{/if}
Expand Down
24 changes: 10 additions & 14 deletions web/dashboard/src/pages/audit-logs/ChatMessage.svelte
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
<script>
// One interaction message in the Interactions drawer: either a collapsible
// function call/result note or a regular chat bubble. The <article> class
// is a computed string (base + roleClass + is-anchor), which keeps the
// compiler from pruning the role/anchor selectors below — those rules must
// live here, next to the element they scope to (CONVENTIONS rule 3).
// is partly dynamic (roleClass), which keeps the compiler from pruning the
// role selectors below — those rules must live here, next to the element
// they scope to (CONVENTIONS rule 3).
import { timezone } from "$lib/stores/timezone.svelte.js";
import { functionExpandedContent } from "./conversation-helpers.js";

let { msg } = $props();

function articleClass(m) {
const base =
m.role === "function_call" || m.role === "function_result"
? "chat-function-note"
: "chat-message";
return [base, m.roleClass, m.isAnchor ? "is-anchor" : "", m.isAfterAnchor ? "is-after-anchor" : ""]
.filter(Boolean)
.join(" ");
}
const isFunctionNote = $derived(msg.role === "function_call" || msg.role === "function_result");

function functionDetailText(m) {
if (m.role === "function_call") {
Expand All @@ -28,11 +20,15 @@
</script>

<article
class={articleClass(msg)}
class={[
isFunctionNote ? "chat-function-note" : "chat-message",
msg.roleClass,
{ "is-anchor": msg.isAnchor, "is-after-anchor": msg.isAfterAnchor },
]}
data-conversation-anchor={msg.isAnchor ? "true" : undefined}
data-entry-id={msg.entryID}
>
{#if msg.role === "function_call" || msg.role === "function_result"}
{#if isFunctionNote}
<details class="chat-function-note-details">
<summary class="chat-function-note-inner">
<span class="chat-function-label">{msg.roleLabel}</span>
Expand Down
7 changes: 4 additions & 3 deletions web/dashboard/src/pages/mcp-servers/McpServerList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,10 @@
</td>
<td>
<span
class="auth-key-status-badge {server.enabled
? 'auth-key-status-active'
: 'auth-key-status-inactive'}"
class={[
"auth-key-status-badge",
server.enabled ? "auth-key-status-active" : "auth-key-status-inactive",
]}
>{server.enabled ? "Enabled" : "Disabled"}</span
>
</td>
Expand Down
5 changes: 3 additions & 2 deletions web/dashboard/src/pages/models/virtualModelsLogic.js
Original file line number Diff line number Diff line change
Expand Up @@ -653,8 +653,9 @@ export function rowAccessSelector(row) {
return qualifiedModelName(row);
}

// Returns a class array for Svelte's clsx-style class attribute.
export function displayRowClass(row) {
if (!row) return "";
if (!row) return [];
const classes = [];
if (row.is_alias) {
classes.push("alias-row", aliasStateClass(row.alias));
Expand All @@ -669,7 +670,7 @@ export function displayRowClass(row) {
if (!row.is_alias && row.access && row.access.effective_enabled === false) {
classes.push("model-access-disabled-row");
}
return classes.join(" ");
return classes;
}

export function aliasRowCanRemove(row) {
Expand Down
Loading