@pega/react-sdk-overrides 0.23.26 → 8.23.11

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 (83) hide show
  1. package/lib/designSystemExtension/AlertBanner/AlertBanner.tsx +43 -0
  2. package/lib/designSystemExtension/AlertBanner/index.tsx +1 -0
  3. package/lib/designSystemExtension/FieldGroupList/FieldGroupList.tsx +1 -3
  4. package/lib/designSystemExtension/Operator/Operator.tsx +16 -11
  5. package/lib/designSystemExtension/WssQuickCreate/WssQuickCreate.tsx +2 -2
  6. package/lib/field/CancelAlert/CancelAlert.tsx +12 -8
  7. package/lib/field/Checkbox/Checkbox.tsx +3 -2
  8. package/lib/field/Currency/currency-utils.ts +4 -1
  9. package/lib/field/Date/Date.tsx +12 -5
  10. package/lib/field/DateTime/DateTime.tsx +1 -1
  11. package/lib/field/Decimal/Decimal.tsx +66 -14
  12. package/lib/field/Dropdown/Dropdown.tsx +49 -10
  13. package/lib/field/Phone/Phone.tsx +2 -1
  14. package/lib/field/RadioButtons/RadioButtons.tsx +43 -4
  15. package/lib/field/SemanticLink/utils.ts +2 -1
  16. package/lib/field/TextInput/TextInput.tsx +26 -6
  17. package/lib/field/Time/Time.tsx +9 -1
  18. package/lib/field/URL/URL.tsx +8 -0
  19. package/lib/field/UserReference/UserReference.tsx +2 -0
  20. package/lib/helpers/{attachmentHelpers.js → attachmentHelpers.ts} +2 -2
  21. package/lib/helpers/authManager.js +16 -13
  22. package/lib/helpers/case-utils.tsx +104 -0
  23. package/lib/helpers/common-utils.ts +4 -0
  24. package/lib/helpers/config_access.js +122 -131
  25. package/lib/helpers/data_page.ts +2 -1
  26. package/lib/helpers/date-format-utils.ts +28 -18
  27. package/lib/helpers/{field-group-utils.js → field-group-utils.ts} +4 -3
  28. package/lib/helpers/formatters/{Currency.js → Currency.ts} +4 -3
  29. package/lib/helpers/formatters/{Date.js → Date.ts} +1 -1
  30. package/lib/helpers/formatters/common.ts +18 -0
  31. package/lib/helpers/simpleTableHelpers.ts +6 -2
  32. package/lib/helpers/state-utils.tsx +50 -0
  33. package/lib/helpers/template-utils.ts +3 -1
  34. package/lib/helpers/utils.ts +12 -4
  35. package/lib/helpers/versionHelpers.ts +3 -1
  36. package/lib/infra/ActionButtons/ActionButtons.tsx +7 -2
  37. package/lib/infra/Assignment/Assignment.tsx +23 -10
  38. package/lib/infra/Containers/FlowContainer/FlowContainer.tsx +24 -11
  39. package/lib/infra/Containers/FlowContainer/{helpers.js → helpers.ts} +21 -16
  40. package/lib/infra/Containers/ModalViewContainer/ModalViewContainer.tsx +28 -9
  41. package/lib/infra/Containers/ViewContainer/ViewContainer.tsx +7 -5
  42. package/lib/infra/DashboardFilter/DashboardFilter.tsx +5 -1
  43. package/lib/infra/DashboardFilter/filterUtils.tsx +2 -0
  44. package/lib/infra/DeferLoad/DeferLoad.tsx +4 -1
  45. package/lib/infra/ErrorBoundary/ErrorBoundary.tsx +10 -5
  46. package/lib/infra/MultiStep/MultiStep.tsx +2 -2
  47. package/lib/infra/NavBar/NavBar.tsx +11 -5
  48. package/lib/infra/RootContainer/RootContainer.tsx +16 -14
  49. package/lib/infra/Stages/Stages.tsx +5 -1
  50. package/lib/infra/View/View.tsx +7 -34
  51. package/lib/template/AppShell/AppShell.tsx +15 -9
  52. package/lib/template/CaseView/CaseView.tsx +116 -78
  53. package/lib/template/CaseViewActionsMenu/CaseViewActionsMenu.tsx +26 -17
  54. package/lib/template/Confirmation/Confirmation.tsx +4 -1
  55. package/lib/template/DataReference/DataReference.tsx +2 -0
  56. package/lib/template/DefaultForm/DefaultForm.tsx +15 -8
  57. package/lib/template/DefaultForm/utils/index.ts +33 -0
  58. package/lib/template/FieldGroupTemplate/FieldGroupTemplate.tsx +5 -2
  59. package/lib/template/ListView/ListView.tsx +3 -1
  60. package/lib/template/ListView/{hooks.js → hooks.ts} +3 -1
  61. package/lib/template/ListView/{utils.js → utils.ts} +12 -10
  62. package/lib/template/MultiReferenceReadOnly/MultiReferenceReadOnly.tsx +5 -1
  63. package/lib/template/PromotedFilters/PromotedFilters.tsx +9 -5
  64. package/lib/template/SimpleTable/SimpleTable/SimpleTable.tsx +4 -1
  65. package/lib/template/SimpleTable/SimpleTableManual/SimpleTableManual.tsx +8 -4
  66. package/lib/template/SimpleTable/SimpleTableSelect/SimpleTableSelect.tsx +6 -1
  67. package/lib/template/SubTabs/tabUtils.ts +3 -1
  68. package/lib/template/WssNavBar/WssNavBar.tsx +2 -2
  69. package/lib/widget/Attachment/Attachment.css +15 -3
  70. package/lib/widget/Attachment/Attachment.tsx +32 -25
  71. package/lib/widget/CaseHistory/CaseHistory.tsx +5 -5
  72. package/lib/widget/FileUtility/FileUtility/FileUtility.tsx +20 -19
  73. package/lib/widget/QuickCreate/QuickCreate.tsx +6 -3
  74. package/lib/widget/SummaryItem/SummaryItem.tsx +2 -4
  75. package/lib/widget/ToDo/ToDo.tsx +17 -9
  76. package/package.json +1 -1
  77. package/lib/helpers/formatters/common.js +0 -14
  78. /package/lib/helpers/{event-utils.js → event-utils.ts} +0 -0
  79. /package/lib/helpers/formatters/{Boolean.js → Boolean.ts} +0 -0
  80. /package/lib/helpers/formatters/{CurrencyMap.js → CurrencyMap.ts} +0 -0
  81. /package/lib/helpers/formatters/{index.js → index.ts} +0 -0
  82. /package/lib/helpers/{reactContextHelpers.js → reactContextHelpers.ts} +0 -0
  83. /package/lib/template/ListView/{DefaultViewMeta.js → DefaultViewMeta.ts} +0 -0
