Skip to content

Commit d3299a6

Browse files
committed
fix(Canvas): Duplicated edge IDs
Currently, edge IDs are not scoped to the owner flow, causing to be duplicated in case two flows use the same step combination. The fix is to scope the edge ID as well, so we avoid the duplication. fix: #1897
1 parent 8ce024a commit d3299a6

File tree

9 files changed

+49
-28
lines changed

9 files changed

+49
-28
lines changed

packages/ui-tests/cypress/e2e/codeEditor/sourceCodeActions.cy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('Test source code editor', () => {
3636
cy.editorDeleteLine(12, 6);
3737
cy.openDesignPage();
3838
// CHECK the kafka-sink step was removed
39-
cy.checkNodeExist('kafka-sink', 0);
39+
cy.checkNodeExist('integration|kafka-sink', 0);
4040
});
4141

4242
it('User edits step in the YAML', () => {

packages/ui-tests/cypress/e2e/designer/branchingFlows/branchingStepAddition.cy.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ describe('Test for Branching actions from the canvas', () => {
6262

6363
cy.checkNodeExist('activemq', 1);
6464
cy.checkEdgeExists(
65+
'eip-action',
6566
'template.from.steps.1.choice.when.0.steps.1.setHeader',
6667
'template.from.steps.1.choice.when.0.steps.2.to',
6768
);
@@ -77,6 +78,7 @@ describe('Test for Branching actions from the canvas', () => {
7778

7879
cy.checkNodeExist('activemq', 1);
7980
cy.checkEdgeExists(
81+
'eip-action',
8082
'template.from.steps.1.choice.when.0.steps.0.to',
8183
'template.from.steps.1.choice.when.0.steps.1.to',
8284
);
@@ -91,6 +93,6 @@ describe('Test for Branching actions from the canvas', () => {
9193
cy.chooseFromCatalog('component', 'activemq');
9294

9395
cy.checkNodeExist('activemq', 1);
94-
cy.checkEdgeExists('template.from.steps.2.to', 'template.from.steps.3.filter');
96+
cy.checkEdgeExists('eip-action', 'template.from.steps.2.to', 'template.from.steps.3.filter');
9597
});
9698
});

packages/ui-tests/cypress/support/cypress.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ declare global {
6161
selectRemoveGroup(groupName: string, nodeIndex?: number): Chainable<JQuery<Element>>;
6262
performNodeAction(nodeName: string, action: ActionType, nodeIndex?: number): Chainable<JQuery<Element>>;
6363
checkNodeExist(inputName: string, nodesCount: number): Chainable<JQuery<Element>>;
64-
checkEdgeExists(sourceName: string, targetName: string): Chainable<JQuery<Element>>;
64+
checkEdgeExists(scope: string, sourceName: string, targetName: string): Chainable<JQuery<Element>>;
6565
deleteBranch(branchIndex: number): Chainable<JQuery<Element>>;
6666
selectCamelRouteType(type: string, subType?: string): Chainable<JQuery<Element>>;
6767
selectRuntimeVersion(type: string): Chainable<JQuery<Element>>;

packages/ui-tests/cypress/support/next-commands/design.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ Cypress.Commands.add('checkNodeExist', (inputName, nodesCount) => {
105105
cy.get(`foreignObject[data-nodelabel="${inputName}"]`).should('have.length', nodesCount);
106106
});
107107

108-
Cypress.Commands.add('checkEdgeExists', (sourceName: string, targetName: string) => {
109-
const idPattern = `${sourceName} >>> ${targetName}`;
108+
Cypress.Commands.add('checkEdgeExists', (scope: string, sourceName: string, targetName: string) => {
109+
const idPattern = `${scope}|${sourceName} >>> ${targetName}`;
110110
// Check if an element with the matching id exists
111111
cy.get('g').should(($elements) => {
112112
// Use Cypress commands to check if any element matches the id pattern

packages/ui/src/components/Visualization/Canvas/__snapshots__/Canvas.test.tsx.snap

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ exports[`Canvas Catalog button should NOT be present if \`CatalogModalContext\`
141141
data-layer-id="default"
142142
>
143143
<g
144-
data-id="route.from >>> route.from.steps.0.set-header"
144+
data-id="route-8888|route.from >>> route.from.steps.0.set-header"
145145
data-kind="edge"
146146
data-type="edge"
147147
style="z-index: 0;"
@@ -210,7 +210,7 @@ exports[`Canvas Catalog button should NOT be present if \`CatalogModalContext\`
210210
</g>
211211
</g>
212212
<g
213-
data-id="route.from.steps.0.set-header >>> route.from.steps.1.choice"
213+
data-id="route-8888|route.from.steps.0.set-header >>> route.from.steps.1.choice"
214214
data-kind="edge"
215215
data-type="edge"
216216
style="z-index: 0;"
@@ -279,7 +279,7 @@ exports[`Canvas Catalog button should NOT be present if \`CatalogModalContext\`
279279
</g>
280280
</g>
281281
<g
282-
data-id="route.from.steps.1.choice.otherwise.steps.0.to >>> route.from.steps.1.choice.otherwise.steps.1.to"
282+
data-id="route-8888|route.from.steps.1.choice.otherwise.steps.0.to >>> route.from.steps.1.choice.otherwise.steps.1.to"
283283
data-kind="edge"
284284
data-type="edge"
285285
style="z-index: 0;"
@@ -348,7 +348,7 @@ exports[`Canvas Catalog button should NOT be present if \`CatalogModalContext\`
348348
</g>
349349
</g>
350350
<g
351-
data-id="route.from.steps.1.choice.otherwise.steps.1.to >>> route.from.steps.1.choice.otherwise.steps.2.log"
351+
data-id="route-8888|route.from.steps.1.choice.otherwise.steps.1.to >>> route.from.steps.1.choice.otherwise.steps.2.log"
352352
data-kind="edge"
353353
data-type="edge"
354354
style="z-index: 0;"
@@ -417,7 +417,7 @@ exports[`Canvas Catalog button should NOT be present if \`CatalogModalContext\`
417417
</g>
418418
</g>
419419
<g
420-
data-id="route.from.steps.1.choice >>> route.from.steps.2.to"
420+
data-id="route-8888|route.from.steps.1.choice >>> route.from.steps.2.to"
421421
data-kind="edge"
422422
data-type="edge"
423423
style="z-index: 0;"
@@ -925,7 +925,7 @@ exports[`Canvas Catalog button should be present if \`CatalogModalContext\` is p
925925
data-layer-id="default"
926926
>
927927
<g
928-
data-id="route.from >>> route.from.steps.0.set-header"
928+
data-id="route-8888|route.from >>> route.from.steps.0.set-header"
929929
data-kind="edge"
930930
data-type="edge"
931931
style="z-index: 0;"
@@ -994,7 +994,7 @@ exports[`Canvas Catalog button should be present if \`CatalogModalContext\` is p
994994
</g>
995995
</g>
996996
<g
997-
data-id="route.from.steps.0.set-header >>> route.from.steps.1.choice"
997+
data-id="route-8888|route.from.steps.0.set-header >>> route.from.steps.1.choice"
998998
data-kind="edge"
999999
data-type="edge"
10001000
style="z-index: 0;"
@@ -1063,7 +1063,7 @@ exports[`Canvas Catalog button should be present if \`CatalogModalContext\` is p
10631063
</g>
10641064
</g>
10651065
<g
1066-
data-id="route.from.steps.1.choice.otherwise.steps.0.to >>> route.from.steps.1.choice.otherwise.steps.1.to"
1066+
data-id="route-8888|route.from.steps.1.choice.otherwise.steps.0.to >>> route.from.steps.1.choice.otherwise.steps.1.to"
10671067
data-kind="edge"
10681068
data-type="edge"
10691069
style="z-index: 0;"
@@ -1132,7 +1132,7 @@ exports[`Canvas Catalog button should be present if \`CatalogModalContext\` is p
11321132
</g>
11331133
</g>
11341134
<g
1135-
data-id="route.from.steps.1.choice.otherwise.steps.1.to >>> route.from.steps.1.choice.otherwise.steps.2.log"
1135+
data-id="route-8888|route.from.steps.1.choice.otherwise.steps.1.to >>> route.from.steps.1.choice.otherwise.steps.2.log"
11361136
data-kind="edge"
11371137
data-type="edge"
11381138
style="z-index: 0;"
@@ -1201,7 +1201,7 @@ exports[`Canvas Catalog button should be present if \`CatalogModalContext\` is p
12011201
</g>
12021202
</g>
12031203
<g
1204-
data-id="route.from.steps.1.choice >>> route.from.steps.2.to"
1204+
data-id="route-8888|route.from.steps.1.choice >>> route.from.steps.2.to"
12051205
data-kind="edge"
12061206
data-type="edge"
12071207
style="z-index: 0;"
@@ -2521,7 +2521,7 @@ exports[`Canvas should render correctly 1`] = `
25212521
data-layer-id="default"
25222522
>
25232523
<g
2524-
data-id="route.from >>> route.from.steps.0.set-header"
2524+
data-id="route-8888|route.from >>> route.from.steps.0.set-header"
25252525
data-kind="edge"
25262526
data-type="edge"
25272527
style="z-index: 0;"
@@ -2590,7 +2590,7 @@ exports[`Canvas should render correctly 1`] = `
25902590
</g>
25912591
</g>
25922592
<g
2593-
data-id="route.from.steps.0.set-header >>> route.from.steps.1.choice"
2593+
data-id="route-8888|route.from.steps.0.set-header >>> route.from.steps.1.choice"
25942594
data-kind="edge"
25952595
data-type="edge"
25962596
style="z-index: 0;"
@@ -2659,7 +2659,7 @@ exports[`Canvas should render correctly 1`] = `
26592659
</g>
26602660
</g>
26612661
<g
2662-
data-id="route.from.steps.1.choice.otherwise.steps.0.to >>> route.from.steps.1.choice.otherwise.steps.1.to"
2662+
data-id="route-8888|route.from.steps.1.choice.otherwise.steps.0.to >>> route.from.steps.1.choice.otherwise.steps.1.to"
26632663
data-kind="edge"
26642664
data-type="edge"
26652665
style="z-index: 0;"
@@ -2728,7 +2728,7 @@ exports[`Canvas should render correctly 1`] = `
27282728
</g>
27292729
</g>
27302730
<g
2731-
data-id="route.from.steps.1.choice.otherwise.steps.1.to >>> route.from.steps.1.choice.otherwise.steps.2.log"
2731+
data-id="route-8888|route.from.steps.1.choice.otherwise.steps.1.to >>> route.from.steps.1.choice.otherwise.steps.2.log"
27322732
data-kind="edge"
27332733
data-type="edge"
27342734
style="z-index: 0;"
@@ -2797,7 +2797,7 @@ exports[`Canvas should render correctly 1`] = `
27972797
</g>
27982798
</g>
27992799
<g
2800-
data-id="route.from.steps.1.choice >>> route.from.steps.2.to"
2800+
data-id="route-8888|route.from.steps.1.choice >>> route.from.steps.2.to"
28012801
data-kind="edge"
28022802
data-type="edge"
28032803
style="z-index: 0;"
@@ -3305,7 +3305,7 @@ exports[`Canvas should render correctly with more routes 1`] = `
33053305
data-layer-id="default"
33063306
>
33073307
<g
3308-
data-id="route.from >>> route.from.steps.0.set-header"
3308+
data-id="route-8888|route.from >>> route.from.steps.0.set-header"
33093309
data-kind="edge"
33103310
data-type="edge"
33113311
style="z-index: 0;"
@@ -3374,7 +3374,7 @@ exports[`Canvas should render correctly with more routes 1`] = `
33743374
</g>
33753375
</g>
33763376
<g
3377-
data-id="route.from.steps.0.set-header >>> route.from.steps.1.choice"
3377+
data-id="route-8888|route.from.steps.0.set-header >>> route.from.steps.1.choice"
33783378
data-kind="edge"
33793379
data-type="edge"
33803380
style="z-index: 0;"
@@ -3443,7 +3443,7 @@ exports[`Canvas should render correctly with more routes 1`] = `
34433443
</g>
34443444
</g>
34453445
<g
3446-
data-id="route.from.steps.1.choice.otherwise.steps.0.to >>> route.from.steps.1.choice.otherwise.steps.1.to"
3446+
data-id="route-8888|route.from.steps.1.choice.otherwise.steps.0.to >>> route.from.steps.1.choice.otherwise.steps.1.to"
34473447
data-kind="edge"
34483448
data-type="edge"
34493449
style="z-index: 0;"
@@ -3512,7 +3512,7 @@ exports[`Canvas should render correctly with more routes 1`] = `
35123512
</g>
35133513
</g>
35143514
<g
3515-
data-id="route.from.steps.1.choice.otherwise.steps.1.to >>> route.from.steps.1.choice.otherwise.steps.2.log"
3515+
data-id="route-8888|route.from.steps.1.choice.otherwise.steps.1.to >>> route.from.steps.1.choice.otherwise.steps.2.log"
35163516
data-kind="edge"
35173517
data-type="edge"
35183518
style="z-index: 0;"
@@ -3581,7 +3581,7 @@ exports[`Canvas should render correctly with more routes 1`] = `
35813581
</g>
35823582
</g>
35833583
<g
3584-
data-id="route.from.steps.1.choice >>> route.from.steps.2.to"
3584+
data-id="route-8888|route.from.steps.1.choice >>> route.from.steps.2.to"
35853585
data-kind="edge"
35863586
data-type="edge"
35873587
style="z-index: 0;"

packages/ui/src/components/Visualization/Canvas/__snapshots__/flow.service.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ exports[`FlowService getFlowDiagram should return nodes and edges for a multiple
399399
[
400400
{
401401
"edgeStyle": "solid",
402-
"id": "node >>> set-header",
402+
"id": "test|node >>> set-header",
403403
"source": "test|node",
404404
"target": "test|set-header",
405405
"type": "edge",

packages/ui/src/components/Visualization/Canvas/flow.service.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,5 +102,23 @@ describe('FlowService', () => {
102102
expect(group.children).toEqual(['test|route.from', 'test|route.from.steps.0.placeholder']);
103103
expect(group.group).toBeTruthy();
104104
});
105+
106+
it('should scope nodes & edges IDs', () => {
107+
const routeNode = new CamelRouteVisualEntity({
108+
route: { id: 'route-8888', from: { uri: 'timer:clock', steps: [{ to: { uri: 'log' } }] } },
109+
}).toVizNode();
110+
111+
const { nodes, edges } = FlowService.getFlowDiagram('test', routeNode);
112+
113+
expect(nodes).toHaveLength(3);
114+
expect(nodes[0].id).toEqual('test|route.from');
115+
expect(nodes[1].id).toEqual('test|route.from.steps.0.to');
116+
expect(nodes[2].id).toEqual('test|route');
117+
118+
expect(edges).toHaveLength(1);
119+
expect(edges[0].id).toEqual('test|route.from >>> route.from.steps.0.to');
120+
expect(edges[0].source).toEqual('test|route.from');
121+
expect(edges[0].target).toEqual('test|route.from.steps.0.to');
122+
});
105123
});
106124
});

packages/ui/src/components/Visualization/Canvas/flow.service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export class FlowService {
2121
node.parentNode = node.parentNode ? `${scope}|${node.parentNode}` : undefined;
2222
});
2323
this.edges.forEach((edge) => {
24+
edge.id = `${scope}|${edge.id}`;
2425
edge.source = `${scope}|${edge.source}`;
2526
edge.target = `${scope}|${edge.target}`;
2627
});

packages/ui/src/tests/__snapshots__/nodes-edges.test.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4645,14 +4645,14 @@ exports[`Nodes and Edges should generate edges for steps with branches 2`] = `
46454645
[
46464646
{
46474647
"edgeStyle": "solid",
4648-
"id": "route.from >>> route.from.steps.0.choice",
4648+
"id": "test|route.from >>> route.from.steps.0.choice",
46494649
"source": "test|route.from",
46504650
"target": "test|route.from.steps.0.choice",
46514651
"type": "edge",
46524652
},
46534653
{
46544654
"edgeStyle": "solid",
4655-
"id": "route.from.steps.0.choice >>> route.from.steps.1.to",
4655+
"id": "test|route.from.steps.0.choice >>> route.from.steps.1.to",
46564656
"source": "test|route.from.steps.0.choice",
46574657
"target": "test|route.from.steps.1.to",
46584658
"type": "edge",

0 commit comments

Comments
 (0)