feat: allow multiple edges with different type

Signed-off-by: David Weber <david.weber@w3tec.ch>
This commit is contained in:
David Weber
2024-03-11 23:08:36 +01:00
committed by David Weber
parent a04ef79d4e
commit 39564b3265
4 changed files with 56 additions and 26 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-graph': patch
---
Allow multiple edges with different type (e.g. `ownedBy` and `applicationOwnerBy`) to have the same source and target node.
@@ -38,7 +38,7 @@ export function DefaultRenderLabel({
return (
<text className={classes.text} textAnchor="middle">
{relations.map((r, i) => (
<tspan key={r} className={classNames(i > 0 && classes.secondary)}>
<tspan key={r} className={classNames(i % 2 !== 0 && classes.secondary)}>
{i > 0 && <tspan> / </tspan>}
{r}
</tspan>
@@ -371,12 +371,6 @@ describe('useEntityRelationNodesAndEdges', () => {
relations: [RELATION_HAS_PART, RELATION_PART_OF],
to: 'b:d/c1',
},
{
from: 'b:d/c',
label: 'visible',
relations: [RELATION_HAS_PART, RELATION_PART_OF],
to: 'b:d/c1',
},
{
from: 'b:d/c1',
label: 'visible',
@@ -389,24 +383,6 @@ describe('useEntityRelationNodesAndEdges', () => {
relations: [RELATION_HAS_PART, RELATION_PART_OF],
to: 'b:d/c2',
},
{
from: 'b:d/c1',
label: 'visible',
relations: [RELATION_HAS_PART, RELATION_PART_OF],
to: 'b:d/c2',
},
{
from: 'b:d/c',
label: 'visible',
relations: [RELATION_OWNER_OF, RELATION_OWNED_BY],
to: 'k:d/a1',
},
{
from: 'b:d/c1',
label: 'visible',
relations: [RELATION_OWNER_OF, RELATION_OWNED_BY],
to: 'k:d/a1',
},
]);
});
@@ -146,11 +146,60 @@ export function useEntityRelationNodesAndEdges({
nodeQueue.push(rel.targetRef);
visitedNodes.add(rel.targetRef);
}
// if unidirectional add missing relations as entities are only visited once
if (unidirectional) {
const findIndex = edges.findIndex(
edge =>
entityRef === edge.from &&
rel.targetRef === edge.to &&
!edge.relations.includes(rel.type),
);
if (findIndex >= 0) {
if (mergeRelations) {
const pair = relationPairs.find(
([l, r]) => l === rel.type || r === rel.type,
) ?? [rel.type];
edges[findIndex].relations = [
...edges[findIndex].relations,
...pair,
];
} else {
edges[findIndex].relations = [
...edges[findIndex].relations,
rel.type,
];
}
}
}
});
}
}
setNodesAndEdges({ nodes, edges });
// Reduce edges as the dependency graph anyway ignores duplicated edges regarding from / to
// Additionally, this will improve rendering speed for the dependency graph
const finalEdges = edges.reduce((previousEdges, currentEdge) => {
const indexFound = previousEdges.findIndex(
previousEdge =>
previousEdge.from === currentEdge.from &&
previousEdge.to === currentEdge.to,
);
if (indexFound >= 0) {
previousEdges[indexFound] = {
...previousEdges[indexFound],
relations: Array.from(
new Set([
...previousEdges[indexFound].relations,
...currentEdge.relations,
]),
),
};
return previousEdges;
}
return [...previousEdges, currentEdge];
}, [] as EntityEdge[]);
setNodesAndEdges({ nodes, edges: finalEdges });
},
100,
[