@reltio/graph 1.4.1585 → 1.4.1586-mui5

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 (164) hide show
  1. package/index.ts +1 -0
  2. package/package.json +26 -9
  3. package/public/bundle.js +205 -0
  4. package/public/bundle.js.LICENSE.txt +88 -0
  5. package/public/package.json +29 -0
  6. package/scripts/build/index.js +20 -0
  7. package/src/__tests__/GraphView.test.tsx +25 -0
  8. package/src/components/CircleLayout/CircleLayout.tsx +76 -0
  9. package/src/components/CircleLayout/__tests__/CircleLayout.test.tsx +194 -0
  10. package/src/components/GotoButton/GotoButton.tsx +23 -0
  11. package/src/components/GotoButton/__tests__/GotoButton.test.tsx +33 -0
  12. package/src/components/GotoButton/styles.ts +15 -0
  13. package/src/components/GraphArea/GraphArea.tsx +113 -0
  14. package/src/components/GraphArea/__tests__/GraphArea.test.tsx +202 -0
  15. package/src/components/GraphArea/styles.ts +30 -0
  16. package/src/components/GraphLayoutSelector/GraphLayoutSelector.tsx +43 -0
  17. package/src/components/GraphLayoutSelector/__tests__/GraphLayoutSelector.spec.tsx +44 -0
  18. package/src/components/GraphLayoutSelector/styles.ts +15 -0
  19. package/src/components/GraphPerspectiveView/GraphPerspectiveView.tsx +58 -0
  20. package/src/components/GraphPerspectiveView/__tests__/GraphPerspectiveView.test.tsx +115 -0
  21. package/src/components/GraphPerspectiveView/__tests__/useGraphLoader.test.tsx +1519 -0
  22. package/src/components/GraphPerspectiveView/__tests__/useRelationshipTable.test.tsx +1003 -0
  23. package/src/components/GraphPerspectiveView/__tests__/useSelectedEntity.test.tsx +373 -0
  24. package/src/components/GraphPerspectiveView/styles.ts +34 -0
  25. package/src/components/GraphRightSidePanel/GraphRightSidePanel.tsx +27 -0
  26. package/src/components/GraphRightSidePanel/__tests__/GraphRightSidePanel.test.tsx +18 -0
  27. package/src/components/GraphRightSidePanel/icons/relationship-icon.svg +3 -0
  28. package/src/components/GraphRightSidePanel/styles.ts +8 -0
  29. package/src/components/GraphTypeSelector/GraphTypeSelector.tsx +56 -0
  30. package/src/components/GraphTypeSelector/__tests__/GraphTypeSelector.test.tsx +109 -0
  31. package/src/components/GraphTypeSelector/styles.ts +17 -0
  32. package/src/components/HierarchyLayout/HierarchyLayout.ts +102 -0
  33. package/src/components/HierarchyLayout/__tests__/HierarchyLayout.spec.tsx +241 -0
  34. package/src/components/HierarchyLayout/__tests__/buildHierarchy.spec.ts +130 -0
  35. package/src/components/HierarchyLayout/__tests__/calculations.spec.ts +230 -0
  36. package/src/components/HierarchyLayout/buildHierarchy.ts +109 -0
  37. package/src/components/HierarchyLayout/calculations.ts +86 -0
  38. package/src/components/RightPanelEntityDetails/RightPanelEntityDetails.tsx +33 -0
  39. package/src/components/RightPanelEntityDetails/__tests__/RightPanelEntityDetails.test.tsx +39 -0
  40. package/src/components/RightPanelEntityDetails/styles.ts +12 -0
  41. package/src/components/RightPanelProfileBand/RightPanelProfileBand.tsx +33 -0
  42. package/src/components/RightPanelProfileBand/__tests__/RightPanelProfileBand.test.tsx +67 -0
  43. package/src/components/RightPanelProfileBand/styles.ts +8 -0
  44. package/src/components/RightPanelRelationship/RightPanelRelationship.tsx +25 -0
  45. package/src/components/RightPanelRelationship/__tests__/RightPanelRelationship.test.tsx +18 -0
  46. package/src/components/RightPanelRelationship/components/CollapsibleTable/CollapsibleTable.tsx +100 -0
  47. package/src/components/RightPanelRelationship/components/CollapsibleTable/TableHead.tsx +38 -0
  48. package/src/components/RightPanelRelationship/components/CollapsibleTable/__tests__/CollapsibleTable.test.tsx +169 -0
  49. package/src/components/RightPanelRelationship/components/CollapsibleTable/__tests__/TableHead.test.tsx +107 -0
  50. package/src/components/RightPanelRelationship/components/CollapsibleTable/styles.ts +38 -0
  51. package/src/components/RightPanelRelationship/components/CollapsibleTable/types.ts +20 -0
  52. package/src/components/RightPanelRelationship/components/DeleteRelationDialog/DeleteRelationDialog.tsx +34 -0
  53. package/src/components/RightPanelRelationship/components/DeleteRelationDialog/__tests__/DeleteRelationDialog.test.tsx +46 -0
  54. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/GraphAddRelationButton.tsx +43 -0
  55. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/GraphAddRelationDialog.tsx +121 -0
  56. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/__tests__/GraphAddRelationButton.test.tsx +80 -0
  57. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/__tests__/GraphAddRelationDialog.test.tsx +262 -0
  58. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/__tests__/mockdata.ts +75 -0
  59. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/styles.ts +25 -0
  60. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/useCreatableInOutRelationTypes.ts +13 -0
  61. package/src/components/RightPanelRelationship/components/RelationshipTable/RelationshipTable.tsx +126 -0
  62. package/src/components/RightPanelRelationship/components/RelationshipTable/__tests__/RelationshipTable.test.tsx +176 -0
  63. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/ControlsCellRenderer.tsx +59 -0
  64. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/DefaultCellRenderer.tsx +29 -0
  65. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/ExpandedRowRenderer.tsx +94 -0
  66. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/HeadCellRenderer.tsx +34 -0
  67. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/ProfileCellRenderer.tsx +41 -0
  68. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/ControlsCellRenderer.test.tsx +80 -0
  69. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/DefaultCellRenderer.test.tsx +47 -0
  70. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/ExpandedRowRenderer.test.tsx +166 -0
  71. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/HeadCellRenderer.test.tsx +23 -0
  72. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/ProfileCellRenderer.test.tsx +47 -0
  73. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/components/DeleteRelationButton.tsx +32 -0
  74. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/components/__tests__/DeleteRelationButton.test.tsx +28 -0
  75. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/styles.ts +113 -0
  76. package/src/components/RightPanelRelationship/components/RelationshipTable/styles.ts +36 -0
  77. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFilters.tsx +41 -0
  78. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFiltersDialog/RelationshipsFiltersDialog.tsx +91 -0
  79. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFiltersDialog/__tests__/RelationshipsFilterDialog.test.tsx +192 -0
  80. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFiltersDialog/styles.ts +34 -0
  81. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsSearchTextField/RelationshipsSearchTextField.tsx +31 -0
  82. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsSearchTextField/__tests__/RelationshipsSearchTextField.test.tsx +43 -0
  83. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsSearchTextField/styles.ts +17 -0
  84. package/src/components/RightPanelRelationship/components/RelationshipsFilters/__tests__/RelationshipsFilters.test.tsx +76 -0
  85. package/src/components/RightPanelRelationship/components/RelationshipsFilters/styles.ts +19 -0
  86. package/src/components/RightPanelRelationship/styles.ts +20 -0
  87. package/src/components/SigmaCustomRenderers/SigmaCustomRenderersContainer.tsx +16 -0
  88. package/src/components/SigmaGraphContainer/SigmaGraphContainer.tsx +55 -0
  89. package/src/components/SigmaGraphContainer/__tests__/SigmaGraphContainer.test.tsx +25 -0
  90. package/src/components/SigmaGraphResizer/SigmaGraphResizer.tsx +13 -0
  91. package/src/components/SigmaGraphResizer/__tests__/SigmaGraphResizer.test.tsx +28 -0
  92. package/src/components/TreeLayout/TreeLayout.tsx +33 -0
  93. package/src/components/TreeLayout/__tests__/TreeLayout.test.tsx +42 -0
  94. package/src/components/TreeLayout/styles.ts +10 -0
  95. package/src/components/ZoomSlider/ZoomSlider.tsx +90 -0
  96. package/src/components/ZoomSlider/__tests__/ZoomSlider.test.tsx +84 -0
  97. package/src/components/ZoomSlider/styles.ts +57 -0
  98. package/src/constants/index.ts +1 -0
  99. package/src/contexts/GraphStateContext.tsx +19 -0
  100. package/src/contexts/SigmaCustomRenderersContext.ts +20 -0
  101. package/src/helpers/relationsHelpers.ts +9 -0
  102. package/src/hooks/__tests__/useGraphLayout.test.tsx +825 -0
  103. package/src/hooks/__tests__/useGraphLayoutSelector.test.tsx +19 -0
  104. package/src/hooks/__tests__/useSelfRelationLoopsRenderer.test.ts +198 -0
  105. package/src/hooks/__tests__/useSigmaCustomRenderers.test.ts +273 -0
  106. package/src/hooks/__tests__/useTooltipRenderer.test.ts +289 -0
  107. package/src/hooks/useGraphLayout.ts +308 -0
  108. package/src/hooks/useGraphLayoutSelector.ts +19 -0
  109. package/src/hooks/useGraphLoader.ts +279 -0
  110. package/src/hooks/useGraphRightSidePanelElements.tsx +36 -0
  111. package/src/hooks/useGraphState.ts +40 -0
  112. package/src/hooks/useGraphType.ts +32 -0
  113. package/src/hooks/useRelationshipTable.ts +212 -0
  114. package/src/hooks/useRelationshipTableFilters.ts +43 -0
  115. package/src/hooks/useSelectedEntity.ts +89 -0
  116. package/src/hooks/useSelfRelationLoopsRenderer.ts +52 -0
  117. package/src/hooks/useSigmaCustomRenderers.ts +112 -0
  118. package/src/hooks/useTooltipRenderer.ts +80 -0
  119. package/src/index.tsx +37 -0
  120. package/src/rendering/canvas/__tests__/hover.spec.ts +31 -0
  121. package/src/rendering/canvas/__tests__/label.spec.ts +64 -0
  122. package/src/rendering/canvas/__tests__/nodeBackground.spec.ts +99 -0
  123. package/src/rendering/canvas/__tests__/selfRelationLoop.spec.ts +88 -0
  124. package/src/rendering/canvas/__tests__/tooltip.spec.ts +33 -0
  125. package/src/rendering/canvas/hover.ts +13 -0
  126. package/src/rendering/canvas/label.ts +33 -0
  127. package/src/rendering/canvas/nodeBackground.ts +61 -0
  128. package/src/rendering/canvas/selfRelationLoop.ts +108 -0
  129. package/src/rendering/canvas/tooltip.ts +38 -0
  130. package/src/rendering/icons/collapseIcon.inline.svg.ts +6 -0
  131. package/src/rendering/icons/expandIcon.inline.svg.ts +5 -0
  132. package/src/rendering/icons/no_photo.inline.svg.ts +13 -0
  133. package/src/rendering/webgl/edge.arrowHead.ts +87 -0
  134. package/src/rendering/webgl/edge.clamped.ts +246 -0
  135. package/src/rendering/webgl/edge.reversedArrowHead.ts +14 -0
  136. package/src/rendering/webgl/helpers/__tests__/imageHelper.spec.ts +36 -0
  137. package/src/rendering/webgl/helpers/imageHelper.ts +13 -0
  138. package/src/rendering/webgl/image.ts +115 -0
  139. package/src/rendering/webgl/node.border.ts +78 -0
  140. package/src/rendering/webgl/node.buttons.ts +241 -0
  141. package/src/rendering/webgl/node.image.ts +169 -0
  142. package/src/rendering/webgl/shaders/edge.clamped.vert.glsl.ts +55 -0
  143. package/src/rendering/webgl/shaders/node.border.frag.glsl.ts +30 -0
  144. package/src/rendering/webgl/shaders/node.border.vert.glsl.ts +37 -0
  145. package/src/rendering/webgl/shaders/node.buttons.frag.glsl.ts +32 -0
  146. package/src/rendering/webgl/shaders/node.buttons.vert.glsl.ts +49 -0
  147. package/src/rendering/webgl/shaders/node.image.frag.glsl.ts +46 -0
  148. package/src/rendering/webgl/shaders/node.image.vert.glsl.ts +42 -0
  149. package/src/types/graphDataTypes.ts +143 -0
  150. package/src/types/sigmaCustomRenderersTypes.ts +13 -0
  151. package/src/utils/__tests__/graph.spec.ts +152 -0
  152. package/src/utils/__tests__/graphLayout.spec.ts +125 -0
  153. package/src/utils/__tests__/hopsData.spec.ts +456 -0
  154. package/src/utils/__tests__/processResponceToGraph.spec.ts +165 -0
  155. package/src/utils/graph.ts +83 -0
  156. package/src/utils/graphLayout.ts +70 -0
  157. package/src/utils/hopsData.ts +198 -0
  158. package/src/utils/processResponseToGraph.ts +32 -0
  159. package/tsconfig.json +4 -0
  160. package/webpack.config.js +10 -0
  161. package/bundle.js +0 -2
  162. package/bundle.js.LICENSE.txt +0 -54
  163. /package/{5271a9e7b6651c852e93.png → public/5271a9e7b6651c852e93.png} +0 -0
  164. /package/{main.css → public/main.css} +0 -0
