From 41111b082cdc5828eed2d7ecc6d0cca51f0e61bf Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Fri, 27 Mar 2026 23:16:39 +0100 Subject: [PATCH] chore: replace Unicode/emoji icons with Lucide React MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds lucide-react and replaces all HTML entity and emoji icons across the UI with proper SVG icon components. Tree-shaken — only imported icons are bundled. Co-Authored-By: Claude Opus 4.6 (1M context) --- ui/package-lock.json | 10 +++++ ui/package.json | 1 + .../components/ProcessDiagram/DiagramNode.tsx | 44 +++++++------------ .../components/ProcessDiagram/NodeToolbar.tsx | 14 +++--- ui/src/pages/Admin/AppConfigDetailPage.tsx | 7 +-- ui/src/pages/Admin/AppConfigPage.tsx | 5 ++- ui/src/pages/AgentHealth/AgentHealth.tsx | 9 ++-- ui/src/pages/AgentInstance/AgentInstance.tsx | 9 ++-- ui/src/pages/Dashboard/Dashboard.tsx | 5 ++- ui/src/pages/Routes/RouteDetail.tsx | 5 ++- 10 files changed, 57 insertions(+), 52 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index a4818979..f5b2abdd 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@cameleer/design-system": "^0.1.17", "@tanstack/react-query": "^5.90.21", + "lucide-react": "^1.7.0", "openapi-fetch": "^0.17.0", "react": "^19.2.4", "react-dom": "^19.2.4", @@ -2583,6 +2584,15 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.7.0.tgz", + "integrity": "sha512-yI7BeItCLZJTXikmK4KNUGCKoGzSvbKlfCvw44bU4fXAL6v3gYS4uHD1jzsLkfwODYwI6Drw5Tu9Z5ulDe0TSg==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", diff --git a/ui/package.json b/ui/package.json index 2fdab049..1a03b332 100644 --- a/ui/package.json +++ b/ui/package.json @@ -16,6 +16,7 @@ "dependencies": { "@cameleer/design-system": "^0.1.17", "@tanstack/react-query": "^5.90.21", + "lucide-react": "^1.7.0", "openapi-fetch": "^0.17.0", "react": "^19.2.4", "react-dom": "^19.2.4", diff --git a/ui/src/components/ProcessDiagram/DiagramNode.tsx b/ui/src/components/ProcessDiagram/DiagramNode.tsx index e4efe737..a1244fe2 100644 --- a/ui/src/components/ProcessDiagram/DiagramNode.tsx +++ b/ui/src/components/ProcessDiagram/DiagramNode.tsx @@ -133,31 +133,19 @@ export function DiagramNode({ {isCompleted && ( <> - - ✓ - + )} {isFailed && ( <> - - ! - + )} @@ -177,15 +165,13 @@ export function DiagramNode({ {/* Sub-route failure: drill-down arrow at bottom-left */} {isFailed && executionState?.subRouteFailed && ( - - ↳ - + + + + )} ); diff --git a/ui/src/components/ProcessDiagram/NodeToolbar.tsx b/ui/src/components/ProcessDiagram/NodeToolbar.tsx index 4a7e1cd2..b5cefa0b 100644 --- a/ui/src/components/ProcessDiagram/NodeToolbar.tsx +++ b/ui/src/components/ProcessDiagram/NodeToolbar.tsx @@ -1,4 +1,6 @@ import { useCallback, useRef, useState } from 'react'; +import { Search, Footprints, Droplets, Ellipsis } from 'lucide-react'; +import type { LucideIcon } from 'lucide-react'; import type { NodeAction } from './types'; import styles from './ProcessDiagram.module.css'; @@ -14,11 +16,11 @@ interface NodeToolbarProps { onMouseLeave: () => void; } -const ACTIONS: { icon: string; action: NodeAction; title: string }[] = [ - { icon: '\uD83D\uDD0D', action: 'inspect', title: 'Inspect' }, - { icon: '\uD83D\uDC63', action: 'toggle-trace', title: 'Toggle tracing' }, - { icon: '\uD83D\uDEB0', action: 'configure-tap', title: 'Configure tap' }, - { icon: '\u22EF', action: 'copy-id', title: 'Copy ID' }, +const ACTIONS: { Icon: LucideIcon; action: NodeAction; title: string }[] = [ + { Icon: Search, action: 'inspect', title: 'Inspect' }, + { Icon: Footprints, action: 'toggle-trace', title: 'Toggle tracing' }, + { Icon: Droplets, action: 'configure-tap', title: 'Configure tap' }, + { Icon: Ellipsis, action: 'copy-id', title: 'Copy ID' }, ]; export function NodeToolbar({ @@ -41,7 +43,7 @@ export function NodeToolbar({ onAction(nodeId, a.action); }} > - {a.icon} + ))} diff --git a/ui/src/pages/Admin/AppConfigDetailPage.tsx b/ui/src/pages/Admin/AppConfigDetailPage.tsx index 137d2733..fbcea6d5 100644 --- a/ui/src/pages/Admin/AppConfigDetailPage.tsx +++ b/ui/src/pages/Admin/AppConfigDetailPage.tsx @@ -1,5 +1,6 @@ import { useEffect, useState, useMemo } from 'react'; import { useParams, useNavigate } from 'react-router'; +import { ArrowLeft, Pencil, X } from 'lucide-react'; import { Button, SectionHeader, MonoText, Badge, DataTable, Spinner, Toggle, useToast, } from '@cameleer/design-system'; @@ -248,7 +249,7 @@ export default function AppConfigDetailPage() { if (row.captureMode === null) return null; return ( ); }, @@ -303,7 +304,7 @@ export default function AppConfigDetailPage() { return (
- + {editing ? (
) : ( - + )}
diff --git a/ui/src/pages/Admin/AppConfigPage.tsx b/ui/src/pages/Admin/AppConfigPage.tsx index 1dcd6872..a7287687 100644 --- a/ui/src/pages/Admin/AppConfigPage.tsx +++ b/ui/src/pages/Admin/AppConfigPage.tsx @@ -1,5 +1,6 @@ import { useState, useMemo, useEffect } from 'react'; import { useNavigate, useSearchParams } from 'react-router'; +import { Pencil, X } from 'lucide-react'; import { DataTable, Badge, MonoText, DetailPanel, SectionHeader, Button, Toggle, Spinner, useToast, } from '@cameleer/design-system'; @@ -197,7 +198,7 @@ function AppConfigDetail({ appId, onClose }: { appId: string; onClose: () => voi ...(editing ? [{ key: '_remove' as const, header: '', width: '36px', render: (_v: unknown, row: TracedTapRow) => row.captureMode === null ? null : ( - + ), }] : []), ], [editing, processorToRoute]); @@ -233,7 +234,7 @@ function AppConfigDetail({ appId, onClose }: { appId: string; onClose: () => voi
) : ( - + )} diff --git a/ui/src/pages/AgentHealth/AgentHealth.tsx b/ui/src/pages/AgentHealth/AgentHealth.tsx index ff7f00cb..6280750f 100644 --- a/ui/src/pages/AgentHealth/AgentHealth.tsx +++ b/ui/src/pages/AgentHealth/AgentHealth.tsx @@ -1,5 +1,6 @@ import { useState, useMemo, useCallback } from 'react'; import { useParams, useNavigate } from 'react-router'; +import { ExternalLink, RefreshCw, Pencil } from 'lucide-react'; import { StatCard, StatusDot, Badge, MonoText, ProgressBar, GroupCard, DataTable, LineChart, EventFeed, DetailPanel, @@ -357,7 +358,7 @@ export default function AgentHealth() { navigate(`/agents/${row.application}/${row.id}`); }} > - ↗ + ), }, @@ -621,7 +622,7 @@ export default function AgentHealth() { Metrics - + )} @@ -695,7 +696,7 @@ export default function AgentHealth() { {logSortAsc ? '\u2191' : '\u2193'} @@ -745,7 +746,7 @@ export default function AgentHealth() { {eventSortAsc ? '\u2191' : '\u2193'} diff --git a/ui/src/pages/AgentInstance/AgentInstance.tsx b/ui/src/pages/AgentInstance/AgentInstance.tsx index 71492bbc..d202f666 100644 --- a/ui/src/pages/AgentInstance/AgentInstance.tsx +++ b/ui/src/pages/AgentInstance/AgentInstance.tsx @@ -1,5 +1,6 @@ import { useMemo, useState } from 'react'; import { useParams, Link } from 'react-router'; +import { RefreshCw, ChevronRight } from 'lucide-react'; import { StatCard, StatusDot, Badge, LineChart, AreaChart, BarChart, EventFeed, Spinner, EmptyState, SectionHeader, MonoText, @@ -230,11 +231,11 @@ export default function AgentInstance() { All Agents - + {appId} - + {agent.name} @@ -407,7 +408,7 @@ export default function AgentInstance() { {logSortAsc ? '\u2191' : '\u2193'} @@ -457,7 +458,7 @@ export default function AgentInstance() { {eventSortAsc ? '\u2191' : '\u2193'} diff --git a/ui/src/pages/Dashboard/Dashboard.tsx b/ui/src/pages/Dashboard/Dashboard.tsx index a39c7fdd..2f77266f 100644 --- a/ui/src/pages/Dashboard/Dashboard.tsx +++ b/ui/src/pages/Dashboard/Dashboard.tsx @@ -1,5 +1,6 @@ import { useState, useMemo, useCallback } from 'react' import { useParams, useNavigate } from 'react-router' +import { ExternalLink, AlertTriangle } from 'lucide-react' import { DataTable, DetailPanel, @@ -344,7 +345,7 @@ export default function Dashboard() { navigate(`/exchanges/${row.executionId}`) }} > - ↗ + ), } @@ -418,7 +419,7 @@ export default function Dashboard() { expandedContent={(row: Row) => row.errorMessage ? (
- {'\u26A0'} +
{row.errorMessage}
Click to view full stack trace
diff --git a/ui/src/pages/Routes/RouteDetail.tsx b/ui/src/pages/Routes/RouteDetail.tsx index 302b8b68..80767e5e 100644 --- a/ui/src/pages/Routes/RouteDetail.tsx +++ b/ui/src/pages/Routes/RouteDetail.tsx @@ -1,5 +1,6 @@ import { useState, useMemo, useCallback } from 'react'; import { useParams, useNavigate, useSearchParams, Link } from 'react-router'; +import { Pencil, Trash2 } from 'lucide-react'; import { KpiStrip, Badge, @@ -613,8 +614,8 @@ export default function RouteDetail() { width: '80px', render: (_, row) => (
- - + +
), },