@pega/react-sdk-overrides 23.1.11 → 24.1.10

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 (41) hide show
  1. package/lib/designSystemExtension/FieldValueList/FieldValueList.tsx +10 -4
  2. package/lib/field/CancelAlert/CancelAlert.tsx +2 -0
  3. package/lib/field/Checkbox/Checkbox.tsx +101 -23
  4. package/lib/field/Currency/Currency.tsx +36 -26
  5. package/lib/field/Decimal/Decimal.tsx +44 -21
  6. package/lib/field/Multiselect/Multiselect.tsx +244 -0
  7. package/lib/field/Multiselect/index.tsx +1 -0
  8. package/lib/field/Multiselect/utils.ts +230 -0
  9. package/lib/field/Percentage/Percentage.tsx +33 -18
  10. package/lib/field/Phone/Phone.tsx +16 -7
  11. package/lib/field/RichText/RichText.tsx +2 -2
  12. package/lib/field/ScalarList/ScalarList.tsx +2 -0
  13. package/lib/field/UserReference/UserReference.tsx +11 -1
  14. package/lib/helpers/common-utils.ts +1 -5
  15. package/lib/helpers/instructions-utils.ts +38 -0
  16. package/lib/infra/Assignment/Assignment.tsx +28 -1
  17. package/lib/infra/Containers/FlowContainer/FlowContainer.tsx +5 -3
  18. package/lib/infra/DashboardFilter/DashboardFilter.tsx +1 -1
  19. package/lib/infra/DeferLoad/DeferLoad.tsx +5 -1
  20. package/lib/infra/MultiStep/MultiStep.tsx +3 -1
  21. package/lib/infra/NavBar/NavBar.tsx +1 -1
  22. package/lib/infra/Reference/Reference.tsx +1 -1
  23. package/lib/template/CaseView/CaseView.tsx +2 -1
  24. package/lib/template/CaseViewActionsMenu/CaseViewActionsMenu.tsx +1 -1
  25. package/lib/template/DataReference/DataReference.tsx +1 -1
  26. package/lib/template/DefaultForm/utils/index.ts +2 -7
  27. package/lib/template/Details/Details/Details.tsx +1 -1
  28. package/lib/template/Details/DetailsThreeColumn/DetailsThreeColumn.tsx +1 -1
  29. package/lib/template/Details/DetailsTwoColumn/DetailsTwoColumn.tsx +1 -1
  30. package/lib/template/FieldGroupTemplate/FieldGroupTemplate.tsx +2 -0
  31. package/lib/template/ListView/ListView.tsx +22 -33
  32. package/lib/template/MultiReferenceReadOnly/MultiReferenceReadOnly.tsx +1 -1
  33. package/lib/template/NarrowWide/NarrowWideDetails/NarrowWideDetails.tsx +1 -1
  34. package/lib/template/PromotedFilters/PromotedFilters.tsx +1 -0
  35. package/lib/template/SimpleTable/SimpleTableManual/SimpleTableManual.tsx +8 -4
  36. package/lib/template/SingleReferenceReadOnly/SingleReferenceReadOnly.tsx +1 -1
  37. package/lib/template/WideNarrow/WideNarrowDetails/WideNarrowDetails.tsx +1 -1
  38. package/lib/widget/Attachment/Attachment.tsx +3 -2
  39. package/lib/widget/FileUtility/FileUtility/FileUtility.tsx +1 -1
  40. package/lib/widget/QuickCreate/QuickCreate.tsx +1 -0
  41. package/package.json +1 -1
@@ -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
- <Typography variant={variant === 'stacked' ? 'h6' : 'body2'} component='span' className={classes.fieldValue}>
67
- {formattedValue}
68
- </Typography>
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
  }
