feat: use endpointUri for cross-route drill-down instead of label parsing
Server: - Add endpointUri to PositionedNode (from RouteNode) - Add fromEndpointUri to RouteSummary (catalog API) - Catalog controller resolves endpoint URI from diagram store UI: - Build endpointRouteMap from catalog's fromEndpointUri field - Drill-down uses exact match on node.endpointUri against the map - Remove label parsing heuristics (extractTargetEndpoint, camelToKebab) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,30 +18,6 @@ const PADDING = 40;
|
||||
/** Types that support drill-down — double-click navigates to the target route */
|
||||
const DRILLDOWN_TYPES = new Set(['DIRECT', 'SEDA']);
|
||||
|
||||
/** Extract the target endpoint name from a node's label */
|
||||
function extractTargetEndpoint(node: DiagramNodeType): string | null {
|
||||
// Labels like "to: direct:orderProcessing" or "direct:orderProcessing"
|
||||
const label = node.label ?? '';
|
||||
const match = label.match(/(?:to:\s*)?(?:direct|seda):(\S+)/i);
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
/** Convert camelCase to kebab-case: "callGetProduct" → "call-get-product" */
|
||||
function camelToKebab(s: string): string {
|
||||
return s.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a direct/seda endpoint name to a routeId.
|
||||
* Tries: exact match, kebab-case conversion, then gives up.
|
||||
*/
|
||||
function resolveRouteId(endpoint: string, knownRouteIds: Set<string>): string | null {
|
||||
if (knownRouteIds.has(endpoint)) return endpoint;
|
||||
const kebab = camelToKebab(endpoint);
|
||||
if (knownRouteIds.has(kebab)) return kebab;
|
||||
return null;
|
||||
}
|
||||
|
||||
export function ProcessDiagram({
|
||||
application,
|
||||
routeId,
|
||||
@@ -51,6 +27,7 @@ export function ProcessDiagram({
|
||||
onNodeAction,
|
||||
nodeConfigs,
|
||||
knownRouteIds,
|
||||
endpointRouteMap,
|
||||
className,
|
||||
diagramLayout,
|
||||
executionOverlay,
|
||||
@@ -190,17 +167,18 @@ export function ProcessDiagram({
|
||||
(nodeId: string) => {
|
||||
const node = findNodeById(sections, nodeId);
|
||||
if (!node || !DRILLDOWN_TYPES.has(node.type ?? '')) return;
|
||||
const endpoint = extractTargetEndpoint(node);
|
||||
if (!endpoint) return;
|
||||
const resolved = knownRouteIds
|
||||
? resolveRouteId(endpoint, knownRouteIds)
|
||||
: endpoint;
|
||||
|
||||
// Resolve via endpointUri → endpointRouteMap (exact match, no heuristics)
|
||||
const uri = node.endpointUri;
|
||||
if (!uri) return;
|
||||
const stripped = uri.split('?')[0];
|
||||
const resolved = endpointRouteMap?.get(stripped);
|
||||
if (resolved) {
|
||||
onNodeSelect?.('');
|
||||
setRouteStack(prev => [...prev, resolved]);
|
||||
}
|
||||
},
|
||||
[sections, onNodeSelect, knownRouteIds],
|
||||
[sections, onNodeSelect, endpointRouteMap],
|
||||
);
|
||||
|
||||
const handleBreadcrumbClick = useCallback(
|
||||
|
||||
@@ -26,6 +26,8 @@ export interface ProcessDiagramProps {
|
||||
nodeConfigs?: Map<string, NodeConfig>;
|
||||
/** Known route IDs for this application (enables drill-down resolution) */
|
||||
knownRouteIds?: Set<string>;
|
||||
/** Maps from() endpoint URI → routeId for cross-route drill-down */
|
||||
endpointRouteMap?: Map<string, string>;
|
||||
className?: string;
|
||||
/** Pre-fetched diagram layout (bypasses internal fetch by application/routeId) */
|
||||
diagramLayout?: DiagramLayout;
|
||||
|
||||
Reference in New Issue
Block a user