@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,192 @@
1
+ import React from 'react';
2
+ import {mount} from 'enzyme';
3
+ import {EntityTypesSelector, RelationTypesSelector} from '@reltio/components';
4
+ import RelationshipsFiltersDialog from '../RelationshipsFiltersDialog';
5
+ import {GraphStateContext} from '../../../../../../contexts/GraphStateContext';
6
+ import {GraphState, Filters} from '../../../../../../types/graphDataTypes';
7
+ import Button from '@mui/material/Button';
8
+ import {act} from 'react-dom/test-utils';
9
+
10
+ jest.mock('@reltio/components', () => {
11
+ const originalModule = jest.requireActual('@reltio/components');
12
+ return {
13
+ ...originalModule,
14
+ EntityTypesSelector: () => null,
15
+ RelationTypesSelector: () => null
16
+ };
17
+ });
18
+
19
+ const onFilter = jest.fn() as (filters: Filters) => void;
20
+
21
+ const entityTypes = [
22
+ {
23
+ uri: 'configuration/entityTypes/HCP',
24
+ label: 'HCP',
25
+ extendsTypeURI: 'configuration/entityTypes/Individual',
26
+ abstract: false
27
+ },
28
+ {
29
+ uri: 'configuration/entityTypes/Individual',
30
+ label: 'Individual',
31
+ extendsTypeURI: 'configuration/entityTypes/Party',
32
+ abstract: false
33
+ }
34
+ ];
35
+
36
+ const relationTypes = [
37
+ {
38
+ uri: 'configuration/relationTypes/Family',
39
+ label: 'Family',
40
+ startObject: {
41
+ uri: 'configuration/relationTypes/Family/startObject',
42
+ objectTypeURI: 'configuration/entityTypes/Individual'
43
+ },
44
+ endObject: {
45
+ uri: 'configuration/relationTypes/Family/endObject',
46
+ objectTypeURI: 'configuration/entityTypes/Individual'
47
+ }
48
+ },
49
+ {
50
+ uri: 'configuration/relationTypes/HeadMatMgmnt',
51
+ label: 'Head of Materials Management',
52
+ startObject: {
53
+ uri: 'configuration/relationTypes/HeadMatMgmnt/startObject',
54
+ objectTypeURI: 'configuration/entityTypes/HCP'
55
+ },
56
+ endObject: {
57
+ uri: 'configuration/relationTypes/HeadMatMgmnt/endObject',
58
+ objectTypeURI: 'configuration/entityTypes/HCO'
59
+ }
60
+ }
61
+ ];
62
+
63
+ const setUp = ({
64
+ open = true,
65
+ graphTypeUri = null,
66
+ filters = {entityTypesUris: [], relationTypesUris: []},
67
+ onClose = jest.fn()
68
+ } = {}) =>
69
+ mount(
70
+ <GraphStateContext.Provider
71
+ value={
72
+ {
73
+ graphTypeUri,
74
+ relationshipTable: {
75
+ filters,
76
+ onFilter,
77
+ entityTypesOptions: entityTypes,
78
+ relationTypesOptions: relationTypes
79
+ }
80
+ } as GraphState
81
+ }
82
+ >
83
+ <RelationshipsFiltersDialog onClose={onClose} open={open} />
84
+ </GraphStateContext.Provider>
85
+ );
86
+
87
+ describe('RelationshipsFilterDialog tests', () => {
88
+ it('should render RelationTypesSelector with correctly relationTypes', () => {
89
+ const component = setUp();
90
+ expect(component.find(RelationTypesSelector).prop('relationTypes')).toEqual(relationTypes);
91
+ });
92
+
93
+ it('should render EntityTypesSelector with correctly entityTypes', () => {
94
+ const component = setUp();
95
+ expect(component.find(EntityTypesSelector).prop('entityTypes')).toEqual(entityTypes);
96
+ });
97
+
98
+ it('handleCancel handler should work correctly', () => {
99
+ const onClose = jest.fn();
100
+ const component = setUp({onClose});
101
+
102
+ expect(component.find(EntityTypesSelector).prop('selectedEntityTypes')).toEqual([]);
103
+ expect(component.find(RelationTypesSelector).prop('selectedRelationTypes')).toEqual([]);
104
+
105
+ act(() => {
106
+ component.find(EntityTypesSelector).prop('onChange')(['configuration/entityTypes/HCP']);
107
+ component.find(RelationTypesSelector).prop('onChange')(['configuration/relationTypes/Family']);
108
+ });
109
+
110
+ component.update();
111
+
112
+ expect(component.find(EntityTypesSelector).prop('selectedEntityTypes')).toEqual([
113
+ 'configuration/entityTypes/HCP'
114
+ ]);
115
+ expect(component.find(RelationTypesSelector).prop('selectedRelationTypes')).toEqual([
116
+ 'configuration/relationTypes/Family'
117
+ ]);
118
+
119
+ act(() => {
120
+ component.find('.footer').find(Button).at(1).prop('onClick')(null);
121
+ });
122
+
123
+ component.update();
124
+
125
+ expect(component.find(EntityTypesSelector).prop('selectedEntityTypes')).toEqual([]);
126
+ expect(component.find(RelationTypesSelector).prop('selectedRelationTypes')).toEqual([]);
127
+
128
+ expect(onClose).toHaveBeenCalled();
129
+ });
130
+
131
+ it('handleClear handler should work correctly', () => {
132
+ const onClose = jest.fn();
133
+ const component = setUp({onClose});
134
+
135
+ expect(component.find(EntityTypesSelector).prop('selectedEntityTypes')).toEqual([]);
136
+ expect(component.find(RelationTypesSelector).prop('selectedRelationTypes')).toEqual([]);
137
+
138
+ act(() => {
139
+ component.find(EntityTypesSelector).prop('onChange')(['configuration/entityTypes/HCP']);
140
+ component.find(RelationTypesSelector).prop('onChange')(['configuration/relationTypes/Family']);
141
+ });
142
+
143
+ component.update();
144
+
145
+ expect(component.find(EntityTypesSelector).prop('selectedEntityTypes')).toEqual([
146
+ 'configuration/entityTypes/HCP'
147
+ ]);
148
+ expect(component.find(RelationTypesSelector).prop('selectedRelationTypes')).toEqual([
149
+ 'configuration/relationTypes/Family'
150
+ ]);
151
+
152
+ act(() => {
153
+ component.find('.footer').find(Button).at(0).prop('onClick')(null);
154
+ });
155
+
156
+ component.update();
157
+
158
+ expect(component.find(EntityTypesSelector).prop('selectedEntityTypes')).toEqual([]);
159
+ expect(component.find(RelationTypesSelector).prop('selectedRelationTypes')).toEqual([]);
160
+ });
161
+
162
+ it('handleApply handler should work correctly', () => {
163
+ const onClose = jest.fn();
164
+ const component = setUp({onClose});
165
+
166
+ expect(component.find(EntityTypesSelector).prop('selectedEntityTypes')).toEqual([]);
167
+ expect(component.find(RelationTypesSelector).prop('selectedRelationTypes')).toEqual([]);
168
+
169
+ act(() => {
170
+ component.find(EntityTypesSelector).prop('onChange')(['configuration/entityTypes/HCP']);
171
+ component.find(RelationTypesSelector).prop('onChange')(['configuration/relationTypes/Family']);
172
+ });
173
+
174
+ component.update();
175
+
176
+ expect(component.find(EntityTypesSelector).prop('selectedEntityTypes')).toEqual([
177
+ 'configuration/entityTypes/HCP'
178
+ ]);
179
+ expect(component.find(RelationTypesSelector).prop('selectedRelationTypes')).toEqual([
180
+ 'configuration/relationTypes/Family'
181
+ ]);
182
+
183
+ act(() => {
184
+ component.find('.footer').find(Button).at(2).prop('onClick')(null);
185
+ });
186
+
187
+ expect(onFilter).toHaveBeenCalledWith({
188
+ entityTypesUris: ['configuration/entityTypes/HCP'],
189
+ relationTypesUris: ['configuration/relationTypes/Family']
190
+ });
191
+ });
192
+ });
@@ -0,0 +1,34 @@
1
+ import {makeStyles} from '@mui/styles';
2
+
3
+ export const useStyles = makeStyles((theme) => ({
4
+ dialogPaper: {
5
+ display: 'flex',
6
+ flexDirection: 'column',
7
+ padding: '12px 16px 8px'
8
+ },
9
+ title: {
10
+ marginBottom: '21px',
11
+ fontWeight: 500,
12
+ fontSize: '20px',
13
+ lineHeight: '23px',
14
+ letterSpacing: '0.25px',
15
+ color: theme.palette.text.primary
16
+ },
17
+ entityTypesSelector: {
18
+ width: '468px',
19
+ marginBottom: '20px'
20
+ },
21
+ relationTypesSelector: {
22
+ width: '468px',
23
+ marginBottom: '32px'
24
+ },
25
+ footer: {
26
+ display: 'flex'
27
+ },
28
+ clearAllButton: {
29
+ marginRight: 'auto'
30
+ },
31
+ cancelButton: {
32
+ marginRight: '8px'
33
+ }
34
+ }));
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import i18n from 'ui-i18n';
3
+ import {pipe, pick, prop} from 'ramda';
4
+ import {SearchInput, withContext} from '@reltio/components';
5
+ import {GraphStateContext} from '../../../../../contexts/GraphStateContext';
6
+ import {useStyles} from './styles';
7
+ import {RelationshipTableState} from '../../../../../types/graphDataTypes';
8
+
9
+ type Props = Partial<Pick<RelationshipTableState, 'searchText' | 'onChangeSearchText'>>;
10
+
11
+ const RelationshipsSearchTextField = ({searchText, onChangeSearchText}: Props) => {
12
+ const styles = useStyles();
13
+
14
+ return (
15
+ <SearchInput
16
+ fullWidth
17
+ height={40}
18
+ autofocus={false}
19
+ value={searchText}
20
+ onSearch={onChangeSearchText}
21
+ placeholder={i18n.text('Search profiles')}
22
+ classes={{input: styles.input}}
23
+ />
24
+ );
25
+ };
26
+
27
+ export default withContext(
28
+ GraphStateContext,
29
+ pipe(prop('relationshipTable'), pick(['searchText', 'onChangeSearchText'])),
30
+ RelationshipsSearchTextField
31
+ );
@@ -0,0 +1,43 @@
1
+ import React from 'react';
2
+ import {mount} from 'enzyme';
3
+ import {SearchInput} from '@reltio/components';
4
+ import RelationshipsSearchTextField from '../RelationshipsSearchTextField';
5
+ import {GraphStateContext} from '../../../../../../contexts/GraphStateContext';
6
+ import {GraphState} from '../../../../../../types/graphDataTypes';
7
+ import {act} from 'react-dom/test-utils';
8
+
9
+ const onChangeSearchText = jest.fn();
10
+
11
+ const setUp = ({searchText = ''} = {}) =>
12
+ mount(
13
+ <GraphStateContext.Provider
14
+ value={
15
+ {
16
+ relationshipTable: {
17
+ searchText,
18
+ onChangeSearchText: onChangeSearchText as (value: string) => void
19
+ }
20
+ } as GraphState
21
+ }
22
+ >
23
+ <RelationshipsSearchTextField />
24
+ </GraphStateContext.Provider>
25
+ );
26
+
27
+ describe('RelationshipsSearchTextField tests', () => {
28
+ it('should pass searchText correctly', () => {
29
+ const searchText = 'some value';
30
+ const component = setUp({searchText});
31
+ expect(component.find(SearchInput).prop('value')).toBe(searchText);
32
+ });
33
+
34
+ it('onChangeTextFilter handler should work correctly', () => {
35
+ const component = setUp();
36
+
37
+ act(() => {
38
+ component.find(SearchInput).prop('onSearch')('changed value');
39
+ });
40
+
41
+ expect(onChangeSearchText).toHaveBeenCalledWith('changed value');
42
+ });
43
+ });
@@ -0,0 +1,17 @@
1
+ import {makeStyles} from '@mui/styles';
2
+
3
+ export const useStyles = makeStyles((theme) => ({
4
+ inactiveSearchIcon: {
5
+ color: theme.palette.text.secondary
6
+ },
7
+ activeSearchIcon: {
8
+ color: theme.palette.text.primary
9
+ },
10
+ input: {
11
+ fontSize: '14px',
12
+ '&::placeholder': {
13
+ color: `${theme.palette.text.secondary} !important`,
14
+ opacity: 1
15
+ }
16
+ }
17
+ }));
@@ -0,0 +1,76 @@
1
+ import React from 'react';
2
+ import {mount} from 'enzyme';
3
+ import {EmptyStub} from '@reltio/components';
4
+ import IconButton from '@mui/material/IconButton';
5
+ import FilterListIcon from '@mui/icons-material/FilterList';
6
+ import RelationshipsFilters from '../RelationshipsFilters';
7
+ import {GraphStateContext} from '../../../../../contexts/GraphStateContext';
8
+ import {GraphState} from '../../../../../types/graphDataTypes';
9
+ import RelationshipsFiltersDialog from '../RelationshipsFiltersDialog/RelationshipsFiltersDialog';
10
+ import RelationshipsSearchTextField from '../RelationshipsSearchTextField/RelationshipsSearchTextField';
11
+ import {act} from 'react-dom/test-utils';
12
+
13
+ jest.mock('../RelationshipsFiltersDialog/RelationshipsFiltersDialog', () => jest.fn());
14
+ jest.mock('../RelationshipsSearchTextField/RelationshipsSearchTextField', () => jest.fn());
15
+ jest.mock('@mui/icons-material/FilterList', () => jest.fn());
16
+
17
+ const setUp = ({filters = {entityTypesUris: [], relationTypesUris: []}} = {}) =>
18
+ mount(
19
+ <GraphStateContext.Provider
20
+ value={
21
+ {
22
+ relationshipTable: {
23
+ filters
24
+ }
25
+ } as GraphState
26
+ }
27
+ >
28
+ <RelationshipsFilters />
29
+ </GraphStateContext.Provider>
30
+ );
31
+
32
+ describe('Relationships tests', () => {
33
+ beforeAll(() => {
34
+ ((RelationshipsFiltersDialog as unknown) as jest.Mock).mockImplementation(EmptyStub);
35
+ ((RelationshipsSearchTextField as unknown) as jest.Mock).mockImplementation(EmptyStub);
36
+ ((FilterListIcon as unknown) as jest.Mock).mockImplementation(EmptyStub);
37
+ });
38
+
39
+ it('should render main parts correctly', () => {
40
+ const component = setUp();
41
+ expect(component.find(RelationshipsFiltersDialog)).toHaveLength(1);
42
+ expect(component.find(RelationshipsSearchTextField)).toHaveLength(1);
43
+ expect(component.find(IconButton)).toHaveLength(1);
44
+ });
45
+
46
+ it('should apply correct className for FilterListIcon if has applied filters', () => {
47
+ const component = setUp({filters: {entityTypesUris: ['configuration/entityTypes/HCP'], relationTypesUris: []}});
48
+ expect(component.find(FilterListIcon).prop('className')).toBe('activeFiltersIcon');
49
+ });
50
+
51
+ it('should apply correct className for FilterListIcon if has not applied filters', () => {
52
+ const component = setUp();
53
+ expect(component.find(FilterListIcon).prop('className')).toBe('inactiveFiltersIcon');
54
+ });
55
+
56
+ it('handleOpenDialog and handleCloseDialog handlers should work correctly', () => {
57
+ const component = setUp();
58
+ expect(component.find(RelationshipsFiltersDialog).prop('open')).toBe(false);
59
+
60
+ act(() => {
61
+ component.find(IconButton).prop('onClick')(null);
62
+ });
63
+
64
+ component.update();
65
+
66
+ expect(component.find(RelationshipsFiltersDialog).prop('open')).toBe(true);
67
+
68
+ act(() => {
69
+ component.find(RelationshipsFiltersDialog).prop('onClose')();
70
+ });
71
+
72
+ component.update();
73
+
74
+ expect(component.find(RelationshipsFiltersDialog).prop('open')).toBe(false);
75
+ });
76
+ });
@@ -0,0 +1,19 @@
1
+ import {makeStyles} from '@mui/styles';
2
+
3
+ export const useStyles = makeStyles((theme) => ({
4
+ wrapper: {
5
+ display: 'flex',
6
+ alignItems: 'center',
7
+ paddingLeft: '16px',
8
+ paddingRight: '2px'
9
+ },
10
+ iconButton: {
11
+ marginLeft: '4px'
12
+ },
13
+ activeFiltersIcon: {
14
+ color: theme.palette.primary.main
15
+ },
16
+ inactiveFiltersIcon: {
17
+ color: theme.palette.text.secondary
18
+ }
19
+ }));
@@ -0,0 +1,20 @@
1
+ import {makeStyles} from '@mui/styles';
2
+
3
+ export const useStyles = makeStyles({
4
+ caption: {
5
+ marginLeft: '16px',
6
+ marginTop: '12px',
7
+ display: 'flex',
8
+ justifyContent: 'space-between',
9
+ alignItems: 'center',
10
+ marginBottom: '14px',
11
+ fontSize: '16px',
12
+ lineHeight: '24px'
13
+ },
14
+ wrapper: {
15
+ flex: 1,
16
+ display: 'flex',
17
+ flexDirection: 'column',
18
+ height: 0
19
+ }
20
+ });
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import {useSigmaCustomRenderers} from '../../hooks/useSigmaCustomRenderers';
3
+ import {SigmaCustomRenderersContext} from '../../contexts/SigmaCustomRenderersContext';
4
+
5
+ type Props = {
6
+ children: React.ReactNode;
7
+ };
8
+
9
+ export const SigmaCustomRenderersContainer = ({children}: Props) => {
10
+ const sigmaCustomRenderers = useSigmaCustomRenderers();
11
+ return (
12
+ <SigmaCustomRenderersContext.Provider value={sigmaCustomRenderers}>
13
+ {children}
14
+ </SigmaCustomRenderersContext.Provider>
15
+ );
16
+ };
@@ -0,0 +1,55 @@
1
+ import React, {useMemo} from 'react';
2
+ import {MultiGraph} from 'graphology';
3
+ import {SigmaContainer} from '@react-sigma/core';
4
+ import '@react-sigma/core/lib/react-sigma.min.css';
5
+ import {createNodeCompoundProgram} from 'sigma/rendering/webgl/programs/common/node';
6
+ import {createEdgeCompoundProgram} from 'sigma/rendering/webgl/programs/common/edge';
7
+ import LineEdgeProgram from 'sigma/rendering/webgl/programs/edge';
8
+ import {SigmaCustomRenderersContainer} from '../SigmaCustomRenderers/SigmaCustomRenderersContainer';
9
+ import {drawHover} from '../../rendering/canvas/hover';
10
+ import {drawLabel} from '../../rendering/canvas/label';
11
+ import NodeProgramBorder from '../../rendering/webgl/node.border';
12
+ import NodeImageProgram from '../../rendering/webgl/node.image';
13
+ import NodeButtonsProgram from '../../rendering/webgl/node.buttons';
14
+ import EdgeArrowHeadProgram from '../../rendering/webgl/edge.arrowHead';
15
+ import EdgeReversedArrowHeadProgram from '../../rendering/webgl/edge.reversedArrowHead';
16
+ import EdgeClampedProgram from '../../rendering/webgl/edge.clamped';
17
+
18
+ type Props = {
19
+ children: React.ReactElement;
20
+ };
21
+
22
+ export const SigmaGraphContainer = ({children}: Props) => {
23
+ const initialSettings = useMemo(
24
+ () => ({
25
+ allowInvalidContainer: true,
26
+ defaultNodeType: 'image',
27
+ hoverRenderer: drawHover,
28
+ labelRenderer: drawLabel,
29
+ nodeProgramClasses: {
30
+ image: createNodeCompoundProgram([NodeImageProgram, NodeProgramBorder, NodeButtonsProgram])
31
+ },
32
+ edgeProgramClasses: {
33
+ line: LineEdgeProgram,
34
+ arrow: createEdgeCompoundProgram([EdgeClampedProgram, EdgeArrowHeadProgram]),
35
+ doubleArrow: createEdgeCompoundProgram([
36
+ EdgeClampedProgram,
37
+ EdgeArrowHeadProgram,
38
+ EdgeReversedArrowHeadProgram
39
+ ])
40
+ },
41
+ labelFont: 'Roboto',
42
+ labelSize: 13,
43
+ labelColor: {
44
+ color: 'rgba(0, 0, 0, 0.87)'
45
+ }
46
+ }),
47
+ []
48
+ );
49
+
50
+ return (
51
+ <SigmaContainer graph={MultiGraph} style={{background: 'transparent'}} settings={initialSettings}>
52
+ <SigmaCustomRenderersContainer>{children}</SigmaCustomRenderersContainer>
53
+ </SigmaContainer>
54
+ );
55
+ };
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import {shallow} from 'enzyme';
3
+ import {SigmaContainer} from '@react-sigma/core';
4
+ import {MultiGraph} from 'graphology';
5
+ import {SigmaGraphContainer} from '../SigmaGraphContainer';
6
+ import {SigmaCustomRenderersContainer} from '../../SigmaCustomRenderers/SigmaCustomRenderersContainer';
7
+
8
+ const children = <div className="children">children</div>;
9
+
10
+ const setUp = () => shallow(<SigmaGraphContainer>{children}</SigmaGraphContainer>);
11
+
12
+ describe('SigmaGraphContainer behavior', () => {
13
+ it('should render SigmaContainer with passed children', () => {
14
+ const component = setUp();
15
+ expect(component.find(SigmaContainer)).toHaveLength(1);
16
+ expect(component.find(SigmaContainer).prop('graph')).toBe(MultiGraph);
17
+ expect(component.find(SigmaContainer).find(SigmaCustomRenderersContainer).prop('children')).toBe(children);
18
+ });
19
+
20
+ it('should render SigmaContainer with initialSettings', () => {
21
+ const component = setUp();
22
+ expect(component.find(SigmaContainer)).toHaveLength(1);
23
+ expect(component.find(SigmaContainer).prop('settings')).not.toBeUndefined();
24
+ });
25
+ });
@@ -0,0 +1,13 @@
1
+ import React, {useCallback} from 'react';
2
+ import ReactResizeDetector from 'react-resize-detector';
3
+ import {useSigma} from '@react-sigma/core';
4
+
5
+ const SigmaGraphResizer = () => {
6
+ const sigma = useSigma();
7
+ const onResize = useCallback(() => {
8
+ sigma.refresh();
9
+ }, [sigma]);
10
+ return <ReactResizeDetector handleWidth onResize={onResize} />;
11
+ };
12
+
13
+ export default SigmaGraphResizer;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import {shallow} from 'enzyme';
3
+ import ReactResizeDetector from 'react-resize-detector';
4
+ import {useSigma} from '@react-sigma/core';
5
+ import SigmaGraphResizer from '../SigmaGraphResizer';
6
+
7
+ jest.mock('@react-sigma/core', () => ({
8
+ ...jest.requireActual<Record<string, unknown>>('@react-sigma/core'),
9
+ useSigma: jest.fn().mockReturnValue({
10
+ refresh: jest.fn()
11
+ })
12
+ }));
13
+
14
+ const setUp = () => shallow(<SigmaGraphResizer />);
15
+
16
+ describe('SigmaGraphResizer behavior', () => {
17
+ it('should render ReactResizeDetector', () => {
18
+ const component = setUp();
19
+ expect(component.find(ReactResizeDetector)).toHaveLength(1);
20
+ });
21
+
22
+ it('should refresh sigma instance on resize', () => {
23
+ const component = setUp();
24
+ expect(useSigma().refresh).not.toHaveBeenCalled();
25
+ (component.find(ReactResizeDetector).prop('onResize') as () => void)();
26
+ expect(useSigma().refresh).toHaveBeenCalled();
27
+ });
28
+ });
@@ -0,0 +1,33 @@
1
+ import React, {useContext, useMemo} from 'react';
2
+ import {ReactReduxContext, useSelector} from 'react-redux';
3
+ import {propEq} from 'ramda';
4
+ import {Entity, getGraphTypesForEntityType, ProfileViewTypes} from '@reltio/mdm-sdk';
5
+ import mdmModule from '@reltio/mdm-module';
6
+ import {HierarchyTreeView} from '@reltio/hierarchy-tree';
7
+ import {useStyles} from './styles';
8
+
9
+ type Props = {
10
+ graphTypeUri: string;
11
+ };
12
+
13
+ const TreeLayout = ({graphTypeUri}: Props) => {
14
+ const styles = useStyles();
15
+ const {store} = useContext(ReactReduxContext);
16
+ const metadata = useSelector(mdmModule.selectors.getMetadata);
17
+ const entity: Entity = useSelector(mdmModule.selectors.getEntity);
18
+ const caption = getGraphTypesForEntityType(metadata, entity.type).find(propEq('uri', graphTypeUri))?.label;
19
+ const config = useMemo(
20
+ () => ({
21
+ id: '___graphView___',
22
+ class: ProfileViewTypes.HierarchyTree,
23
+ graph: {
24
+ type: graphTypeUri
25
+ },
26
+ caption
27
+ }),
28
+ [caption, graphTypeUri]
29
+ );
30
+ return <HierarchyTreeView config={config} store={store} className={styles.hierarchyTree} isGraphView={true} />;
31
+ };
32
+
33
+ export default TreeLayout;
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import {shallow} from 'enzyme';
3
+ import * as reactRedux from 'react-redux';
4
+ import {HierarchyTreeView} from '@reltio/hierarchy-tree';
5
+ import TreeLayout from '../TreeLayout';
6
+ import {ProfileViewTypes} from '@reltio/mdm-sdk';
7
+
8
+ const store = {};
9
+ const graphTypeUri = 'graphTypeUri';
10
+ const label = 'graph type label';
11
+
12
+ jest.mock('react', () => ({
13
+ ...jest.requireActual<Record<string, unknown>>('react'),
14
+ useContext: () => ({
15
+ store
16
+ })
17
+ }));
18
+
19
+ jest.mock('@reltio/mdm-sdk', () => ({
20
+ ...jest.requireActual<Record<string, unknown>>('@reltio/mdm-sdk'),
21
+ getGraphTypesForEntityType: jest.fn().mockReturnValue([{uri: 'graphTypeUri', label}])
22
+ }));
23
+
24
+ describe('TreeLayout tests', () => {
25
+ it('should render HierarchyTreeView', () => {
26
+ jest.spyOn(reactRedux, 'useSelector').mockReturnValue({});
27
+ const config = {
28
+ id: '___graphView___',
29
+ class: ProfileViewTypes.HierarchyTree,
30
+ graph: {
31
+ type: graphTypeUri
32
+ },
33
+ caption: label
34
+ };
35
+ const treeLayoutComponent = shallow(<TreeLayout graphTypeUri={graphTypeUri} />);
36
+ const hierarchyTreeViewComponent = treeLayoutComponent.find(HierarchyTreeView);
37
+ expect(hierarchyTreeViewComponent).toHaveLength(1);
38
+ expect(hierarchyTreeViewComponent.prop('config')).toEqual(config);
39
+ expect(hierarchyTreeViewComponent.prop('store')).toEqual(store);
40
+ expect(hierarchyTreeViewComponent.prop('isGraphView')).toBeTruthy();
41
+ });
42
+ });
@@ -0,0 +1,10 @@
1
+ import {makeStyles} from '@mui/styles';
2
+
3
+ export const useStyles = makeStyles({
4
+ hierarchyTree: {
5
+ position: 'relative',
6
+ width: 'calc(100% - 190px)',
7
+ margin: '80px 95px 0',
8
+ height: 'calc(100% - 100px)'
9
+ }
10
+ });