@@ -21,6 +21,7 @@ export default function CancelAlert(props: CancelAlertProps) {
21
21
  const actionsAPI = getPConnect().getActionsApi();
22
22
  const containerManagerAPI = getPConnect().getContainerManager();
23
23
  const isLocalAction = getPConnect().getValue(PCore.getConstants().CASE_INFO.IS_LOCAL_ACTION);
24
+ // @ts-ignore - Property 'options' is private and only accessible within class 'C11nEnv'.
24
25
  const isBulkAction = getPConnect()?.options?.isBulkAction;
25
26
  const localizedVal = PCore.getLocaleUtils().getLocaleValue;
26
27
  const broadCastUtils: any = PCore.getCoexistenceManager().getBroadcastUtils();
@@ -83,6 +84,7 @@ export default function CancelAlert(props: CancelAlertProps) {
83
84
  actionsAPI.cancelBulkAction(containerItemID);
84
85
  } else {
85
86
  dismiss(true);
87
+ // @ts-ignore - Argument of type '{ containerItemID: string; skipReleaseLockRequest: any; }' is not assignable to parameter of type 'ContainerInfo'.
86
88
  containerManagerAPI.removeContainerItem({ containerItemID, skipReleaseLockRequest });
87
89
  }
88
90
  }
@@ -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
- value = false,
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
- let theCheckbox = <Checkbox color='primary' disabled={disabled} />;
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
- if (readOnly) {
70
- // Workaround for lack of InputProps readOnly from https://github.com/mui-org/material-ui/issues/17043
71
- // Also note that we need to turn off the onChange call in the FormControlLabel wrapper, too. See below!
72
- theCheckbox = <Checkbox value={value || false} readOnly={readOnly} />;
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
  );
@@ -1,18 +1,19 @@
1
- import CurrencyTextField from '@unicef/material-ui-currency-textfield';
2
-
1
+ import { TextField } from '@material-ui/core';
2
+ import { useState } from 'react';
3
+ import { NumericFormat } from 'react-number-format';
3
4
  import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
