@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,47 @@
1
+ import React from 'react';
2
+ import {ReactWrapper, shallow} from 'enzyme';
3
+ import {ExpandedValueTooltip} from '@reltio/components';
4
+
5
+ import DefaultCellRenderer from '../DefaultCellRenderer';
6
+
7
+ describe('DefaultCellRenderer tests', () => {
8
+ it('should render main parts', () => {
9
+ const wrapper = shallow(<DefaultCellRenderer />);
10
+ const cell = wrapper.find(ExpandedValueTooltip);
11
+ expect(cell).toHaveLength(1);
12
+ expect(cell.prop('value')).toEqual('');
13
+ expect(new ReactWrapper(cell.prop('children')).text()).toBe('');
14
+ });
15
+
16
+ it('should render correct value', () => {
17
+ const value = 'Test';
18
+ const wrapper = shallow(<DefaultCellRenderer value={value} />);
19
+ const expandedValueTooltip = wrapper.find(ExpandedValueTooltip);
20
+ expect(expandedValueTooltip).toHaveLength(1);
21
+ expect(expandedValueTooltip.prop('value')).toEqual(value);
22
+ const cell = expandedValueTooltip.find('.defaultCell');
23
+ expect(cell.text()).toBe(value);
24
+ expect(cell.hasClass('clickable')).toBe(false);
25
+ expect(cell.prop('onClick')).toBeUndefined();
26
+ });
27
+
28
+ it('should support onClick', () => {
29
+ const value = 'Test';
30
+ const onClick = jest.fn();
31
+ const wrapper = shallow(<DefaultCellRenderer value={value} onClick={onClick} />);
32
+ const cell = wrapper.find(ExpandedValueTooltip).find('.defaultCell');
33
+ expect(cell.text()).toBe(value);
34
+ expect(cell.hasClass('clickable')).toBe(true);
35
+ expect(cell.prop('onClick')).toBe(onClick);
36
+ });
37
+
38
+ it('should support tooltip prop', () => {
39
+ const value = 'Test';
40
+ const tooltip = 'Tooltip';
41
+ const wrapper = shallow(<DefaultCellRenderer value={value} tooltip={tooltip} />);
42
+ const expandedValueTooltip = wrapper.find(ExpandedValueTooltip);
43
+ expect(expandedValueTooltip).toHaveLength(1);
44
+ expect(expandedValueTooltip.prop('value')).toEqual(tooltip);
45
+ expect(expandedValueTooltip.find('.defaultCell').text()).toBe(value);
46
+ });
47
+ });
@@ -0,0 +1,166 @@
1
+ import {mount} from 'enzyme';
2
+ import ExpandedRowRenderer from '../ExpandedRowRenderer';
3
+ import React from 'react';
4
+ import {ConnectionEditor} from '@reltio/components';
5
+ import Button from '@mui/material/Button';
6
+ import {GraphStateContext} from '../../../../../../contexts/GraphStateContext';
7
+ import {GraphState, RelationshipTableState} from '../../../../../../types/graphDataTypes';
8
+ import * as reactRedux from 'react-redux';
9
+
10
+ jest.mock('@reltio/components', () => ({
11
+ ...jest.requireActual<Record<string, unknown>>('@reltio/components'),
12
+ useEditableConnection: jest.fn().mockImplementation(({onConnectionChange}) => ({
13
+ onChangeAttribute: (attribute) => onConnectionChange({relation: {type: 'onChange', payload: attribute}}),
14
+ onAddAttributes: (attributes) => onConnectionChange({relation: {type: 'onAdd', payload: attributes}}),
15
+ onRemoveAttribute: (attribute) => onConnectionChange({relation: {type: 'onRemove', payload: attribute}})
16
+ })),
17
+ ConnectionEditor: () => null
18
+ }));
19
+
20
+ const relation = {
21
+ attributes: {
22
+ FirstName: [
23
+ {
24
+ type: 'configuration/entityTypes/HCP/attributes/FirstName',
25
+ ov: true,
26
+ value: 'HCP_5',
27
+ uri: 'entities/19oYeyx1/attributes/FirstName/1dg2njmxf'
28
+ }
29
+ ]
30
+ },
31
+ uri: 'relation/uri',
32
+ type: 'configuration/relationTypes/HCPtoHCA',
33
+ startDate: 123
34
+ };
35
+
36
+ const props = {
37
+ open: true,
38
+ rowValue: {
39
+ relation: {
40
+ uri: 'relation/uri',
41
+ type: 'configuration/relationTypes/HCPtoHCA'
42
+ },
43
+ entity: {uri: 'entity', label: 'label', type: 'HCP'},
44
+ entityLabel: '',
45
+ entityTypeLabel: '',
46
+ relationTypeLabel: ''
47
+ }
48
+ };
49
+
50
+ const relationshipTable: RelationshipTableState = {
51
+ onSaveEditingRelation: jest.fn(),
52
+ onCancelRelationEditing: jest.fn(),
53
+ onUpdateEditingRelation: jest.fn(),
54
+ editingRelations: [
55
+ {
56
+ initialRelation: relation,
57
+ relation
58
+ }
59
+ ]
60
+ };
61
+
62
+ const store = {
63
+ metadata: {
64
+ t1: {
65
+ relationTypes: [
66
+ {
67
+ uri: 'configuration/relationTypes/HCPtoHCA'
68
+ }
69
+ ]
70
+ }
71
+ },
72
+ tenant: {id: 't1'}
73
+ };
74
+
75
+ const setUp = () =>
76
+ mount(
77
+ <GraphStateContext.Provider value={{relationshipTable} as GraphState}>
78
+ <ExpandedRowRenderer {...props} />
79
+ </GraphStateContext.Provider>
80
+ );
81
+
82
+ describe('ExpandedRowRenderer tests', () => {
83
+ beforeAll(() => {
84
+ jest.spyOn(reactRedux, 'useSelector').mockImplementation((selector) => selector(store));
85
+ jest.spyOn(reactRedux, 'useDispatch').mockReturnValue(jest.fn());
86
+ });
87
+ it('should render ConnectionEditor', () => {
88
+ const component = setUp();
89
+ const payloadItem = {
90
+ parentUri: 'relations/8908',
91
+ attributeType: {
92
+ label: 'Role',
93
+ name: 'Role',
94
+ type: 'String',
95
+ uri: 'configuration/relationTypes/knowledge/attributes/Role'
96
+ },
97
+ index: 0
98
+ };
99
+ expect(component.find(ConnectionEditor)).toHaveLength(1);
100
+ expect(component.find(ConnectionEditor).prop('connection')).toEqual({
101
+ relation: relationshipTable.editingRelations[0].relation
102
+ });
103
+ component.find(ConnectionEditor).prop('onAddAttributes')([payloadItem, payloadItem]);
104
+ expect(relationshipTable.onUpdateEditingRelation).toHaveBeenCalledWith({
105
+ type: 'onAdd',
106
+ payload: [payloadItem, payloadItem]
107
+ });
108
+ component.find(ConnectionEditor).prop('onChangeAttribute')(payloadItem);
109
+ expect(relationshipTable.onUpdateEditingRelation).toHaveBeenCalledWith({
110
+ type: 'onChange',
111
+ payload: payloadItem
112
+ });
113
+ component.find(ConnectionEditor).prop('onRemoveAttribute')(payloadItem);
114
+ expect(relationshipTable.onUpdateEditingRelation).toHaveBeenCalledWith({
115
+ type: 'onRemove',
116
+ payload: payloadItem
117
+ });
118
+ });
119
+
120
+ it('should call onSaveEditingRelation on click saving button', () => {
121
+ const component = setUp();
122
+ const button = component.find(Button).at(1);
123
+ expect(button.prop('children')).toEqual('Save');
124
+ expect(button.prop('disabled')).toBe(true);
125
+ expect(button.prop('children')).toEqual('Save');
126
+ component.setProps({
127
+ value: {
128
+ relationshipTable: {
129
+ ...relationshipTable,
130
+ editingRelations: [
131
+ {
132
+ ...relationshipTable.editingRelations[0],
133
+ relation: {
134
+ ...relationshipTable.editingRelations[0].relation,
135
+ attributes: {}
136
+ }
137
+ }
138
+ ]
139
+ }
140
+ }
141
+ });
142
+
143
+ component.update();
144
+
145
+ const buttonAfterUpdating = component.find(Button).at(1);
146
+ expect(buttonAfterUpdating.prop('children')).toEqual('Save');
147
+ expect(buttonAfterUpdating.prop('disabled')).toBe(false);
148
+ expect(relationshipTable.onSaveEditingRelation).not.toHaveBeenCalled();
149
+ buttonAfterUpdating.simulate('click');
150
+ expect(relationshipTable.onSaveEditingRelation).toHaveBeenCalledWith(
151
+ relationshipTable.editingRelations[0].initialRelation,
152
+ {
153
+ ...relationshipTable.editingRelations[0].relation,
154
+ attributes: {}
155
+ }
156
+ );
157
+ });
158
+
159
+ it('should call onCancelRelationEditing on click cancel button', () => {
160
+ const component = setUp();
161
+ const button = component.find(Button).at(0);
162
+ expect(button.prop('children')).toEqual('Cancel');
163
+ button.simulate('click');
164
+ expect(relationshipTable.onCancelRelationEditing).toHaveBeenCalled();
165
+ });
166
+ });
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import {ReactWrapper, shallow} from 'enzyme';
3
+ import DefaultHeadCellRenderer from 'react-components/dist/Table/DefaultHeadCellRenderer/DefaultHeadCellRenderer';
4
+ import {ExpandedValueTooltip} from '@reltio/components';
5
+
6
+ import HeadCellRenderer from '../HeadCellRenderer';
7
+ import {ColumnsDataItem} from '../../../CollapsibleTable/types';
8
+
9
+ describe('HeadCellRenderer tests', () => {
10
+ it('should render main parts', () => {
11
+ const header = 'Test header';
12
+ const wrapper = shallow(<HeadCellRenderer headCellData={{label: header} as ColumnsDataItem} />);
13
+ const cell = wrapper.find(DefaultHeadCellRenderer);
14
+ expect(cell).toHaveLength(1);
15
+ const headCellData = cell.prop('headCellData') as {label: JSX.Element};
16
+ const cellData = new ReactWrapper(headCellData.label);
17
+ expect(cellData).toHaveLength(1);
18
+ const labelWrapper = cellData.find(ExpandedValueTooltip);
19
+ expect(labelWrapper).toHaveLength(1);
20
+ expect(labelWrapper.prop('value')).toEqual(header);
21
+ expect(new ReactWrapper(labelWrapper.prop('children')).text()).toBe(header);
22
+ });
23
+ });
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import {mount, ReactWrapper} from 'enzyme';
3
+ import {identity} from 'ramda';
4
+
5
+ import ProfileCellRenderer from '../ProfileCellRenderer';
6
+ import {GraphStateContext} from '../../../../../../contexts/GraphStateContext';
7
+ import {GraphState, RelationshipRow} from '../../../../../../types/graphDataTypes';
8
+ import DefaultCellRenderer from '../DefaultCellRenderer';
9
+ import {EntityAvatar} from '@reltio/components';
10
+
11
+ jest.mock('@reltio/components', () => ({
12
+ ...jest.requireActual<Record<string, unknown>>('@reltio/components'),
13
+ EntityAvatar: () => null
14
+ }));
15
+
16
+ const profileValue = 'Profile1';
17
+ const entity = {uri: '1'};
18
+
19
+ const setUp = ({value = profileValue, className = 'class1', rowValue = {entity}, onEntitySelect = identity} = {}) =>
20
+ mount(
21
+ <GraphStateContext.Provider value={{onEntitySelect} as GraphState}>
22
+ <ProfileCellRenderer value={value} rowValue={rowValue as RelationshipRow} className={className} />
23
+ </GraphStateContext.Provider>
24
+ );
25
+
26
+ describe('ProfileCellRenderer tests', () => {
27
+ it('should render DefaultCellRenderer with correct props', () => {
28
+ const component = setUp();
29
+ const defaultCellRenderer = component.find(DefaultCellRenderer);
30
+ expect(defaultCellRenderer).toHaveLength(1);
31
+ expect(defaultCellRenderer.prop('tooltip')).toBe(profileValue);
32
+ expect(defaultCellRenderer.hasClass('class1')).toBe(true);
33
+ const cellValue = new ReactWrapper(defaultCellRenderer.prop('value') as JSX.Element);
34
+ expect(cellValue.find(EntityAvatar)).toHaveLength(1);
35
+ expect(cellValue.find(EntityAvatar).prop('entity')).toBe(entity);
36
+ expect(cellValue.at(1).text()).toBe(profileValue);
37
+ });
38
+
39
+ it('should render DefaultCellRenderer with correct props', () => {
40
+ const onEntitySelect = jest.fn();
41
+ const component = setUp({onEntitySelect});
42
+ const defaultCellRenderer = component.find(DefaultCellRenderer);
43
+ expect(defaultCellRenderer).toHaveLength(1);
44
+ defaultCellRenderer.prop('onClick')();
45
+ expect(onEntitySelect).toHaveBeenCalledWith(entity.uri);
46
+ });
47
+ });
@@ -0,0 +1,32 @@
1
+ import React, {memo, useCallback, useState} from 'react';
2
+ import i18n from 'ui-i18n';
3
+ import {SmallIconButtonWithTooltip} from '@reltio/components';
4
+ import DeleteIcon from '@mui/icons-material/Delete';
5
+
6
+ import DeleteRelationDialog from '../../../DeleteRelationDialog/DeleteRelationDialog';
7
+
8
+ type Props = {
9
+ uri: string;
10
+ };
11
+
12
+ const DeleteRelationButton = memo(({uri}: Props) => {
13
+ const [open, setOpen] = useState(false);
14
+ const onOpen = useCallback(() => setOpen(true), []);
15
+ const onClose = useCallback(() => setOpen(false), []);
16
+ return (
17
+ <>
18
+ <SmallIconButtonWithTooltip
19
+ icon={DeleteIcon}
20
+ size={'XXS'}
21
+ tooltipTitle={i18n.text('Delete')}
22
+ data-reltio-id="reltio-delete-relation-button"
23
+ onClick={onOpen}
24
+ />
25
+ <DeleteRelationDialog open={open} onClose={onClose} uri={uri} />
26
+ </>
27
+ );
28
+ });
29
+
30
+ DeleteRelationButton.displayName = 'DeleteRelationButton';
31
+
32
+ export default DeleteRelationButton;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import {shallow} from 'enzyme';
3
+ import {act} from 'react-dom/test-utils';
4
+ import {SmallIconButtonWithTooltip} from '@reltio/components';
5
+
6
+ import DeleteRelationButton from '../DeleteRelationButton';
7
+ import DeleteRelationDialog from '../../../../DeleteRelationDialog/DeleteRelationDialog';
8
+ import {rerenderWrapper} from '../../../../../../../../../../__mocks__/test-utils';
9
+
10
+ const setUp = ({uri = ''} = {}) => {
11
+ return shallow(<DeleteRelationButton uri={uri} />);
12
+ };
13
+
14
+ describe('DeleteRelationButton tests', () => {
15
+ it('should open DeleteRelationDialog on SmallIconButtonWithTooltip click', () => {
16
+ const component = setUp({uri: '1'});
17
+ expect(component.find(SmallIconButtonWithTooltip)).toHaveLength(1);
18
+ expect(component.find(DeleteRelationDialog)).toHaveLength(1);
19
+ const deleteButton = component.find(SmallIconButtonWithTooltip);
20
+ expect(deleteButton.prop('tooltipTitle')).toBe('Delete');
21
+ expect(component.find(DeleteRelationDialog).prop('open')).toBe(false);
22
+ act(() => {
23
+ (deleteButton.prop('onClick') as () => void)();
24
+ });
25
+ rerenderWrapper(component);
26
+ expect(component.find(DeleteRelationDialog).prop('open')).toBe(true);
27
+ });
28
+ });
@@ -0,0 +1,113 @@
1
+ import {makeStyles} from '@mui/styles';
2
+ import {collapsibleTableRowClassName, hoverBackground} from '../styles';
3
+
4
+ const textOverflow = {
5
+ content: '""',
6
+ position: 'absolute',
7
+ right: 0,
8
+ top: 0,
9
+ width: '40px',
10
+ height: '100%',
11
+ background: 'linear-gradient(to right, rgba(255, 255, 255, 0.2), #fff 100%)',
12
+ pointerEvents: 'none'
13
+ };
14
+
15
+ const hoverRule = `.${collapsibleTableRowClassName}:hover &`;
16
+
17
+ const textOverflowWithHover = {
18
+ ...textOverflow,
19
+ [hoverRule]: {
20
+ background: `linear-gradient(to right, rgba(238, 238, 238, 0), ${hoverBackground} 100%)`
21
+ }
22
+ };
23
+
24
+ export const useStyles = makeStyles((theme) => ({
25
+ headCell: {
26
+ position: 'relative',
27
+ display: 'flex',
28
+ alignItems: 'center',
29
+ height: '33px',
30
+ padding: '6px 0 6px 16px',
31
+ '&>div': {
32
+ flexDirection: 'row'
33
+ },
34
+ '&>div>span[role=button]': {
35
+ width: 'calc(100% + 49px)'
36
+ }
37
+ },
38
+ headLabel: {
39
+ color: theme.palette.text.primary,
40
+ fontSize: '12px',
41
+ fontWeight: 500,
42
+ lineHeight: '16px',
43
+ whiteSpace: 'nowrap',
44
+ overflow: 'hidden',
45
+ '&:after': textOverflow
46
+ },
47
+ defaultCell: {
48
+ position: 'relative',
49
+ color: theme.palette.text.primary,
50
+ fontSize: '13px',
51
+ fontWeight: 'normal',
52
+ lineHeight: '15px',
53
+ whiteSpace: 'nowrap',
54
+ overflow: 'hidden',
55
+ display: 'flex',
56
+ alignItems: 'center',
57
+ height: '100%',
58
+ padding: '6px 16px',
59
+ '&:after': textOverflowWithHover
60
+ },
61
+ clickable: {
62
+ cursor: 'pointer'
63
+ },
64
+ profileCell: {
65
+ paddingTop: '3px',
66
+ paddingBottom: '4px'
67
+ },
68
+ controlsCell: {
69
+ position: 'absolute',
70
+ display: 'flex',
71
+ alignItems: 'center',
72
+ height: '100%',
73
+ flexShrink: 0,
74
+ top: 0,
75
+ right: '9px',
76
+ visibility: 'hidden',
77
+ [hoverRule]: {
78
+ visibility: 'visible',
79
+ background: hoverBackground
80
+ }
81
+ },
82
+ editingMode: {
83
+ visibility: 'visible'
84
+ },
85
+ hidden: {
86
+ visibility: 'hidden'
87
+ },
88
+ editButton: {
89
+ marginRight: '7px'
90
+ },
91
+ entityAvatar: {
92
+ width: '20px',
93
+ height: '20px',
94
+ marginRight: '8px'
95
+ },
96
+ actionButtons: {
97
+ display: 'flex',
98
+ justifyContent: 'flex-end',
99
+ margin: '0 8px 10px',
100
+
101
+ '& > button': {
102
+ fontSize: '14px',
103
+ lineHeight: '16px',
104
+ marginLeft: '8px',
105
+ padding: '10px 8px',
106
+ backgroundColor: 'rgba(98, 2, 238, 0)'
107
+ }
108
+ },
109
+ expandedRow: {
110
+ padding: '0 16px 6px',
111
+ fontSize: '13px'
112
+ }
113
+ }));
@@ -0,0 +1,36 @@
1
+ import {makeStyles} from '@mui/styles';
2
+
3
+ export const collapsibleTableRowClassName = 'collapsibleTableRow';
4
+ export const hoverBackground = 'rgba(238, 238, 238, 1)';
5
+
6
+ export const useStyles = makeStyles({
7
+ tableWithPagination: {
8
+ flex: 1,
9
+ overflow: 'hidden',
10
+ paddingRight: '1px',
11
+ display: 'flex',
12
+ flexDirection: 'column'
13
+ },
14
+ tableContainer: {
15
+ flex: 1,
16
+ overflow: 'hidden'
17
+ },
18
+ profileColumn: {
19
+ minWidth: '180px',
20
+ flex: 3
21
+ },
22
+ relationshipTypeColumn: {
23
+ minWidth: '70px',
24
+ flex: 1
25
+ },
26
+ entityTypeColumn: {
27
+ minWidth: '70px',
28
+ flex: 1
29
+ },
30
+ row: {
31
+ position: 'relative',
32
+ '&:hover': {
33
+ background: hoverBackground
34
+ }
35
+ }
36
+ });
@@ -0,0 +1,41 @@
1
+ import React, {useState} from 'react';
2
+ import {pick, pipe, prop} from 'ramda';
3
+ import {withContext} from '@reltio/components';
4
+ import FilterListIcon from '@mui/icons-material/FilterList';
5
+ import IconButton from '@mui/material/IconButton';
6
+ import RelationshipsSearchTextField from './RelationshipsSearchTextField/RelationshipsSearchTextField';
7
+ import RelationshipsFiltersDialog from './RelationshipsFiltersDialog/RelationshipsFiltersDialog';
8
+ import {RelationshipTableState} from '../../../../types/graphDataTypes';
9
+ import {GraphStateContext} from '../../../../contexts/GraphStateContext';
10
+ import {useStyles} from './styles';
11
+
12
+ type Props = Partial<Pick<RelationshipTableState, 'filters'>>;
13
+
14
+ const RelationshipsFilters = ({filters}: Props) => {
15
+ const styles = useStyles();
16
+ const [open, setOpen] = useState(false);
17
+
18
+ const handleOpenDialog = () => setOpen(true);
19
+ const handleCloseDialog = () => setOpen(false);
20
+
21
+ const {entityTypesUris, relationTypesUris} = filters;
22
+
23
+ const hasAppliedFilters = entityTypesUris.length || relationTypesUris.length;
24
+
25
+ return (
26
+ <div className={styles.wrapper}>
27
+ <RelationshipsSearchTextField />
28
+ <IconButton
29
+ data-reltio-id="reltio-filter-relationship-button"
30
+ className={styles.iconButton}
31
+ onClick={handleOpenDialog}
32
+ size="large"
33
+ >
34
+ <FilterListIcon className={hasAppliedFilters ? styles.activeFiltersIcon : styles.inactiveFiltersIcon} />
35
+ </IconButton>
36
+ <RelationshipsFiltersDialog open={open} onClose={handleCloseDialog} />
37
+ </div>
38
+ );
39
+ };
40
+
41
+ export default withContext(GraphStateContext, pipe(prop('relationshipTable'), pick(['filters'])), RelationshipsFilters);
@@ -0,0 +1,91 @@
1
+ import React, {useEffect, useState} from 'react';
2
+ import i18n from 'ui-i18n';
3
+ import {pipe, pick, prop} from 'ramda';
4
+ import {EntityTypesSelector, RelationTypesSelector, withContext} from '@reltio/components';
5
+ import Button from '@mui/material/Button';
6
+ import Dialog from '@mui/material/Dialog';
7
+ import Typography from '@mui/material/Typography';
8
+ import {GraphStateContext} from '../../../../../contexts/GraphStateContext';
9
+ import {RelationshipTableState} from '../../../../../types/graphDataTypes';
10
+ import {useStyles} from './styles';
11
+
12
+ type Props = {
13
+ open: boolean;
14
+ onClose: () => void;
15
+ } & Partial<Pick<RelationshipTableState, 'filters' | 'onFilter' | 'entityTypesOptions' | 'relationTypesOptions'>>;
16
+
17
+ const RelationshipsFiltersDialog = ({
18
+ open,
19
+ onClose,
20
+ filters,
21
+ onFilter,
22
+ entityTypesOptions,
23
+ relationTypesOptions
24
+ }: Props) => {
25
+ const styles = useStyles();
26
+
27
+ const [localSelectedEntityTypes, setLocalSelectedEntityTypes] = useState([]);
28
+ const [localSelectedRelationTypes, setLocalSelectedRelationTypes] = useState([]);
29
+
30
+ const handleCancel = () => {
31
+ setLocalSelectedEntityTypes(filters.entityTypesUris);
32
+ setLocalSelectedRelationTypes(filters.relationTypesUris);
33
+ onClose();
34
+ };
35
+
36
+ const handleApply = () => {
37
+ onFilter({entityTypesUris: localSelectedEntityTypes, relationTypesUris: localSelectedRelationTypes});
38
+ onClose();
39
+ };
40
+
41
+ const handleClear = () => {
42
+ setLocalSelectedEntityTypes([]);
43
+ setLocalSelectedRelationTypes([]);
44
+ };
45
+
46
+ useEffect(() => {
47
+ setLocalSelectedEntityTypes(filters.entityTypesUris);
48
+ setLocalSelectedRelationTypes(filters.relationTypesUris);
49
+ }, [filters.entityTypesUris, filters.relationTypesUris]);
50
+
51
+ return (
52
+ <Dialog classes={{paper: styles.dialogPaper}} onClose={handleCancel} open={open}>
53
+ <Typography className={styles.title}>{i18n.text('Filter')}</Typography>
54
+ <EntityTypesSelector
55
+ classes={{
56
+ root: styles.entityTypesSelector
57
+ }}
58
+ entityTypes={entityTypesOptions}
59
+ selectedEntityTypes={localSelectedEntityTypes}
60
+ enableEmptyValueUnderline
61
+ onChange={setLocalSelectedEntityTypes}
62
+ />
63
+ <RelationTypesSelector
64
+ classes={{
65
+ root: styles.relationTypesSelector
66
+ }}
67
+ relationTypes={relationTypesOptions}
68
+ selectedRelationTypes={localSelectedRelationTypes}
69
+ enableEmptyValueUnderline
70
+ onChange={setLocalSelectedRelationTypes}
71
+ />
72
+ <div className={styles.footer}>
73
+ <Button className={styles.clearAllButton} onClick={handleClear}>
74
+ {i18n.text('Clear All')}
75
+ </Button>
76
+ <Button className={styles.cancelButton} onClick={handleCancel}>
77
+ {i18n.text('Cancel')}
78
+ </Button>
79
+ <Button onClick={handleApply} color="primary">
80
+ {i18n.text('Apply')}
81
+ </Button>
82
+ </div>
83
+ </Dialog>
84
+ );
85
+ };
86
+
87
+ export default withContext(
88
+ GraphStateContext,
89
+ pipe(prop('relationshipTable'), pick(['onFilter', 'filters', 'entityTypesOptions', 'relationTypesOptions'])),
90
+ RelationshipsFiltersDialog
91
+ );