@@ -9,7 +9,10 @@ import ToDo from '@pega/react-sdk-components/lib/components/widget/ToDo';
9
9
  import Details from '@pega/react-sdk-components/lib/components/template/Details/Details';
10
10
  import { Button, Card, makeStyles } from '@material-ui/core';
11
11
 
12
- declare const PCore;
12
+ import PCoreType from '@pega/pcore-pconnect-typedefs/types/pcore';
13
+
14
+ declare const PCore: typeof PCoreType;
15
+
13
16
 
14
17
  const useStyles = makeStyles(theme => ({
15
18
  root: {
@@ -5,8 +5,10 @@ import MultiReferenceReadonly from '@pega/react-sdk-components/lib/components/te
5
5
 
6
6
  const SELECTION_MODE = { SINGLE: 'single', MULTI: 'multi' };
7
7
 
8
+ // Remove this and use "real" PCore type once .d.ts is fixed (currently shows ~7 errors)
8
9
  declare const PCore: any;
9
10
 
11
+
10
12
  export default function DataReference(props) {
11
13
  const {
12
14
  children,
@@ -1,15 +1,21 @@
1
1
  import React, { createElement } from 'react';
2
2
  import PropTypes from 'prop-types';
3
-
4
3
  import { getInstructions } from '@pega/react-sdk-components/lib/components/helpers/template-utils';
5
4
  import createPConnectComponent from '@pega/react-sdk-components/lib/bridge/react_pconnect';
5
+ import connectToState from '@pega/react-sdk-components/lib/components/helpers/state-utils';
6
+ import { getKeyForMappedField, mapStateToProps } from './utils';
6
7
 
7
8
  import './DefaultForm.css';
8
9
 
10
+ const Child = connectToState(mapStateToProps)(props => {
11
+ const { key, visibility, ...rest } = props;
12
+
13
+ return createElement(createPConnectComponent(), { ...rest, key, visibility });
14
+ });
15
+
9
16
  export default function DefaultForm(props) {
10
17
  const { getPConnect, NumCols } = props;
11
18
  const instructions = getInstructions(getPConnect(), props.instructions);
12
- const instructionText = instructions?.replace(/<\/?[^>]+(>|$)/g, '');
13
19
 
14
20
  let divClass: string;
15
21
 
@@ -35,15 +41,16 @@ export default function DefaultForm(props) {
35
41
  // to take the children and create components for them, put in an array and pass as the
36
42
  // defaultForm kids
37
43
  const arChildren = getPConnect().getChildren()[0].getPConnect().getChildren();
38
- const dfChildren = arChildren.map((kid, idx) =>
39
- // eslint-disable-next-line react/no-array-index-key
40
- createElement(createPConnectComponent(), { ...kid, key: idx })
41
- );
44
+ const dfChildren = arChildren.map(kid => <Child key={getKeyForMappedField(kid)} {...kid} />);
42
45
 
43
46
  return (
44
47
  <>
45
- {instructionText && (
46
- <div className='psdk-default-form-instruction-text'>{instructionText}</div>
48
+ {instructions && (
49
+ <div className='psdk-default-form-instruction-text'>
50
+ {/* server performs sanitization method for instructions html content */}
51
+ { /* eslint-disable react/no-danger */ }
52
+ <div key="instructions" id="instruction-text" dangerouslySetInnerHTML={{ __html: instructions }} />
53
+ </div>
47
54
  )}
48
55
  <div className={divClass}>{dfChildren}</div>
49
56
  </>
@@ -0,0 +1,33 @@
1
+ import { v4 as uuidv4 } from 'uuid';
2
+
3
+ export const mapStateToProps: any = (_, ownProps) => {
4
+ const { getPConnect } = ownProps;
5
+
6
+ return {
7
+ visibility: getPConnect().getComputedVisibility(),
8
+ getPConnect
9
+ };
10
+ };
11
+
12
+ export const getKeyForMappedField = field => {
13
+ if (Array.isArray(field)) {
14
+ return field
15
+ .map(item => {
16
+ return getKeyForMappedField(item);
17
+ })
18
+ .join('__');
19
+ }
20
+
21
+ const pConnect = field?.getPConnect?.();
22
+
23
+ if (pConnect?.meta?.type && pConnect?.meta?.config?.name) {
24
+ return `${pConnect.meta.type}_${pConnect.meta.config.name}`;
25
+ }
26
+
27
+ // Using label as a fallback if name is not defined.
28
+ if (pConnect?.meta?.type && pConnect?.meta?.config?.label) {
29
+ return `${pConnect.meta.type}_${pConnect.meta.config.label}`;
30
+ }
31
+
32
+ return uuidv4();
33
+ };
@@ -6,7 +6,10 @@ import FieldGroup from '@pega/react-sdk-components/lib/components/designSystemEx
6
6
  import FieldGroupList from '@pega/react-sdk-components/lib/components/designSystemExtension/FieldGroupList';
7
7
  import { getReferenceList, buildView } from '@pega/react-sdk-components/lib/components/helpers/field-group-utils';
8
8
 
9
- declare const PCore: any;
9
+ import PCoreType from '@pega/pcore-pconnect-typedefs/types/pcore';
10
+
11
+ declare const PCore: typeof PCoreType;
12
+
10
13
 
11
14
  export default function FieldGroupTemplate(props) {
12
15
  const {
@@ -38,7 +41,7 @@ export default function FieldGroupTemplate(props) {
38
41
  if (PCore.getPCoreVersion()?.includes('8.7')) {
39
42
  pConn.getListActions().insert({ classID: contextClass }, referenceList.length, pageReference);
40
43
  } else {
41
- pConn.getListActions().insert({ classID: contextClass }, referenceList.length);
44
+ pConn.getListActions().insert({}, referenceList.length);
42
45
  }
43
46
  };
44
47
 
@@ -42,6 +42,8 @@ import './ListView.css';
42
42
  import useInit from './hooks'
43
43
 
44
44
  const SELECTION_MODE = { SINGLE: 'single', MULTI: 'multi' };
45
+
46
+ // Remove this and use "real" PCore type once .d.ts is fixed (currently shows 3 errors)
45
47
  declare const PCore: any;
46
48
 
47
49
  let myRows: Array<any>;
@@ -1002,7 +1004,7 @@ export default function ListView(props) {
1002
1004
  </Grid>
1003
1005
  <Grid item>
1004
1006
  <TextField
1005
- label='Search'
1007
+ label={ PCore.getLocaleUtils().getLocaleValue('Search', 'Search') }
1006
1008
  fullWidth
1007
1009
  variant='outlined'
1008
1010
  placeholder=''
@@ -1,8 +1,10 @@
1
1
  import { useEffect } from 'react';
2
2
  import { getContext, readContextResponse } from './utils';
3
3
 
4
+ // Remove this and use "real" PCore type once .d.ts is fixed (currently shows 1 error)
5
+ declare const PCore: any;
6
+
4
7
  export default function useInit(props) {
5
- const PCore = window.PCore;
6
8
  const {
7
9
  referenceList,
8
10
  getPConnect,
@@ -1,6 +1,8 @@
1
- /* eslint-disable no-undef */
2
1
  import getDefaultViewMeta from './DefaultViewMeta';
3
2
 
3
+ // Remove this and use "real" PCore type once .d.ts is fixed (currently shows 5 errors)
4
+ declare const PCore: any;
5
+
4
6
  const USER_REFERENCE = 'UserReference';
5
7
  const PAGE = '!P!';
6
8
  const PAGELIST = '!PL!';
@@ -72,7 +74,7 @@ export const isEmbeddedField = (field) => {
72
74
  * @returns {Array} Metadata of configured embedded fields
73
75
  */
74
76
  export function getConfigEmbeddedFieldsMeta(configFields, classID) {
75
- const configEmbeddedFieldsMeta = [];
77
+ const configEmbeddedFieldsMeta:Array<any> = [];
76
78
  configFields.forEach((field) => {
77
79
  let value = field;
78
80
  if (isEmbeddedField(value)) {
@@ -172,9 +174,9 @@ function getPresetMetaAttribute(attribute) {
172
174
  (primaryField) =>
173
175
  !presetConfigFields.some((presetConfigField) => presetConfigField.config.value.split('.')[1] === primaryField)
174
176
  );
175
- const uncommonFieldsRawMeta = [];
177
+ const uncommonFieldsRawMeta:Array<any> = [];
176
178
  uncommonFieldsList.forEach((uncommonField) => {
177
- const uncommonFieldMeta = metaFields.find((metaField) => metaField.fieldID === uncommonField);
179
+ const uncommonFieldMeta= metaFields.find((metaField) => metaField.fieldID === uncommonField);
178
180
  if (uncommonFieldMeta) uncommonFieldsRawMeta.push(uncommonFieldMeta);
179
181
  });
180
182
  const uncommonFieldsConfigMeta = generateViewMetaData(uncommonFieldsRawMeta, classID, true);
@@ -444,8 +446,8 @@ function populateRenderingOptions(name, config, field) {
444
446
  }
445
447
  }
446
448
  export function initializeColumns(
447
- fields = [],
448
- getMappedProperty
449
+ fields:Array<any> = [],
450
+ getMappedProperty:any = null
449
451
  ) {
450
452
  return fields.map((field, originalColIndex) => {
451
453
  let name = field.config.value;
@@ -495,9 +497,9 @@ export const getItemKey = (fields) => {
495
497
  };
496
498
 
497
499
  export function preparePatchQueryFields(fields, isDataObject = false, classID = '') {
498
- const queryFields = [];
500
+ const queryFields:Array<any> = [];
499
501
  fields.forEach((field) => {
500
- const patchFields = [];
502
+ const patchFields:Array<any> = [];
501
503
  if (field.cellRenderer === 'WorkLink') {
502
504
  if (field.customObject && field.customObject.isAssignmentLink) {
503
505
  const associationName = field.name.includes(':') ? `${field.name.split(':')[0]}:` : '';
@@ -542,7 +544,7 @@ export const readContextResponse = async (context, params) => {
542
544
  } = params;
543
545
  const { promisesResponseArray, apiContext: otherContext } = context;
544
546
  // eslint-disable-next-line sonarjs/no-unused-collection
545
- const listOfComponents = [];
547
+ const listOfComponents:Array<any> = [];
546
548
  const {
547
549
  data: { fields: metaFields, classID, isQueryable }
548
550
  } = promisesResponseArray[0];
@@ -562,7 +564,7 @@ export const readContextResponse = async (context, params) => {
562
564
 
563
565
 
564
566
  if (isDataObject) {
565
- const compositeKeys = [];
567
+ const compositeKeys:Array<any> = [];
566
568
  const dataViewName = PCore.getDataTypeUtils().getSavableDataPage(classID);
567
569
  const dataPageKeys = PCore.getDataTypeUtils().getDataPageKeys(dataViewName);
568
570
  dataPageKeys?.forEach((item) =>
@@ -1,7 +1,11 @@
1
1
  import PropTypes from "prop-types";
2
2
  import React from "react";
3
3
 
4
- declare const PCore;
4
+ import PCoreType from '@pega/pcore-pconnect-typedefs/types/pcore';
5
+
6
+ declare const PCore: typeof PCoreType;
7
+
8
+
5
9
  export default function MultiReferenceReadOnly(props) {
6
10
  const { getPConnect, label, hideLabel, config } = props;
7
11
  const { referenceList, readonlyContextList } = config;
@@ -4,10 +4,14 @@ import Button from '@material-ui/core/Button';
4
4
 
5
5
  import createPConnectComponent from '@pega/react-sdk-components/lib/bridge/react_pconnect';
6
6
  import ListView from '@pega/react-sdk-components/lib/components/template/ListView';
7
- import Utils from '@pega/react-sdk-components/lib/components/helpers/utils';
7
+ import { isEmptyObject } from '@pega/react-sdk-components/lib/components/helpers/common-utils';
8
8
  import './PromotedFilters.css';
9
9
 
10
- declare const PCore;
10
+ import PCoreType from '@pega/pcore-pconnect-typedefs/types/pcore';
11
+
12
+ declare const PCore: typeof PCoreType;
13
+
14
+
11
15
  const localeCategory = 'SimpleTable';
12
16
  const SUPPORTED_TYPES_IN_PROMOTED_FILTERS = [
13
17
  'TextInput',
@@ -112,7 +116,7 @@ export default function PromotedFilters(props) {
112
116
  dataViewParameters: parameters
113
117
  };
114
118
 
115
- if (!Utils.isEmptyObject(promotedFilters)) {
119
+ if (!isEmptyObject(promotedFilters)) {
116
120
  Query.query = { filter: { filterConditions: promotedFilters } };
117
121
  }
118
122
  setPayload(Query);
@@ -135,10 +139,10 @@ export default function PromotedFilters(props) {
135
139
  </div>
136
140
  <div>
137
141
  <Button key='1' type='button' onClick={clearFilterData} data-testid='clear' variant='contained' color='primary'>
138
- {localizedVal('Clear', localeCategory)}
142
+ {localizedVal('Clear', localeCategory)}
139
143
  </Button>
140
144
  <Button style={{float: 'right'}} key='2' type='submit' onClick={getFilterData} data-testid='search' variant='contained' color='primary'>
141
- {localizedVal('Search', localeCategory)}
145
+ {localizedVal('Search', localeCategory)}
142
146
  </Button>
143
147
  </div>
144
148
  {initTable && <ListView {...listViewProps} title='' payload={payload}
@@ -2,7 +2,10 @@ import React from 'react';
2
2
  import FieldGroupTemplate from '@pega/react-sdk-components/lib/components/template/FieldGroupTemplate';
3
3
  import SimpleTableManual from '@pega/react-sdk-components/lib/components/template/SimpleTable/SimpleTableManual';
4
4
 
5
- declare const PCore: any;
5
+ import PCoreType from '@pega/pcore-pconnect-typedefs/types/pcore';
6
+
7
+ declare const PCore: typeof PCoreType;
8
+
6
9
 
7
10
  export default function SimpleTable(props) {
8
11
  const { getPConnect, multiRecordDisplayAs, allowTableEdit } = props;
@@ -31,6 +31,11 @@ import Select from '@material-ui/core/Select';
31
31
  import Button from '@material-ui/core/Button';
32
32
  import TextField from '@material-ui/core/TextField';
33
33
 
34
+ import PCoreType from '@pega/pcore-pconnect-typedefs/types/pcore';
35
+
36
+ declare const PCore: typeof PCoreType;
37
+
38
+
34
39
  const useStyles = makeStyles((/* theme */) => ({
35
40
  label: {
36
41
  margin: '8px'
@@ -58,7 +63,6 @@ const useStyles = makeStyles((/* theme */) => ({
58
63
  }
59
64
  }));
60
65
 
61
- declare const PCore: any;
62
66
 
63
67
  let menuColumnId = '';
64
68
  let menuColumnType = '';
@@ -113,7 +117,7 @@ export default function SimpleTableManual(props) {
113
117
  const resolvedList = getReferenceList(pConn);
114
118
  const pageReference = `${pConn.getPageReference()}${resolvedList}`;
115
119
  pConn.setReferenceList(resolvedList);
116
- const menuIconOverride$ = Utils.getImageSrc('trash', PCore.getAssetLoader().getStaticServerUrl());
120
+ const menuIconOverride$ = Utils.getImageSrc('trash', Utils.getSDKStaticConentUrl());
117
121
 
118
122
  const resolvedFields = children?.[0]?.children || presets?.[0].children?.[0].children;
119
123
  // NOTE: props has each child.config with datasource and value undefined
@@ -186,8 +190,8 @@ export default function SimpleTableManual(props) {
186
190
  };
187
191
 
188
192
  function generateRowsData() {
189
- // if dataPageName property value exists then make a datapage fetch call and get the list of data.
190
- if (dataPageName) {
193
+ // if referenceList is empty and dataPageName property value exists then make a datapage fetch call and get the list of data.
194
+ if (!referenceList.length && dataPageName) {
191
195
  getDataPage(dataPageName, parameters, context).then(listData => {
192
196
  const data = formatRowsData(listData);
193
197
  myRows = data;
@@ -5,11 +5,16 @@ import SimpleTable from '@pega/react-sdk-components/lib/components/template/Simp
5
5
 
6
6
  import PromotedFilters from '@pega/react-sdk-components/lib/components/template/PromotedFilters';
7
7
 
8
+ import PCoreType from '@pega/pcore-pconnect-typedefs/types/pcore';
9
+
10
+ declare const PCore: typeof PCoreType;
11
+
12
+
8
13
  const isSelfReferencedProperty = (param, referenceProp) => {
9
14
  const [, parentPropName] = param.split('.');
10
15
  return parentPropName === referenceProp;
11
16
  };
12
- declare const PCore;
17
+
13
18
  /**
14
19
  * SimpleTable react component
15
20
  * @param {*} props - props
@@ -1,5 +1,7 @@
1
+ import PCoreType from '@pega/pcore-pconnect-typedefs/types/pcore';
2
+
3
+ declare const PCore: typeof PCoreType;
1
4
 
2
- declare const PCore;
3
5
 
4
6
  export const getDeferFriendlyTabs = allTabs => {
5
7
  return allTabs.map(tab => {
@@ -56,7 +56,7 @@ export default function WssNavBar(props) {
56
56
  };
57
57
 
58
58
  const navLinksContent = (
59
- <Box
59
+ <Box id="nav-links"
60
60
  sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}
61
61
  style={{ justifyContent: alignment }}
62
62
  >
@@ -73,7 +73,7 @@ export default function WssNavBar(props) {
73
73
  <AppBar position='static' color='primary'>
74
74
  <Container maxWidth='xl'>
75
75
  <Toolbar disableGutters style={{ justifyContent: 'space-between' }}>
76
- <Button style={{ textTransform: 'capitalize' }} onClick={appInfo.onClick}>
76
+ <Button id="appName" style={{ textTransform: 'capitalize' }} onClick={appInfo.onClick}>
77
77
  <img src={appInfo.imageSrc} className={classes.appListLogo} />
78
78
  <span className={classes.appName}>{appInfo.appName}</span>
79
79
  </Button>
@@ -4,7 +4,15 @@
4
4
  }
5
5
 
6
6
  .file-div {
7
- border: 1px dashed #262626;
7
+ border: 1px dashed var(--app-neutral-dark-color);
8
+ width: 100%;
9
+ padding: 0.5rem;
10
+ text-align: center;
11
+ position: relative;
12
+ }
13
+
14
+ .file-div-error {
15
+ border: 1px dashed var(--app-error-color);
8
16
  width: 100%;
9
17
  padding: 0.5rem;
10
18
  text-align: center;
@@ -17,9 +25,13 @@
17
25
  left: 47%;
18
26
  }
19
27
 
20
- file-label::after {
28
+ .file-label::after {
21
29
  display: inline;
22
30
  content: " *";
23
31
  vertical-align: top;
24
- color: rgb(217, 28, 41);
32
+ color: var(--app-neutral-dark-color);
33
+ }
34
+
35
+ .file-error {
36
+ color: var(--app-error-color);
25
37
  }
@@ -8,14 +8,19 @@ import SummaryList from '@pega/react-sdk-components/lib/components/widget/Summar
8
8
  import { CircularProgress } from "@material-ui/core";
9
9
  import download from "downloadjs";
10
10
 
11
+ // Remove this and use "real" PCore type once .d.ts is fixed (currently shows 2 errors)
11
12
  declare const PCore: any;
12
13
 
13
- function getCurrentAttachmentsList(context) {
14
- return PCore.getStoreValue('.attachmentsList', 'context_data', context) || [];
14
+
15
+ const getAttachmentKey = (name='') => name ? `attachmentsList.${name}` : 'attachmentsList';
16
+
17
+ function getCurrentAttachmentsList(key, context) {
18
+ return PCore.getStoreValue(`.${key}`, 'context_data', context) || [];
15
19
  }
16
20
 
17
21
  export default function Attachment(props) {
18
- const {value, getPConnect, label} = props;
22
+ const PCoreVersion = PCore.getPCoreVersion();
23
+ const {value, getPConnect, label, validatemessage} = props;
19
24
  /* this is a temporary fix because required is supposed to be passed as a boolean and NOT as a string */
20
25
  let { required, disabled } = props;
21
26
  [required, disabled] = [required, disabled].map(
@@ -36,7 +41,7 @@ export default function Attachment(props) {
36
41
  const [file, setFile] = useState(fileTemp);
37
42
 
38
43
  const resetAttachmentStoredState = () => {
39
- PCore.getStateUtils().updateState(pConn.getContextName(), 'attachmentsList', undefined, {
44
+ PCore.getStateUtils().updateState(pConn.getContextName(), getAttachmentKey(PCoreVersion?.includes('8.23') ? valueRef : ''), undefined, {
40
45
  pageReference: 'context_data',
41
46
  isArrayDeepMerge: false
42
47
  });
@@ -59,10 +64,11 @@ export default function Attachment(props) {
59
64
 
60
65
  function setNewFiles(arFiles) {
61
66
  let index = 0;
67
+ const maxAttachmentSize = 5;
62
68
  for (const item of arFiles) {
63
- if (!validateMaxSize(item, 5)) {
69
+ if (!validateMaxSize(item, maxAttachmentSize)) {
64
70
  item.error = true;
65
- item.meta = "File is too big. Max allowed size is 5MB.";
71
+ item.meta = pConn.getLocalizedValue(`File is too big. Max allowed size is ${maxAttachmentSize}MB.`);
66
72
  }
67
73
  item.mimeType = item.type;
68
74
  item.icon = getIconFromFileType(item.type);
@@ -76,7 +82,7 @@ export default function Attachment(props) {
76
82
  return setNewFiles(arFiles);
77
83
  }
78
84
 
79
- function getNewListUtilityItemProps({
85
+ function getNewListUtilityItemProps(this: any, {
80
86
  att,
81
87
  cancelFile,
82
88
  downloadFile,
@@ -88,7 +94,7 @@ export default function Attachment(props) {
88
94
  actions = [
89
95
  {
90
96
  id: `Cancel-${att.ID}`,
91
- text: "Cancel",
97
+ text: pConn.getLocalizedValue('Cancel'),
92
98
  icon: "times",
93
99
  onClick: cancelFile
94
100
  }
@@ -101,7 +107,7 @@ export default function Attachment(props) {
101
107
  "download",
102
108
  {
103
109
  id: `download-${ID}`,
104
- text: isFile ? "Download" : "Open",
110
+ text: isFile ? pConn.getLocalizedValue('Download') : pConn.getLocalizedValue('Open'),
105
111
  icon: isFile ? "download" : "open",
106
112
  onClick: downloadFile
107
113
  }
@@ -110,7 +116,7 @@ export default function Attachment(props) {
110
116
  "delete",
111
117
  {
112
118
  id: `Delete-${ID}`,
113
- text: "Delete",
119
+ text: pConn.getLocalizedValue('Delete'),
114
120
  icon: "trash",
115
121
  onClick: deleteFile
116
122
  }
@@ -126,7 +132,7 @@ export default function Attachment(props) {
126
132
  actions = [
127
133
  {
128
134
  id: `Remove-${att.ID}`,
129
- text: "Remove",
135
+ text: pConn.getLocalizedValue('Remove'),
130
136
  icon: "trash",
131
137
  onClick: removeFile
132
138
  }
@@ -135,7 +141,7 @@ export default function Attachment(props) {
135
141
  return {
136
142
  id: att.ID,
137
143
  visual: {
138
- icon: getIconForAttachment(att),
144
+ icon: getIconForAttachment(this, att),
139
145
  progress: att.progress === 100 ? undefined: att.progress,
140
146
  },
141
147
  primary: {
@@ -211,7 +217,7 @@ export default function Attachment(props) {
211
217
  )
212
218
  .then((fileRes) => {
213
219
  let reqObj;
214
- if (PCore.getPCoreVersion()?.includes('8.7')) {
220
+ if (PCoreVersion?.includes('8.7')) {
215
221
  reqObj = {
216
222
  type: "File",
217
223
  attachmentFieldName: valueRef,
@@ -227,12 +233,12 @@ export default function Attachment(props) {
227
233
  handle: fileRes.ID,
228
234
  ID: fileRes.clientFileID
229
235
  };
230
- const currentAttachmentList = getCurrentAttachmentsList(pConn.getContextName()).filter(
236
+ const currentAttachmentList = getCurrentAttachmentsList( getAttachmentKey(PCoreVersion?.includes('8.23') ? valueRef : ''), pConn.getContextName()).filter(
231
237
  (f) => f.label !== valueRef
232
238
  );
233
239
  PCore.getStateUtils().updateState(
234
240
  pConn.getContextName(),
235
- 'attachmentsList',
241
+ getAttachmentKey(PCoreVersion?.includes('8.23') ? valueRef : ''),
236
242
  [...currentAttachmentList, reqObj],
237
243
  {
238
244
  pageReference: 'context_data',
@@ -249,7 +255,7 @@ export default function Attachment(props) {
249
255
  pageReference: pConn.getPageReference(),
250
256
  context
251
257
  });
252
- myFiles[0].meta = "Uploaded Successfully";
258
+ myFiles[0].meta = pConn.getLocalizedValue('Uploaded successfully');
253
259
 
254
260
  arFileList$ = myFiles.map((att) => {
255
261
  return getNewListUtilityItemProps({
@@ -283,7 +289,7 @@ export default function Attachment(props) {
283
289
  function _removeFileFromList(item: any, list) {
284
290
  const arFileList = file.props ? file.props.arFileList$ : list;
285
291
  const fileIndex = arFileList.findIndex(element => element?.id === item?.id);
286
- if (PCore.getPCoreVersion()?.includes('8.7')) {
292
+ if (PCoreVersion?.includes('8.7')) {
287
293
  if (value) {
288
294
  pConn.attachmentsInfo = {
289
295
  type: "File",
@@ -303,7 +309,7 @@ export default function Attachment(props) {
303
309
  });
304
310
  } else {
305
311
  const attachmentsList = [];
306
- const currentAttachmentList = getCurrentAttachmentsList(pConn.getContextName()).filter(
312
+ const currentAttachmentList = getCurrentAttachmentsList( getAttachmentKey(PCoreVersion?.includes('8.23') ? valueRef : ''), pConn.getContextName()).filter(
307
313
  (f) => f.label !== valueRef
308
314
  );
309
315
  if (value && value.pxResults && +value.pyCount > 0) {
@@ -318,7 +324,7 @@ export default function Attachment(props) {
318
324
  // updating the redux store to help form-handler in passing the data to delete the file from server
319
325
  PCore.getStateUtils().updateState(
320
326
  pConn.getContextName(),
321
- 'attachmentsList',
327
+ getAttachmentKey(PCoreVersion?.includes('8.23') ? valueRef : ''),
322
328
  [...currentAttachmentList, deletedFile],
323
329
  {
324
330
  pageReference: 'context_data',
@@ -328,7 +334,7 @@ export default function Attachment(props) {
328
334
  } else {
329
335
  PCore.getStateUtils().updateState(
330
336
  pConn.getContextName(),
331
- 'attachmentsList',
337
+ getAttachmentKey(PCoreVersion?.includes('8.23') ? valueRef : ''),
332
338
  [...currentAttachmentList, ...attachmentsList],
333
339
  {
334
340
  pageReference: 'context_data',
@@ -372,12 +378,12 @@ export default function Attachment(props) {
372
378
  let oMenu: any = {};
373
379
 
374
380
  oMenu.icon = "download";
375
- oMenu.text = "Download";
381
+ oMenu.text = pConn.getLocalizedValue('Download');
376
382
  oMenu.onClick = () => { _downloadFileFromList(value.pxResults[0])}
377
383
  arMenuList.push(oMenu);
378
384
  oMenu = {};
379
385
  oMenu.icon = "trash";
380
- oMenu.text = "Delete";
386
+ oMenu.text = pConn.getLocalizedValue('Delete');
381
387
  oMenu.onClick = () => { _removeFileFromList(arFileList$[0], arFileList$)}
382
388
  arMenuList.push(oMenu);
383
389
 
@@ -405,7 +411,7 @@ export default function Attachment(props) {
405
411
  }
406
412
 
407
413
  if (fileTemp) {
408
- const currentAttachmentList = getCurrentAttachmentsList(pConn.getContextName());
414
+ const currentAttachmentList = getCurrentAttachmentsList( getAttachmentKey(PCoreVersion?.includes('8.23') ? valueRef : ''), pConn.getContextName());
409
415
  const index = currentAttachmentList.findIndex(element => element.props.ID === fileTemp.props.ID);
410
416
  let tempFiles: any = [];
411
417
  if (index < 0) {
@@ -413,7 +419,7 @@ export default function Attachment(props) {
413
419
  }
414
420
  PCore.getStateUtils().updateState(
415
421
  pConn.getContextName(),
416
- 'attachmentsList',
422
+ getAttachmentKey(PCoreVersion?.includes('8.23') ? valueRef : ''),
417
423
  [...currentAttachmentList, ...tempFiles],
418
424
  {
419
425
  pageReference: 'context_data',
@@ -434,7 +440,7 @@ export default function Attachment(props) {
434
440
  }, []);
435
441
 
436
442
  let content = (
437
- <div className='file-div'>
443
+ <div className={`${validatemessage === '' ? 'file-div' : 'file-div-error'}`}>
438
444
  {file.inProgress && (<div className="progress-div"><CircularProgress /></div>)}
439
445
  <div hidden={true} id="attachment-ID">{valueRef}</div>
440
446
  <label htmlFor={valueRef}>
@@ -467,6 +473,7 @@ export default function Attachment(props) {
467
473
  <div className='file-upload-container'>
468
474
  <span className={`label ${required ? 'file-label' : ''}`}>{label}</span>
469
475
  <section>{content}</section>
476
+ {validatemessage !== "" ? <span className='file-error'>{validatemessage}</span> : ''}
470
477
  </div>
471
478
  );
472
479
  }
@@ -10,8 +10,8 @@ import TableRow from '@material-ui/core/TableRow';
10
10
  import isDeepEqual from 'fast-deep-equal/react';
11
11
  import { Utils } from '@pega/react-sdk-components/lib/components/helpers/utils';
12
12
 
13
- declare const PCore;
14
-
13
+ // Remove this and use "real" PCore type once .d.ts is fixed (currently shows 2 errors)
14
+ declare const PCore: any;
15
15
 
16
16
  const StyledTableCell = withStyles((theme: Theme) =>
17
17
  createStyles({
@@ -38,9 +38,9 @@ export default function CaseHistory(props) {
38
38
  // let waitingForData = true;
39
39
 
40
40
  const displayedColumns = [
41
- { label: "Date", type: "DateTime", fieldName: "pxTimeCreated" },
42
- { label: "Description", type: "TextInput", fieldName: "pyMessageKey" },
43
- { label: "User", type: "TextInput", fieldName: "pyPerformer" }
41
+ { label: thePConn.getLocalizedValue('Date'), type: "DateTime", fieldName: "pxTimeCreated" },
42
+ { label: thePConn.getLocalizedValue('Description'), type: "TextInput", fieldName: "pyMessageKey" },
43
+ { label: thePConn.getLocalizedValue('Performed by'), type: "TextInput", fieldName: "pyPerformer" }
44
44
  ];
45
45
 
46
46
  const rowData: any = useRef([]);