@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.
- package/index.ts +1 -0
- package/package.json +26 -9
- package/public/bundle.js +205 -0
- package/public/bundle.js.LICENSE.txt +88 -0
- package/public/package.json +29 -0
- package/scripts/build/index.js +20 -0
- package/src/__tests__/GraphView.test.tsx +25 -0
- package/src/components/CircleLayout/CircleLayout.tsx +76 -0
- package/src/components/CircleLayout/__tests__/CircleLayout.test.tsx +194 -0
- package/src/components/GotoButton/GotoButton.tsx +23 -0
- package/src/components/GotoButton/__tests__/GotoButton.test.tsx +33 -0
- package/src/components/GotoButton/styles.ts +15 -0
- package/src/components/GraphArea/GraphArea.tsx +113 -0
- package/src/components/GraphArea/__tests__/GraphArea.test.tsx +202 -0
- package/src/components/GraphArea/styles.ts +30 -0
- package/src/components/GraphLayoutSelector/GraphLayoutSelector.tsx +43 -0
- package/src/components/GraphLayoutSelector/__tests__/GraphLayoutSelector.spec.tsx +44 -0
- package/src/components/GraphLayoutSelector/styles.ts +15 -0
- package/src/components/GraphPerspectiveView/GraphPerspectiveView.tsx +58 -0
- package/src/components/GraphPerspectiveView/__tests__/GraphPerspectiveView.test.tsx +115 -0
- package/src/components/GraphPerspectiveView/__tests__/useGraphLoader.test.tsx +1519 -0
- package/src/components/GraphPerspectiveView/__tests__/useRelationshipTable.test.tsx +1003 -0
- package/src/components/GraphPerspectiveView/__tests__/useSelectedEntity.test.tsx +373 -0
- package/src/components/GraphPerspectiveView/styles.ts +34 -0
- package/src/components/GraphRightSidePanel/GraphRightSidePanel.tsx +27 -0
- package/src/components/GraphRightSidePanel/__tests__/GraphRightSidePanel.test.tsx +18 -0
- package/src/components/GraphRightSidePanel/icons/relationship-icon.svg +3 -0
- package/src/components/GraphRightSidePanel/styles.ts +8 -0
- package/src/components/GraphTypeSelector/GraphTypeSelector.tsx +56 -0
- package/src/components/GraphTypeSelector/__tests__/GraphTypeSelector.test.tsx +109 -0
- package/src/components/GraphTypeSelector/styles.ts +17 -0
- package/src/components/HierarchyLayout/HierarchyLayout.ts +102 -0
- package/src/components/HierarchyLayout/__tests__/HierarchyLayout.spec.tsx +241 -0
- package/src/components/HierarchyLayout/__tests__/buildHierarchy.spec.ts +130 -0
- package/src/components/HierarchyLayout/__tests__/calculations.spec.ts +230 -0
- package/src/components/HierarchyLayout/buildHierarchy.ts +109 -0
- package/src/components/HierarchyLayout/calculations.ts +86 -0
- package/src/components/RightPanelEntityDetails/RightPanelEntityDetails.tsx +33 -0
- package/src/components/RightPanelEntityDetails/__tests__/RightPanelEntityDetails.test.tsx +39 -0
- package/src/components/RightPanelEntityDetails/styles.ts +12 -0
- package/src/components/RightPanelProfileBand/RightPanelProfileBand.tsx +33 -0
- package/src/components/RightPanelProfileBand/__tests__/RightPanelProfileBand.test.tsx +67 -0
- package/src/components/RightPanelProfileBand/styles.ts +8 -0
- package/src/components/RightPanelRelationship/RightPanelRelationship.tsx +25 -0
- package/src/components/RightPanelRelationship/__tests__/RightPanelRelationship.test.tsx +18 -0
- package/src/components/RightPanelRelationship/components/CollapsibleTable/CollapsibleTable.tsx +100 -0
- package/src/components/RightPanelRelationship/components/CollapsibleTable/TableHead.tsx +38 -0
- package/src/components/RightPanelRelationship/components/CollapsibleTable/__tests__/CollapsibleTable.test.tsx +169 -0
- package/src/components/RightPanelRelationship/components/CollapsibleTable/__tests__/TableHead.test.tsx +107 -0
- package/src/components/RightPanelRelationship/components/CollapsibleTable/styles.ts +38 -0
- package/src/components/RightPanelRelationship/components/CollapsibleTable/types.ts +20 -0
- package/src/components/RightPanelRelationship/components/DeleteRelationDialog/DeleteRelationDialog.tsx +34 -0
- package/src/components/RightPanelRelationship/components/DeleteRelationDialog/__tests__/DeleteRelationDialog.test.tsx +46 -0
- package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/GraphAddRelationButton.tsx +43 -0
- package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/GraphAddRelationDialog.tsx +121 -0
- package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/__tests__/GraphAddRelationButton.test.tsx +80 -0
- package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/__tests__/GraphAddRelationDialog.test.tsx +262 -0
- package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/__tests__/mockdata.ts +75 -0
- package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/styles.ts +25 -0
- package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/useCreatableInOutRelationTypes.ts +13 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/RelationshipTable.tsx +126 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/__tests__/RelationshipTable.test.tsx +176 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/ControlsCellRenderer.tsx +59 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/DefaultCellRenderer.tsx +29 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/ExpandedRowRenderer.tsx +94 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/HeadCellRenderer.tsx +34 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/ProfileCellRenderer.tsx +41 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/ControlsCellRenderer.test.tsx +80 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/DefaultCellRenderer.test.tsx +47 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/ExpandedRowRenderer.test.tsx +166 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/HeadCellRenderer.test.tsx +23 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/ProfileCellRenderer.test.tsx +47 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/components/DeleteRelationButton.tsx +32 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/components/__tests__/DeleteRelationButton.test.tsx +28 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/styles.ts +113 -0
- package/src/components/RightPanelRelationship/components/RelationshipTable/styles.ts +36 -0
- package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFilters.tsx +41 -0
- package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFiltersDialog/RelationshipsFiltersDialog.tsx +91 -0
- package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFiltersDialog/__tests__/RelationshipsFilterDialog.test.tsx +192 -0
- package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFiltersDialog/styles.ts +34 -0
- package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsSearchTextField/RelationshipsSearchTextField.tsx +31 -0
- package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsSearchTextField/__tests__/RelationshipsSearchTextField.test.tsx +43 -0
- package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsSearchTextField/styles.ts +17 -0
- package/src/components/RightPanelRelationship/components/RelationshipsFilters/__tests__/RelationshipsFilters.test.tsx +76 -0
- package/src/components/RightPanelRelationship/components/RelationshipsFilters/styles.ts +19 -0
- package/src/components/RightPanelRelationship/styles.ts +20 -0
- package/src/components/SigmaCustomRenderers/SigmaCustomRenderersContainer.tsx +16 -0
- package/src/components/SigmaGraphContainer/SigmaGraphContainer.tsx +55 -0
- package/src/components/SigmaGraphContainer/__tests__/SigmaGraphContainer.test.tsx +25 -0
- package/src/components/SigmaGraphResizer/SigmaGraphResizer.tsx +13 -0
- package/src/components/SigmaGraphResizer/__tests__/SigmaGraphResizer.test.tsx +28 -0
- package/src/components/TreeLayout/TreeLayout.tsx +33 -0
- package/src/components/TreeLayout/__tests__/TreeLayout.test.tsx +42 -0
- package/src/components/TreeLayout/styles.ts +10 -0
- package/src/components/ZoomSlider/ZoomSlider.tsx +90 -0
- package/src/components/ZoomSlider/__tests__/ZoomSlider.test.tsx +84 -0
- package/src/components/ZoomSlider/styles.ts +57 -0
- package/src/constants/index.ts +1 -0
- package/src/contexts/GraphStateContext.tsx +19 -0
- package/src/contexts/SigmaCustomRenderersContext.ts +20 -0
- package/src/helpers/relationsHelpers.ts +9 -0
- package/src/hooks/__tests__/useGraphLayout.test.tsx +825 -0
- package/src/hooks/__tests__/useGraphLayoutSelector.test.tsx +19 -0
- package/src/hooks/__tests__/useSelfRelationLoopsRenderer.test.ts +198 -0
- package/src/hooks/__tests__/useSigmaCustomRenderers.test.ts +273 -0
- package/src/hooks/__tests__/useTooltipRenderer.test.ts +289 -0
- package/src/hooks/useGraphLayout.ts +308 -0
- package/src/hooks/useGraphLayoutSelector.ts +19 -0
- package/src/hooks/useGraphLoader.ts +279 -0
- package/src/hooks/useGraphRightSidePanelElements.tsx +36 -0
- package/src/hooks/useGraphState.ts +40 -0
- package/src/hooks/useGraphType.ts +32 -0
- package/src/hooks/useRelationshipTable.ts +212 -0
- package/src/hooks/useRelationshipTableFilters.ts +43 -0
- package/src/hooks/useSelectedEntity.ts +89 -0
- package/src/hooks/useSelfRelationLoopsRenderer.ts +52 -0
- package/src/hooks/useSigmaCustomRenderers.ts +112 -0
- package/src/hooks/useTooltipRenderer.ts +80 -0
- package/src/index.tsx +37 -0
- package/src/rendering/canvas/__tests__/hover.spec.ts +31 -0
- package/src/rendering/canvas/__tests__/label.spec.ts +64 -0
- package/src/rendering/canvas/__tests__/nodeBackground.spec.ts +99 -0
- package/src/rendering/canvas/__tests__/selfRelationLoop.spec.ts +88 -0
- package/src/rendering/canvas/__tests__/tooltip.spec.ts +33 -0
- package/src/rendering/canvas/hover.ts +13 -0
- package/src/rendering/canvas/label.ts +33 -0
- package/src/rendering/canvas/nodeBackground.ts +61 -0
- package/src/rendering/canvas/selfRelationLoop.ts +108 -0
- package/src/rendering/canvas/tooltip.ts +38 -0
- package/src/rendering/icons/collapseIcon.inline.svg.ts +6 -0
- package/src/rendering/icons/expandIcon.inline.svg.ts +5 -0
- package/src/rendering/icons/no_photo.inline.svg.ts +13 -0
- package/src/rendering/webgl/edge.arrowHead.ts +87 -0
- package/src/rendering/webgl/edge.clamped.ts +246 -0
- package/src/rendering/webgl/edge.reversedArrowHead.ts +14 -0
- package/src/rendering/webgl/helpers/__tests__/imageHelper.spec.ts +36 -0
- package/src/rendering/webgl/helpers/imageHelper.ts +13 -0
- package/src/rendering/webgl/image.ts +115 -0
- package/src/rendering/webgl/node.border.ts +78 -0
- package/src/rendering/webgl/node.buttons.ts +241 -0
- package/src/rendering/webgl/node.image.ts +169 -0
- package/src/rendering/webgl/shaders/edge.clamped.vert.glsl.ts +55 -0
- package/src/rendering/webgl/shaders/node.border.frag.glsl.ts +30 -0
- package/src/rendering/webgl/shaders/node.border.vert.glsl.ts +37 -0
- package/src/rendering/webgl/shaders/node.buttons.frag.glsl.ts +32 -0
- package/src/rendering/webgl/shaders/node.buttons.vert.glsl.ts +49 -0
- package/src/rendering/webgl/shaders/node.image.frag.glsl.ts +46 -0
- package/src/rendering/webgl/shaders/node.image.vert.glsl.ts +42 -0
- package/src/types/graphDataTypes.ts +143 -0
- package/src/types/sigmaCustomRenderersTypes.ts +13 -0
- package/src/utils/__tests__/graph.spec.ts +152 -0
- package/src/utils/__tests__/graphLayout.spec.ts +125 -0
- package/src/utils/__tests__/hopsData.spec.ts +456 -0
- package/src/utils/__tests__/processResponceToGraph.spec.ts +165 -0
- package/src/utils/graph.ts +83 -0
- package/src/utils/graphLayout.ts +70 -0
- package/src/utils/hopsData.ts +198 -0
- package/src/utils/processResponseToGraph.ts +32 -0
- package/tsconfig.json +4 -0
- package/webpack.config.js +10 -0
- package/bundle.js +0 -2
- package/bundle.js.LICENSE.txt +0 -54
- /package/{5271a9e7b6651c852e93.png → public/5271a9e7b6651c852e93.png} +0 -0
- /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
|
+
);
|