@truedat/core 8.6.7 → 8.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/src/components/AddMemberForm.js +3 -3
- package/src/components/Alert.js +3 -3
- package/src/components/AlertExporter.js +4 -4
- package/src/components/AvailableFilters.js +5 -5
- package/src/components/CSVFileModal.js +1 -1
- package/src/components/CardGroupsAccordion.js +4 -4
- package/src/components/CatalogMenu.js +2 -2
- package/src/components/CommentsForm.js +1 -1
- package/src/components/DomainSearchFilter.js +9 -9
- package/src/components/DomainSelector.js +1 -1
- package/src/components/FilterDropdown.js +5 -5
- package/src/components/FilterMultilevelDropdown.js +9 -9
- package/src/components/GlossaryMenu.js +10 -7
- package/src/components/Graph.js +199 -127
- package/src/components/GroupActions.js +2 -2
- package/src/components/Hierarchy.js +1 -1
- package/src/components/HierarchyFilterDropdown.js +7 -7
- package/src/components/HierarchySelector.js +1 -1
- package/src/components/LanguagesTabs.js +2 -2
- package/src/components/OptionGroup.js +8 -9
- package/src/components/QualityMenu.js +6 -8
- package/src/components/ResourceMembers.js +3 -3
- package/src/components/SearchFilterDropdown.js +3 -3
- package/src/components/SidebarToggle.js +1 -1
- package/src/components/Submenu.js +46 -27
- package/src/components/SystemsLoader.js +1 -1
- package/src/components/TemplatesLoader.js +1 -1
- package/src/components/TreeSelector.js +2 -2
- package/src/components/UploadJob.js +3 -3
- package/src/components/UploadJobBreadcrumbs.js +4 -1
- package/src/components/UploadJobParser.js +4 -3
- package/src/components/UploadModal.js +1 -1
- package/src/components/UserFilter.js +1 -1
- package/src/components/UserFilters.js +2 -2
- package/src/components/__tests__/ArrayDecorator.spec.js +2 -2
- package/src/components/__tests__/CardGroupsAccordion.spec.js +6 -6
- package/src/components/__tests__/CatalogMenu.spec.js +1 -1
- package/src/components/__tests__/DateTime.spec.js +1 -1
- package/src/components/__tests__/DomainSearchFilter.spec.js +2 -2
- package/src/components/__tests__/DomainSearchFilterItem.spec.js +7 -7
- package/src/components/__tests__/DomainSelector.spec.js +3 -3
- package/src/components/__tests__/DropdownMenuItem.spec.js +3 -3
- package/src/components/__tests__/FilterDropdown.spec.js +11 -11
- package/src/components/__tests__/FilterMultilevelDropdown.spec.js +2 -2
- package/src/components/__tests__/GlossaryMenu.spec.js +2 -2
- package/src/components/__tests__/Graph.spec.js +12 -4
- package/src/components/__tests__/GroupActions.spec.js +4 -4
- package/src/components/__tests__/Hierarchy.spec.js +1 -1
- package/src/components/__tests__/HierarchyFilterDropdown.spec.js +5 -5
- package/src/components/__tests__/HierarchyNodeFinder.spec.js +4 -4
- package/src/components/__tests__/HierarchySelector.spec.js +7 -5
- package/src/components/__tests__/Markdown.spec.js +22 -8
- package/src/components/__tests__/ModalSaveFilter.spec.js +1 -1
- package/src/components/__tests__/Pagination.spec.js +2 -2
- package/src/components/__tests__/ResourceMembers.spec.js +4 -4
- package/src/components/__tests__/SearchDateFilter.spec.js +10 -5
- package/src/components/__tests__/SearchFilterDropdown.spec.js +1 -1
- package/src/components/__tests__/SelectedFilters.spec.js +7 -7
- package/src/components/__tests__/SideMenu.spec.js +1 -1
- package/src/components/__tests__/Submenu.spec.js +1 -1
- package/src/components/__tests__/TemplateSelector.spec.js +5 -5
- package/src/components/__tests__/TreeSelector.spec.js +23 -24
- package/src/components/__tests__/UploadJob.spec.js +1 -3
- package/src/components/__tests__/UploadJobBreadcrumbs.spec.js +4 -4
- package/src/components/__tests__/UploadJobParser.spec.js +42 -38
- package/src/components/__tests__/UploadModal.spec.js +9 -9
- package/src/components/__tests__/UserFilters.spec.js +1 -1
- package/src/components/graph/ColoredEdge.js +29 -23
- package/src/components/graph/edgeLayout.js +4 -1
- package/src/hooks/__tests__/useActiveRoutes.spec.js +32 -18
- package/src/hooks/useAclEntries.js +2 -2
- package/src/hooks/useActiveRoutes.js +14 -6
- package/src/hooks/useAuthorized.js +3 -3
- package/src/hooks/useHierarchies.js +8 -8
- package/src/hooks/useLocales.js +3 -3
- package/src/hooks/useMessages.js +1 -1
- package/src/hooks/useOnScreen.js +1 -1
- package/src/hooks/useUploadJobs.js +2 -8
- package/src/hooks/useUserFilters.js +1 -1
- package/src/i18n/components/LangProvider.js +6 -6
- package/src/i18n/components/Languages.js +4 -4
- package/src/i18n/components/MessageForm.js +24 -13
- package/src/i18n/components/Messages.js +5 -5
- package/src/i18n/components/__tests__/I18nRoutes.spec.js +1 -1
- package/src/messages/index.js +1 -1
- package/src/reducers/comments.js +3 -3
- package/src/router/__tests__/ProtectedRoute.spec.js +1 -1
- package/src/routes.js +1 -1
- package/src/routesTree.js +6 -1
- package/src/routines.js +2 -2
- package/src/search/FilterDropdown.js +1 -1
- package/src/search/FilterMultilevelDropdown.js +10 -10
- package/src/search/FilterQueryDropdown.js +4 -4
- package/src/search/HierarchyFilterDropdown.js +7 -7
- package/src/search/SearchContext.js +19 -19
- package/src/search/SearchDateFilter.js +12 -2
- package/src/search/SearchFilters.js +1 -1
- package/src/search/SearchSelectedFilters.js +1 -1
- package/src/search/SearchWidget.js +6 -2
- package/src/search/UserFilter.js +1 -1
- package/src/search/UserFilters.js +4 -4
- package/src/search/__tests__/FilterDropdown.spec.js +3 -3
- package/src/search/__tests__/FilterQueryDropdown.spec.js +20 -18
- package/src/search/__tests__/ModalSaveFilter.spec.js +2 -2
- package/src/search/__tests__/SearchContext.spec.js +42 -42
- package/src/search/__tests__/SearchSelectedFilters.spec.js +21 -17
- package/src/search/__tests__/SearchWidget.spec.js +4 -4
- package/src/selectors/__tests__/getRiSubscopes.spec.js +1 -1
- package/src/selectors/__tests__/makeSearchQuerySelector.spec.js +2 -2
- package/src/selectors/getConceptSubscope.js +1 -1
- package/src/selectors/getDashboardConfig.js +3 -3
- package/src/selectors/getMessage.js +3 -3
- package/src/selectors/getRecipients.js +3 -3
- package/src/selectors/getRiSubscopes.js +2 -2
- package/src/selectors/getSidemenuGlossarySubscopes.js +1 -1
- package/src/selectors/makeActiveFiltersSelector.js +2 -2
- package/src/selectors/makeDateFiltersSelector.js +1 -1
- package/src/selectors/makeSearchQuerySelector.js +10 -10
- package/src/selectors/makeTagOptionsSelector.js +1 -4
- package/src/selectors/subscopedTemplates.js +2 -2
- package/src/services/columnPredicate.js +1 -1
- package/src/services/dateFilterFormatter.js +1 -1
- package/src/services/fieldType.js +1 -1
- package/src/services/formRules.js +16 -13
- package/src/services/getHierarchyOptions.js +2 -2
- package/src/services/message.js +7 -8
- package/src/services/operators.js +5 -5
- package/src/services/sort.js +2 -2
- package/src/services/swr.js +1 -1
- package/src/services/tree.js +2 -2
package/src/components/Graph.js
CHANGED
|
@@ -96,18 +96,22 @@ const buildSignedNodeLevels = (nodes = [], edges = [], rootNodeId) => {
|
|
|
96
96
|
const getNodeOrderingMeta = (node, levels, edges) => {
|
|
97
97
|
const rank = levels.get(node.id) || 0;
|
|
98
98
|
const connectedEdges = edges.filter(
|
|
99
|
-
(edge) => edge.source === node.id || edge.target === node.id
|
|
99
|
+
(edge) => edge.source === node.id || edge.target === node.id,
|
|
100
100
|
);
|
|
101
101
|
|
|
102
102
|
const preferredEdges = connectedEdges.filter((edge) => {
|
|
103
103
|
if (rank < 0 && edge.source === node.id) {
|
|
104
104
|
const neighbourRank = levels.get(edge.target);
|
|
105
|
-
return
|
|
105
|
+
return (
|
|
106
|
+
neighbourRank !== undefined && Math.abs(neighbourRank) < Math.abs(rank)
|
|
107
|
+
);
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
if (rank > 0 && edge.target === node.id) {
|
|
109
111
|
const neighbourRank = levels.get(edge.source);
|
|
110
|
-
return
|
|
112
|
+
return (
|
|
113
|
+
neighbourRank !== undefined && Math.abs(neighbourRank) < Math.abs(rank)
|
|
114
|
+
);
|
|
111
115
|
}
|
|
112
116
|
|
|
113
117
|
return false;
|
|
@@ -147,7 +151,8 @@ const orderNodesByRelationGroup = (nodes = [], edges = [], rootNodeId) => {
|
|
|
147
151
|
if (metaA.relationGroup !== metaB.relationGroup) {
|
|
148
152
|
return metaA.relationGroup.localeCompare(metaB.relationGroup);
|
|
149
153
|
}
|
|
150
|
-
if (metaA.label !== metaB.label)
|
|
154
|
+
if (metaA.label !== metaB.label)
|
|
155
|
+
return metaA.label.localeCompare(metaB.label);
|
|
151
156
|
|
|
152
157
|
return nodeA.id.localeCompare(nodeB.id);
|
|
153
158
|
});
|
|
@@ -156,7 +161,8 @@ const orderNodesByRelationGroup = (nodes = [], edges = [], rootNodeId) => {
|
|
|
156
161
|
const getNodeHeight = (node) =>
|
|
157
162
|
node.height ?? node.measured?.height ?? DEFAULT_NODE_HEIGHT;
|
|
158
163
|
|
|
159
|
-
const getNodeCenterY = (node) =>
|
|
164
|
+
const getNodeCenterY = (node) =>
|
|
165
|
+
(node.y ?? node.position?.y ?? 0) + getNodeHeight(node) / 2;
|
|
160
166
|
|
|
161
167
|
const alignNodesToConnectionPoints = (nodes = [], edges = [], rootNodeId) => {
|
|
162
168
|
if (!rootNodeId) return nodes;
|
|
@@ -176,12 +182,18 @@ const alignNodesToConnectionPoints = (nodes = [], edges = [], rootNodeId) => {
|
|
|
176
182
|
const preferredEdges = edges.filter((edge) => {
|
|
177
183
|
if (rank < 0 && edge.source === node.id) {
|
|
178
184
|
const neighbourRank = levels.get(edge.target);
|
|
179
|
-
return
|
|
185
|
+
return (
|
|
186
|
+
neighbourRank !== undefined &&
|
|
187
|
+
Math.abs(neighbourRank) < Math.abs(rank)
|
|
188
|
+
);
|
|
180
189
|
}
|
|
181
190
|
|
|
182
191
|
if (rank > 0 && edge.target === node.id) {
|
|
183
192
|
const neighbourRank = levels.get(edge.source);
|
|
184
|
-
return
|
|
193
|
+
return (
|
|
194
|
+
neighbourRank !== undefined &&
|
|
195
|
+
Math.abs(neighbourRank) < Math.abs(rank)
|
|
196
|
+
);
|
|
185
197
|
}
|
|
186
198
|
|
|
187
199
|
return false;
|
|
@@ -192,7 +204,7 @@ const alignNodesToConnectionPoints = (nodes = [], edges = [], rootNodeId) => {
|
|
|
192
204
|
const edge = preferredEdges[0];
|
|
193
205
|
const slotOffset = getTargetSlotOffset(
|
|
194
206
|
edge.data?.targetSlotIndex,
|
|
195
|
-
edge.data?.targetSlotCount
|
|
207
|
+
edge.data?.targetSlotCount,
|
|
196
208
|
);
|
|
197
209
|
|
|
198
210
|
if (rank < 0) {
|
|
@@ -225,22 +237,33 @@ const alignNodesToConnectionPoints = (nodes = [], edges = [], rootNodeId) => {
|
|
|
225
237
|
|
|
226
238
|
nodesByRank.forEach((rankNodes) => {
|
|
227
239
|
const orderedNodes = [...rankNodes].sort((nodeA, nodeB) => {
|
|
228
|
-
const desiredA =
|
|
229
|
-
|
|
240
|
+
const desiredA =
|
|
241
|
+
desiredCentersById.get(nodeA.id) ?? getNodeCenterY(nodeA);
|
|
242
|
+
const desiredB =
|
|
243
|
+
desiredCentersById.get(nodeB.id) ?? getNodeCenterY(nodeB);
|
|
230
244
|
|
|
231
245
|
if (desiredA !== desiredB) return desiredA - desiredB;
|
|
232
246
|
|
|
233
|
-
return (
|
|
247
|
+
return (
|
|
248
|
+
(nodeA.y ?? nodeA.position?.y ?? 0) -
|
|
249
|
+
(nodeB.y ?? nodeB.position?.y ?? 0)
|
|
250
|
+
);
|
|
234
251
|
});
|
|
235
252
|
|
|
253
|
+
// eslint-disable-next-line fp/no-let
|
|
236
254
|
let previousBottom = Number.NEGATIVE_INFINITY;
|
|
237
255
|
|
|
238
256
|
orderedNodes.forEach((node) => {
|
|
239
257
|
const height = getNodeHeight(node);
|
|
240
|
-
const desiredCenter =
|
|
258
|
+
const desiredCenter =
|
|
259
|
+
desiredCentersById.get(node.id) ?? getNodeCenterY(node);
|
|
241
260
|
const desiredTop = desiredCenter - height / 2;
|
|
242
|
-
const nextTop = Math.max(
|
|
261
|
+
const nextTop = Math.max(
|
|
262
|
+
desiredTop,
|
|
263
|
+
previousBottom + MIN_NODE_VERTICAL_GAP,
|
|
264
|
+
);
|
|
243
265
|
|
|
266
|
+
// eslint-disable-next-line fp/no-mutation
|
|
244
267
|
previousBottom = nextTop + height;
|
|
245
268
|
alignedNodes.set(node.id, {
|
|
246
269
|
...node,
|
|
@@ -257,9 +280,10 @@ export const getMinZoomForDiagram = (
|
|
|
257
280
|
nodes = [],
|
|
258
281
|
viewportWidth,
|
|
259
282
|
viewportHeight,
|
|
260
|
-
padding = FIT_VIEW_PADDING
|
|
283
|
+
padding = FIT_VIEW_PADDING,
|
|
261
284
|
) => {
|
|
262
|
-
if (!nodes.length || !viewportWidth || !viewportHeight)
|
|
285
|
+
if (!nodes.length || !viewportWidth || !viewportHeight)
|
|
286
|
+
return DEFAULT_MIN_ZOOM;
|
|
263
287
|
|
|
264
288
|
const bounds = getNodesBounds(nodes);
|
|
265
289
|
|
|
@@ -272,9 +296,9 @@ export const getMinZoomForDiagram = (
|
|
|
272
296
|
viewportHeight,
|
|
273
297
|
DEFAULT_MIN_ZOOM,
|
|
274
298
|
DEFAULT_MAX_ZOOM,
|
|
275
|
-
padding
|
|
299
|
+
padding,
|
|
276
300
|
).zoom,
|
|
277
|
-
DEFAULT_MIN_ZOOM
|
|
301
|
+
DEFAULT_MIN_ZOOM,
|
|
278
302
|
);
|
|
279
303
|
};
|
|
280
304
|
|
|
@@ -299,7 +323,8 @@ const getTranslateExtent = (nodes = []) => {
|
|
|
299
323
|
const bounds = nodes.reduce(
|
|
300
324
|
(acc, node) => {
|
|
301
325
|
const width = node.measured?.width ?? node.width ?? DEFAULT_NODE_WIDTH;
|
|
302
|
-
const height =
|
|
326
|
+
const height =
|
|
327
|
+
node.measured?.height ?? node.height ?? DEFAULT_NODE_HEIGHT;
|
|
303
328
|
const x = node.position?.x ?? node.x ?? 0;
|
|
304
329
|
const y = node.position?.y ?? node.y ?? 0;
|
|
305
330
|
|
|
@@ -315,7 +340,7 @@ const getTranslateExtent = (nodes = []) => {
|
|
|
315
340
|
minY: Number.POSITIVE_INFINITY,
|
|
316
341
|
maxX: Number.NEGATIVE_INFINITY,
|
|
317
342
|
maxY: Number.NEGATIVE_INFINITY,
|
|
318
|
-
}
|
|
343
|
+
},
|
|
319
344
|
);
|
|
320
345
|
|
|
321
346
|
return [
|
|
@@ -353,74 +378,71 @@ const LayoutFlow = ({
|
|
|
353
378
|
sourcePosition: Position.Right,
|
|
354
379
|
targetPosition: Position.Left,
|
|
355
380
|
})),
|
|
356
|
-
[initialNodes]
|
|
381
|
+
[initialNodes],
|
|
357
382
|
);
|
|
358
|
-
const parsedEdges = useMemo(
|
|
359
|
-
() => {
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
style
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
};
|
|
375
|
-
});
|
|
383
|
+
const parsedEdges = useMemo(() => {
|
|
384
|
+
const edgesWithStroke = initialEdges.map((edge) => {
|
|
385
|
+
const stroke = edge.style?.stroke || DEFAULT_EDGE_STROKE;
|
|
386
|
+
return {
|
|
387
|
+
...edge,
|
|
388
|
+
style: {
|
|
389
|
+
strokeWidth: 1.5,
|
|
390
|
+
...edge.style,
|
|
391
|
+
stroke,
|
|
392
|
+
},
|
|
393
|
+
data: {
|
|
394
|
+
...edge.data,
|
|
395
|
+
edgeStroke: stroke,
|
|
396
|
+
},
|
|
397
|
+
};
|
|
398
|
+
});
|
|
376
399
|
|
|
377
|
-
|
|
400
|
+
const groupsByTarget = new Map();
|
|
378
401
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
402
|
+
edgesWithStroke.forEach((edge) => {
|
|
403
|
+
const stroke = edge.style?.stroke || DEFAULT_EDGE_STROKE;
|
|
404
|
+
const groupKey = getIncomingEdgeGroupKey(edge, stroke);
|
|
405
|
+
const targetGroups = groupsByTarget.get(edge.target) || new Map();
|
|
406
|
+
const group = targetGroups.get(groupKey) || [];
|
|
384
407
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
408
|
+
group.push(edge.id);
|
|
409
|
+
targetGroups.set(groupKey, group);
|
|
410
|
+
groupsByTarget.set(edge.target, targetGroups);
|
|
411
|
+
});
|
|
389
412
|
|
|
390
|
-
|
|
413
|
+
const groupMetaByEdgeId = new Map();
|
|
391
414
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
415
|
+
groupsByTarget.forEach((targetGroups) => {
|
|
416
|
+
const orderedGroups = Array.from(targetGroups.entries()).sort(
|
|
417
|
+
([groupKeyA], [groupKeyB]) => groupKeyA.localeCompare(groupKeyB),
|
|
418
|
+
);
|
|
395
419
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
});
|
|
420
|
+
orderedGroups.forEach(([groupKey, edgeIds], groupIndex) => {
|
|
421
|
+
edgeIds.forEach((edgeId, edgeIndex) => {
|
|
422
|
+
groupMetaByEdgeId.set(edgeId, {
|
|
423
|
+
targetSlotCount: orderedGroups.length,
|
|
424
|
+
targetSlotIndex: groupIndex,
|
|
425
|
+
showTargetArrow: edgeIndex === edgeIds.length - 1,
|
|
426
|
+
incomingGroupKey: groupKey,
|
|
404
427
|
});
|
|
405
428
|
});
|
|
406
429
|
});
|
|
430
|
+
});
|
|
407
431
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
[initialEdges]
|
|
423
|
-
);
|
|
432
|
+
return edgesWithStroke.map((edge) => ({
|
|
433
|
+
...edge,
|
|
434
|
+
markerEnd: edge.markerEnd || {
|
|
435
|
+
type: MarkerType.ArrowClosed,
|
|
436
|
+
width: 12,
|
|
437
|
+
height: 12,
|
|
438
|
+
color: edge.style?.stroke || DEFAULT_EDGE_STROKE,
|
|
439
|
+
},
|
|
440
|
+
data: {
|
|
441
|
+
...edge.data,
|
|
442
|
+
...groupMetaByEdgeId.get(edge.id),
|
|
443
|
+
},
|
|
444
|
+
}));
|
|
445
|
+
}, [initialEdges]);
|
|
424
446
|
const [nodes, setNodes, onNodesChange] = useNodesState(parsedNodes);
|
|
425
447
|
const [edges, setEdges, onEdgesChange] = useEdgesState(parsedEdges);
|
|
426
448
|
const translateExtent = useMemo(() => getTranslateExtent(nodes), [nodes]);
|
|
@@ -428,7 +450,7 @@ const LayoutFlow = ({
|
|
|
428
450
|
const safeNodes = orderNodesByRelationGroup(
|
|
429
451
|
parsedNodes.filter((node) => node && node.id),
|
|
430
452
|
parsedEdges,
|
|
431
|
-
rootNodeId
|
|
453
|
+
rootNodeId,
|
|
432
454
|
);
|
|
433
455
|
const safeNodeIds = new Set(safeNodes.map((node) => node.id));
|
|
434
456
|
const safeEdges = parsedEdges.filter(
|
|
@@ -438,7 +460,7 @@ const LayoutFlow = ({
|
|
|
438
460
|
edge.source &&
|
|
439
461
|
edge.target &&
|
|
440
462
|
safeNodeIds.has(edge.source) &&
|
|
441
|
-
safeNodeIds.has(edge.target)
|
|
463
|
+
safeNodeIds.has(edge.target),
|
|
442
464
|
);
|
|
443
465
|
|
|
444
466
|
return { nodes: safeNodes, edges: safeEdges };
|
|
@@ -462,7 +484,7 @@ const LayoutFlow = ({
|
|
|
462
484
|
const nextMinZoom = getMinZoomForDiagram(
|
|
463
485
|
measuredNodes.length ? measuredNodes : nodesForFit,
|
|
464
486
|
containerRef.current?.clientWidth,
|
|
465
|
-
containerRef.current?.clientHeight
|
|
487
|
+
containerRef.current?.clientHeight,
|
|
466
488
|
);
|
|
467
489
|
|
|
468
490
|
setMinZoom(nextMinZoom);
|
|
@@ -501,29 +523,33 @@ const LayoutFlow = ({
|
|
|
501
523
|
edges: edgesToLayout,
|
|
502
524
|
};
|
|
503
525
|
|
|
504
|
-
elk
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
526
|
+
elk
|
|
527
|
+
.layout(graph)
|
|
528
|
+
.then(({ children = [] }) => {
|
|
529
|
+
if (currentLayoutRunId !== layoutRunId.current) return;
|
|
530
|
+
children.forEach((node) => {
|
|
531
|
+
// eslint-disable-next-line fp/no-mutation
|
|
532
|
+
node.position = { x: node.x, y: node.y };
|
|
533
|
+
});
|
|
509
534
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
535
|
+
const alignedChildren = alignNodesToConnectionPoints(
|
|
536
|
+
children,
|
|
537
|
+
edgesToLayout,
|
|
538
|
+
rootNodeId,
|
|
539
|
+
);
|
|
515
540
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
541
|
+
setNodes(alignedChildren);
|
|
542
|
+
scheduleFitView(alignedChildren, edgesToLayout);
|
|
543
|
+
})
|
|
544
|
+
.catch(() => {
|
|
545
|
+
if (currentLayoutRunId !== layoutRunId.current) return;
|
|
520
546
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
547
|
+
setNodes(nodesToLayout);
|
|
548
|
+
setEdges(edgesToLayout);
|
|
549
|
+
scheduleFitView(nodesToLayout, edgesToLayout);
|
|
550
|
+
});
|
|
525
551
|
},
|
|
526
|
-
[containerRef, fitView, getNodes, rootNodeId, setEdges, setNodes]
|
|
552
|
+
[containerRef, fitView, getNodes, rootNodeId, setEdges, setNodes],
|
|
527
553
|
);
|
|
528
554
|
|
|
529
555
|
const onInit = useCallback(() => {
|
|
@@ -543,20 +569,17 @@ const LayoutFlow = ({
|
|
|
543
569
|
});
|
|
544
570
|
|
|
545
571
|
return () => cancelAnimationFrame(animationFrameId);
|
|
546
|
-
}, [
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
}
|
|
558
|
-
layoutRunId.current += 1;
|
|
559
|
-
}, []);
|
|
572
|
+
}, [isInitialized, layoutInput, setNodes, setEdges, getLayoutedElements]);
|
|
573
|
+
|
|
574
|
+
useEffect(
|
|
575
|
+
() => () => {
|
|
576
|
+
if (fitViewFrameId.current) {
|
|
577
|
+
cancelAnimationFrame(fitViewFrameId.current);
|
|
578
|
+
}
|
|
579
|
+
layoutRunId.current += 1;
|
|
580
|
+
},
|
|
581
|
+
[],
|
|
582
|
+
);
|
|
560
583
|
|
|
561
584
|
return (
|
|
562
585
|
<ReactFlow
|
|
@@ -586,40 +609,83 @@ const LayoutFlow = ({
|
|
|
586
609
|
showFitView={false}
|
|
587
610
|
showInteractive={false}
|
|
588
611
|
>
|
|
589
|
-
<GraphControlTooltip
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
612
|
+
<GraphControlTooltip
|
|
613
|
+
content={formatMessage({ id: "graph.controls.zoom_in" })}
|
|
614
|
+
>
|
|
615
|
+
<ControlButton
|
|
616
|
+
onClick={() => zoomIn({ duration: 200 })}
|
|
617
|
+
aria-label={formatMessage({ id: "graph.controls.zoom_in" })}
|
|
618
|
+
>
|
|
619
|
+
<svg
|
|
620
|
+
viewBox="0 0 24 24"
|
|
621
|
+
fill="none"
|
|
622
|
+
stroke="currentColor"
|
|
623
|
+
strokeWidth="2"
|
|
624
|
+
strokeLinecap="round"
|
|
625
|
+
>
|
|
626
|
+
<line x1="12" y1="5" x2="12" y2="19" />
|
|
627
|
+
<line x1="5" y1="12" x2="19" y2="12" />
|
|
593
628
|
</svg>
|
|
594
629
|
</ControlButton>
|
|
595
630
|
</GraphControlTooltip>
|
|
596
|
-
<GraphControlTooltip
|
|
597
|
-
|
|
598
|
-
|
|
631
|
+
<GraphControlTooltip
|
|
632
|
+
content={formatMessage({ id: "graph.controls.zoom_out" })}
|
|
633
|
+
>
|
|
634
|
+
<ControlButton
|
|
635
|
+
onClick={() => zoomOut({ duration: 200 })}
|
|
636
|
+
aria-label={formatMessage({ id: "graph.controls.zoom_out" })}
|
|
637
|
+
>
|
|
638
|
+
<svg
|
|
639
|
+
viewBox="0 0 24 24"
|
|
640
|
+
fill="none"
|
|
641
|
+
stroke="currentColor"
|
|
642
|
+
strokeWidth="2"
|
|
643
|
+
strokeLinecap="round"
|
|
644
|
+
>
|
|
599
645
|
<line x1="5" y1="12" x2="19" y2="12" />
|
|
600
646
|
</svg>
|
|
601
647
|
</ControlButton>
|
|
602
648
|
</GraphControlTooltip>
|
|
603
|
-
<GraphControlTooltip
|
|
649
|
+
<GraphControlTooltip
|
|
650
|
+
content={formatMessage({ id: "graph.controls.fit_view" })}
|
|
651
|
+
>
|
|
604
652
|
<ControlButton
|
|
605
653
|
onClick={() =>
|
|
606
654
|
fitView({ padding: FIT_VIEW_PADDING, duration: 300, minZoom })
|
|
607
655
|
}
|
|
608
656
|
aria-label={formatMessage({ id: "graph.controls.fit_view" })}
|
|
609
657
|
>
|
|
610
|
-
<svg
|
|
611
|
-
|
|
612
|
-
|
|
658
|
+
<svg
|
|
659
|
+
viewBox="0 0 24 24"
|
|
660
|
+
fill="none"
|
|
661
|
+
stroke="currentColor"
|
|
662
|
+
strokeWidth="2"
|
|
663
|
+
strokeLinecap="round"
|
|
664
|
+
strokeLinejoin="round"
|
|
665
|
+
>
|
|
666
|
+
<path d="M8 3H5a2 2 0 0 0-2 2v3" />
|
|
667
|
+
<path d="M21 8V5a2 2 0 0 0-2-2h-3" />
|
|
668
|
+
<path d="M3 16v3a2 2 0 0 0 2 2h3" />
|
|
669
|
+
<path d="M16 21h3a2 2 0 0 0 2-2v-3" />
|
|
613
670
|
</svg>
|
|
614
671
|
</ControlButton>
|
|
615
672
|
</GraphControlTooltip>
|
|
616
673
|
{onOpenExpanded ? (
|
|
617
|
-
<GraphControlTooltip
|
|
674
|
+
<GraphControlTooltip
|
|
675
|
+
content={formatMessage({ id: "graph.controls.open_expanded" })}
|
|
676
|
+
>
|
|
618
677
|
<ControlButton
|
|
619
678
|
onClick={onOpenExpanded}
|
|
620
679
|
aria-label={formatMessage({ id: "graph.controls.open_expanded" })}
|
|
621
680
|
>
|
|
622
|
-
<svg
|
|
681
|
+
<svg
|
|
682
|
+
viewBox="0 0 24 24"
|
|
683
|
+
fill="none"
|
|
684
|
+
stroke="currentColor"
|
|
685
|
+
strokeWidth="2"
|
|
686
|
+
strokeLinecap="round"
|
|
687
|
+
strokeLinejoin="round"
|
|
688
|
+
>
|
|
623
689
|
<path d="M15 3h6v6" />
|
|
624
690
|
<path d="M9 21H3v-6" />
|
|
625
691
|
<path d="M21 3l-7 7" />
|
|
@@ -653,7 +719,11 @@ const GraphCanvas = ({
|
|
|
653
719
|
const containerRef = useRef(null);
|
|
654
720
|
|
|
655
721
|
return (
|
|
656
|
-
<div
|
|
722
|
+
<div
|
|
723
|
+
className="td-graph-container"
|
|
724
|
+
style={{ "--td-graph-container-height": height }}
|
|
725
|
+
ref={containerRef}
|
|
726
|
+
>
|
|
657
727
|
<ReactFlowProvider>
|
|
658
728
|
<LayoutFlow
|
|
659
729
|
initialNodes={nodes}
|
|
@@ -710,7 +780,9 @@ export const Graph = ({
|
|
|
710
780
|
closeOnEscape
|
|
711
781
|
className="td-graph-modal"
|
|
712
782
|
>
|
|
713
|
-
<Modal.Header>
|
|
783
|
+
<Modal.Header>
|
|
784
|
+
{formatMessage({ id: "graph.expanded.header" })}
|
|
785
|
+
</Modal.Header>
|
|
714
786
|
<Modal.Content>
|
|
715
787
|
<GraphCanvas
|
|
716
788
|
nodes={nodes}
|
|
@@ -170,7 +170,7 @@ const ListHierarchy = ({
|
|
|
170
170
|
const { formatMessage } = useIntl();
|
|
171
171
|
const [newNodeName, setNewNodeName] = useState();
|
|
172
172
|
const generation = hierarchy.nodes.filter(
|
|
173
|
-
(node) => node.parentId == parentId
|
|
173
|
+
(node) => node.parentId == parentId,
|
|
174
174
|
);
|
|
175
175
|
const addNodeTo = (id = null) => (
|
|
176
176
|
<Form
|
|
@@ -22,7 +22,7 @@ const PopulatedHierarchyFilterDropdown = (props) => {
|
|
|
22
22
|
_.first,
|
|
23
23
|
_.prop("value"),
|
|
24
24
|
(value) => value.split("_"),
|
|
25
|
-
_.first
|
|
25
|
+
_.first,
|
|
26
26
|
)(options);
|
|
27
27
|
|
|
28
28
|
const { data, error, loading: hierarchyLoading } = useHierarchy(hierarchyId);
|
|
@@ -34,29 +34,29 @@ const PopulatedHierarchyFilterDropdown = (props) => {
|
|
|
34
34
|
const includedKeys = _.flow(
|
|
35
35
|
_.map("value"),
|
|
36
36
|
_.flatMap(getKeyAndParents(hierarchyOptions)),
|
|
37
|
-
_.uniq
|
|
37
|
+
_.uniq,
|
|
38
38
|
)(options);
|
|
39
39
|
|
|
40
40
|
const filterIncludedKeys = _.filter(({ key }) =>
|
|
41
|
-
_.includes(key)(includedKeys)
|
|
41
|
+
_.includes(key)(includedKeys),
|
|
42
42
|
);
|
|
43
43
|
|
|
44
44
|
const filteredChildren = _.flow(_.prop("children"), filterIncludedKeys);
|
|
45
45
|
|
|
46
46
|
const filteredOptions = _.flow(
|
|
47
47
|
filterIncludedKeys,
|
|
48
|
-
_.map((node) => ({ ...node, children: filteredChildren(node) }))
|
|
48
|
+
_.map((node) => ({ ...node, children: filteredChildren(node) })),
|
|
49
49
|
)(hierarchyOptions);
|
|
50
50
|
|
|
51
51
|
const idActiveValues = _.map((key) =>
|
|
52
|
-
_.flow(_.find({ key }), _.prop("id"))(filteredOptions)
|
|
52
|
+
_.flow(_.find({ key }), _.prop("id"))(filteredOptions),
|
|
53
53
|
)(activeValues);
|
|
54
54
|
|
|
55
55
|
const handleToggleFilterValue = ({ filter, value }) => {
|
|
56
56
|
const getChildrenKeys = (id) => {
|
|
57
57
|
const { key, descendents } = _.flow(
|
|
58
58
|
_.find({ id }),
|
|
59
|
-
_.pick(["key", "descendents"])
|
|
59
|
+
_.pick(["key", "descendents"]),
|
|
60
60
|
)(filteredOptions);
|
|
61
61
|
const descendentKeys = _.map("key")(descendents);
|
|
62
62
|
return [key, ...descendentKeys];
|
|
@@ -64,7 +64,7 @@ const PopulatedHierarchyFilterDropdown = (props) => {
|
|
|
64
64
|
const newValue = _.flow(
|
|
65
65
|
_.flatMap(getChildrenKeys),
|
|
66
66
|
_.uniq,
|
|
67
|
-
_.reject(_.isNil)
|
|
67
|
+
_.reject(_.isNil),
|
|
68
68
|
)(value);
|
|
69
69
|
toggleFilterValue({ filter, value: newValue });
|
|
70
70
|
};
|
|
@@ -31,22 +31,21 @@ export const OptionGroup = ({
|
|
|
31
31
|
setOptions(
|
|
32
32
|
_.flow(
|
|
33
33
|
_.filter(
|
|
34
|
-
(o) => flatOptionMatches(o, searchQuery) || _.has("options")(o)
|
|
34
|
+
(o) => flatOptionMatches(o, searchQuery) || _.has("options")(o),
|
|
35
35
|
),
|
|
36
36
|
_.map((o) =>
|
|
37
|
-
_.has("options")(o) ? filterNestedOptions(o, searchQuery) : o
|
|
37
|
+
_.has("options")(o) ? filterNestedOptions(o, searchQuery) : o,
|
|
38
38
|
),
|
|
39
39
|
_.filter(
|
|
40
40
|
(o) =>
|
|
41
41
|
(_.has("options")(o) && !_.isEmpty(_.prop("options")(o))) ||
|
|
42
|
-
!_.has("options")(o)
|
|
43
|
-
)
|
|
44
|
-
)(options)
|
|
42
|
+
!_.has("options")(o),
|
|
43
|
+
),
|
|
44
|
+
)(options),
|
|
45
45
|
);
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
useEffect(() => {
|
|
49
|
-
// eslint-disable-next-line prettier/prettier
|
|
50
49
|
_.flow(toFlattenedShorthands, setFlattenedOptions)(availableOptions);
|
|
51
50
|
}, [availableOptions]);
|
|
52
51
|
|
|
@@ -56,7 +55,7 @@ export const OptionGroup = ({
|
|
|
56
55
|
const filterNestedOptions = (o, searchQuery) => ({
|
|
57
56
|
...o,
|
|
58
57
|
options: _.filter(optionMatches(lowerDeburr(searchQuery)))(
|
|
59
|
-
_.prop("options")(o)
|
|
58
|
+
_.prop("options")(o),
|
|
60
59
|
),
|
|
61
60
|
});
|
|
62
61
|
|
|
@@ -80,10 +79,10 @@ export const OptionGroup = ({
|
|
|
80
79
|
_.reduce(
|
|
81
80
|
(acc, o) =>
|
|
82
81
|
_.has("options")(o) ? [...acc, ..._.prop("options")(o)] : [...acc, o],
|
|
83
|
-
[]
|
|
82
|
+
[],
|
|
84
83
|
),
|
|
85
84
|
_.find((o) => o.value == value),
|
|
86
|
-
_.prop("text")
|
|
85
|
+
_.prop("text"),
|
|
87
86
|
);
|
|
88
87
|
|
|
89
88
|
const text = value && !query ? findText(options) : "";
|