feat: add interactive ProcessDiagram SVG component (sub-project 1/3)
New interactive route diagram component with SVG rendering using
server-computed ELK layout coordinates. TIBCO BW5-inspired top-bar
card node style with zoom/pan, hover toolbars, config badges, and
error handler sections below the main flow.
Backend: add direction query parameter (LR/TB) to diagram render
endpoints, defaulting to left-to-right layout.
Frontend: 14-file ProcessDiagram component in ui/src/components/
with DiagramNode, CompoundNode, DiagramEdge, ConfigBadge, NodeToolbar,
ErrorSection, ZoomControls, and supporting hooks. Dev test page at
/dev/diagram for validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:55:29 +01:00
|
|
|
import { useCallback, useRef, useState } from 'react';
|
2026-03-27 23:16:39 +01:00
|
|
|
import { Search, Footprints, Droplets, Ellipsis } from 'lucide-react';
|
2026-03-29 15:45:06 +02:00
|
|
|
import type { NodeAction, NodeConfig } from './types';
|
2026-03-27 16:33:24 +01:00
|
|
|
import styles from './ProcessDiagram.module.css';
|
feat: add interactive ProcessDiagram SVG component (sub-project 1/3)
New interactive route diagram component with SVG rendering using
server-computed ELK layout coordinates. TIBCO BW5-inspired top-bar
card node style with zoom/pan, hover toolbars, config badges, and
error handler sections below the main flow.
Backend: add direction query parameter (LR/TB) to diagram render
endpoints, defaulting to left-to-right layout.
Frontend: 14-file ProcessDiagram component in ui/src/components/
with DiagramNode, CompoundNode, DiagramEdge, ConfigBadge, NodeToolbar,
ErrorSection, ZoomControls, and supporting hooks. Dev test page at
/dev/diagram for validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:55:29 +01:00
|
|
|
|
|
|
|
|
const HIDE_DELAY = 150;
|
2026-03-29 15:45:06 +02:00
|
|
|
const TRACE_ACTIVE_COLOR = '#1A7F8E';
|
feat: add interactive ProcessDiagram SVG component (sub-project 1/3)
New interactive route diagram component with SVG rendering using
server-computed ELK layout coordinates. TIBCO BW5-inspired top-bar
card node style with zoom/pan, hover toolbars, config badges, and
error handler sections below the main flow.
Backend: add direction query parameter (LR/TB) to diagram render
endpoints, defaulting to left-to-right layout.
Frontend: 14-file ProcessDiagram component in ui/src/components/
with DiagramNode, CompoundNode, DiagramEdge, ConfigBadge, NodeToolbar,
ErrorSection, ZoomControls, and supporting hooks. Dev test page at
/dev/diagram for validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:55:29 +01:00
|
|
|
|
|
|
|
|
interface NodeToolbarProps {
|
|
|
|
|
nodeId: string;
|
2026-03-27 16:33:24 +01:00
|
|
|
/** Screen-space position (already transformed by zoom/pan) */
|
|
|
|
|
screenX: number;
|
|
|
|
|
screenY: number;
|
feat: add interactive ProcessDiagram SVG component (sub-project 1/3)
New interactive route diagram component with SVG rendering using
server-computed ELK layout coordinates. TIBCO BW5-inspired top-bar
card node style with zoom/pan, hover toolbars, config badges, and
error handler sections below the main flow.
Backend: add direction query parameter (LR/TB) to diagram render
endpoints, defaulting to left-to-right layout.
Frontend: 14-file ProcessDiagram component in ui/src/components/
with DiagramNode, CompoundNode, DiagramEdge, ConfigBadge, NodeToolbar,
ErrorSection, ZoomControls, and supporting hooks. Dev test page at
/dev/diagram for validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:55:29 +01:00
|
|
|
onAction: (nodeId: string, action: NodeAction) => void;
|
|
|
|
|
onMouseEnter: () => void;
|
|
|
|
|
onMouseLeave: () => void;
|
2026-03-29 15:45:06 +02:00
|
|
|
/** Current config for this node (trace/tap state) */
|
|
|
|
|
nodeConfig?: NodeConfig;
|
feat: add interactive ProcessDiagram SVG component (sub-project 1/3)
New interactive route diagram component with SVG rendering using
server-computed ELK layout coordinates. TIBCO BW5-inspired top-bar
card node style with zoom/pan, hover toolbars, config badges, and
error handler sections below the main flow.
Backend: add direction query parameter (LR/TB) to diagram render
endpoints, defaulting to left-to-right layout.
Frontend: 14-file ProcessDiagram component in ui/src/components/
with DiagramNode, CompoundNode, DiagramEdge, ConfigBadge, NodeToolbar,
ErrorSection, ZoomControls, and supporting hooks. Dev test page at
/dev/diagram for validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:55:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function NodeToolbar({
|
2026-03-29 15:45:06 +02:00
|
|
|
nodeId, screenX, screenY, onAction, onMouseEnter, onMouseLeave, nodeConfig,
|
feat: add interactive ProcessDiagram SVG component (sub-project 1/3)
New interactive route diagram component with SVG rendering using
server-computed ELK layout coordinates. TIBCO BW5-inspired top-bar
card node style with zoom/pan, hover toolbars, config badges, and
error handler sections below the main flow.
Backend: add direction query parameter (LR/TB) to diagram render
endpoints, defaulting to left-to-right layout.
Frontend: 14-file ProcessDiagram component in ui/src/components/
with DiagramNode, CompoundNode, DiagramEdge, ConfigBadge, NodeToolbar,
ErrorSection, ZoomControls, and supporting hooks. Dev test page at
/dev/diagram for validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:55:29 +01:00
|
|
|
}: NodeToolbarProps) {
|
2026-03-29 15:45:06 +02:00
|
|
|
const traceActive = !!nodeConfig?.traceEnabled;
|
|
|
|
|
const tapActive = !!nodeConfig?.tapExpression;
|
|
|
|
|
|
feat: add interactive ProcessDiagram SVG component (sub-project 1/3)
New interactive route diagram component with SVG rendering using
server-computed ELK layout coordinates. TIBCO BW5-inspired top-bar
card node style with zoom/pan, hover toolbars, config badges, and
error handler sections below the main flow.
Backend: add direction query parameter (LR/TB) to diagram render
endpoints, defaulting to left-to-right layout.
Frontend: 14-file ProcessDiagram component in ui/src/components/
with DiagramNode, CompoundNode, DiagramEdge, ConfigBadge, NodeToolbar,
ErrorSection, ZoomControls, and supporting hooks. Dev test page at
/dev/diagram for validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:55:29 +01:00
|
|
|
return (
|
2026-03-27 16:33:24 +01:00
|
|
|
<div
|
|
|
|
|
className={styles.nodeToolbar}
|
|
|
|
|
style={{ left: screenX, top: screenY }}
|
feat: add interactive ProcessDiagram SVG component (sub-project 1/3)
New interactive route diagram component with SVG rendering using
server-computed ELK layout coordinates. TIBCO BW5-inspired top-bar
card node style with zoom/pan, hover toolbars, config badges, and
error handler sections below the main flow.
Backend: add direction query parameter (LR/TB) to diagram render
endpoints, defaulting to left-to-right layout.
Frontend: 14-file ProcessDiagram component in ui/src/components/
with DiagramNode, CompoundNode, DiagramEdge, ConfigBadge, NodeToolbar,
ErrorSection, ZoomControls, and supporting hooks. Dev test page at
/dev/diagram for validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:55:29 +01:00
|
|
|
onMouseEnter={onMouseEnter}
|
|
|
|
|
onMouseLeave={onMouseLeave}
|
|
|
|
|
>
|
2026-03-29 15:45:06 +02:00
|
|
|
<button
|
|
|
|
|
className={styles.nodeToolbarBtn}
|
|
|
|
|
title="Inspect"
|
|
|
|
|
onClick={(e) => { e.stopPropagation(); onAction(nodeId, 'inspect'); }}
|
|
|
|
|
>
|
|
|
|
|
<Search size={14} />
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
className={`${styles.nodeToolbarBtn} ${traceActive ? styles.nodeToolbarBtnActive : ''}`}
|
|
|
|
|
title={traceActive ? 'Disable tracing' : 'Enable tracing'}
|
|
|
|
|
onClick={(e) => { e.stopPropagation(); onAction(nodeId, 'toggle-trace'); }}
|
|
|
|
|
style={traceActive ? { color: TRACE_ACTIVE_COLOR } : undefined}
|
|
|
|
|
>
|
|
|
|
|
<Footprints size={14} />
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
className={`${styles.nodeToolbarBtn} ${tapActive ? styles.nodeToolbarBtnActive : ''}`}
|
|
|
|
|
title={tapActive ? 'Edit tap' : 'Configure tap'}
|
|
|
|
|
onClick={(e) => { e.stopPropagation(); onAction(nodeId, 'configure-tap'); }}
|
|
|
|
|
style={tapActive ? { color: '#7C3AED' } : undefined}
|
|
|
|
|
>
|
|
|
|
|
<Droplets size={14} />
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
className={styles.nodeToolbarBtn}
|
|
|
|
|
title="Copy ID"
|
|
|
|
|
onClick={(e) => { e.stopPropagation(); onAction(nodeId, 'copy-id'); }}
|
|
|
|
|
>
|
|
|
|
|
<Ellipsis size={14} />
|
|
|
|
|
</button>
|
2026-03-27 16:33:24 +01:00
|
|
|
</div>
|
feat: add interactive ProcessDiagram SVG component (sub-project 1/3)
New interactive route diagram component with SVG rendering using
server-computed ELK layout coordinates. TIBCO BW5-inspired top-bar
card node style with zoom/pan, hover toolbars, config badges, and
error handler sections below the main flow.
Backend: add direction query parameter (LR/TB) to diagram render
endpoints, defaulting to left-to-right layout.
Frontend: 14-file ProcessDiagram component in ui/src/components/
with DiagramNode, CompoundNode, DiagramEdge, ConfigBadge, NodeToolbar,
ErrorSection, ZoomControls, and supporting hooks. Dev test page at
/dev/diagram for validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:55:29 +01:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Hook to manage toolbar visibility with hide delay */
|
|
|
|
|
export function useToolbarHover() {
|
|
|
|
|
const [hoveredNodeId, setHoveredNodeId] = useState<string | null>(null);
|
|
|
|
|
const hideTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
|
|
|
|
|
|
|
|
const onNodeEnter = useCallback((nodeId: string) => {
|
|
|
|
|
if (hideTimer.current) {
|
|
|
|
|
clearTimeout(hideTimer.current);
|
|
|
|
|
hideTimer.current = null;
|
|
|
|
|
}
|
|
|
|
|
setHoveredNodeId(nodeId);
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const onNodeLeave = useCallback(() => {
|
|
|
|
|
hideTimer.current = setTimeout(() => {
|
|
|
|
|
setHoveredNodeId(null);
|
|
|
|
|
hideTimer.current = null;
|
|
|
|
|
}, HIDE_DELAY);
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const onToolbarEnter = useCallback(() => {
|
|
|
|
|
if (hideTimer.current) {
|
|
|
|
|
clearTimeout(hideTimer.current);
|
|
|
|
|
hideTimer.current = null;
|
|
|
|
|
}
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const onToolbarLeave = useCallback(() => {
|
|
|
|
|
hideTimer.current = setTimeout(() => {
|
|
|
|
|
setHoveredNodeId(null);
|
|
|
|
|
hideTimer.current = null;
|
|
|
|
|
}, HIDE_DELAY);
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
return { hoveredNodeId, onNodeEnter, onNodeLeave, onToolbarEnter, onToolbarLeave };
|
|
|
|
|
}
|