@reltio/interactions 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 +38 -21
- package/public/bundle.js +205 -0
- package/public/bundle.js.LICENSE.txt +79 -0
- package/public/package.json +22 -0
- package/scripts/build/index.js +20 -0
- package/src/InteractionsTableView/InteractionsTable/InteractionsTable.tsx +87 -0
- package/src/InteractionsTableView/InteractionsTable/__tests__/InteractionsTable.test.js +146 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/ActorsRenderer.js +57 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/AttributesRenderer.js +50 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/BlobRenderer.js +14 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/DefaultCellValueRenderer.js +22 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/HeadCellRenderer.js +16 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/LinkRenderer.js +22 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/RowCellRenderer.js +31 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/__tests__/ActorsRenderer.test.js +87 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/__tests__/AttributesRenderer.test.js +118 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/__tests__/DefaultCellValueRenderer.test.js +23 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/__tests__/LinkRenderer.test.js +20 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/__tests__/RowCellRenderer.test.js +53 -0
- package/src/InteractionsTableView/InteractionsTable/cell-renderers/styles.js +67 -0
- package/src/InteractionsTableView/InteractionsTable/helpers/__tests__/dataHelpers.spec.js +286 -0
- package/src/InteractionsTableView/InteractionsTable/helpers/dataHelpers.ts +120 -0
- package/src/InteractionsTableView/InteractionsTable/styles.ts +29 -0
- package/src/InteractionsTableView/InteractionsTableHeader/InteractionTypeSelector/InteractionTypeSelector.tsx +26 -0
- package/src/InteractionsTableView/InteractionsTableHeader/InteractionTypeSelector/__tests__/InteractionTypeSelector.test.js +34 -0
- package/src/InteractionsTableView/InteractionsTableHeader/InteractionsTableHeader.js +76 -0
- package/src/InteractionsTableView/InteractionsTableHeader/__tests__/InteractionsTableHeader.test.js +106 -0
- package/src/InteractionsTableView/InteractionsTableHeader/styles.js +21 -0
- package/src/InteractionsTableView/__tests__/InteractionsTableView.test.js +570 -0
- package/src/InteractionsTableView/__tests__/stateReducer.test.js +260 -0
- package/src/InteractionsTableView/helpers/__tests__/filtersHelper.test.js +221 -0
- package/src/InteractionsTableView/helpers/__tests__/tableHelper.test.js +300 -0
- package/src/InteractionsTableView/helpers/filtersHelpers.ts +18 -0
- package/src/InteractionsTableView/helpers/tableHelpers.ts +157 -0
- package/src/InteractionsTableView/hooks/useInteractions.ts +45 -0
- package/src/InteractionsTableView/index.tsx +200 -0
- package/src/InteractionsTableView/stateReducer.ts +132 -0
- package/src/InteractionsTableView/styles.ts +18 -0
- package/src/InteractionsTableView/types/index.ts +8 -0
- package/src/index.tsx +59 -0
- package/stories/Interactions.stories.js +31 -0
- package/stories/utils/entity.js +11 -0
- package/stories/utils/interactions.js +837 -0
- package/stories/utils/interactionsViewConfig.js +6 -0
- package/stories/utils/mdmStore.js +28 -0
- package/stories/utils/metadata.js +7221 -0
- package/tsconfig.json +4 -0
- package/webpack.config.js +10 -0
- package/bundle.js +0 -2
- package/bundle.js.LICENSE.txt +0 -36
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/*
|
|
2
|
+
object-assign
|
|
3
|
+
(c) Sindre Sorhus
|
|
4
|
+
@license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @license React
|
|
9
|
+
* react-is.production.min.js
|
|
10
|
+
*
|
|
11
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
12
|
+
*
|
|
13
|
+
* This source code is licensed under the MIT license found in the
|
|
14
|
+
* LICENSE file in the root directory of this source tree.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @mui/material v5.13.4
|
|
19
|
+
*
|
|
20
|
+
* @license MIT
|
|
21
|
+
* This source code is licensed under the MIT license found in the
|
|
22
|
+
* LICENSE file in the root directory of this source tree.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @mui/styled-engine v5.13.2
|
|
27
|
+
*
|
|
28
|
+
* @license MIT
|
|
29
|
+
* This source code is licensed under the MIT license found in the
|
|
30
|
+
* LICENSE file in the root directory of this source tree.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A better abstraction over CSS.
|
|
35
|
+
*
|
|
36
|
+
* @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present
|
|
37
|
+
* @website https://github.com/cssinjs/jss
|
|
38
|
+
* @license MIT
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* React Router DOM v6.2.1
|
|
43
|
+
*
|
|
44
|
+
* Copyright (c) Remix Software Inc.
|
|
45
|
+
*
|
|
46
|
+
* This source code is licensed under the MIT license found in the
|
|
47
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
48
|
+
*
|
|
49
|
+
* @license MIT
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* React Router v6.2.1
|
|
54
|
+
*
|
|
55
|
+
* Copyright (c) Remix Software Inc.
|
|
56
|
+
*
|
|
57
|
+
* This source code is licensed under the MIT license found in the
|
|
58
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
59
|
+
*
|
|
60
|
+
* @license MIT
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
/** @license React v16.13.1
|
|
64
|
+
* react-is.production.min.js
|
|
65
|
+
*
|
|
66
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
67
|
+
*
|
|
68
|
+
* This source code is licensed under the MIT license found in the
|
|
69
|
+
* LICENSE file in the root directory of this source tree.
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
/** @license React v17.0.2
|
|
73
|
+
* react-jsx-runtime.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
|
+
*/
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reltio/interactions",
|
|
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.5",
|
|
8
|
+
"@reltio/mdm-module": "^1.4.1586-mui5",
|
|
9
|
+
"@reltio/mdm-sdk": "^1.4.1586-mui5",
|
|
10
|
+
"classnames": "^2.2.5",
|
|
11
|
+
"memoize-one": "^5.1.0",
|
|
12
|
+
"prop-types": "^15.6.2",
|
|
13
|
+
"ramda": "^0.28.0",
|
|
14
|
+
"react-redux": "^7.2.3",
|
|
15
|
+
"react-resize-detector": "^4.2.0",
|
|
16
|
+
"redux": "^4.1.2",
|
|
17
|
+
"ui-i18n": "bitbucket:reltio-ondemand/ui-i18n#v1.4.0"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const outputDir = path.resolve(process.cwd(), 'public');
|
|
4
|
+
|
|
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,87 @@
|
|
|
1
|
+
import React, {ForwardedRef, useCallback, useLayoutEffect, useMemo} from 'react';
|
|
2
|
+
import RowCellRenderer from './cell-renderers/RowCellRenderer';
|
|
3
|
+
import {BasicTable, ColumnData, ColumnFilter, RowCellAutoSizer} from '@reltio/components';
|
|
4
|
+
import {getBasicTableColumnsData, getBasicTableRowsData, getStaticRowCellHeight} from './helpers/dataHelpers';
|
|
5
|
+
import {Interaction, Metadata, SortingField} from '@reltio/mdm-sdk';
|
|
6
|
+
import {useDynamicRowCellHeight} from '@reltio/components';
|
|
7
|
+
import {either} from 'ramda';
|
|
8
|
+
|
|
9
|
+
import {useStyles} from './styles';
|
|
10
|
+
|
|
11
|
+
type Props = {
|
|
12
|
+
columnsData: ColumnData;
|
|
13
|
+
interactions: Interaction[];
|
|
14
|
+
metadata: Metadata;
|
|
15
|
+
sorting: SortingField;
|
|
16
|
+
onSort: (field: string) => void;
|
|
17
|
+
filters?: Record<string, ColumnFilter>;
|
|
18
|
+
onFilter: (event: {columnId: string; filter: ColumnFilter}) => void;
|
|
19
|
+
basicTableRef: ForwardedRef<unknown>;
|
|
20
|
+
};
|
|
21
|
+
const InteractionsTable = ({
|
|
22
|
+
columnsData,
|
|
23
|
+
interactions,
|
|
24
|
+
metadata,
|
|
25
|
+
sorting,
|
|
26
|
+
onSort,
|
|
27
|
+
filters,
|
|
28
|
+
onFilter,
|
|
29
|
+
basicTableRef
|
|
30
|
+
}: Props) => {
|
|
31
|
+
const tableRowsData = useMemo(
|
|
32
|
+
() => getBasicTableRowsData(interactions, columnsData, metadata),
|
|
33
|
+
[interactions, columnsData, metadata]
|
|
34
|
+
);
|
|
35
|
+
const tableColumnsData = useMemo(() => getBasicTableColumnsData(columnsData), [columnsData]);
|
|
36
|
+
|
|
37
|
+
const styles = useStyles();
|
|
38
|
+
|
|
39
|
+
const {getDynamicRowCellHeight, changeRowCellHeight, clearHeightsCache} = useDynamicRowCellHeight();
|
|
40
|
+
|
|
41
|
+
useLayoutEffect(clearHeightsCache, [interactions]);
|
|
42
|
+
|
|
43
|
+
const renderRowCell = useCallback(
|
|
44
|
+
(props) => (
|
|
45
|
+
<RowCellAutoSizer onChangeHeight={changeRowCellHeight} {...props}>
|
|
46
|
+
<RowCellRenderer
|
|
47
|
+
{...props}
|
|
48
|
+
isSorted={
|
|
49
|
+
!!sorting && sorting.field === props.columnData.id /* eslint-disable-line react/prop-types */
|
|
50
|
+
}
|
|
51
|
+
/>
|
|
52
|
+
</RowCellAutoSizer>
|
|
53
|
+
),
|
|
54
|
+
[sorting, changeRowCellHeight]
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const getRowCellHeight = useCallback(either(getDynamicRowCellHeight, getStaticRowCellHeight), [
|
|
58
|
+
getDynamicRowCellHeight,
|
|
59
|
+
getStaticRowCellHeight
|
|
60
|
+
]);
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div className={styles.tableContainer}>
|
|
64
|
+
<BasicTable
|
|
65
|
+
columnsData={tableColumnsData}
|
|
66
|
+
rowsData={tableRowsData}
|
|
67
|
+
sorting={sorting}
|
|
68
|
+
onSort={onSort}
|
|
69
|
+
filters={filters}
|
|
70
|
+
onFilter={onFilter}
|
|
71
|
+
hoverStateEnabled={true}
|
|
72
|
+
defaultColumnWidth={250}
|
|
73
|
+
defaultColumnMinWidth={200}
|
|
74
|
+
getRowCellHeight={getRowCellHeight}
|
|
75
|
+
headRowHeight={56}
|
|
76
|
+
renderRowCell={renderRowCell}
|
|
77
|
+
classes={{
|
|
78
|
+
hoveredRowRightContentWrapper: styles['row-cell__buttons-wrapper'],
|
|
79
|
+
hoveredRowRightContentContainer: styles['row-cell__buttons-container']
|
|
80
|
+
}}
|
|
81
|
+
ref={basicTableRef}
|
|
82
|
+
/>
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export default InteractionsTable;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {mount, ReactWrapper} from 'enzyme';
|
|
3
|
+
import {act} from 'react-dom/test-utils';
|
|
4
|
+
|
|
5
|
+
import InteractionsTable from '../InteractionsTable';
|
|
6
|
+
import * as dataHelpers from '../helpers/dataHelpers';
|
|
7
|
+
import {ACTORS_COLUMN_ID, INTERACTION_TYPE_COLUMN_ID} from '../../helpers/tableHelpers';
|
|
8
|
+
import * as mdmSdk from '@reltio/mdm-sdk';
|
|
9
|
+
import {DataTypes} from '@reltio/mdm-sdk';
|
|
10
|
+
import {BasicTable} from '@reltio/components';
|
|
11
|
+
|
|
12
|
+
jest.mock('@reltio/mdm-sdk');
|
|
13
|
+
|
|
14
|
+
jest.mock('@reltio/components', () => ({
|
|
15
|
+
...jest.requireActual('@reltio/components'),
|
|
16
|
+
BasicTable: () => null
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
describe('Interactions table tests', () => {
|
|
20
|
+
const props = {
|
|
21
|
+
columnsData: [
|
|
22
|
+
{
|
|
23
|
+
id: 'timestamp'
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: INTERACTION_TYPE_COLUMN_ID
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: ACTORS_COLUMN_ID
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
interactions: [],
|
|
33
|
+
metadata: {
|
|
34
|
+
entityTypes: [],
|
|
35
|
+
interactionTypes: []
|
|
36
|
+
},
|
|
37
|
+
filters: null,
|
|
38
|
+
onFilter: jest.fn(),
|
|
39
|
+
sorting: {
|
|
40
|
+
field: 'timestamp',
|
|
41
|
+
order: 'desc'
|
|
42
|
+
},
|
|
43
|
+
onSort: jest.fn()
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const ROWS_DATA_MOCK = [];
|
|
47
|
+
const COLUMNS_DATA_MOCK = [];
|
|
48
|
+
|
|
49
|
+
beforeAll(() => {
|
|
50
|
+
jest.spyOn(dataHelpers, 'getBasicTableRowsData').mockReturnValue(ROWS_DATA_MOCK);
|
|
51
|
+
jest.spyOn(dataHelpers, 'getBasicTableColumnsData').mockReturnValue(COLUMNS_DATA_MOCK);
|
|
52
|
+
jest.spyOn(mdmSdk, 'debounce').mockImplementation((func) => func);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
afterEach(() => {
|
|
56
|
+
jest.clearAllMocks();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should render basic table with correct params', () => {
|
|
60
|
+
const wrapper = mount(<InteractionsTable {...props} />);
|
|
61
|
+
expect(wrapper.find(BasicTable).props()).toMatchObject({
|
|
62
|
+
columnsData: COLUMNS_DATA_MOCK,
|
|
63
|
+
rowsData: ROWS_DATA_MOCK,
|
|
64
|
+
sorting: props.sorting,
|
|
65
|
+
onSort: props.onSort,
|
|
66
|
+
filters: props.filters,
|
|
67
|
+
onFilter: props.onFilter,
|
|
68
|
+
hoverStateEnabled: true
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should use static height for cell if dynamic has not been computed', () => {
|
|
73
|
+
const STATIC_HEIGHT = 48;
|
|
74
|
+
jest.spyOn(dataHelpers, 'getStaticRowCellHeight').mockReturnValue(STATIC_HEIGHT);
|
|
75
|
+
const wrapper = mount(<InteractionsTable {...props} />);
|
|
76
|
+
const cellProps = {
|
|
77
|
+
rowIndex: 0,
|
|
78
|
+
columnIndex: 0,
|
|
79
|
+
cellIndex: 0,
|
|
80
|
+
columnData: {
|
|
81
|
+
id: 'timestamp',
|
|
82
|
+
dataTypeDefinition: {
|
|
83
|
+
type: DataTypes.TYPE_TIMESTAMP
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
cell: {values: []}
|
|
87
|
+
};
|
|
88
|
+
const height = wrapper.find(BasicTable).prop('getRowCellHeight')(cellProps);
|
|
89
|
+
expect(dataHelpers.getStaticRowCellHeight).toBeCalledWith(cellProps);
|
|
90
|
+
expect(height).toBe(STATIC_HEIGHT);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should wrap each cell in autosizer to compute dynamic height', () => {
|
|
94
|
+
const wrapper = mount(<InteractionsTable {...props} />);
|
|
95
|
+
const cellProps = {
|
|
96
|
+
rowIndex: 0,
|
|
97
|
+
columnIndex: 0,
|
|
98
|
+
cellIndex: 0,
|
|
99
|
+
columnData: {
|
|
100
|
+
id: 'timestamp',
|
|
101
|
+
dataTypeDefinition: {
|
|
102
|
+
type: DataTypes.TYPE_TIMESTAMP
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
cell: {values: []},
|
|
106
|
+
rowValue: {
|
|
107
|
+
rawValue: {uri: 'interactions/1'}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
const cell = new ReactWrapper(wrapper.find(BasicTable).prop('renderRowCell')(cellProps));
|
|
111
|
+
expect(cell.find('RowCellAutoSizer').props()).toMatchObject({
|
|
112
|
+
...cellProps
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should use dynamic height for cell if it has been computed', () => {
|
|
117
|
+
jest.spyOn(dataHelpers, 'getStaticRowCellHeight');
|
|
118
|
+
const wrapper = mount(<InteractionsTable {...props} />);
|
|
119
|
+
const cellProps = {
|
|
120
|
+
rowIndex: 0,
|
|
121
|
+
columnIndex: 0,
|
|
122
|
+
cellIndex: 0,
|
|
123
|
+
columnData: {
|
|
124
|
+
id: 'timestamp',
|
|
125
|
+
dataTypeDefinition: {
|
|
126
|
+
type: DataTypes.TYPE_TIMESTAMP
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
cell: {values: []},
|
|
130
|
+
rowValue: {
|
|
131
|
+
rawValue: {uri: 'interactions/1'}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const cell = new ReactWrapper(wrapper.find(BasicTable).prop('renderRowCell')(cellProps));
|
|
135
|
+
const DYNAMIC_HEIGHT = 32;
|
|
136
|
+
|
|
137
|
+
act(() => {
|
|
138
|
+
cell.find('RowCellAutoSizer').prop('onChangeHeight')(cellProps, DYNAMIC_HEIGHT);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
wrapper.update();
|
|
142
|
+
const height = wrapper.find('BasicTable').prop('getRowCellHeight')(cellProps);
|
|
143
|
+
expect(dataHelpers.getStaticRowCellHeight).not.toBeCalled();
|
|
144
|
+
expect(height).toBe(DYNAMIC_HEIGHT);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import React, {useContext} from 'react';
|
|
3
|
+
import mdm, {ui} from '@reltio/mdm-module';
|
|
4
|
+
import {chain, pipe, prop, uniqBy, values} from 'ramda';
|
|
5
|
+
import {useDispatch, useSelector} from 'react-redux';
|
|
6
|
+
import {useStyles} from './styles';
|
|
7
|
+
import {EntityTypeType, getEntityType, getLabel} from '@reltio/mdm-sdk';
|
|
8
|
+
import {EntityTypeIcon, ViewIdContext} from '@reltio/components';
|
|
9
|
+
import classnames from 'classnames';
|
|
10
|
+
|
|
11
|
+
const MemberItem = ({entityType, label, onClick}) => {
|
|
12
|
+
const styles = useStyles();
|
|
13
|
+
const labelCaption = getLabel(label);
|
|
14
|
+
return (
|
|
15
|
+
<div className={styles.memberWrapper}>
|
|
16
|
+
<EntityTypeIcon className={styles.entityAvatar} entityType={entityType} />
|
|
17
|
+
<span className={classnames(styles.entityLabel, styles.link)} onClick={onClick}>
|
|
18
|
+
{labelCaption}
|
|
19
|
+
</span>
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
MemberItem.propTypes = {
|
|
24
|
+
entityType: EntityTypeType,
|
|
25
|
+
label: PropTypes.string,
|
|
26
|
+
onClick: PropTypes.func
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const getActorsMembers = pipe(values, chain(prop('members')), uniqBy(prop('objectURI')));
|
|
30
|
+
|
|
31
|
+
const ActorsRenderer = ({value}) => {
|
|
32
|
+
const styles = useStyles();
|
|
33
|
+
const members = getActorsMembers(value);
|
|
34
|
+
const dispatch = useDispatch();
|
|
35
|
+
const viewId = useContext(ViewIdContext);
|
|
36
|
+
const metadata = useSelector(mdm.selectors.getMetadata);
|
|
37
|
+
const openEntityWithUri = (uri) => dispatch(ui.actions.openEntity({uri, viewId}));
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div className={styles.actorsWrapper}>
|
|
41
|
+
{members.map(({objectURI, type, label}) => (
|
|
42
|
+
<MemberItem
|
|
43
|
+
key={objectURI}
|
|
44
|
+
entityType={getEntityType(metadata, type)}
|
|
45
|
+
label={label}
|
|
46
|
+
onClick={() => openEntityWithUri(objectURI)}
|
|
47
|
+
/>
|
|
48
|
+
))}
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
ActorsRenderer.propTypes = {
|
|
54
|
+
value: PropTypes.object
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default ActorsRenderer;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React, {useMemo, useState} from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import {useSelector} from 'react-redux';
|
|
4
|
+
|
|
5
|
+
import {ReadOnlyAttributesList, ViewMoreToggle} from '@reltio/components';
|
|
6
|
+
import {useStyles} from './styles';
|
|
7
|
+
import mdmModule from '@reltio/mdm-module';
|
|
8
|
+
import {getInteractionType} from '@reltio/mdm-sdk';
|
|
9
|
+
import {pick, propEq} from 'ramda';
|
|
10
|
+
|
|
11
|
+
const AttributesRenderer = ({value, rowValue, columnData}) => {
|
|
12
|
+
const styles = useStyles();
|
|
13
|
+
|
|
14
|
+
const metadata = useSelector(mdmModule.selectors.getMetadata);
|
|
15
|
+
const interaction = rowValue.rawValue;
|
|
16
|
+
const attrTypes = useMemo(() => {
|
|
17
|
+
const interactionType = getInteractionType(metadata, interaction.type);
|
|
18
|
+
return interactionType.attributes;
|
|
19
|
+
}, [interaction, metadata]);
|
|
20
|
+
|
|
21
|
+
const [expanded, setExpanded] = useState(false);
|
|
22
|
+
const toggleExpanded = () => setExpanded((expanded) => !expanded);
|
|
23
|
+
|
|
24
|
+
const attributes = value;
|
|
25
|
+
const attrNames = Object.keys(attributes);
|
|
26
|
+
|
|
27
|
+
const visibleCountLimit = columnData.maxAttrsToShow;
|
|
28
|
+
const hasExtraValuesToShow = attrNames.length > visibleCountLimit;
|
|
29
|
+
const attrNamesToShow = expanded ? attrNames : attrNames.slice(0, visibleCountLimit);
|
|
30
|
+
|
|
31
|
+
const attrsToShow = pick(attrNamesToShow, attributes);
|
|
32
|
+
const attrTypesToShow = attrNamesToShow.map((name) => attrTypes.find(propEq('name', name)));
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div className={styles.attributesWrapper}>
|
|
36
|
+
<ReadOnlyAttributesList entity={{attributes: attrsToShow}} attrTypes={attrTypesToShow} drawLines={false} />
|
|
37
|
+
{hasExtraValuesToShow && (
|
|
38
|
+
<ViewMoreToggle active={expanded} onClick={toggleExpanded} className={styles.viewMore} />
|
|
39
|
+
)}
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
AttributesRenderer.propTypes = {
|
|
45
|
+
value: PropTypes.object,
|
|
46
|
+
rowValue: PropTypes.object,
|
|
47
|
+
columnData: PropTypes.object
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default AttributesRenderer;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import {useStyles} from './styles';
|
|
4
|
+
|
|
5
|
+
const BlobRender = ({value}) => {
|
|
6
|
+
const styles = useStyles();
|
|
7
|
+
return <div className={styles.blobWrapper}>{value}</div>;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
BlobRender.propTypes = {
|
|
11
|
+
value: PropTypes.any
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default BlobRender;
|
package/src/InteractionsTableView/InteractionsTable/cell-renderers/DefaultCellValueRenderer.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import {useStyles} from './styles';
|
|
4
|
+
import {DataTypeValue} from '@reltio/components';
|
|
5
|
+
|
|
6
|
+
const DefaultCellValueRenderer = ({value, columnData: {dataTypeDefinition}}) => {
|
|
7
|
+
const styles = useStyles();
|
|
8
|
+
return (
|
|
9
|
+
<div className={styles.defaultWrapper}>
|
|
10
|
+
<DataTypeValue value={value} dataTypeDefinition={dataTypeDefinition} />
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
DefaultCellValueRenderer.propTypes = {
|
|
16
|
+
value: PropTypes.any,
|
|
17
|
+
columnData: PropTypes.shape({
|
|
18
|
+
dataTypeDefinition: PropTypes.object
|
|
19
|
+
})
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default DefaultCellValueRenderer;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import DefaultHeadCellRenderer from 'react-components/dist/Table/DefaultHeadCellRenderer/DefaultHeadCellRenderer';
|
|
4
|
+
import {withFilterAtBottom} from '@reltio/components';
|
|
5
|
+
import {useStyles} from './styles';
|
|
6
|
+
|
|
7
|
+
const HeadCellRenderer = (props) => {
|
|
8
|
+
const styles = useStyles();
|
|
9
|
+
return (
|
|
10
|
+
<div className={styles.headCell}>
|
|
11
|
+
<DefaultHeadCellRenderer {...props} />
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default withFilterAtBottom(HeadCellRenderer);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
|
|
4
|
+
import {useStyles} from './styles';
|
|
5
|
+
import Link from '@mui/material/Link';
|
|
6
|
+
|
|
7
|
+
const LinkRenderer = ({value}) => {
|
|
8
|
+
const styles = useStyles();
|
|
9
|
+
return (
|
|
10
|
+
<div className={styles.defaultWrapper}>
|
|
11
|
+
<Link className={styles.link} href={value} target="_blank" underline="none">
|
|
12
|
+
{value}
|
|
13
|
+
</Link>
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
LinkRenderer.propTypes = {
|
|
19
|
+
value: PropTypes.any
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default LinkRenderer;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import classnames from 'classnames';
|
|
4
|
+
import {useStyles} from './styles';
|
|
5
|
+
|
|
6
|
+
const RowCellRenderer = ({cell, CellValueRenderer, isSorted, ...otherProps}) => {
|
|
7
|
+
const styles = useStyles();
|
|
8
|
+
return (
|
|
9
|
+
<div
|
|
10
|
+
className={classnames(
|
|
11
|
+
{
|
|
12
|
+
[styles['row-cell--sorted']]: isSorted
|
|
13
|
+
},
|
|
14
|
+
styles.rowCell
|
|
15
|
+
)}
|
|
16
|
+
>
|
|
17
|
+
{cell.values.map((value, index) => (
|
|
18
|
+
<CellValueRenderer key={index} value={value} {...otherProps} />
|
|
19
|
+
))}
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
RowCellRenderer.propTypes = {
|
|
25
|
+
rowValue: PropTypes.object,
|
|
26
|
+
cell: PropTypes.object,
|
|
27
|
+
CellValueRenderer: PropTypes.elementType,
|
|
28
|
+
isSorted: PropTypes.bool
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default RowCellRenderer;
|
package/src/InteractionsTableView/InteractionsTable/cell-renderers/__tests__/ActorsRenderer.test.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {mount} from 'enzyme';
|
|
3
|
+
import ActorsRenderer from '../ActorsRenderer';
|
|
4
|
+
import mdm, {ui} from '@reltio/mdm-module';
|
|
5
|
+
import * as reactRedux from 'react-redux';
|
|
6
|
+
import {EntityTypeIcon, ViewIdContext} from '@reltio/components';
|
|
7
|
+
|
|
8
|
+
describe('Actors Renderer scenario', () => {
|
|
9
|
+
const NO_LABEL = '<No label>';
|
|
10
|
+
const dispatch = jest.fn();
|
|
11
|
+
const metadata = {
|
|
12
|
+
entityTypes: [
|
|
13
|
+
{
|
|
14
|
+
uri: 'configuration/entityTypes/Type',
|
|
15
|
+
label: 'Type label',
|
|
16
|
+
name: 'Type'
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
beforeAll(() => {
|
|
22
|
+
jest.spyOn(reactRedux, 'useDispatch').mockReturnValue(dispatch);
|
|
23
|
+
jest.spyOn(reactRedux, 'useSelector').mockImplementation((selector) => selector());
|
|
24
|
+
jest.spyOn(mdm.selectors, 'getAbsoluteImagePath').mockReturnValue('/some/image/path');
|
|
25
|
+
jest.spyOn(mdm.selectors, 'getMetadata').mockReturnValue(metadata);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should render actor member icon and label', () => {
|
|
29
|
+
const actors = {
|
|
30
|
+
Type: {
|
|
31
|
+
members: [
|
|
32
|
+
{
|
|
33
|
+
objectURI: 'uri',
|
|
34
|
+
label: 'Type Actor',
|
|
35
|
+
type: 'configuration/entityTypes/Type'
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const wrapper = mount(<ActorsRenderer value={actors} />);
|
|
41
|
+
const entityTypeIcon = wrapper.find(EntityTypeIcon);
|
|
42
|
+
expect(entityTypeIcon).toHaveLength(1);
|
|
43
|
+
expect(entityTypeIcon.props()).toMatchObject({
|
|
44
|
+
entityType: metadata.entityTypes[0]
|
|
45
|
+
});
|
|
46
|
+
expect(wrapper.find('.entityLabel').text()).toBe(actors.Type.members[0].label);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should render <No label> if entity label is empty', () => {
|
|
50
|
+
const actors = {
|
|
51
|
+
Type: {
|
|
52
|
+
members: [
|
|
53
|
+
{
|
|
54
|
+
objectURI: 'uri',
|
|
55
|
+
type: 'configuration/entityTypes/Type'
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const wrapper = mount(<ActorsRenderer value={actors} />);
|
|
61
|
+
expect(wrapper.find('.entityLabel').text()).toBe(NO_LABEL);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should dispatch open entity action on entity label click', () => {
|
|
65
|
+
const actors = {
|
|
66
|
+
Type: {
|
|
67
|
+
members: [
|
|
68
|
+
{
|
|
69
|
+
objectURI: 'uri',
|
|
70
|
+
label: 'Type Actor',
|
|
71
|
+
type: 'configuration/entityTypes/Type'
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const wrapper = mount(
|
|
77
|
+
<ViewIdContext.Provider value="view123">
|
|
78
|
+
<ActorsRenderer value={actors} />
|
|
79
|
+
</ViewIdContext.Provider>
|
|
80
|
+
);
|
|
81
|
+
expect(dispatch).not.toBeCalled();
|
|
82
|
+
wrapper.find('.entityLabel').simulate('click');
|
|
83
|
+
expect(dispatch).toHaveBeenCalledWith(
|
|
84
|
+
ui.actions.openEntity({uri: actors.Type.members[0].objectURI, viewId: 'view123'})
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
});
|