feat: replace Unicode diagram icons with lucide SVG icons
Each of the ~40 node types now has a distinct, semantically meaningful lucide icon rendered as crisp SVG paths. Compound node headers also show their icon left-aligned in the header bar. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import type { DiagramNode as DiagramNodeType, DiagramEdge as DiagramEdgeType } from '../../api/queries/diagrams';
|
import type { DiagramNode as DiagramNodeType, DiagramEdge as DiagramEdgeType } from '../../api/queries/diagrams';
|
||||||
import type { NodeConfig } from './types';
|
import type { NodeConfig } from './types';
|
||||||
import type { NodeExecutionState, IterationInfo } from '../ExecutionDiagram/types';
|
import type { NodeExecutionState, IterationInfo } from '../ExecutionDiagram/types';
|
||||||
import { colorForType, isCompoundType } from './node-colors';
|
import { colorForType, isCompoundType, iconForType, type IconElement } from './node-colors';
|
||||||
import { DiagramNode } from './DiagramNode';
|
import { DiagramNode } from './DiagramNode';
|
||||||
import { DiagramEdge } from './DiagramEdge';
|
import { DiagramEdge } from './DiagramEdge';
|
||||||
import styles from './ProcessDiagram.module.css';
|
import styles from './ProcessDiagram.module.css';
|
||||||
@@ -118,7 +118,15 @@ export function CompoundNode({
|
|||||||
<rect x={0} y={0} width={w} height={HEADER_HEIGHT} rx={CORNER_RADIUS} fill={color} />
|
<rect x={0} y={0} width={w} height={HEADER_HEIGHT} rx={CORNER_RADIUS} fill={color} />
|
||||||
<rect x={CORNER_RADIUS} y={CORNER_RADIUS} width={w - CORNER_RADIUS * 2} height={HEADER_HEIGHT - CORNER_RADIUS} fill={color} />
|
<rect x={CORNER_RADIUS} y={CORNER_RADIUS} width={w - CORNER_RADIUS * 2} height={HEADER_HEIGHT - CORNER_RADIUS} fill={color} />
|
||||||
|
|
||||||
{/* Header label */}
|
{/* Header icon (left-aligned) */}
|
||||||
|
<g transform={`translate(6, ${HEADER_HEIGHT / 2 - 5}) scale(0.417)`}>
|
||||||
|
{iconForType(node.type).map((el: IconElement, i: number) =>
|
||||||
|
'd' in el
|
||||||
|
? <path key={i} d={el.d} fill="none" stroke="white" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" />
|
||||||
|
: <circle key={i} cx={el.cx} cy={el.cy} r={el.r} fill="none" stroke="white" strokeWidth={2} />
|
||||||
|
)}
|
||||||
|
</g>
|
||||||
|
{/* Header label (centered) */}
|
||||||
<text
|
<text
|
||||||
x={w / 2}
|
x={w / 2}
|
||||||
y={HEADER_HEIGHT / 2 + 4}
|
y={HEADER_HEIGHT / 2 + 4}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { DiagramNode as DiagramNodeType } from '../../api/queries/diagrams';
|
import type { DiagramNode as DiagramNodeType } from '../../api/queries/diagrams';
|
||||||
import type { NodeConfig } from './types';
|
import type { NodeConfig } from './types';
|
||||||
import type { NodeExecutionState } from '../ExecutionDiagram/types';
|
import type { NodeExecutionState } from '../ExecutionDiagram/types';
|
||||||
import { colorForType, iconForType } from './node-colors';
|
import { colorForType, iconForType, type IconElement } from './node-colors';
|
||||||
import { ConfigBadge } from './ConfigBadge';
|
import { ConfigBadge } from './ConfigBadge';
|
||||||
|
|
||||||
const TOP_BAR_HEIGHT = 6;
|
const TOP_BAR_HEIGHT = 6;
|
||||||
@@ -37,7 +37,7 @@ export function DiagramNode({
|
|||||||
const w = node.width ?? 120;
|
const w = node.width ?? 120;
|
||||||
const h = node.height ?? 40;
|
const h = node.height ?? 40;
|
||||||
const color = colorForType(node.type);
|
const color = colorForType(node.type);
|
||||||
const icon = iconForType(node.type);
|
const iconElements = iconForType(node.type);
|
||||||
|
|
||||||
// Extract label parts: type name and detail
|
// Extract label parts: type name and detail
|
||||||
const typeName = node.type?.replace(/^EIP_/, '').replace(/_/g, ' ') ?? '';
|
const typeName = node.type?.replace(/^EIP_/, '').replace(/_/g, ' ') ?? '';
|
||||||
@@ -116,10 +116,14 @@ export function DiagramNode({
|
|||||||
<rect x={TEXT_LEFT} y={TOP_BAR_HEIGHT} width={w - TEXT_LEFT - TEXT_RIGHT_PAD} height={h - TOP_BAR_HEIGHT} />
|
<rect x={TEXT_LEFT} y={TOP_BAR_HEIGHT} width={w - TEXT_LEFT - TEXT_RIGHT_PAD} height={h - TOP_BAR_HEIGHT} />
|
||||||
</clipPath>
|
</clipPath>
|
||||||
|
|
||||||
{/* Icon */}
|
{/* Icon (lucide 24×24 scaled to 14px) */}
|
||||||
<text x={14} y={h / 2 + 4} fill={statusColor ?? color} fontSize={14}>
|
<g transform={`translate(6, ${h / 2 - 7}) scale(0.583)`}>
|
||||||
{icon}
|
{iconElements.map((el: IconElement, i: number) =>
|
||||||
</text>
|
'd' in el
|
||||||
|
? <path key={i} d={el.d} fill="none" stroke={statusColor ?? color} strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" />
|
||||||
|
: <circle key={i} cx={el.cx} cy={el.cy} r={el.r} fill="none" stroke={statusColor ?? color} strokeWidth={2} />
|
||||||
|
)}
|
||||||
|
</g>
|
||||||
|
|
||||||
{/* Type name + detail (clipped to available width) */}
|
{/* Type name + detail (clipped to available width) */}
|
||||||
<g clipPath={`url(#clip-${node.id})`}>
|
<g clipPath={`url(#clip-${node.id})`}>
|
||||||
|
|||||||
@@ -91,17 +91,241 @@ export function isCompletionCompoundType(type: string | undefined): boolean {
|
|||||||
return !!type && COMPLETION_COMPOUND_TYPES.has(type);
|
return !!type && COMPLETION_COMPOUND_TYPES.has(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Icon character for a node type */
|
/**
|
||||||
export function iconForType(type: string | undefined): string {
|
* Lucide-based icon definitions for node types.
|
||||||
if (!type) return '\u2699'; // gear
|
* Each icon is an array of SVG element descriptors (path d-strings or circles).
|
||||||
const t = type.toUpperCase();
|
*/
|
||||||
if (t === 'ENDPOINT') return '\u25B6'; // play
|
export type IconElement = { d: string } | { cx: number; cy: number; r: number };
|
||||||
if (t === 'TO' || t === 'TO_DYNAMIC' || t === 'DIRECT' || t === 'SEDA') return '\u25A0'; // square
|
|
||||||
if (t.startsWith('EIP_CHOICE') || t === 'EIP_WHEN' || t === 'EIP_OTHERWISE') return '\u25C6'; // diamond
|
// Lucide icon path data (24×24 viewBox, stroke-based)
|
||||||
if (t === 'ON_COMPLETION') return '\u2714'; // checkmark
|
const ICONS: Record<string, IconElement[]> = {
|
||||||
if (t === 'ON_EXCEPTION' || t === 'ERROR_HANDLER' || t.startsWith('TRY') || t.startsWith('DO_')) return '\u26A0'; // warning
|
// Play — ENDPOINT
|
||||||
if (t === 'EIP_SPLIT' || t === 'EIP_MULTICAST') return '\u2442'; // fork
|
play: [{ d: 'M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z' }],
|
||||||
if (t === 'EIP_LOOP') return '\u21BA'; // loop arrow
|
// Send — TO
|
||||||
if (t === 'EIP_WIRE_TAP' || t === 'EIP_ENRICH' || t === 'EIP_POLL_ENRICH') return '\u2197'; // arrow
|
send: [
|
||||||
return '\u2699'; // gear
|
{ d: 'M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z' },
|
||||||
|
{ d: 'm21.854 2.147-10.94 10.939' },
|
||||||
|
],
|
||||||
|
// Shuffle — TO_DYNAMIC
|
||||||
|
shuffle: [
|
||||||
|
{ d: 'm18 14 4 4-4 4' },
|
||||||
|
{ d: 'm18 2 4 4-4 4' },
|
||||||
|
{ d: 'M2 18h1.973a4 4 0 0 0 3.3-1.7l5.454-8.6a4 4 0 0 1 3.3-1.7H22' },
|
||||||
|
{ d: 'M2 6h1.972a4 4 0 0 1 3.6 2.2' },
|
||||||
|
{ d: 'M22 18h-6.041a4 4 0 0 1-3.3-1.8l-.359-.45' },
|
||||||
|
],
|
||||||
|
// Zap — DIRECT
|
||||||
|
zap: [{ d: 'M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z' }],
|
||||||
|
// Layers — SEDA
|
||||||
|
layers: [
|
||||||
|
{ d: 'M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z' },
|
||||||
|
{ d: 'M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12' },
|
||||||
|
{ d: 'M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17' },
|
||||||
|
],
|
||||||
|
// Cog — PROCESSOR (default)
|
||||||
|
cog: [
|
||||||
|
{ d: 'M11 10.27 7 3.34' }, { d: 'm11 13.73-4 6.93' },
|
||||||
|
{ d: 'M12 22v-2' }, { d: 'M12 2v2' }, { d: 'M14 12h8' },
|
||||||
|
{ d: 'm17 20.66-1-1.73' }, { d: 'm17 3.34-1 1.73' },
|
||||||
|
{ d: 'M2 12h2' }, { d: 'm20.66 17-1.73-1' }, { d: 'm20.66 7-1.73 1' },
|
||||||
|
{ d: 'm3.34 17 1.73-1' }, { d: 'm3.34 7 1.73 1' },
|
||||||
|
{ cx: 12, cy: 12, r: 3 },
|
||||||
|
],
|
||||||
|
// Coffee — BEAN
|
||||||
|
coffee: [
|
||||||
|
{ d: 'M10 2v2' }, { d: 'M14 2v2' }, { d: 'M6 2v2' },
|
||||||
|
{ d: 'M16 8a1 1 0 0 1 1 1v8a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1h14a4 4 0 1 1 0 8h-1' },
|
||||||
|
],
|
||||||
|
// FileText — LOG
|
||||||
|
fileText: [
|
||||||
|
{ d: 'M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z' },
|
||||||
|
{ d: 'M14 2v5a1 1 0 0 0 1 1h5' },
|
||||||
|
{ d: 'M10 9H8' }, { d: 'M16 13H8' }, { d: 'M16 17H8' },
|
||||||
|
],
|
||||||
|
// Tag — SET_HEADER
|
||||||
|
tag: [{ d: 'M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z' }, { cx: 7.5, cy: 7.5, r: 1 }],
|
||||||
|
// PenLine — SET_BODY
|
||||||
|
penLine: [
|
||||||
|
{ d: 'M13 21h8' },
|
||||||
|
{ d: 'M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z' },
|
||||||
|
],
|
||||||
|
// RefreshCw — TRANSFORM
|
||||||
|
refreshCw: [
|
||||||
|
{ d: 'M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8' },
|
||||||
|
{ d: 'M21 3v5h-5' },
|
||||||
|
{ d: 'M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16' },
|
||||||
|
{ d: 'M8 16H3v5' },
|
||||||
|
],
|
||||||
|
// Package — MARSHAL
|
||||||
|
package: [
|
||||||
|
{ d: 'M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z' },
|
||||||
|
{ d: 'M12 22V12' }, { d: 'm7.5 4.27 9 5.15' },
|
||||||
|
],
|
||||||
|
// PackageOpen — UNMARSHAL
|
||||||
|
packageOpen: [
|
||||||
|
{ d: 'M12 22v-9' },
|
||||||
|
{ d: 'M15.17 2.21a1.67 1.67 0 0 1 1.63 0L21 4.57a1.93 1.93 0 0 1 0 3.36L8.82 14.79a1.655 1.655 0 0 1-1.64 0L3 12.43a1.93 1.93 0 0 1 0-3.36z' },
|
||||||
|
{ d: 'M20 13v3.87a2.06 2.06 0 0 1-1.11 1.83l-6 3.08a1.93 1.93 0 0 1-1.78 0l-6-3.08A2.06 2.06 0 0 1 4 16.87V13' },
|
||||||
|
{ d: 'M21 12.43a1.93 1.93 0 0 0 0-3.36L8.83 2.2a1.64 1.64 0 0 0-1.63 0L3 4.57a1.93 1.93 0 0 0 0 3.36l12.18 6.86a1.636 1.636 0 0 0 1.63 0z' },
|
||||||
|
],
|
||||||
|
// GitBranch — EIP_CHOICE
|
||||||
|
gitBranch: [{ d: 'M15 6a9 9 0 0 0-9 9V3' }, { cx: 18, cy: 6, r: 3 }, { cx: 6, cy: 18, r: 3 }],
|
||||||
|
// CircleAlert — EIP_WHEN (condition)
|
||||||
|
circleAlert: [{ cx: 12, cy: 12, r: 10 }, { d: 'M12 8v4' }, { d: 'M12 16h.01' }],
|
||||||
|
// CircleDot — EIP_OTHERWISE (default)
|
||||||
|
circleDot: [{ cx: 12, cy: 12, r: 10 }, { cx: 12, cy: 12, r: 1 }],
|
||||||
|
// Split — EIP_SPLIT
|
||||||
|
split: [
|
||||||
|
{ d: 'M16 3h5v5' }, { d: 'M8 3H3v5' },
|
||||||
|
{ d: 'M12 22v-8.3a4 4 0 0 0-1.172-2.872L3 3' },
|
||||||
|
{ d: 'm15 9 6-6' },
|
||||||
|
],
|
||||||
|
// Share2 — EIP_MULTICAST
|
||||||
|
share2: [
|
||||||
|
{ cx: 18, cy: 5, r: 3 }, { cx: 6, cy: 12, r: 3 }, { cx: 18, cy: 19, r: 3 },
|
||||||
|
{ d: 'M8.59 13.51 15.42 17.49' }, { d: 'M15.41 6.51 8.59 10.49' },
|
||||||
|
],
|
||||||
|
// Repeat — EIP_LOOP
|
||||||
|
repeat: [
|
||||||
|
{ d: 'm17 2 4 4-4 4' },
|
||||||
|
{ d: 'M3 11v-1a4 4 0 0 1 4-4h14' },
|
||||||
|
{ d: 'm7 22-4-4 4-4' },
|
||||||
|
{ d: 'M21 13v1a4 4 0 0 1-4 4H3' },
|
||||||
|
],
|
||||||
|
// Merge — EIP_AGGREGATE
|
||||||
|
merge: [{ d: 'm8 6 4-4 4 4' }, { d: 'M12 2v10.3a4 4 0 0 1-1.172 2.872L4 22' }, { d: 'm20 22-5-5' }],
|
||||||
|
// Funnel — EIP_FILTER
|
||||||
|
funnel: [{ d: 'M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z' }],
|
||||||
|
// Users — EIP_RECIPIENT_LIST
|
||||||
|
users: [
|
||||||
|
{ d: 'M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2' },
|
||||||
|
{ cx: 9, cy: 7, r: 4 },
|
||||||
|
{ d: 'M16 3.128a4 4 0 0 1 0 7.744' },
|
||||||
|
{ d: 'M22 21v-2a4 4 0 0 0-3-3.87' },
|
||||||
|
],
|
||||||
|
// Navigation — EIP_ROUTING_SLIP
|
||||||
|
navigation: [{ d: 'M3,11 L22,2 L13,21 L11,13Z' }],
|
||||||
|
// Waypoints — EIP_DYNAMIC_ROUTER
|
||||||
|
waypoints: [
|
||||||
|
{ d: 'm10.586 5.414-5.172 5.172' }, { d: 'm18.586 13.414-5.172 5.172' },
|
||||||
|
{ d: 'M6 12h12' },
|
||||||
|
{ cx: 12, cy: 20, r: 2 }, { cx: 12, cy: 4, r: 2 },
|
||||||
|
{ cx: 20, cy: 12, r: 2 }, { cx: 4, cy: 12, r: 2 },
|
||||||
|
],
|
||||||
|
// Scale — EIP_LOAD_BALANCE
|
||||||
|
scale: [
|
||||||
|
{ d: 'M12 3v18' },
|
||||||
|
{ d: 'm19 8 3 8a5 5 0 0 1-6 0zV7' },
|
||||||
|
{ d: 'M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1' },
|
||||||
|
{ d: 'm5 8 3 8a5 5 0 0 1-6 0zV7' },
|
||||||
|
{ d: 'M7 21h10' },
|
||||||
|
],
|
||||||
|
// Gauge — EIP_THROTTLE
|
||||||
|
gauge: [{ d: 'm12 14 4-4' }, { d: 'M3.34 19a10 10 0 1 1 17.32 0' }],
|
||||||
|
// Clock — EIP_DELAY
|
||||||
|
clock: [{ cx: 12, cy: 12, r: 10 }, { d: 'M12 6v6l4 2' }],
|
||||||
|
// Hash — EIP_IDEMPOTENT_CONSUMER
|
||||||
|
hash: [{ d: 'M4 9L20 9' }, { d: 'M4 15L20 15' }, { d: 'M10 3L8 21' }, { d: 'M16 3L14 21' }],
|
||||||
|
// ZapOff — EIP_CIRCUIT_BREAKER
|
||||||
|
zapOff: [
|
||||||
|
{ d: 'M10.513 4.856 13.12 2.17a.5.5 0 0 1 .86.46l-1.377 4.317' },
|
||||||
|
{ d: 'M15.656 10H20a1 1 0 0 1 .78 1.63l-1.72 1.773' },
|
||||||
|
{ d: 'M16.273 16.273 10.88 21.83a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14H4a1 1 0 0 1-.78-1.63l4.507-4.643' },
|
||||||
|
{ d: 'm2 2 20 20' },
|
||||||
|
],
|
||||||
|
// Workflow — EIP_PIPELINE
|
||||||
|
workflow: [
|
||||||
|
{ d: 'M5,3h4a2,2 0 0 1 2,2v4a2,2 0 0 1-2,2h-4a2,2 0 0 1-2,-2v-4a2,2 0 0 1 2,-2Z' },
|
||||||
|
{ d: 'M7 11v4a2 2 0 0 0 2 2h4' },
|
||||||
|
{ d: 'M15,13h4a2,2 0 0 1 2,2v4a2,2 0 0 1-2,2h-4a2,2 0 0 1-2,-2v-4a2,2 0 0 1 2,-2Z' },
|
||||||
|
],
|
||||||
|
// ShieldAlert — ERROR_HANDLER
|
||||||
|
shieldAlert: [
|
||||||
|
{ d: 'M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z' },
|
||||||
|
{ d: 'M12 8v4' }, { d: 'M12 16h.01' },
|
||||||
|
],
|
||||||
|
// OctagonAlert — ON_EXCEPTION
|
||||||
|
octagonAlert: [
|
||||||
|
{ d: 'M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z' },
|
||||||
|
{ d: 'M12 8v4' }, { d: 'M12 16h.01' },
|
||||||
|
],
|
||||||
|
// Shield — DO_TRY
|
||||||
|
shield: [{ d: 'M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z' }],
|
||||||
|
// Hand — DO_CATCH
|
||||||
|
hand: [
|
||||||
|
{ d: 'M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2' },
|
||||||
|
{ d: 'M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2' },
|
||||||
|
{ d: 'M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8' },
|
||||||
|
{ d: 'M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15' },
|
||||||
|
],
|
||||||
|
// ListChecks — DO_FINALLY
|
||||||
|
listChecks: [
|
||||||
|
{ d: 'M13 5h8' }, { d: 'M13 12h8' }, { d: 'M13 19h8' },
|
||||||
|
{ d: 'm3 17 2 2 4-4' }, { d: 'm3 7 2 2 4-4' },
|
||||||
|
],
|
||||||
|
// Eye — EIP_WIRE_TAP
|
||||||
|
eye: [
|
||||||
|
{ d: 'M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0' },
|
||||||
|
{ cx: 12, cy: 12, r: 3 },
|
||||||
|
],
|
||||||
|
// CirclePlus — EIP_ENRICH
|
||||||
|
circlePlus: [{ cx: 12, cy: 12, r: 10 }, { d: 'M8 12h8' }, { d: 'M12 8v8' }],
|
||||||
|
// CircleArrowDown — EIP_POLL_ENRICH
|
||||||
|
circleArrowDown: [{ cx: 12, cy: 12, r: 10 }, { d: 'M12 8v8' }, { d: 'm8 12 4 4 4-4' }],
|
||||||
|
// CircleCheck — ON_COMPLETION
|
||||||
|
circleCheck: [{ cx: 12, cy: 12, r: 10 }, { d: 'm9 12 2 2 4-4' }],
|
||||||
|
};
|
||||||
|
|
||||||
|
const ICON_MAP: Record<string, IconElement[]> = {
|
||||||
|
ENDPOINT: ICONS.play,
|
||||||
|
TO: ICONS.send,
|
||||||
|
TO_DYNAMIC: ICONS.shuffle,
|
||||||
|
DIRECT: ICONS.zap,
|
||||||
|
SEDA: ICONS.layers,
|
||||||
|
|
||||||
|
PROCESSOR: ICONS.cog,
|
||||||
|
BEAN: ICONS.coffee,
|
||||||
|
LOG: ICONS.fileText,
|
||||||
|
SET_HEADER: ICONS.tag,
|
||||||
|
SET_BODY: ICONS.penLine,
|
||||||
|
TRANSFORM: ICONS.refreshCw,
|
||||||
|
MARSHAL: ICONS.package,
|
||||||
|
UNMARSHAL: ICONS.packageOpen,
|
||||||
|
|
||||||
|
EIP_CHOICE: ICONS.gitBranch,
|
||||||
|
EIP_WHEN: ICONS.circleAlert,
|
||||||
|
EIP_OTHERWISE: ICONS.circleDot,
|
||||||
|
EIP_SPLIT: ICONS.split,
|
||||||
|
EIP_MULTICAST: ICONS.share2,
|
||||||
|
EIP_LOOP: ICONS.repeat,
|
||||||
|
EIP_AGGREGATE: ICONS.merge,
|
||||||
|
EIP_FILTER: ICONS.funnel,
|
||||||
|
EIP_RECIPIENT_LIST: ICONS.users,
|
||||||
|
EIP_ROUTING_SLIP: ICONS.navigation,
|
||||||
|
EIP_DYNAMIC_ROUTER: ICONS.waypoints,
|
||||||
|
EIP_LOAD_BALANCE: ICONS.scale,
|
||||||
|
EIP_THROTTLE: ICONS.gauge,
|
||||||
|
EIP_DELAY: ICONS.clock,
|
||||||
|
EIP_IDEMPOTENT_CONSUMER: ICONS.hash,
|
||||||
|
EIP_CIRCUIT_BREAKER: ICONS.zapOff,
|
||||||
|
EIP_PIPELINE: ICONS.workflow,
|
||||||
|
|
||||||
|
ERROR_HANDLER: ICONS.shieldAlert,
|
||||||
|
ON_EXCEPTION: ICONS.octagonAlert,
|
||||||
|
TRY_CATCH: ICONS.shield,
|
||||||
|
DO_TRY: ICONS.shield,
|
||||||
|
DO_CATCH: ICONS.hand,
|
||||||
|
DO_FINALLY: ICONS.listChecks,
|
||||||
|
|
||||||
|
EIP_WIRE_TAP: ICONS.eye,
|
||||||
|
EIP_ENRICH: ICONS.circlePlus,
|
||||||
|
EIP_POLL_ENRICH: ICONS.circleArrowDown,
|
||||||
|
|
||||||
|
ON_COMPLETION: ICONS.circleCheck,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Lucide SVG icon elements for a node type (24×24 viewBox, stroke-based) */
|
||||||
|
export function iconForType(type: string | undefined): IconElement[] {
|
||||||
|
if (!type) return ICONS.cog;
|
||||||
|
return ICON_MAP[type.toUpperCase()] ?? ICONS.cog;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user