fix: show resolvedEndpointUri in info tab, reflect trace/tap state in toolbar
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m40s
CI / docker (push) Successful in 1m49s
CI / deploy (push) Successful in 53s
CI / deploy-feature (push) Has been skipped

- Info tab now reads processor.resolvedEndpointUri instead of hardcoded "-"
- Toolbar buttons highlight in teal/purple when trace/tap is active
- Tooltip changes to "Disable tracing" / "Edit tap" when active

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-29 15:45:06 +02:00
parent 604e5db874
commit 32cde5363f
4 changed files with 44 additions and 24 deletions

View File

@@ -80,7 +80,7 @@ export function InfoTab({ processor, executionDetail }: InfoTabProps) {
<Field label="Duration" value={formatDuration(processor.durationMs)} mono /> <Field label="Duration" value={formatDuration(processor.durationMs)} mono />
<Field label="Endpoint URI" value={processor.processorType} /> <Field label="Endpoint URI" value={processor.processorType} />
<Field label="Resolved URI" value="-" /> <Field label="Resolved URI" value={processor.resolvedEndpointUri ?? '-'} mono />
<div /> <div />
</div> </div>
<Attributes attrs={processor.attributes} /> <Attributes attrs={processor.attributes} />

View File

@@ -1,10 +1,10 @@
import { useCallback, useRef, useState } from 'react'; import { useCallback, useRef, useState } from 'react';
import { Search, Footprints, Droplets, Ellipsis } from 'lucide-react'; import { Search, Footprints, Droplets, Ellipsis } from 'lucide-react';
import type { LucideIcon } from 'lucide-react'; import type { NodeAction, NodeConfig } from './types';
import type { NodeAction } from './types';
import styles from './ProcessDiagram.module.css'; import styles from './ProcessDiagram.module.css';
const HIDE_DELAY = 150; const HIDE_DELAY = 150;
const TRACE_ACTIVE_COLOR = '#1A7F8E';
interface NodeToolbarProps { interface NodeToolbarProps {
nodeId: string; nodeId: string;
@@ -14,18 +14,16 @@ interface NodeToolbarProps {
onAction: (nodeId: string, action: NodeAction) => void; onAction: (nodeId: string, action: NodeAction) => void;
onMouseEnter: () => void; onMouseEnter: () => void;
onMouseLeave: () => void; onMouseLeave: () => void;
/** Current config for this node (trace/tap state) */
nodeConfig?: NodeConfig;
} }
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({ export function NodeToolbar({
nodeId, screenX, screenY, onAction, onMouseEnter, onMouseLeave, nodeId, screenX, screenY, onAction, onMouseEnter, onMouseLeave, nodeConfig,
}: NodeToolbarProps) { }: NodeToolbarProps) {
const traceActive = !!nodeConfig?.traceEnabled;
const tapActive = !!nodeConfig?.tapExpression;
return ( return (
<div <div
className={styles.nodeToolbar} className={styles.nodeToolbar}
@@ -33,19 +31,36 @@ export function NodeToolbar({
onMouseEnter={onMouseEnter} onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave} onMouseLeave={onMouseLeave}
> >
{ACTIONS.map(a => ( <button
<button className={styles.nodeToolbarBtn}
key={a.action} title="Inspect"
className={styles.nodeToolbarBtn} onClick={(e) => { e.stopPropagation(); onAction(nodeId, 'inspect'); }}
title={a.title} >
onClick={(e) => { <Search size={14} />
e.stopPropagation(); </button>
onAction(nodeId, a.action); <button
}} className={`${styles.nodeToolbarBtn} ${traceActive ? styles.nodeToolbarBtnActive : ''}`}
> title={traceActive ? 'Disable tracing' : 'Enable tracing'}
<a.Icon size={14} /> onClick={(e) => { e.stopPropagation(); onAction(nodeId, 'toggle-trace'); }}
</button> 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>
</div> </div>
); );
} }

View File

@@ -171,6 +171,10 @@
color: var(--text-primary, #1A1612); color: var(--text-primary, #1A1612);
} }
.nodeToolbarBtnActive {
background: var(--bg-hover, #F5F0EA);
}
.iterationStepper { .iterationStepper {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@@ -395,6 +395,7 @@ export function ProcessDiagram({
onAction={handleNodeAction} onAction={handleNodeAction}
onMouseEnter={toolbar.onToolbarEnter} onMouseEnter={toolbar.onToolbarEnter}
onMouseLeave={toolbar.onToolbarLeave} onMouseLeave={toolbar.onToolbarLeave}
nodeConfig={nodeConfigs?.get(toolbar.hoveredNodeId!)}
/> />
); );
})()} })()}