@@ -0,0 +1,88 @@
1
+ /*
2
+ object-assign
3
+ (c) Sindre Sorhus
4
+ @license MIT
5
+ */
6
+
7
+ /**
8
+ * @license
9
+ * Lodash <https://lodash.com/>
10
+ * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
11
+ * Released under MIT license <https://lodash.com/license>
12
+ * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
13
+ * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
14
+ */
15
+
16
+ /**
17
+ * @license React
18
+ * react-is.production.min.js
19
+ *
20
+ * Copyright (c) Facebook, Inc. and its affiliates.
21
+ *
22
+ * This source code is licensed under the MIT license found in the
23
+ * LICENSE file in the root directory of this source tree.
24
+ */
25
+
26
+ /**
27
+ * @mui/material v5.13.4
28
+ *
29
+ * @license MIT
30
+ * This source code is licensed under the MIT license found in the
31
+ * LICENSE file in the root directory of this source tree.
32
+ */
33
+
34
+ /**
35
+ * @mui/styled-engine v5.13.2
36
+ *
37
+ * @license MIT
38
+ * This source code is licensed under the MIT license found in the
39
+ * LICENSE file in the root directory of this source tree.
40
+ */
41
+
42
+ /**
43
+ * A better abstraction over CSS.
44
+ *
45
+ * @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present
46
+ * @website https://github.com/cssinjs/jss
47
+ * @license MIT
48
+ */
49
+
50
+ /**
51
+ * React Router DOM v6.2.1
52
+ *
53
+ * Copyright (c) Remix Software Inc.
54
+ *
55
+ * This source code is licensed under the MIT license found in the
56
+ * LICENSE.md file in the root directory of this source tree.
57
+ *
58
+ * @license MIT
59
+ */
60
+
61
+ /**
62
+ * React Router v6.2.1
63
+ *
64
+ * Copyright (c) Remix Software Inc.
65
+ *
66
+ * This source code is licensed under the MIT license found in the
67
+ * LICENSE.md file in the root directory of this source tree.
68
+ *
69
+ * @license MIT
70
+ */
71
+
72
+ /** @license React v16.13.1
73
+ * react-is.production.min.js
74
+ *
75
+ * Copyright (c) Facebook, Inc. and its affiliates.
76
+ *
77
+ * This source code is licensed under the MIT license found in the
78
+ * LICENSE file in the root directory of this source tree.
79
+ */
80
+
81
+ /** @license React v17.0.2
82
+ * react-jsx-runtime.production.min.js
83
+ *
84
+ * Copyright (c) Facebook, Inc. and its affiliates.
85
+ *
86
+ * This source code is licensed under the MIT license found in the
87
+ * LICENSE file in the root directory of this source tree.
88
+ */
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@reltio/graph",
3
+ "version": "1.4.1586-mui5",
4
+ "license": "SEE LICENSE IN LICENSE FILE",
5
+ "main": "bundle.js",
6
+ "dependencies": {
7
+ "@date-io/moment": "^1.3.13",
8
+ "@react-sigma/core": "^3.1.0",
9
+ "@reltio/hierarchy-tree": "^1.4.1586-mui5",
10
+ "@reltio/mdm-module": "^1.4.1586-mui5",
11
+ "@reltio/mdm-sdk": "^1.4.1586-mui5",
12
+ "classnames": "^2.2.5",
13
+ "graphology": "^0.25.1",
14
+ "graphology-layout": "^0.6.1",
15
+ "graphology-layout-forceatlas2": "^0.10.1",
16
+ "graphology-operators": "^1.6.0",
17
+ "graphology-shortest-path": "^2.0.1",
18
+ "graphology-types": "^0.24.5",
19
+ "ramda": "^0.28.0",
20
+ "react-redux": "^7.2.3",
21
+ "react-resize-detector": "^4.2.0",
22
+ "redux": "^4.1.2",
23
+ "sigma": "^2.4.0",
24
+ "ui-i18n": "bitbucket:reltio-ondemand/ui-i18n#v1.4.0"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ }
29
+ }
@@ -0,0 +1,20 @@
1
+ const path = require('path');
2
+ const fs = require('fs');
3
+
4
+ const outputDir = path.resolve(process.cwd(), 'public');
5
+ const generatePackageJson = () => {
6
+ const packageJson = require('../../package.json');
7
+ const result = {
8
+ name: packageJson.name,
9
+ version: packageJson.version,
10
+ license: 'SEE LICENSE IN LICENSE FILE',
11
+ main: 'bundle.js',
12
+ dependencies: packageJson.dependencies,
13
+ peerDependencies: packageJson.peerDependencies,
14
+ publishConfig: packageJson.publishConfig
15
+ };
16
+ const source = JSON.stringify(result, null, 2);
17
+ fs.writeFileSync(path.join(outputDir, 'package.json'), source);
18
+ };
19
+
20
+ generatePackageJson();
@@ -0,0 +1,25 @@
1
+ import GraphView from '../';
2
+ import {shallow} from 'enzyme';
3
+ import {Store} from 'redux';
4
+ import React from 'react';
5
+ import {Provider} from 'react-redux';
6
+ import {ErrorPopup} from '@reltio/components';
7
+ import {LocalizationProvider} from '@mui/x-date-pickers/LocalizationProvider';
8
+ import {AdapterMoment} from '@mui/x-date-pickers/AdapterMoment';
9
+ import GraphPerspectiveView from '../components/GraphPerspectiveView/GraphPerspectiveView';
10
+
11
+ const store = {} as Store;
12
+ const setUp = () => shallow(<GraphView store={store} />);
13
+
14
+ describe('graph view test', () => {
15
+ it('should render redux provider, StylesProvider, LocalizationProvider', () => {
16
+ const component = setUp();
17
+ expect(component.find(Provider)).toHaveLength(1);
18
+ expect(component.find(Provider).prop('store')).toBe(store);
19
+ expect(component.find(GraphPerspectiveView)).toHaveLength(1);
20
+ expect(component.find(ErrorPopup)).toHaveLength(1);
21
+ expect(component.find(ErrorPopup).prop('showErrorFromStore')).toBe(true);
22
+ expect(component.find(LocalizationProvider)).toHaveLength(1);
23
+ expect(component.find(LocalizationProvider).prop('dateAdapter')).toBe(AdapterMoment);
24
+ });
25
+ });
@@ -0,0 +1,76 @@
1
+ import {useMemo} from 'react';
2
+ import circular from 'graphology-layout/circular';
3
+ import forceAtlas2 from 'graphology-layout-forceatlas2';
4
+ import FA2Layout from 'graphology-layout-forceatlas2/worker';
5
+ import Graph from 'graphology';
6
+ import {difference, prop} from 'ramda';
7
+ import {HopsResponse, GraphLayout} from '@reltio/mdm-sdk';
8
+ import {useDidUpdateEffect, usePrevious} from '@reltio/components';
9
+
10
+ import {useGraphLayout} from '../../hooks/useGraphLayout';
11
+ import {GraphPathType, Filters} from '../../types/graphDataTypes';
12
+
13
+ type CircleLayoutProps = {
14
+ data: HopsResponse;
15
+ graph: Graph;
16
+ selectedNode: string;
17
+ onNodeClick: (node: string) => void;
18
+ onNodeCollapse: (node: string, path: GraphPathType) => void;
19
+ onNodeExpand: (node: string) => void;
20
+ layout: GraphLayout;
21
+ filters?: Filters;
22
+ };
23
+
24
+ export const CircleLayout = ({
25
+ data,
26
+ graph,
27
+ selectedNode,
28
+ layout,
29
+ onNodeClick,
30
+ onNodeCollapse,
31
+ onNodeExpand,
32
+ filters
33
+ }: CircleLayoutProps) => {
34
+ const prevData: HopsResponse = usePrevious(data);
35
+
36
+ useDidUpdateEffect(() => {
37
+ if (prevData) {
38
+ const newNodesIds = difference(data.entities.map(prop('uri')), prevData.entities.map(prop('uri')));
39
+ if (newNodesIds.length) {
40
+ const tempGraph = graph.copy();
41
+ circular.assign(tempGraph);
42
+ newNodesIds.forEach((id) => {
43
+ graph.setNodeAttribute(id, 'x', tempGraph.getNodeAttribute(id, 'x'));
44
+ graph.setNodeAttribute(id, 'y', tempGraph.getNodeAttribute(id, 'y'));
45
+ });
46
+ }
47
+ }
48
+ }, [data]);
49
+
50
+ const layoutSettings = useMemo(() => {
51
+ circular.assign(graph);
52
+ return {
53
+ settings: {
54
+ ...forceAtlas2.inferSettings(graph),
55
+ gravity: 1
56
+ }
57
+ };
58
+ }, [graph]);
59
+
60
+ useGraphLayout({
61
+ workerLayout: FA2Layout,
62
+ layoutSettings,
63
+ data,
64
+ graph,
65
+ selectedNode,
66
+ onNodeClick,
67
+ isDirected: layout === GraphLayout.DIRECTED_NETWORK,
68
+ onNodeCollapse,
69
+ onNodeExpand,
70
+ filters
71
+ });
72
+
73
+ return null;
74
+ };
75
+
76
+ export default CircleLayout;
@@ -0,0 +1,194 @@
1
+ import React from 'react';
2
+ import {mount} from 'enzyme';
3
+ import {MultiGraph} from 'graphology';
4
+ import FA2Layout from 'graphology-layout-forceatlas2/worker';
5
+ import {HopsResponse, GraphLayout} from '@reltio/mdm-sdk';
6
+
7
+ import CircleLayout from '../CircleLayout';
8
+ import * as useGraphLayoutImport from '../../../hooks/useGraphLayout';
9
+ import {useGraphLayout} from '../../../hooks/useGraphLayout';
10
+ import {fillGraphWithHopsResponse} from '../../../utils/graph';
11
+
12
+ jest.mock('../../../hooks/useGraphLayout', () => ({
13
+ ...(jest.requireActual('../../../hooks/useGraphLayout') as Record<string, unknown>),
14
+ useGraphLayout: jest.fn()
15
+ }));
16
+
17
+ describe('CircleLayout tests', () => {
18
+ const data: HopsResponse = {
19
+ entities: [
20
+ {uri: 'node1', type: ''},
21
+ {uri: 'node2', type: ''},
22
+ {uri: 'node3', type: ''},
23
+ {uri: 'node4', type: ''}
24
+ ],
25
+ relations: [
26
+ {
27
+ uri: 'r1',
28
+ type: '',
29
+ startObject: {
30
+ objectURI: 'node1'
31
+ },
32
+ endObject: {
33
+ objectURI: 'node2'
34
+ }
35
+ },
36
+ {
37
+ uri: 'r2',
38
+ type: '',
39
+ startObject: {
40
+ objectURI: 'node2'
41
+ },
42
+ endObject: {
43
+ objectURI: 'node3'
44
+ }
45
+ },
46
+ {
47
+ uri: 'r3',
48
+ type: '',
49
+ startObject: {
50
+ objectURI: 'node2'
51
+ },
52
+ endObject: {
53
+ objectURI: 'node4'
54
+ }
55
+ }
56
+ ]
57
+ };
58
+ const graph = new MultiGraph();
59
+ fillGraphWithHopsResponse(graph, data);
60
+ const basicProps = {
61
+ data,
62
+ graph,
63
+ selectedNode: 'entities/uri1',
64
+ onNodeClick: jest.fn(),
65
+ onNodeCollapse: jest.fn(),
66
+ onNodeExpand: jest.fn(),
67
+ filters: {entityTypesUris: ['hcp'], relationTypesUris: []}
68
+ };
69
+
70
+ beforeAll(() => {
71
+ jest.spyOn(useGraphLayoutImport, 'useGraphLayout').mockReturnValue(undefined);
72
+ });
73
+
74
+ afterEach(() => {
75
+ jest.clearAllMocks();
76
+ });
77
+
78
+ it('should call useGraphLayout with correctly params if layout is not directed network', () => {
79
+ const props = {
80
+ ...basicProps,
81
+ layout: GraphLayout.SIMPLE_NETWORK
82
+ };
83
+ mount(<CircleLayout {...props} />);
84
+ expect(useGraphLayout).toHaveBeenCalledWith({
85
+ workerLayout: FA2Layout,
86
+ layoutSettings: {
87
+ settings: {
88
+ barnesHutOptimize: false,
89
+ gravity: 1,
90
+ scalingRatio: 10,
91
+ slowDown: expect.any(Number),
92
+ strongGravityMode: true
93
+ }
94
+ },
95
+ isDirected: false,
96
+ filters: {
97
+ entityTypesUris: ['hcp'],
98
+ relationTypesUris: []
99
+ },
100
+ graph,
101
+ data: props.data,
102
+ onNodeClick: props.onNodeClick,
103
+ onNodeCollapse: props.onNodeCollapse,
104
+ onNodeExpand: props.onNodeExpand,
105
+ selectedNode: props.selectedNode
106
+ });
107
+ });
108
+
109
+ it('should call useGraphLayout with correctly params if layout is directed network', () => {
110
+ const props = {
111
+ ...basicProps,
112
+ layout: GraphLayout.DIRECTED_NETWORK
113
+ };
114
+ mount(<CircleLayout {...props} />);
115
+ expect(useGraphLayout).toHaveBeenCalledWith({
116
+ workerLayout: FA2Layout,
117
+ layoutSettings: {
118
+ settings: {
119
+ barnesHutOptimize: false,
120
+ gravity: 1,
121
+ scalingRatio: 10,
122
+ slowDown: expect.any(Number),
123
+ strongGravityMode: true
124
+ }
125
+ },
126
+ isDirected: true,
127
+ graph,
128
+ data: props.data,
129
+ onNodeClick: props.onNodeClick,
130
+ onNodeExpand: props.onNodeExpand,
131
+ onNodeCollapse: props.onNodeCollapse,
132
+ selectedNode: props.selectedNode,
133
+ filters: props.filters
134
+ });
135
+ });
136
+
137
+ it('should assign circular layout for new nodes if new nodes were added to data', () => {
138
+ const props = {
139
+ ...basicProps,
140
+ layout: GraphLayout.SIMPLE_NETWORK
141
+ };
142
+ const component = mount(<CircleLayout {...props} />);
143
+
144
+ const newData = {
145
+ entities: [...data.entities, {uri: 'node5', type: ''}, {uri: 'node6', type: ''}],
146
+ relations: [
147
+ ...data.relations,
148
+ {
149
+ uri: 'r4',
150
+ type: '',
151
+ startObject: {
152
+ objectURI: 'node4'
153
+ },
154
+ endObject: {
155
+ objectURI: 'node5'
156
+ }
157
+ },
158
+ {
159
+ uri: 'r5',
160
+ type: '',
161
+ startObject: {
162
+ objectURI: 'node4'
163
+ },
164
+ endObject: {
165
+ objectURI: 'node6'
166
+ }
167
+ }
168
+ ]
169
+ };
170
+
171
+ const newGraph = new MultiGraph();
172
+ fillGraphWithHopsResponse(newGraph, newData);
173
+ expect(newGraph.getNodeAttributes('node5')).toMatchObject({
174
+ x: 1,
175
+ y: 1
176
+ });
177
+ expect(newGraph.getNodeAttributes('node6')).toMatchObject({
178
+ x: 1,
179
+ y: 1
180
+ });
181
+
182
+ component.setProps({...props, data: newData, graph: newGraph});
183
+ component.update();
184
+
185
+ expect(newGraph.getNodeAttributes('node5')).toMatchObject({
186
+ x: -0.5000000000000004,
187
+ y: -0.8660254037844385
188
+ });
189
+ expect(newGraph.getNodeAttributes('node6')).toMatchObject({
190
+ x: 0.5000000000000001,
191
+ y: -0.8660254037844386
192
+ });
193
+ });
194
+ });
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import {useCamera} from '@react-sigma/core';
3
+ import MyLocationIcon from '@mui/icons-material/MyLocation';
4
+ import IconButton from '@mui/material/IconButton';
5
+
6
+ import {useStyles} from './styles';
7
+
8
+ type Props = {
9
+ node: string;
10
+ };
11
+
12
+ const GotoButton = ({node}: Props) => {
13
+ const styles = useStyles();
14
+ const {gotoNode} = useCamera();
15
+
16
+ return (
17
+ <IconButton className={styles.button} onClick={() => gotoNode(node)} size="large">
18
+ <MyLocationIcon className={styles.icon} />
19
+ </IconButton>
20
+ );
21
+ };
22
+
23
+ export default GotoButton;
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import {shallow} from 'enzyme';
3
+ import {act} from 'react-dom/test-utils';
4
+ import {useCamera} from '@react-sigma/core';
5
+ import IconButton from '@mui/material/IconButton';
6
+ import MyLocationIcon from '@mui/icons-material/MyLocation';
7
+ import GotoButton from '../GotoButton';
8
+
9
+ jest.mock('@react-sigma/core', () => ({
10
+ ...jest.requireActual<Record<string, unknown>>('@react-sigma/core'),
11
+ useCamera: jest.fn().mockReturnValue({
12
+ gotoNode: jest.fn()
13
+ })
14
+ }));
15
+
16
+ describe('GotoButton tests', () => {
17
+ it('should render main parts', () => {
18
+ const component = shallow(<GotoButton node={undefined} />);
19
+ expect(component.find(IconButton)).toHaveLength(1);
20
+ expect(component.find(MyLocationIcon)).toHaveLength(1);
21
+ });
22
+
23
+ it('should call gotoNode on click', () => {
24
+ const nodeUri = 'testUri';
25
+ const component = shallow(<GotoButton node={nodeUri} />);
26
+ expect(component.find(IconButton)).toHaveLength(1);
27
+ act(() => {
28
+ component.find(IconButton).simulate('click');
29
+ });
30
+
31
+ expect(useCamera().gotoNode).toHaveBeenCalledWith(nodeUri);
32
+ });
33
+ });
@@ -0,0 +1,15 @@
1
+ import {makeStyles} from '@mui/styles';
2
+
3
+ export const useStyles = makeStyles({
4
+ button: {
5
+ background: '#FFFFFF',
6
+ boxShadow: '0 1px 1px rgba(0,0,0,0.14), 0 2px 1px rgba(0,0,0,0.12), 0 1px 3px rgba(0,0,0,0.2)',
7
+ width: '28px',
8
+ height: '28px',
9
+ borderRadius: '4px'
10
+ },
11
+ icon: {
12
+ width: '18px',
13
+ height: '18px'
14
+ }
15
+ });
@@ -0,0 +1,113 @@
1
+ import React from 'react';
2
+ import Graph from 'graphology';
3
+ import {withContext} from '@reltio/components';
4
+ import {HopsResponse, GraphLayout} from '@reltio/mdm-sdk';
5
+ import {SigmaGraphContainer} from '../SigmaGraphContainer/SigmaGraphContainer';
6
+ import CircleLayout from '../CircleLayout/CircleLayout';
7
+ import HierarchyLayout from '../HierarchyLayout/HierarchyLayout';
8
+ import {GraphStateContext} from '../../contexts/GraphStateContext';
9
+ import {Filters, GraphPathType} from '../../types/graphDataTypes';
10
+ import GraphTypeSelector from '../GraphTypeSelector/GraphTypeSelector';
11
+ import GraphLayoutSelector from '../GraphLayoutSelector/GraphLayoutSelector';
12
+ import SigmaGraphResizer from '../SigmaGraphResizer/SigmaGraphResizer';
13
+ import ZoomSlider from '../ZoomSlider/ZoomSlider';
14
+ import GotoButton from '../GotoButton/GotoButton';
15
+ import TreeLayout from '../TreeLayout/TreeLayout';
16
+ import {useStyles} from './styles';
17
+
18
+ type Props = {
19
+ data?: HopsResponse;
20
+ graph?: Graph;
21
+ selectedNode?: string;
22
+ onNodeSelect?: (uri: string) => void;
23
+ onNodeCollapse?: (uri: string, path: GraphPathType) => void;
24
+ onNodeExpand?: (uri: string) => void;
25
+ filters?: Filters;
26
+ graphTypeUri?: string;
27
+ layout?: GraphLayout;
28
+ setLayout?: (layout: GraphLayout) => void;
29
+ };
30
+
31
+ const GraphArea = ({
32
+ data,
33
+ graph,
34
+ selectedNode,
35
+ onNodeSelect,
36
+ onNodeCollapse,
37
+ onNodeExpand,
38
+ filters,
39
+ graphTypeUri,
40
+ layout,
41
+ setLayout
42
+ }: Props) => {
43
+ const styles = useStyles();
44
+
45
+ const commonProps = {
46
+ data,
47
+ graph,
48
+ selectedNode,
49
+ layout,
50
+ onNodeClick: onNodeSelect,
51
+ onNodeCollapse,
52
+ onNodeExpand,
53
+ filters
54
+ };
55
+ return (
56
+ <div className={styles.wrapper}>
57
+ <div className={styles.selectors}>
58
+ <GraphTypeSelector />
59
+ <GraphLayoutSelector value={layout} onChangeHandler={setLayout} graphTypeUri={graphTypeUri} />
60
+ </div>
61
+ <div className={styles.graph}>
62
+ {layout === GraphLayout.TREE ? (
63
+ <TreeLayout graphTypeUri={graphTypeUri} />
64
+ ) : (
65
+ graph && (
66
+ <SigmaGraphContainer>
67
+ <>
68
+ <SigmaGraphResizer />
69
+ {layout === GraphLayout.SIMPLE_NETWORK || layout === GraphLayout.DIRECTED_NETWORK ? (
70
+ <CircleLayout {...commonProps} />
71
+ ) : (
72
+ <HierarchyLayout {...commonProps} />
73
+ )}
74
+ <div className={styles.rightBottomControls}>
75
+ <ZoomSlider className={styles.zoomSlider} min={30} max={300} />
76
+ <GotoButton node={selectedNode} />
77
+ </div>
78
+ </>
79
+ </SigmaGraphContainer>
80
+ )
81
+ )}
82
+ </div>
83
+ </div>
84
+ );
85
+ };
86
+
87
+ export default withContext(
88
+ GraphStateContext,
89
+ ({
90
+ data,
91
+ graphologyGraph,
92
+ selectedEntity,
93
+ onEntitySelect,
94
+ onCollapseEntity,
95
+ onExpandEntity,
96
+ relationshipTable: {filters},
97
+ graphTypeUri,
98
+ layout,
99
+ setLayout
100
+ }) => ({
101
+ data,
102
+ graph: graphologyGraph,
103
+ selectedNode: selectedEntity?.uri,
104
+ onNodeSelect: onEntitySelect,
105
+ onNodeCollapse: onCollapseEntity,
106
+ onNodeExpand: onExpandEntity,
107
+ filters,
108
+ graphTypeUri,
109
+ layout,
110
+ setLayout
111
+ }),
112
+ GraphArea
113
+ );