@truedat/core 8.7.0 → 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.
Files changed (131) hide show
  1. package/package.json +3 -3
  2. package/src/components/AddMemberForm.js +3 -3
  3. package/src/components/Alert.js +3 -3
  4. package/src/components/AlertExporter.js +4 -4
  5. package/src/components/AvailableFilters.js +5 -5
  6. package/src/components/CSVFileModal.js +1 -1
  7. package/src/components/CardGroupsAccordion.js +4 -4
  8. package/src/components/CatalogMenu.js +2 -2
  9. package/src/components/CommentsForm.js +1 -1
  10. package/src/components/DomainSearchFilter.js +9 -9
  11. package/src/components/DomainSelector.js +1 -1
  12. package/src/components/FilterDropdown.js +5 -5
  13. package/src/components/FilterMultilevelDropdown.js +9 -9
  14. package/src/components/GlossaryMenu.js +10 -7
  15. package/src/components/Graph.js +199 -127
  16. package/src/components/GroupActions.js +2 -2
  17. package/src/components/Hierarchy.js +1 -1
  18. package/src/components/HierarchyFilterDropdown.js +7 -7
  19. package/src/components/HierarchySelector.js +1 -1
  20. package/src/components/LanguagesTabs.js +2 -2
  21. package/src/components/OptionGroup.js +8 -9
  22. package/src/components/QualityMenu.js +6 -8
  23. package/src/components/ResourceMembers.js +3 -3
  24. package/src/components/SearchFilterDropdown.js +3 -3
  25. package/src/components/SidebarToggle.js +1 -1
  26. package/src/components/Submenu.js +46 -27
  27. package/src/components/SystemsLoader.js +1 -1
  28. package/src/components/TemplatesLoader.js +1 -1
  29. package/src/components/TreeSelector.js +2 -2
  30. package/src/components/UploadJob.js +3 -3
  31. package/src/components/UploadJobBreadcrumbs.js +4 -1
  32. package/src/components/UploadJobParser.js +4 -3
  33. package/src/components/UploadModal.js +1 -1
  34. package/src/components/UserFilter.js +1 -1
  35. package/src/components/UserFilters.js +2 -2
  36. package/src/components/__tests__/ArrayDecorator.spec.js +2 -2
  37. package/src/components/__tests__/CardGroupsAccordion.spec.js +6 -6
  38. package/src/components/__tests__/CatalogMenu.spec.js +1 -1
  39. package/src/components/__tests__/DateTime.spec.js +1 -1
  40. package/src/components/__tests__/DomainSearchFilter.spec.js +2 -2
  41. package/src/components/__tests__/DomainSearchFilterItem.spec.js +7 -7
  42. package/src/components/__tests__/DomainSelector.spec.js +3 -3
  43. package/src/components/__tests__/DropdownMenuItem.spec.js +3 -3
  44. package/src/components/__tests__/FilterDropdown.spec.js +11 -11
  45. package/src/components/__tests__/FilterMultilevelDropdown.spec.js +2 -2
  46. package/src/components/__tests__/GlossaryMenu.spec.js +2 -2
  47. package/src/components/__tests__/Graph.spec.js +12 -4
  48. package/src/components/__tests__/GroupActions.spec.js +4 -4
  49. package/src/components/__tests__/Hierarchy.spec.js +1 -1
  50. package/src/components/__tests__/HierarchyFilterDropdown.spec.js +5 -5
  51. package/src/components/__tests__/HierarchyNodeFinder.spec.js +4 -4
  52. package/src/components/__tests__/HierarchySelector.spec.js +7 -5
  53. package/src/components/__tests__/Markdown.spec.js +22 -8
  54. package/src/components/__tests__/ModalSaveFilter.spec.js +1 -1
  55. package/src/components/__tests__/Pagination.spec.js +2 -2
  56. package/src/components/__tests__/ResourceMembers.spec.js +4 -4
  57. package/src/components/__tests__/SearchDateFilter.spec.js +10 -5
  58. package/src/components/__tests__/SearchFilterDropdown.spec.js +1 -1
  59. package/src/components/__tests__/SelectedFilters.spec.js +7 -7
  60. package/src/components/__tests__/SideMenu.spec.js +1 -1
  61. package/src/components/__tests__/Submenu.spec.js +1 -1
  62. package/src/components/__tests__/TemplateSelector.spec.js +5 -5
  63. package/src/components/__tests__/TreeSelector.spec.js +23 -24
  64. package/src/components/__tests__/UploadJob.spec.js +1 -3
  65. package/src/components/__tests__/UploadJobBreadcrumbs.spec.js +4 -4
  66. package/src/components/__tests__/UploadJobParser.spec.js +42 -38
  67. package/src/components/__tests__/UploadModal.spec.js +9 -9
  68. package/src/components/__tests__/UserFilters.spec.js +1 -1
  69. package/src/components/graph/ColoredEdge.js +29 -23
  70. package/src/components/graph/edgeLayout.js +4 -1
  71. package/src/hooks/__tests__/useActiveRoutes.spec.js +32 -18
  72. package/src/hooks/useAclEntries.js +2 -2
  73. package/src/hooks/useActiveRoutes.js +14 -6
  74. package/src/hooks/useAuthorized.js +3 -3
  75. package/src/hooks/useHierarchies.js +8 -8
  76. package/src/hooks/useLocales.js +3 -3
  77. package/src/hooks/useMessages.js +1 -1
  78. package/src/hooks/useOnScreen.js +1 -1
  79. package/src/hooks/useUploadJobs.js +2 -8
  80. package/src/hooks/useUserFilters.js +1 -1
  81. package/src/i18n/components/LangProvider.js +6 -6
  82. package/src/i18n/components/Languages.js +4 -4
  83. package/src/i18n/components/MessageForm.js +24 -13
  84. package/src/i18n/components/Messages.js +5 -5
  85. package/src/i18n/components/__tests__/I18nRoutes.spec.js +1 -1
  86. package/src/messages/index.js +1 -1
  87. package/src/reducers/comments.js +3 -3
  88. package/src/router/__tests__/ProtectedRoute.spec.js +1 -1
  89. package/src/routes.js +1 -1
  90. package/src/routesTree.js +6 -1
  91. package/src/routines.js +2 -2
  92. package/src/search/FilterDropdown.js +1 -1
  93. package/src/search/FilterMultilevelDropdown.js +10 -10
  94. package/src/search/FilterQueryDropdown.js +4 -4
  95. package/src/search/HierarchyFilterDropdown.js +7 -7
  96. package/src/search/SearchContext.js +19 -19
  97. package/src/search/SearchDateFilter.js +12 -2
  98. package/src/search/SearchFilters.js +1 -1
  99. package/src/search/SearchSelectedFilters.js +1 -1
  100. package/src/search/SearchWidget.js +6 -2
  101. package/src/search/UserFilter.js +1 -1
  102. package/src/search/UserFilters.js +4 -4
  103. package/src/search/__tests__/FilterDropdown.spec.js +3 -3
  104. package/src/search/__tests__/FilterQueryDropdown.spec.js +20 -18
  105. package/src/search/__tests__/ModalSaveFilter.spec.js +2 -2
  106. package/src/search/__tests__/SearchContext.spec.js +42 -42
  107. package/src/search/__tests__/SearchSelectedFilters.spec.js +21 -17
  108. package/src/search/__tests__/SearchWidget.spec.js +4 -4
  109. package/src/selectors/__tests__/getRiSubscopes.spec.js +1 -1
  110. package/src/selectors/__tests__/makeSearchQuerySelector.spec.js +2 -2
  111. package/src/selectors/getConceptSubscope.js +1 -1
  112. package/src/selectors/getDashboardConfig.js +3 -3
  113. package/src/selectors/getMessage.js +3 -3
  114. package/src/selectors/getRecipients.js +3 -3
  115. package/src/selectors/getRiSubscopes.js +2 -2
  116. package/src/selectors/getSidemenuGlossarySubscopes.js +1 -1
  117. package/src/selectors/makeActiveFiltersSelector.js +2 -2
  118. package/src/selectors/makeDateFiltersSelector.js +1 -1
  119. package/src/selectors/makeSearchQuerySelector.js +10 -10
  120. package/src/selectors/makeTagOptionsSelector.js +1 -4
  121. package/src/selectors/subscopedTemplates.js +2 -2
  122. package/src/services/columnPredicate.js +1 -1
  123. package/src/services/dateFilterFormatter.js +1 -1
  124. package/src/services/fieldType.js +1 -1
  125. package/src/services/formRules.js +16 -13
  126. package/src/services/getHierarchyOptions.js +2 -2
  127. package/src/services/message.js +7 -8
  128. package/src/services/operators.js +5 -5
  129. package/src/services/sort.js +2 -2
  130. package/src/services/swr.js +1 -1
  131. package/src/services/tree.js +2 -2
