feat: allow multiple edges with different type
Signed-off-by: David Weber <david.weber@w3tec.ch>
This commit is contained in:
@@ -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>
|
||||
|
||||
-24
@@ -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',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
+50
-1
@@ -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,
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user