4
5
  import { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
5
6
  import handleEvent from '@pega/react-sdk-components/lib/components/helpers/event-utils';
6
7
  import { format } from '@pega/react-sdk-components/lib/components/helpers/formatters';
7
8
  import { getCurrencyCharacters, getCurrencyOptions } from './currency-utils';
8
9
 
9
- /* Using @unicef/material-ui-currency-textfield component here, since it allows formatting decimal values,
10
+ /* Using react-number-format component here, since it allows formatting decimal values,
10
11
  as per the locale.
11
12
  */
12
-
13
13
  interface CurrrencyProps extends PConnFieldProps {
14
14
  // If any, enter additional props that only exist on Currency here
15
15
  currencyISOCode?: string;
16
+ allowDecimals: boolean;
16
17
  }
17
18
 
18
19
  export default function Currency(props: CurrrencyProps) {
@@ -34,15 +35,15 @@ export default function Currency(props: CurrrencyProps) {
34
35
  displayMode,
35
36
  hideLabel,
36
37
  currencyISOCode = 'USD',
37
- placeholder
38
+ placeholder,
39
+ allowDecimals
38
40
  } = props;
39
41
 
40
42
  const pConn = getPConnect();
41
43
  const actions = pConn.getActionsApi();
42
44
  const propName = (pConn.getStateProps() as any).value;
43
45
  const helperTextToDisplay = validatemessage || helperText;
44
-
45
- // console.log(`Currency: label: ${label} value: ${value}`);
46
+ const [values, setValues] = useState(value.toString());
46
47
 
47
48
  const testProp = {
48
49
  'data-test-id': testId
@@ -57,6 +58,15 @@ export default function Currency(props: CurrrencyProps) {
57
58
  const theCurrencyOptions = getCurrencyOptions(currencyISOCode);
58
59
  const formattedValue = format(value, pConn.getComponentName().toLowerCase(), theCurrencyOptions);
59
60
 
61
+ let readOnlyProp = {}; // Note: empty if NOT ReadOnly
62
+
63
+ if (readOnly) {
64
+ readOnlyProp = { readOnly: true };
65
+ }
66
+
67
+ let currencyProp = {};
68
+ currencyProp = { prefix: theCurrSym, decimalSeparator: theCurrDec, thousandSeparator: theCurrSep };
69
+
60
70
  if (displayMode === 'LABELS_LEFT') {
61
71
  return <FieldValueList name={hideLabel ? '' : label} value={formattedValue} />;
62
72
  }
@@ -65,34 +75,34 @@ export default function Currency(props: CurrrencyProps) {
65
75
  return <FieldValueList name={hideLabel ? '' : label} value={formattedValue} variant='stacked' />;
66
76
  }
67
77
 
68
- function currOnBlur(event, inValue) {
69
- // console.log(`Currency currOnBlur inValue: ${inValue}`);
70
- handleEvent(actions, 'changeNblur', propName, inValue !== '' ? Number(inValue) : inValue);
78
+ function currOnBlur() {
79
+ handleEvent(actions, 'changeNblur', propName, values);
71
80
  }
72
81
 
73
- // console.log(`theCurrSym: ${theCurrSym} | theCurrDec: ${theCurrDec} | theCurrSep: ${theCurrSep}`);
82
+ const handleChange = val => {
83
+ setValues(val.value);
84
+ };
74
85
 
75
86
  return (
76
- <CurrencyTextField
77
- fullWidth
78
- variant={readOnly ? 'standard' : 'outlined'}
87
+ <NumericFormat
88
+ valueIsNumericString
89
+ label={label}
79
90
  helperText={helperTextToDisplay}
80
91
  placeholder={placeholder ?? ''}
81
- size='small'
82
92
  required={required}
83
93
  disabled={disabled}
84
- readOnly={!!readOnly}
85
- error={status === 'error'}
86
- label={label}
87
- value={value}
88
- type='text'
89
- outputFormat='number'
90
- textAlign='left'
91
- InputProps={{ inputProps: { ...testProp } }}
92
- currencySymbol={theCurrSym}
93
- decimalCharacter={theCurrDec}
94
- digitGroupSeparator={theCurrSep}
94
+ onValueChange={val => {
95
+ handleChange(val);
96
+ }}
95
97
  onBlur={!readOnly ? currOnBlur : undefined}
98
+ error={status === 'error'}
99
+ name='numberformat'
100
+ value={values}
101
+ {...currencyProp}
102
+ decimalScale={allowDecimals !== false ? 2 : 0}
103
+ fixedDecimalScale={allowDecimals}
104
+ InputProps={{ ...readOnlyProp, inputProps: { ...testProp } }}
105
+ customInput={TextField}
96
106
  />
97
107
  );
98
108
  }
@@ -1,12 +1,13 @@
1
- import CurrencyTextField from '@unicef/material-ui-currency-textfield';
2
-
1
+ import { TextField } from '@material-ui/core';
2
+ import { NumericFormat } from 'react-number-format';
3
+ import { useState } from 'react';
3
4
  import { getCurrencyCharacters, getCurrencyOptions } from '@pega/react-sdk-components/lib/components/field/Currency/currency-utils';
4
5
  import handleEvent from '@pega/react-sdk-components/lib/components/helpers/event-utils';
5
6
  import { format } from '@pega/react-sdk-components/lib/components/helpers/formatters';
6
7
  import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
7
8
  import { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
8
9
 
9
- /* Using @unicef/material-ui-currency-textfield component here, since it allows formatting decimal values,
10
+ /* Using react-number-format component here, since it allows formatting decimal values,
10
11
  as per the locale.
11
12
  */
12
13
 
@@ -14,7 +15,8 @@ interface DecimalProps extends PConnFieldProps {
14
15
  // If any, enter additional props that only exist on Decimal here
15
16
  currencyISOCode?: string;
16
17
  decimalPrecision?: number;
17
- showGroupSeparators?: string;
18
+ showGroupSeparators?: boolean;
19
+ formatter?: string;
18
20
  }
19
21
 
20
22
  export default function Decimal(props: DecimalProps) {
@@ -35,12 +37,15 @@ export default function Decimal(props: DecimalProps) {
35
37
  displayMode,
36
38
  hideLabel,
37
39
  currencyISOCode = 'USD',
38
- decimalPrecision = 2,
39
- showGroupSeparators = true,
40
+ decimalPrecision,
41
+ showGroupSeparators,
40
42
  testId,
41
- placeholder
43
+ placeholder,
44
+ formatter
42
45
  } = props;
43
46
 
47
+ const [values, setValues] = useState(value.toString());
48
+
44
49
  const pConn = getPConnect();
45
50
  const actions = pConn.getActionsApi();
46
51
  const propName = (pConn.getStateProps() as any).value;
@@ -49,9 +54,22 @@ export default function Decimal(props: DecimalProps) {
49
54
  const theSymbols = getCurrencyCharacters(currencyISOCode);
50
55
  const theCurrDec = theSymbols.theDecimalIndicator;
51
56
  const theCurrSep = theSymbols.theDigitGroupSeparator;
57
+ const theCurrSym = theSymbols.theCurrencySymbol;
52
58
 
53
59
  const theCurrencyOptions = getCurrencyOptions(currencyISOCode);
54
- const formattedValue = format(value, pConn.getComponentName().toLowerCase(), theCurrencyOptions);
60
+
61
+ let readOnlyProp = {}; // Note: empty if NOT ReadOnly
62
+
63
+ if (readOnly) {
64
+ readOnlyProp = { readOnly: true };
65
+ }
66
+
67
+ let formattedValue = '';
68
+ if (formatter === 'Currency') {
69
+ formattedValue = format(value, formatter.toLowerCase(), theCurrencyOptions);
70
+ } else {
71
+ formattedValue = format(value, pConn.getComponentName().toLowerCase(), theCurrencyOptions);
72
+ }
55
73
 
56
74
  if (displayMode === 'LABELS_LEFT') {
57
75
  return <FieldValueList name={hideLabel ? '' : label} value={formattedValue} />;
@@ -65,12 +83,17 @@ export default function Decimal(props: DecimalProps) {
65
83
  'data-test-id': testId
66
84
  };
67
85
 
68
- function decimalOnBlur(event, inValue) {
69
- handleEvent(actions, 'changeNblur', propName, inValue !== '' ? Number(inValue) : inValue);
86
+ function decimalOnBlur() {
87
+ handleEvent(actions, 'changeNblur', propName, values);
70
88
  }
71
89
 
90
+ const handleChange = val => {
91
+ setValues(val.value);
92
+ };
93
+
72
94
  return (
73
- <CurrencyTextField
95
+ <NumericFormat
96
+ valueIsNumericString
74
97
  fullWidth
75
98
  variant={readOnly ? 'standard' : 'outlined'}
76
99
  helperText={helperTextToDisplay}
@@ -80,17 +103,17 @@ export default function Decimal(props: DecimalProps) {
80
103
  disabled={disabled}
81
104
  error={status === 'error'}
82
105
  label={label}
83
- value={value}
84
- readOnly={!!readOnly}
85
- type='text'
86
- outputFormat='number'
87
- textAlign='left'
88
- InputProps={{ inputProps: { ...testProp } }}
89
- currencySymbol=''
90
- decimalCharacter={theCurrDec}
91
- digitGroupSeparator={showGroupSeparators ? theCurrSep : ''}
92
- decimalPlaces={decimalPrecision}
106
+ value={values}
107
+ onValueChange={val => {
108
+ handleChange(val);
109
+ }}
93
110
  onBlur={!readOnly ? decimalOnBlur : undefined}
111
+ prefix={readOnly && formatter === 'Currency' ? theCurrSym : ''}
112
+ decimalSeparator={theCurrDec}
113
+ thousandSeparator={showGroupSeparators ? theCurrSep : ''}
114
+ decimalScale={readOnly && formatter === 'Currency' ? undefined : decimalPrecision}
115
+ InputProps={{ ...readOnlyProp, inputProps: { ...testProp } }}
116
+ customInput={TextField}
94
117
  />
95
118
  );
96
119
  }