fix(dashboard): route skip-forward edges to side (planner→end was hidden)
This commit is contained in:
@@ -62,7 +62,7 @@ function computeLayers(edges: readonly WorkflowGraphEdge[]): string[][] {
|
|||||||
for (const id of ids) adj.set(id, []);
|
for (const id of ids) adj.set(id, []);
|
||||||
for (const e of edges) {
|
for (const e of edges) {
|
||||||
if (e.from !== e.to) {
|
if (e.from !== e.to) {
|
||||||
adj.get(e.from)!.push(e.to);
|
adj.get(e.from)?.push(e.to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,16 +247,17 @@ function computeLayout(input: LayoutInput): LayoutResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build edges with label positions
|
// Build edges with label positions
|
||||||
// For feedback edges (target rank < source rank), we'll compute label at midpoint
|
// Feedback edges (target rank < source rank) and skip-forward edges (span > 1 layer)
|
||||||
// of the right-side arc. The actual SVG path is drawn by ConditionEdge component.
|
// are routed to the side. Adjacent forward edges go straight down.
|
||||||
// Track feedback edge count per target node for alternating sides
|
// Track routed edge count per side for alternating
|
||||||
const feedbackCountByTarget = new Map<string, number>();
|
const routedCountByTarget = new Map<string, number>();
|
||||||
const edges: Edge[] = input.edges.map((e) => {
|
const edges: Edge[] = input.edges.map((e) => {
|
||||||
const isFallback = e.condition === "FALLBACK";
|
const isFallback = e.condition === "FALLBACK";
|
||||||
const isSelfLoop = e.from === e.to;
|
const isSelfLoop = e.from === e.to;
|
||||||
const sourceRank = rank.get(e.from) ?? 0;
|
const sourceRank = rank.get(e.from) ?? 0;
|
||||||
const targetRank = rank.get(e.to) ?? 0;
|
const targetRank = rank.get(e.to) ?? 0;
|
||||||
const isFeedback = !isSelfLoop && targetRank <= sourceRank;
|
const isFeedback = !isSelfLoop && targetRank <= sourceRank;
|
||||||
|
const isSkipForward = !isSelfLoop && !isFeedback && targetRank - sourceRank > 1;
|
||||||
|
|
||||||
const sourcePos = nodePositions.get(e.from);
|
const sourcePos = nodePositions.get(e.from);
|
||||||
const targetPos = nodePositions.get(e.to);
|
const targetPos = nodePositions.get(e.to);
|
||||||
@@ -266,10 +267,10 @@ function computeLayout(input: LayoutInput): LayoutResult {
|
|||||||
let feedbackSide: "right" | "left" | null = null;
|
let feedbackSide: "right" | "left" | null = null;
|
||||||
|
|
||||||
if (sourcePos !== undefined && targetPos !== undefined) {
|
if (sourcePos !== undefined && targetPos !== undefined) {
|
||||||
if (isFeedback) {
|
if (isFeedback || isSkipForward) {
|
||||||
// Alternate feedback edges left/right per target node
|
// Route to side — alternate left/right per target node
|
||||||
const count = feedbackCountByTarget.get(e.to) ?? 0;
|
const count = routedCountByTarget.get(e.to) ?? 0;
|
||||||
feedbackCountByTarget.set(e.to, count + 1);
|
routedCountByTarget.set(e.to, count + 1);
|
||||||
feedbackSide = count % 2 === 0 ? "right" : "left";
|
feedbackSide = count % 2 === 0 ? "right" : "left";
|
||||||
const offsetX =
|
const offsetX =
|
||||||
feedbackSide === "right"
|
feedbackSide === "right"
|
||||||
@@ -292,18 +293,20 @@ function computeLayout(input: LayoutInput): LayoutResult {
|
|||||||
id: edgeKey(e),
|
id: edgeKey(e),
|
||||||
source: e.from,
|
source: e.from,
|
||||||
target: e.to,
|
target: e.to,
|
||||||
sourceHandle: isFeedback
|
sourceHandle:
|
||||||
? feedbackSide === "left"
|
isFeedback || isSkipForward
|
||||||
? "left-out"
|
? feedbackSide === "left"
|
||||||
: "right-out"
|
? "left-out"
|
||||||
: "bottom-out",
|
: "right-out"
|
||||||
targetHandle: isFeedback ? (feedbackSide === "left" ? "left-in" : "right-in") : "top-in",
|
: "bottom-out",
|
||||||
|
targetHandle:
|
||||||
|
isFeedback || isSkipForward ? (feedbackSide === "left" ? "left-in" : "right-in") : "top-in",
|
||||||
type: "condition",
|
type: "condition",
|
||||||
data: {
|
data: {
|
||||||
condition: e.condition,
|
condition: e.condition,
|
||||||
conditionDescription: e.conditionDescription,
|
conditionDescription: e.conditionDescription,
|
||||||
isFallback,
|
isFallback,
|
||||||
isFeedback,
|
isFeedback: isFeedback || isSkipForward,
|
||||||
isSelfLoop,
|
isSelfLoop,
|
||||||
feedbackSide,
|
feedbackSide,
|
||||||
labelX,
|
labelX,
|
||||||
|
|||||||
Reference in New Issue
Block a user