@@ -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 neighbourRank !== undefined && Math.abs(neighbourRank) < Math.abs(rank);
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 neighbourRank !== undefined && Math.abs(neighbourRank) < Math.abs(rank);
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) return metaA.label.localeCompare(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) => (node.y ?? node.position?.y ?? 0) + getNodeHeight(node) / 2;
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 neighbourRank !== undefined && Math.abs(neighbourRank) < Math.abs(rank);
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 neighbourRank !== undefined && Math.abs(neighbourRank) < Math.abs(rank);
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 = desiredCentersById.get(nodeA.id) ?? getNodeCenterY(nodeA);
229
- const desiredB = desiredCentersById.get(nodeB.id) ?? getNodeCenterY(nodeB);
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 (nodeA.y ?? nodeA.position?.y ?? 0) - (nodeB.y ?? nodeB.position?.y ?? 0);
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 = desiredCentersById.get(node.id) ?? getNodeCenterY(node);
258
+ const desiredCenter =
259
+ desiredCentersById.get(node.id) ?? getNodeCenterY(node);
241
260
  const desiredTop = desiredCenter - height / 2;
242
- const nextTop = Math.max(desiredTop, previousBottom + MIN_NODE_VERTICAL_GAP);
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) return DEFAULT_MIN_ZOOM;
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 = node.measured?.height ?? node.height ?? DEFAULT_NODE_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 edgesWithStroke = initialEdges.map((edge) => {
361
- const stroke =
362
- edge.style?.stroke || DEFAULT_EDGE_STROKE;
363
- return {
364
- ...edge,
365
- style: {
366
- strokeWidth: 1.5,
367
- ...edge.style,
368
- stroke,
369
- },
370
- data: {
371
- ...edge.data,
372
- edgeStroke: stroke,
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
- const groupsByTarget = new Map();
400
+ const groupsByTarget = new Map();
378
401
 
379
- edgesWithStroke.forEach((edge) => {
380
- const stroke = edge.style?.stroke || DEFAULT_EDGE_STROKE;
381
- const groupKey = getIncomingEdgeGroupKey(edge, stroke);
382
- const targetGroups = groupsByTarget.get(edge.target) || new Map();
383
- const group = targetGroups.get(groupKey) || [];
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
- group.push(edge.id);
386
- targetGroups.set(groupKey, group);
387
- groupsByTarget.set(edge.target, targetGroups);
388
- });
408
+ group.push(edge.id);
409
+ targetGroups.set(groupKey, group);
410
+ groupsByTarget.set(edge.target, targetGroups);
411
+ });
389
412
 
390
- const groupMetaByEdgeId = new Map();
413
+ const groupMetaByEdgeId = new Map();
391
414
 
392
- groupsByTarget.forEach((targetGroups) => {
393
- const orderedGroups = Array.from(targetGroups.entries())
394
- .sort(([groupKeyA], [groupKeyB]) => groupKeyA.localeCompare(groupKeyB));
415
+ groupsByTarget.forEach((targetGroups) => {
416
+ const orderedGroups = Array.from(targetGroups.entries()).sort(
417
+ ([groupKeyA], [groupKeyB]) => groupKeyA.localeCompare(groupKeyB),
418
+ );
395
419
 
396
- orderedGroups.forEach(([groupKey, edgeIds], groupIndex) => {
397
- edgeIds.forEach((edgeId, edgeIndex) => {
398
- groupMetaByEdgeId.set(edgeId, {
399
- targetSlotCount: orderedGroups.length,
400
- targetSlotIndex: groupIndex,
401
- showTargetArrow: edgeIndex === edgeIds.length - 1,
402
- incomingGroupKey: groupKey,
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
- return edgesWithStroke.map((edge) => ({
409
- ...edge,
410
- markerEnd: edge.markerEnd || {
411
- type: MarkerType.ArrowClosed,
412
- width: 12,
413
- height: 12,
414
- color: edge.style?.stroke || DEFAULT_EDGE_STROKE,
415
- },
416
- data: {
417
- ...edge.data,
418
- ...groupMetaByEdgeId.get(edge.id),
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.layout(graph).then(({ children = [] }) => {
505
- if (currentLayoutRunId !== layoutRunId.current) return;
506
- children.forEach((node) => {
507
- node.position = { x: node.x, y: node.y };
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
- const alignedChildren = alignNodesToConnectionPoints(
511
- children,
512
- edgesToLayout,
513
- rootNodeId
514
- );
535
+ const alignedChildren = alignNodesToConnectionPoints(
536
+ children,
537
+ edgesToLayout,
538
+ rootNodeId,
539
+ );
515
540
 
516
- setNodes(alignedChildren);
517
- scheduleFitView(alignedChildren, edgesToLayout);
518
- }).catch(() => {
519
- if (currentLayoutRunId !== layoutRunId.current) return;
541
+ setNodes(alignedChildren);
542
+ scheduleFitView(alignedChildren, edgesToLayout);
543
+ })
544
+ .catch(() => {
545
+ if (currentLayoutRunId !== layoutRunId.current) return;
520
546
 
521
- setNodes(nodesToLayout);
522
- setEdges(edgesToLayout);
523
- scheduleFitView(nodesToLayout, edgesToLayout);
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
- isInitialized,
548
- layoutInput,
549
- setNodes,
550
- setEdges,
551
- getLayoutedElements,
552
- ]);
553
-
554
- useEffect(() => () => {
555
- if (fitViewFrameId.current) {
556
- cancelAnimationFrame(fitViewFrameId.current);
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 content={formatMessage({ id: "graph.controls.zoom_in" })}>
590
- <ControlButton onClick={() => zoomIn({ duration: 200 })} aria-label={formatMessage({ id: "graph.controls.zoom_in" })}>
591
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
592
- <line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" />
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 content={formatMessage({ id: "graph.controls.zoom_out" })}>
597
- <ControlButton onClick={() => zoomOut({ duration: 200 })} aria-label={formatMessage({ id: "graph.controls.zoom_out" })}>
598
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
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 content={formatMessage({ id: "graph.controls.fit_view" })}>
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 viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
611
- <path d="M8 3H5a2 2 0 0 0-2 2v3" /><path d="M21 8V5a2 2 0 0 0-2-2h-3" />
612
- <path d="M3 16v3a2 2 0 0 0 2 2h3" /><path d="M16 21h3a2 2 0 0 0 2-2v-3" />
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 content={formatMessage({ id: "graph.controls.open_expanded" })}>
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 viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
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 className="td-graph-container" style={{ "--td-graph-container-height": height }} ref={containerRef}>
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>{formatMessage({ id: "graph.expanded.header" })}</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}
@@ -37,9 +37,9 @@ export const GroupActions = ({
37
37
  action?.onClick?.(event, data);
38
38
  },
39
39
  ...(closeDropdownOnClose ? { closeDropdown } : {}),
40
- })
40
+ });
41
41
  }),
42
- [availableActions, closeDropdown]
42
+ [availableActions, closeDropdown],
43
43
  );
44
44
 
45
45
  return (
@@ -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
  };
@@ -40,7 +40,7 @@ const HierarchySelector = ({
40
40
  _.sortBy(accentInsensitivePathOrder("name")),
41
41
  stratify({}),
42
42
  flatten,
43
- maybeMapKeys
43
+ maybeMapKeys,
44
44
  )(data);
45
45
 
46
46
  return (
@@ -69,9 +69,9 @@ const LanguagesTabs = ({
69
69
  }}
70
70
  activeIndex={Math.max(
71
71
  translationTabs.findIndex(
72
- (tab) => tab.lang === (selectedLang || initLang)
72
+ (tab) => tab.lang === (selectedLang || initLang),
73
73
  ),
74
- 0
74
+ 0,
75
75
  )}
76
76
  />
77
77
  );
@@ -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) : "";