@pega/react-sdk-overrides 23.1.11 → 23.1.12
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/lib/designSystemExtension/CaseSummaryFields/CaseSummaryFields.tsx +2 -2
- package/lib/designSystemExtension/FieldValueList/FieldValueList.tsx +10 -4
- package/lib/field/Checkbox/Checkbox.tsx +101 -23
- package/lib/field/Decimal/Decimal.tsx +12 -3
- package/lib/field/MultiSelect/Multiselect.tsx +244 -0
- package/lib/field/MultiSelect/index.tsx +1 -0
- package/lib/field/MultiSelect/utils.ts +230 -0
- package/lib/field/RichText/RichText.tsx +2 -2
- package/lib/helpers/common-utils.ts +1 -1
- package/lib/helpers/instructions-utils.ts +38 -0
- package/lib/infra/NavBar/NavBar.tsx +1 -1
- package/lib/infra/Reference/Reference.tsx +1 -1
- package/lib/template/ListView/ListView.tsx +6 -6
- package/lib/template/SimpleTable/SimpleTableManual/SimpleTableManual.tsx +4 -4
- package/package.json +1 -1
|
@@ -109,9 +109,9 @@ export default function CaseSummaryFields(props: CaseSummaryFieldsProps) {
|
|
|
109
109
|
label={field.config.label}
|
|
110
110
|
InputProps={{
|
|
111
111
|
readOnly: true,
|
|
112
|
+
disableUnderline: true,
|
|
112
113
|
inputProps: {
|
|
113
|
-
style: { cursor: 'pointer' }
|
|
114
|
-
disableUnderline: true
|
|
114
|
+
style: { cursor: 'pointer' }
|
|
115
115
|
}
|
|
116
116
|
}}
|
|
117
117
|
/>
|
|
@@ -9,6 +9,7 @@ interface FieldValueListProps {
|
|
|
9
9
|
name?: string;
|
|
10
10
|
value: any;
|
|
11
11
|
variant?: string;
|
|
12
|
+
isHtml?: boolean;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
const useStyles = makeStyles(theme => ({
|
|
@@ -45,7 +46,7 @@ function formatItemValue(value) {
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
export default function FieldValueList(props: FieldValueListProps) {
|
|
48
|
-
const { name, value, variant = 'inline' } = props;
|
|
49
|
+
const { name, value, variant = 'inline', isHtml = false } = props;
|
|
49
50
|
const classes = useStyles();
|
|
50
51
|
|
|
51
52
|
function getGridItemLabel() {
|
|
@@ -63,9 +64,14 @@ export default function FieldValueList(props: FieldValueListProps) {
|
|
|
63
64
|
|
|
64
65
|
return (
|
|
65
66
|
<Grid item xs={variant === 'stacked' ? 12 : 6} className={variant === 'stacked' ? classes.noPaddingTop : ''}>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
{isHtml ? (
|
|
68
|
+
// eslint-disable-next-line react/no-danger
|
|
69
|
+
<div dangerouslySetInnerHTML={{ __html: formattedValue }} />
|
|
70
|
+
) : (
|
|
71
|
+
<Typography variant={variant === 'stacked' ? 'h6' : 'body2'} component='span' className={classes.fieldValue}>
|
|
72
|
+
{formattedValue}
|
|
73
|
+
</Typography>
|
|
74
|
+
)}
|
|
69
75
|
</Grid>
|
|
70
76
|
);
|
|
71
77
|
}
|
|
@@ -1,19 +1,35 @@
|
|
|
1
|
+
/* eslint-disable react/no-array-index-key */
|
|
1
2
|
import { useState, useEffect } from 'react';
|
|
2
3
|
import { Checkbox, FormControl, FormControlLabel, FormGroup, FormHelperText, FormLabel } from '@material-ui/core';
|
|
3
4
|
|
|
4
5
|
import handleEvent from '@pega/react-sdk-components/lib/components/helpers/event-utils';
|
|
5
6
|
import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
|
|
7
|
+
import { insertInstruction, deleteInstruction, updateNewInstuctions } from '@pega/react-sdk-components/lib/components/helpers/instructions-utils';
|
|
6
8
|
import { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
|
|
9
|
+
import { makeStyles } from '@material-ui/core/styles';
|
|
7
10
|
|
|
8
11
|
interface CheckboxProps extends Omit<PConnFieldProps, 'value'> {
|
|
9
12
|
// If any, enter additional props that only exist on Checkbox here
|
|
10
13
|
value?: boolean;
|
|
11
|
-
// eslint-disable-next-line react/no-unused-prop-types
|
|
12
14
|
caption?: string;
|
|
13
15
|
trueLabel?: string;
|
|
14
16
|
falseLabel?: string;
|
|
17
|
+
selectionMode?: string;
|
|
18
|
+
datasource?: any;
|
|
19
|
+
selectionKey?: string;
|
|
20
|
+
selectionList?: any;
|
|
21
|
+
primaryField: string;
|
|
22
|
+
readonlyContextList: any;
|
|
23
|
+
referenceList: string;
|
|
15
24
|
}
|
|
16
25
|
|
|
26
|
+
const useStyles = makeStyles(() => ({
|
|
27
|
+
checkbox: {
|
|
28
|
+
display: 'flex',
|
|
29
|
+
flexDirection: 'column'
|
|
30
|
+
}
|
|
31
|
+
}));
|
|
32
|
+
|
|
17
33
|
export default function CheckboxComponent(props: CheckboxProps) {
|
|
18
34
|
// Get emitted components from map (so we can get any override that may exist)
|
|
19
35
|
const FieldValueList = getComponentFromMap('FieldValueList');
|
|
@@ -21,7 +37,8 @@ export default function CheckboxComponent(props: CheckboxProps) {
|
|
|
21
37
|
const {
|
|
22
38
|
getPConnect,
|
|
23
39
|
label,
|
|
24
|
-
|
|
40
|
+
caption,
|
|
41
|
+
value,
|
|
25
42
|
readOnly,
|
|
26
43
|
testId,
|
|
27
44
|
required,
|
|
@@ -32,22 +49,34 @@ export default function CheckboxComponent(props: CheckboxProps) {
|
|
|
32
49
|
displayMode,
|
|
33
50
|
hideLabel,
|
|
34
51
|
trueLabel,
|
|
35
|
-
falseLabel
|
|
52
|
+
falseLabel,
|
|
53
|
+
selectionMode,
|
|
54
|
+
datasource,
|
|
55
|
+
selectionKey,
|
|
56
|
+
selectionList,
|
|
57
|
+
primaryField,
|
|
58
|
+
referenceList,
|
|
59
|
+
readonlyContextList: selectedvalues
|
|
36
60
|
} = props;
|
|
61
|
+
const classes = useStyles();
|
|
37
62
|
const helperTextToDisplay = validatemessage || helperText;
|
|
38
|
-
|
|
39
63
|
const thePConn = getPConnect();
|
|
40
|
-
const theConfigProps = thePConn.getConfigProps() as CheckboxProps;
|
|
41
|
-
const caption = theConfigProps.caption;
|
|
42
64
|
const actionsApi = thePConn.getActionsApi();
|
|
43
65
|
const propName = (thePConn.getStateProps() as any).value;
|
|
44
66
|
|
|
45
|
-
const [checked, setChecked] = useState(false);
|
|
67
|
+
const [checked, setChecked] = useState<any>(false);
|
|
46
68
|
useEffect(() => {
|
|
47
69
|
// This update theSelectedButton which will update the UI to show the selected button correctly
|
|
48
70
|
setChecked(value);
|
|
49
71
|
}, [value]);
|
|
50
72
|
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (referenceList?.length > 0) {
|
|
75
|
+
thePConn.setReferenceList(selectionList);
|
|
76
|
+
updateNewInstuctions(thePConn, selectionList);
|
|
77
|
+
}
|
|
78
|
+
}, [thePConn]);
|
|
79
|
+
|
|
51
80
|
if (displayMode === 'LABELS_LEFT') {
|
|
52
81
|
return <FieldValueList name={hideLabel ? '' : caption} value={value ? trueLabel : falseLabel} />;
|
|
53
82
|
}
|
|
@@ -64,28 +93,77 @@ export default function CheckboxComponent(props: CheckboxProps) {
|
|
|
64
93
|
thePConn.getValidationApi().validate(event.target.checked);
|
|
65
94
|
};
|
|
66
95
|
|
|
67
|
-
|
|
96
|
+
const handleChangeMultiMode = (event, element) => {
|
|
97
|
+
if (event.target.checked) {
|
|
98
|
+
insertInstruction(thePConn, selectionList, selectionKey, primaryField, {
|
|
99
|
+
id: element.key,
|
|
100
|
+
primary: element.text ?? element.value
|
|
101
|
+
});
|
|
102
|
+
} else {
|
|
103
|
+
deleteInstruction(thePConn, selectionList, selectionKey, {
|
|
104
|
+
id: element.key,
|
|
105
|
+
primary: element.text ?? element.value
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
thePConn.clearErrorMessages({
|
|
109
|
+
property: selectionList,
|
|
110
|
+
category: '',
|
|
111
|
+
context: ''
|
|
112
|
+
});
|
|
113
|
+
};
|
|
68
114
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
115
|
+
let theCheckbox;
|
|
116
|
+
const listOfCheckboxes: any = [];
|
|
117
|
+
if (selectionMode === 'multi') {
|
|
118
|
+
const listSourceItems = datasource?.source ?? [];
|
|
119
|
+
const dataField: any = selectionKey?.split?.('.')[1];
|
|
120
|
+
listSourceItems.forEach((element, index) => {
|
|
121
|
+
listOfCheckboxes.push(
|
|
122
|
+
<FormControlLabel
|
|
123
|
+
control={
|
|
124
|
+
<Checkbox
|
|
125
|
+
key={index}
|
|
126
|
+
checked={selectedvalues?.some?.(data => data[dataField] === element.key)}
|
|
127
|
+
onChange={event => handleChangeMultiMode(event, element)}
|
|
128
|
+
onBlur={() => {
|
|
129
|
+
thePConn.getValidationApi().validate(selectedvalues, selectionList);
|
|
130
|
+
}}
|
|
131
|
+
data-testid={`${testId}:${element.value}`}
|
|
132
|
+
/>
|
|
133
|
+
}
|
|
134
|
+
key={index}
|
|
135
|
+
label={element.text ?? element.value}
|
|
136
|
+
labelPlacement='end'
|
|
137
|
+
data-test-id={testId}
|
|
138
|
+
/>
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
theCheckbox = <div className={classes.checkbox}>{listOfCheckboxes}</div>;
|
|
142
|
+
} else {
|
|
143
|
+
theCheckbox = (
|
|
144
|
+
<FormControlLabel
|
|
145
|
+
control={
|
|
146
|
+
<Checkbox
|
|
147
|
+
color='primary'
|
|
148
|
+
checked={checked}
|
|
149
|
+
onChange={!readOnly ? handleChange : undefined}
|
|
150
|
+
onBlur={!readOnly ? handleBlur : undefined}
|
|
151
|
+
value={value}
|
|
152
|
+
disabled={disabled}
|
|
153
|
+
readOnly={readOnly}
|
|
154
|
+
/>
|
|
155
|
+
}
|
|
156
|
+
label={caption}
|
|
157
|
+
labelPlacement='end'
|
|
158
|
+
data-test-id={testId}
|
|
159
|
+
/>
|
|
160
|
+
);
|
|
73
161
|
}
|
|
74
162
|
|
|
75
163
|
return (
|
|
76
164
|
<FormControl required={required} error={status === 'error'}>
|
|
77
165
|
{!hideLabel && <FormLabel component='legend'>{label}</FormLabel>}
|
|
78
|
-
<FormGroup>
|
|
79
|
-
<FormControlLabel
|
|
80
|
-
control={theCheckbox}
|
|
81
|
-
checked={checked}
|
|
82
|
-
onChange={!readOnly ? handleChange : undefined}
|
|
83
|
-
onBlur={!readOnly ? handleBlur : undefined}
|
|
84
|
-
label={caption}
|
|
85
|
-
labelPlacement='end'
|
|
86
|
-
data-test-id={testId}
|
|
87
|
-
/>
|
|
88
|
-
</FormGroup>
|
|
166
|
+
<FormGroup>{theCheckbox}</FormGroup>
|
|
89
167
|
<FormHelperText>{helperTextToDisplay}</FormHelperText>
|
|
90
168
|
</FormControl>
|
|
91
169
|
);
|
|
@@ -15,6 +15,7 @@ interface DecimalProps extends PConnFieldProps {
|
|
|
15
15
|
currencyISOCode?: string;
|
|
16
16
|
decimalPrecision?: number;
|
|
17
17
|
showGroupSeparators?: string;
|
|
18
|
+
formatter?: string;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export default function Decimal(props: DecimalProps) {
|
|
@@ -38,7 +39,8 @@ export default function Decimal(props: DecimalProps) {
|
|
|
38
39
|
decimalPrecision = 2,
|
|
39
40
|
showGroupSeparators = true,
|
|
40
41
|
testId,
|
|
41
|
-
placeholder
|
|
42
|
+
placeholder,
|
|
43
|
+
formatter
|
|
42
44
|
} = props;
|
|
43
45
|
|
|
44
46
|
const pConn = getPConnect();
|
|
@@ -49,9 +51,16 @@ export default function Decimal(props: DecimalProps) {
|
|
|
49
51
|
const theSymbols = getCurrencyCharacters(currencyISOCode);
|
|
50
52
|
const theCurrDec = theSymbols.theDecimalIndicator;
|
|
51
53
|
const theCurrSep = theSymbols.theDigitGroupSeparator;
|
|
54
|
+
const theCurrSym = theSymbols.theCurrencySymbol;
|
|
52
55
|
|
|
53
56
|
const theCurrencyOptions = getCurrencyOptions(currencyISOCode);
|
|
54
|
-
|
|
57
|
+
|
|
58
|
+
let formattedValue = '';
|
|
59
|
+
if (formatter === 'Currency') {
|
|
60
|
+
formattedValue = format(value, formatter.toLowerCase(), theCurrencyOptions);
|
|
61
|
+
} else {
|
|
62
|
+
formattedValue = format(value, pConn.getComponentName().toLowerCase(), theCurrencyOptions);
|
|
63
|
+
}
|
|
55
64
|
|
|
56
65
|
if (displayMode === 'LABELS_LEFT') {
|
|
57
66
|
return <FieldValueList name={hideLabel ? '' : label} value={formattedValue} />;
|
|
@@ -86,7 +95,7 @@ export default function Decimal(props: DecimalProps) {
|
|
|
86
95
|
outputFormat='number'
|
|
87
96
|
textAlign='left'
|
|
88
97
|
InputProps={{ inputProps: { ...testProp } }}
|
|
89
|
-
currencySymbol=''
|
|
98
|
+
currencySymbol={readOnly && formatter === 'Currency' ? theCurrSym : ''}
|
|
90
99
|
decimalCharacter={theCurrDec}
|
|
91
100
|
digitGroupSeparator={showGroupSeparators ? theCurrSep : ''}
|
|
92
101
|
decimalPlaces={decimalPrecision}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { Checkbox, TextField } from '@material-ui/core';
|
|
2
|
+
import Autocomplete from '@material-ui/lab/Autocomplete';
|
|
3
|
+
import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';
|
|
4
|
+
import CheckBoxIcon from '@material-ui/icons/CheckBox';
|
|
5
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
6
|
+
import { doSearch, getDisplayFieldsMetaData, useDeepMemo, preProcessColumns, getGroupDataForItemsTree } from './utils';
|
|
7
|
+
import { insertInstruction, deleteInstruction } from '@pega/react-sdk-components/lib/components/helpers/instructions-utils';
|
|
8
|
+
import { debounce } from 'throttle-debounce';
|
|
9
|
+
|
|
10
|
+
const icon = <CheckBoxOutlineBlankIcon fontSize='small' />;
|
|
11
|
+
const checkedIcon = <CheckBoxIcon fontSize='small' />;
|
|
12
|
+
|
|
13
|
+
export default function Multiselect(props) {
|
|
14
|
+
const {
|
|
15
|
+
getPConnect,
|
|
16
|
+
label,
|
|
17
|
+
placeholder,
|
|
18
|
+
referenceList,
|
|
19
|
+
selectionKey,
|
|
20
|
+
primaryField,
|
|
21
|
+
initialCaseClass,
|
|
22
|
+
showSecondaryInSearchOnly = false,
|
|
23
|
+
listType = '',
|
|
24
|
+
isGroupData = false,
|
|
25
|
+
referenceType,
|
|
26
|
+
secondaryFields,
|
|
27
|
+
groupDataSource = [],
|
|
28
|
+
parameters = {},
|
|
29
|
+
matchPosition = 'contains',
|
|
30
|
+
maxResultsDisplay,
|
|
31
|
+
groupColumnsConfig = [{}],
|
|
32
|
+
selectionList,
|
|
33
|
+
value
|
|
34
|
+
} = props;
|
|
35
|
+
let { datasource = [], columns = [{}] } = props;
|
|
36
|
+
|
|
37
|
+
if (referenceList.length > 0) {
|
|
38
|
+
datasource = referenceList;
|
|
39
|
+
columns = [
|
|
40
|
+
{
|
|
41
|
+
value: primaryField,
|
|
42
|
+
display: 'true',
|
|
43
|
+
useForSearch: true,
|
|
44
|
+
primary: 'true'
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
value: selectionKey,
|
|
48
|
+
setProperty: selectionKey,
|
|
49
|
+
key: 'true'
|
|
50
|
+
}
|
|
51
|
+
];
|
|
52
|
+
let secondaryColumns: any = [];
|
|
53
|
+
if (secondaryFields) {
|
|
54
|
+
secondaryColumns = secondaryFields.map(secondaryField => ({
|
|
55
|
+
value: secondaryField,
|
|
56
|
+
display: 'true',
|
|
57
|
+
secondary: 'true',
|
|
58
|
+
useForSearch: 'true'
|
|
59
|
+
}));
|
|
60
|
+
} else {
|
|
61
|
+
secondaryColumns = [
|
|
62
|
+
{
|
|
63
|
+
value: selectionKey,
|
|
64
|
+
display: 'true',
|
|
65
|
+
secondary: 'true',
|
|
66
|
+
useForSearch: 'true'
|
|
67
|
+
}
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
if (referenceType === 'Case') {
|
|
71
|
+
columns = [...columns, ...secondaryColumns];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const [inputValue, setInputValue] = useState(value);
|
|
75
|
+
const [selectedItems, setSelectedItems] = useState([]);
|
|
76
|
+
|
|
77
|
+
const dataConfig = useDeepMemo(() => {
|
|
78
|
+
return {
|
|
79
|
+
dataSource: datasource,
|
|
80
|
+
groupDataSource,
|
|
81
|
+
isGroupData,
|
|
82
|
+
showSecondaryInSearchOnly,
|
|
83
|
+
parameters,
|
|
84
|
+
matchPosition,
|
|
85
|
+
listType,
|
|
86
|
+
maxResultsDisplay: maxResultsDisplay || '100',
|
|
87
|
+
columns: preProcessColumns(columns),
|
|
88
|
+
groupColumnsConfig: preProcessColumns(groupColumnsConfig)
|
|
89
|
+
};
|
|
90
|
+
}, [
|
|
91
|
+
datasource,
|
|
92
|
+
groupDataSource,
|
|
93
|
+
isGroupData,
|
|
94
|
+
showSecondaryInSearchOnly,
|
|
95
|
+
parameters,
|
|
96
|
+
matchPosition,
|
|
97
|
+
listType,
|
|
98
|
+
maxResultsDisplay,
|
|
99
|
+
columns,
|
|
100
|
+
groupColumnsConfig
|
|
101
|
+
]);
|
|
102
|
+
const groupsDisplayFieldMeta = useMemo(
|
|
103
|
+
() => (listType !== 'associated' ? getDisplayFieldsMetaData(dataConfig.groupColumnsConfig) : null),
|
|
104
|
+
[dataConfig.groupColumnsConfig]
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const itemsTreeBaseData = getGroupDataForItemsTree(groupDataSource, groupsDisplayFieldMeta, showSecondaryInSearchOnly) || [];
|
|
108
|
+
|
|
109
|
+
const [itemsTree, setItemsTree] = useState(
|
|
110
|
+
isGroupData ? getGroupDataForItemsTree(groupDataSource, groupsDisplayFieldMeta, showSecondaryInSearchOnly) : []
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const displayFieldMeta = listType !== 'associated' ? getDisplayFieldsMetaData(dataConfig.columns) : null;
|
|
114
|
+
const getCaseListBasedOnParamsDebounced: any = useRef();
|
|
115
|
+
const pConn = getPConnect();
|
|
116
|
+
const contextName = pConn.getContextName();
|
|
117
|
+
const listActions = pConn.getListActions();
|
|
118
|
+
const dataApiObj = useRef();
|
|
119
|
+
|
|
120
|
+
// main search function trigger
|
|
121
|
+
const getCaseListBasedOnParams = async (searchText, group, selectedRows, currentItemsTree, isTriggeredFromSearch = false) => {
|
|
122
|
+
if (referenceList && referenceList.length > 0) {
|
|
123
|
+
selectedRows = await listActions.getSelectedRows(true);
|
|
124
|
+
|
|
125
|
+
selectedRows =
|
|
126
|
+
selectedRows &&
|
|
127
|
+
selectedRows.map(item => {
|
|
128
|
+
return {
|
|
129
|
+
id: item[selectionKey.startsWith('.') ? selectionKey.substring(1) : selectionKey],
|
|
130
|
+
primary: item[primaryField.startsWith('.') ? primaryField.substring(1) : primaryField]
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
setSelectedItems(selectedRows);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// if items tree is null or text search is triggered then always should use fresh data object, we use the original object
|
|
137
|
+
const initalItemsTree = isTriggeredFromSearch || !currentItemsTree ? [...itemsTreeBaseData] : [...currentItemsTree];
|
|
138
|
+
const res = await doSearch(
|
|
139
|
+
searchText,
|
|
140
|
+
group,
|
|
141
|
+
initialCaseClass,
|
|
142
|
+
displayFieldMeta,
|
|
143
|
+
dataApiObj.current,
|
|
144
|
+
initalItemsTree,
|
|
145
|
+
isGroupData,
|
|
146
|
+
showSecondaryInSearchOnly,
|
|
147
|
+
selectedRows || []
|
|
148
|
+
);
|
|
149
|
+
setItemsTree(res);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
if (referenceList && referenceList.length > 0) {
|
|
154
|
+
pConn.setReferenceList(selectionList);
|
|
155
|
+
}
|
|
156
|
+
}, [pConn]);
|
|
157
|
+
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
getCaseListBasedOnParamsDebounced.current = debounce(500, getCaseListBasedOnParams);
|
|
160
|
+
}, []);
|
|
161
|
+
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
if (listType !== 'associated') {
|
|
164
|
+
PCore.getDataApi()
|
|
165
|
+
?.init(dataConfig, contextName)
|
|
166
|
+
.then(dataObj => {
|
|
167
|
+
dataApiObj.current = dataObj;
|
|
168
|
+
if (!isGroupData) {
|
|
169
|
+
getCaseListBasedOnParamsDebounced.current(inputValue ?? '', '', [...selectedItems], [...itemsTree]);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}, [dataConfig, listType, dataConfig.columns, inputValue, dataConfig.groupColumnsConfig, showSecondaryInSearchOnly]);
|
|
174
|
+
|
|
175
|
+
const onSearchHandler = ev => {
|
|
176
|
+
const searchText = ev.target.value;
|
|
177
|
+
setInputValue(searchText);
|
|
178
|
+
getCaseListBasedOnParamsDebounced.current(searchText, '', [...selectedItems], [...itemsTree], true);
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const setSelectedItemsForReferenceList = item => {
|
|
182
|
+
// Clear error messages if any
|
|
183
|
+
const propName = pConn.getStateProps().selectionList;
|
|
184
|
+
pConn.clearErrorMessages({
|
|
185
|
+
property: propName
|
|
186
|
+
});
|
|
187
|
+
const { selected } = item;
|
|
188
|
+
if (selected) {
|
|
189
|
+
insertInstruction(pConn, selectionList, selectionKey, primaryField, item);
|
|
190
|
+
} else {
|
|
191
|
+
deleteInstruction(pConn, selectionList, selectionKey, item);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const handleChange = (event, newSelectedValues) => {
|
|
196
|
+
let clickedItem;
|
|
197
|
+
let updatedItems: any = [];
|
|
198
|
+
if (newSelectedValues && newSelectedValues.length > 0) {
|
|
199
|
+
updatedItems = newSelectedValues.map(ele => {
|
|
200
|
+
ele.selected = true;
|
|
201
|
+
return ele;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
if (newSelectedValues.length > selectedItems.length) {
|
|
205
|
+
clickedItem = newSelectedValues.filter(item => !selectedItems.some((ele: any) => ele.id === item.id));
|
|
206
|
+
} else {
|
|
207
|
+
clickedItem = selectedItems.filter((item: any) => !newSelectedValues.some((ele: any) => ele.id === item.id));
|
|
208
|
+
clickedItem[0].selected = false;
|
|
209
|
+
}
|
|
210
|
+
itemsTree.forEach(ele => {
|
|
211
|
+
ele.selected = !!updatedItems.find(item => item.id === ele.id);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
setSelectedItems(updatedItems);
|
|
215
|
+
setItemsTree(itemsTree);
|
|
216
|
+
|
|
217
|
+
setInputValue('');
|
|
218
|
+
|
|
219
|
+
// if this is a referenceList case
|
|
220
|
+
if (referenceList) setSelectedItemsForReferenceList(clickedItem[0]);
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
return (
|
|
224
|
+
<Autocomplete
|
|
225
|
+
multiple
|
|
226
|
+
fullWidth
|
|
227
|
+
options={itemsTree}
|
|
228
|
+
disableCloseOnSelect
|
|
229
|
+
getOptionSelected={(option: any, val: any) => option?.primary === val?.primary}
|
|
230
|
+
getOptionLabel={(option: any) => option?.primary}
|
|
231
|
+
onChange={handleChange}
|
|
232
|
+
value={selectedItems}
|
|
233
|
+
renderOption={(option: any, { selected }) => (
|
|
234
|
+
<>
|
|
235
|
+
<Checkbox icon={icon} checkedIcon={checkedIcon} style={{ marginRight: 8 }} checked={selected} />
|
|
236
|
+
{option.primary}
|
|
237
|
+
</>
|
|
238
|
+
)}
|
|
239
|
+
renderInput={params => (
|
|
240
|
+
<TextField {...params} variant='outlined' fullWidth label={label} placeholder={placeholder} size='small' onChange={onSearchHandler} />
|
|
241
|
+
)}
|
|
242
|
+
/>
|
|
243
|
+
);
|
|
244
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './Multiselect';
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
import equal from 'fast-deep-equal';
|
|
3
|
+
import cloneDeep from 'lodash/cloneDeep';
|
|
4
|
+
import { updateNewInstuctions, insertInstruction, deleteInstruction } from '@pega/react-sdk-components/lib/components/helpers/instructions-utils';
|
|
5
|
+
|
|
6
|
+
export const setVisibilityForList = (c11nEnv, visibility) => {
|
|
7
|
+
const { selectionMode, selectionList, renderMode, referenceList } = c11nEnv.getComponentConfig();
|
|
8
|
+
// usecase:multiselect, fieldgroup, editable table
|
|
9
|
+
if ((selectionMode === PCore.getConstants().LIST_SELECTION_MODE.MULTI && selectionList) || (renderMode === 'Editable' && referenceList)) {
|
|
10
|
+
c11nEnv.getListActions().setVisibility(visibility);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const useDeepMemo = (memoFn, key) => {
|
|
15
|
+
const ref: any = useRef();
|
|
16
|
+
if (!ref.current || !equal(key, ref.current.key)) {
|
|
17
|
+
ref.current = { key, value: memoFn() };
|
|
18
|
+
}
|
|
19
|
+
return ref.current.value;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const preProcessColumns = columns => {
|
|
23
|
+
return columns?.map(col => {
|
|
24
|
+
const tempColObj = { ...col };
|
|
25
|
+
tempColObj.value = col.value && col.value.startsWith('.') ? col.value.substring(1) : col.value;
|
|
26
|
+
if (tempColObj.setProperty) {
|
|
27
|
+
tempColObj.setProperty = col.setProperty && col.setProperty.startsWith('.') ? col.setProperty.substring(1) : col.setProperty;
|
|
28
|
+
}
|
|
29
|
+
return tempColObj;
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const getDisplayFieldsMetaData = columns => {
|
|
34
|
+
const displayColumns = columns?.filter(col => col.display === 'true');
|
|
35
|
+
const metaDataObj: any = {
|
|
36
|
+
key: '',
|
|
37
|
+
primary: '',
|
|
38
|
+
secondary: []
|
|
39
|
+
};
|
|
40
|
+
const keyCol = columns?.filter(col => col.key === 'true');
|
|
41
|
+
metaDataObj.key = keyCol?.length > 0 ? keyCol[0].value : 'auto';
|
|
42
|
+
const itemsRecordsColumn = columns?.filter(col => col.itemsRecordsColumn === 'true');
|
|
43
|
+
if (itemsRecordsColumn?.length > 0) {
|
|
44
|
+
metaDataObj.itemsRecordsColumn = itemsRecordsColumn[0].value;
|
|
45
|
+
}
|
|
46
|
+
const itemsGroupKeyColumn = columns?.filter(col => col.itemsGroupKeyColumn === 'true');
|
|
47
|
+
if (itemsGroupKeyColumn?.length > 0) {
|
|
48
|
+
metaDataObj.itemsGroupKeyColumn = itemsGroupKeyColumn[0].value;
|
|
49
|
+
}
|
|
50
|
+
for (let index = 0; index < displayColumns?.length; index += 1) {
|
|
51
|
+
if (displayColumns[index].secondary === 'true') {
|
|
52
|
+
metaDataObj.secondary.push(displayColumns[index].value);
|
|
53
|
+
} else if (displayColumns[index].primary === 'true') {
|
|
54
|
+
metaDataObj.primary = displayColumns[index].value;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return metaDataObj;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const createSingleTreeObejct = (entry, displayFieldMeta, showSecondaryData, selected) => {
|
|
61
|
+
const secondaryArr: any = [];
|
|
62
|
+
displayFieldMeta.secondary.forEach(col => {
|
|
63
|
+
secondaryArr.push(entry[col]);
|
|
64
|
+
});
|
|
65
|
+
const isSelected = selected.some(item => item.id === entry[displayFieldMeta.key]);
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
id: entry[displayFieldMeta.key],
|
|
69
|
+
primary: entry[displayFieldMeta.primary],
|
|
70
|
+
secondary: showSecondaryData ? secondaryArr : [],
|
|
71
|
+
selected: isSelected
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const putItemsDataInItemsTree = (listObjData, displayFieldMeta, itemsTree, showSecondaryInSearchOnly, selected) => {
|
|
76
|
+
let newTreeItems = itemsTree.slice();
|
|
77
|
+
const showSecondaryData = !showSecondaryInSearchOnly;
|
|
78
|
+
for (const obj of listObjData) {
|
|
79
|
+
const items = obj[displayFieldMeta.itemsRecordsColumn].map(entry => createSingleTreeObejct(entry, displayFieldMeta, showSecondaryData, selected));
|
|
80
|
+
|
|
81
|
+
newTreeItems = newTreeItems.map(caseObject => {
|
|
82
|
+
if (caseObject.id === obj[displayFieldMeta.itemsGroupKeyColumn]) {
|
|
83
|
+
caseObject.items = [...items];
|
|
84
|
+
}
|
|
85
|
+
return caseObject;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return newTreeItems;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const prepareSearchResults = (listObjData, displayFieldMeta) => {
|
|
92
|
+
const searchResults: any = [];
|
|
93
|
+
for (const obj of listObjData) {
|
|
94
|
+
searchResults.push(...obj[displayFieldMeta.itemsRecordsColumn]);
|
|
95
|
+
}
|
|
96
|
+
return searchResults;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const doSearch = async (
|
|
100
|
+
searchText,
|
|
101
|
+
clickedGroup,
|
|
102
|
+
initialCaseClass,
|
|
103
|
+
displayFieldMeta,
|
|
104
|
+
dataApiObj, // deep clone of the dataApiObj
|
|
105
|
+
itemsTree,
|
|
106
|
+
isGroupData,
|
|
107
|
+
showSecondaryInSearchOnly,
|
|
108
|
+
selected
|
|
109
|
+
) => {
|
|
110
|
+
let searchTextForUngroupedData = '';
|
|
111
|
+
if (dataApiObj) {
|
|
112
|
+
// creating dataApiObject in grouped data cases
|
|
113
|
+
if (isGroupData) {
|
|
114
|
+
dataApiObj = cloneDeep(dataApiObj);
|
|
115
|
+
dataApiObj.fetchedNQData = false;
|
|
116
|
+
dataApiObj.cache = {};
|
|
117
|
+
|
|
118
|
+
// if we have no search text and no group selected, return the original tree
|
|
119
|
+
if (searchText === '' && clickedGroup === '') {
|
|
120
|
+
return itemsTree;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// setting the inital search text & search classes in ApiObject
|
|
124
|
+
dataApiObj.parameters[Object.keys(dataApiObj.parameters)[1]] = searchText;
|
|
125
|
+
dataApiObj.parameters[Object.keys(dataApiObj.parameters)[0]] = initialCaseClass;
|
|
126
|
+
|
|
127
|
+
// if we have a selected group
|
|
128
|
+
if (clickedGroup) {
|
|
129
|
+
// check if the data for this group is already present and no search text
|
|
130
|
+
if (searchText === '') {
|
|
131
|
+
const containsData = itemsTree.find(item => item.id === clickedGroup);
|
|
132
|
+
// do not make API call when items of respective group are already fetched
|
|
133
|
+
if (containsData?.items?.length) return itemsTree;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
dataApiObj.parameters[Object.keys(dataApiObj.parameters)[0]] = JSON.stringify([clickedGroup]);
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
searchTextForUngroupedData = searchText;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// search API call
|
|
143
|
+
const response = await dataApiObj.fetchData(searchTextForUngroupedData).catch(() => {
|
|
144
|
+
return itemsTree;
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
let listObjData = response.data;
|
|
148
|
+
let newItemsTree = [];
|
|
149
|
+
if (isGroupData) {
|
|
150
|
+
if (searchText) {
|
|
151
|
+
listObjData = prepareSearchResults(listObjData, displayFieldMeta);
|
|
152
|
+
} else {
|
|
153
|
+
newItemsTree = putItemsDataInItemsTree(listObjData, displayFieldMeta, itemsTree, showSecondaryInSearchOnly, selected);
|
|
154
|
+
return newItemsTree;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const showSecondaryData = showSecondaryInSearchOnly ? !!searchText : true;
|
|
158
|
+
if (listObjData !== undefined && listObjData.length > 0) {
|
|
159
|
+
newItemsTree = listObjData.map(entry => createSingleTreeObejct(entry, displayFieldMeta, showSecondaryData, selected));
|
|
160
|
+
}
|
|
161
|
+
return newItemsTree;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return itemsTree;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const setValuesToPropertyList = (searchText, assocProp, items, columns, actions, updatePropertyInRedux = true) => {
|
|
168
|
+
const setPropertyList = columns
|
|
169
|
+
?.filter(col => col.setProperty)
|
|
170
|
+
.map(col => {
|
|
171
|
+
return {
|
|
172
|
+
source: col.value,
|
|
173
|
+
target: col.setProperty,
|
|
174
|
+
key: col.key,
|
|
175
|
+
primary: col.primary
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
const valueToSet: any = [];
|
|
179
|
+
if (setPropertyList.length > 0) {
|
|
180
|
+
setPropertyList.forEach(prop => {
|
|
181
|
+
items.forEach(item => {
|
|
182
|
+
if (prop.key === 'true' && item) {
|
|
183
|
+
valueToSet.push(item.id);
|
|
184
|
+
} else if (prop.primary === 'true' || !item) {
|
|
185
|
+
valueToSet.push(searchText);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
if (updatePropertyInRedux) {
|
|
190
|
+
// BUG-666851 setting options so that the store values are replaced and not merged
|
|
191
|
+
const options = {
|
|
192
|
+
isArrayDeepMerge: false
|
|
193
|
+
};
|
|
194
|
+
if (prop.target === 'Associated property') {
|
|
195
|
+
actions.updateFieldValue(assocProp, valueToSet, options);
|
|
196
|
+
} else {
|
|
197
|
+
actions.updateFieldValue(`.${prop.target}`, valueToSet, options);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
return valueToSet;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const getGroupDataForItemsTree = (groupDataSource, groupsDisplayFieldMeta, showSecondaryInSearchOnly) => {
|
|
206
|
+
return groupDataSource?.map(group => {
|
|
207
|
+
const secondaryArr: any = [];
|
|
208
|
+
groupsDisplayFieldMeta.secondary.forEach(col => {
|
|
209
|
+
secondaryArr.push(group[col]);
|
|
210
|
+
});
|
|
211
|
+
return {
|
|
212
|
+
id: group[groupsDisplayFieldMeta.key],
|
|
213
|
+
primary: group[groupsDisplayFieldMeta.primary],
|
|
214
|
+
secondary: showSecondaryInSearchOnly ? [] : secondaryArr,
|
|
215
|
+
items: []
|
|
216
|
+
};
|
|
217
|
+
});
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
export {
|
|
221
|
+
useDeepMemo,
|
|
222
|
+
preProcessColumns,
|
|
223
|
+
getDisplayFieldsMetaData,
|
|
224
|
+
doSearch,
|
|
225
|
+
setValuesToPropertyList,
|
|
226
|
+
getGroupDataForItemsTree,
|
|
227
|
+
updateNewInstuctions,
|
|
228
|
+
insertInstruction,
|
|
229
|
+
deleteInstruction
|
|
230
|
+
};
|
|
@@ -24,11 +24,11 @@ export default function RichText(props: RichTextProps) {
|
|
|
24
24
|
const helperTextToDisplay = validatemessage || helperText;
|
|
25
25
|
|
|
26
26
|
if (displayMode === 'LABELS_LEFT') {
|
|
27
|
-
return <FieldValueList name={hideLabel ? '' : label} value={value} />;
|
|
27
|
+
return <FieldValueList name={hideLabel ? '' : label} value={value} isHtml />;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
if (displayMode === 'STACKED_LARGE_VAL') {
|
|
31
|
-
return <FieldValueList name={hideLabel ? '' : label} value={value} variant='stacked' />;
|
|
31
|
+
return <FieldValueList name={hideLabel ? '' : label} value={value} isHtml variant='stacked' />;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
let richTextComponent;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const isSelfReferencedProperty = (param, referenceProp) => {
|
|
2
|
+
const [, parentPropName] = param.split('.');
|
|
3
|
+
const referencePropParent = referenceProp?.split('.').pop();
|
|
4
|
+
return parentPropName === referencePropParent;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const updateNewInstuctions = (c11nEnv, selectionList) => {
|
|
8
|
+
const { datasource: { parameters = {} } = {} } = c11nEnv.getFieldMetadata(selectionList) || {};
|
|
9
|
+
const compositeKeys: any = [];
|
|
10
|
+
Object.values(parameters).forEach((param: any) => {
|
|
11
|
+
if (isSelfReferencedProperty(param, selectionList)) compositeKeys.push(param.substring(param.lastIndexOf('.') + 1));
|
|
12
|
+
});
|
|
13
|
+
c11nEnv.getListActions().initDefaultPageInstructions(selectionList, compositeKeys);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const insertInstruction = (c11nEnv, selectionList, selectionKey, primaryField, item) => {
|
|
17
|
+
const { id, primary } = item;
|
|
18
|
+
const actualProperty = selectionKey.startsWith('.') ? selectionKey.substring(1) : selectionKey;
|
|
19
|
+
const displayProperty = primaryField.startsWith('.') ? primaryField.substring(1) : primaryField;
|
|
20
|
+
const rows = c11nEnv.getValue(`${c11nEnv.getPageReference()}${selectionList}`) || [];
|
|
21
|
+
const startIndex = rows.length;
|
|
22
|
+
const content = {
|
|
23
|
+
[actualProperty]: id,
|
|
24
|
+
[displayProperty]: primary,
|
|
25
|
+
nonFormProperties: actualProperty !== displayProperty ? [displayProperty] : []
|
|
26
|
+
};
|
|
27
|
+
c11nEnv.getListActions().insert(content, startIndex);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const deleteInstruction = (c11nEnv, selectionList, selectionKey, item) => {
|
|
31
|
+
const { id } = item;
|
|
32
|
+
const actualProperty = selectionKey.startsWith('.') ? selectionKey.substring(1) : selectionKey;
|
|
33
|
+
const rows = c11nEnv.getValue(`${c11nEnv.getPageReference()}${selectionList}`) || [];
|
|
34
|
+
const index = rows.findIndex(row => row[actualProperty] === id);
|
|
35
|
+
c11nEnv.getListActions().deleteEntry(index);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export { updateNewInstuctions, insertInstruction, deleteInstruction };
|
|
@@ -249,7 +249,7 @@ export default function NavBar(props: NavBarProps) {
|
|
|
249
249
|
<Divider />
|
|
250
250
|
<List className='marginTopAuto'>
|
|
251
251
|
<>
|
|
252
|
-
<ListItem onClick={navPanelOperatorButtonClick}>
|
|
252
|
+
<ListItem onClick={navPanelOperatorButtonClick} style={{ cursor: 'pointer' }}>
|
|
253
253
|
<ListItemIcon>
|
|
254
254
|
<PersonOutlineIcon fontSize='large' />
|
|
255
255
|
</ListItemIcon>
|
|
@@ -36,7 +36,7 @@ export default function Reference(props: ReferenceProps) {
|
|
|
36
36
|
|
|
37
37
|
// @ts-ignore - Argument of type 'null' is not assignable to parameter of type 'string'.
|
|
38
38
|
const viewComponent: any = pConnect.createComponent(viewObject, null, null, {
|
|
39
|
-
pageReference: context
|
|
39
|
+
pageReference: context && context.startsWith('@CLASS') ? '' : context
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
viewComponent.props.getPConnect().setInheritedConfig({
|
|
@@ -209,10 +209,10 @@ export default function ListView(props: ListViewProps) {
|
|
|
209
209
|
};
|
|
210
210
|
|
|
211
211
|
function descendingComparator<T>(a: T, b: T, orderedBy: keyof T) {
|
|
212
|
-
if (b[orderedBy] < a[orderedBy]) {
|
|
212
|
+
if (!b[orderedBy] || b[orderedBy] < a[orderedBy]) {
|
|
213
213
|
return -1;
|
|
214
214
|
}
|
|
215
|
-
if (b[orderedBy] > a[orderedBy]) {
|
|
215
|
+
if (!a[orderedBy] || b[orderedBy] > a[orderedBy]) {
|
|
216
216
|
return 1;
|
|
217
217
|
}
|
|
218
218
|
return 0;
|
|
@@ -981,7 +981,7 @@ export default function ListView(props: ListViewProps) {
|
|
|
981
981
|
break;
|
|
982
982
|
|
|
983
983
|
default:
|
|
984
|
-
val = column.format && typeof value === 'number' ? column.format(value) : value;
|
|
984
|
+
val = column.format && typeof value === 'number' ? column.format(value) : value || '---';
|
|
985
985
|
}
|
|
986
986
|
return val;
|
|
987
987
|
};
|
|
@@ -1047,7 +1047,7 @@ export default function ListView(props: ListViewProps) {
|
|
|
1047
1047
|
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
|
1048
1048
|
.map(row => {
|
|
1049
1049
|
return (
|
|
1050
|
-
<TableRow key={row.pxRefObjectInsName || row.pyID}>
|
|
1050
|
+
<TableRow key={row.pxRefObjectInsName || row.pyID || row.pyGUID}>
|
|
1051
1051
|
{arColumns.map(column => {
|
|
1052
1052
|
const value = row[column.id];
|
|
1053
1053
|
return (
|
|
@@ -1062,7 +1062,7 @@ export default function ListView(props: ListViewProps) {
|
|
|
1062
1062
|
{column.format && typeof value === 'number' ? column.format(value) : value}
|
|
1063
1063
|
</Link>
|
|
1064
1064
|
) : (
|
|
1065
|
-
<>{column.format && typeof value === 'number' ? column.format(value) : value}</>
|
|
1065
|
+
<>{column.format && typeof value === 'number' ? column.format(value) : value || '---'}</>
|
|
1066
1066
|
)}
|
|
1067
1067
|
</TableCell>
|
|
1068
1068
|
);
|
|
@@ -1104,7 +1104,7 @@ export default function ListView(props: ListViewProps) {
|
|
|
1104
1104
|
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
|
1105
1105
|
.map(row => {
|
|
1106
1106
|
return (
|
|
1107
|
-
<TableRow key={row
|
|
1107
|
+
<TableRow key={row.pxRefObjectInsName || row.pyGUID || row.pyID}>
|
|
1108
1108
|
{selectionMode === SELECTION_MODE.SINGLE && (
|
|
1109
1109
|
<TableCell>
|
|
1110
1110
|
<Radio
|
|
@@ -374,10 +374,10 @@ export default function SimpleTableManual(props: PropsWithChildren<SimpleTableMa
|
|
|
374
374
|
};
|
|
375
375
|
|
|
376
376
|
function descendingComparator<T>(a: T, b: T, orderedBy: keyof T) {
|
|
377
|
-
if (b[orderedBy] < a[orderedBy]) {
|
|
377
|
+
if (!b[orderedBy] || b[orderedBy] < a[orderedBy]) {
|
|
378
378
|
return -1;
|
|
379
379
|
}
|
|
380
|
-
if (b[orderedBy] > a[orderedBy]) {
|
|
380
|
+
if (!a[orderedBy] || b[orderedBy] > a[orderedBy]) {
|
|
381
381
|
return 1;
|
|
382
382
|
}
|
|
383
383
|
return 0;
|
|
@@ -588,7 +588,7 @@ export default function SimpleTableManual(props: PropsWithChildren<SimpleTableMa
|
|
|
588
588
|
direction={orderBy === displayedColumns[index] ? order : 'asc'}
|
|
589
589
|
onClick={createSortHandler(displayedColumns[index])}
|
|
590
590
|
>
|
|
591
|
-
{field.label}
|
|
591
|
+
{field.label || '---'}
|
|
592
592
|
{_showFilteredIcon(field.name) && <FilterListIcon className={classes.moreIcon} />}
|
|
593
593
|
{orderBy === displayedColumns[index] ? (
|
|
594
594
|
<span className={classes.visuallyHidden}>{order === 'desc' ? 'sorted descending' : 'sorted ascending'}</span>
|
|
@@ -671,7 +671,7 @@ export default function SimpleTableManual(props: PropsWithChildren<SimpleTableMa
|
|
|
671
671
|
) : typeof row[colKey] === 'boolean' && row[colKey] ? (
|
|
672
672
|
'True'
|
|
673
673
|
) : (
|
|
674
|
-
row[colKey]
|
|
674
|
+
row[colKey] || '---'
|
|
675
675
|
)}
|
|
676
676
|
</TableCell>
|
|
677
677
|
);
|
package/package.json
CHANGED