@pega/react-sdk-overrides 24.2.11 → 25.1.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 (173) hide show
  1. package/lib/designSystemExtension/AlertBanner/AlertBanner.css +46 -0
  2. package/lib/designSystemExtension/AlertBanner/AlertBanner.tsx +37 -20
  3. package/lib/designSystemExtension/Banner/Banner.css +1 -1
  4. package/lib/designSystemExtension/Banner/Banner.tsx +10 -7
  5. package/lib/designSystemExtension/CaseSummaryFields/CaseSummaryFields.css +0 -1
  6. package/lib/designSystemExtension/CaseSummaryFields/CaseSummaryFields.tsx +53 -37
  7. package/lib/designSystemExtension/DetailsFields/DetailsFields.tsx +11 -13
  8. package/lib/designSystemExtension/FieldGroup/FieldGroup.tsx +8 -9
  9. package/lib/designSystemExtension/FieldGroupList/FieldGroupList.tsx +9 -9
  10. package/lib/designSystemExtension/FieldValueList/FieldValueList.tsx +7 -8
  11. package/lib/designSystemExtension/Operator/Operator.tsx +21 -19
  12. package/lib/designSystemExtension/Pulse/Pulse.tsx +1 -1
  13. package/lib/designSystemExtension/RichTextEditor/RichTextEditor.tsx +32 -4
  14. package/lib/designSystemExtension/WssQuickCreate/WssQuickCreate.css +7 -14
  15. package/lib/designSystemExtension/WssQuickCreate/WssQuickCreate.tsx +13 -2
  16. package/lib/field/AutoComplete/AutoComplete.tsx +1 -1
  17. package/lib/field/CancelAlert/CancelAlert.css +4 -4
  18. package/lib/field/CancelAlert/CancelAlert.tsx +6 -6
  19. package/lib/field/Checkbox/Checkbox.tsx +97 -4
  20. package/lib/field/Currency/Currency.tsx +3 -3
  21. package/lib/field/Currency/currency-utils.ts +1 -2
  22. package/lib/field/Date/Date.tsx +3 -7
  23. package/lib/field/DateTime/DateTime.tsx +3 -8
  24. package/lib/field/Decimal/Decimal.tsx +3 -5
  25. package/lib/field/Dropdown/Dropdown.tsx +5 -7
  26. package/lib/field/Email/Email.tsx +11 -13
  27. package/lib/field/Group/Group.tsx +10 -8
  28. package/lib/field/Integer/Integer.tsx +5 -7
  29. package/lib/field/Location/Location.css +4 -0
  30. package/lib/field/Location/Location.tsx +258 -0
  31. package/lib/field/Location/config-ext.json +8 -0
  32. package/lib/field/Location/index.tsx +1 -0
  33. package/lib/field/Multiselect/utils.ts +1 -1
  34. package/lib/field/ObjectReference/ObjectReference.tsx +235 -0
  35. package/lib/field/ObjectReference/index.tsx +1 -0
  36. package/lib/field/ObjectReference/utils.ts +111 -0
  37. package/lib/field/Percentage/Percentage.tsx +3 -7
  38. package/lib/field/Phone/Phone.tsx +7 -5
  39. package/lib/field/RadioButtons/RadioButtons.tsx +47 -2
  40. package/lib/field/RichText/RichText.css +79 -0
  41. package/lib/field/RichText/RichText.tsx +3 -1
  42. package/lib/field/ScalarList/ScalarList.tsx +2 -3
  43. package/lib/field/SelectableCard/SelectableCard.tsx +189 -0
  44. package/lib/field/SelectableCard/index.tsx +1 -0
  45. package/lib/field/SelectableCard/utils.tsx +223 -0
  46. package/lib/field/SemanticLink/SemanticLink.tsx +160 -28
  47. package/lib/field/SemanticLink/utils.ts +1 -1
  48. package/lib/field/TextArea/TextArea.tsx +5 -7
  49. package/lib/field/TextContent/TextContent.tsx +1 -2
  50. package/lib/field/TextInput/TextInput.tsx +5 -7
  51. package/lib/field/Time/Time.tsx +3 -7
  52. package/lib/field/URL/URL.tsx +5 -7
  53. package/lib/field/UserReference/UserReference.tsx +2 -3
  54. package/lib/helpers/attachmentShared.ts +6 -0
  55. package/lib/helpers/common-utils.ts +3 -4
  56. package/lib/helpers/data_page.ts +0 -1
  57. package/lib/helpers/field-group-utils.ts +1 -1
  58. package/lib/helpers/formatters/Currency.ts +9 -4
  59. package/lib/helpers/formatters/CurrencyMap.ts +0 -2
  60. package/lib/helpers/object-utils.ts +10 -0
  61. package/lib/helpers/simpleTableHelpers.ts +118 -6
  62. package/lib/helpers/utils.ts +8 -1
  63. package/lib/helpers/versionHelpers.ts +0 -1
  64. package/lib/infra/ActionButtons/ActionButtons.tsx +28 -21
  65. package/lib/infra/Assignment/Assignment.tsx +47 -31
  66. package/lib/infra/Assignment/useValidationBanner.ts +29 -0
  67. package/lib/infra/AssignmentCard/AssignmentCard.tsx +2 -2
  68. package/lib/infra/Containers/FlowContainer/FlowContainer.tsx +22 -102
  69. package/lib/infra/Containers/ModalViewContainer/ListViewActionButtons/ListViewActionButtons.tsx +1 -2
  70. package/lib/infra/Containers/ModalViewContainer/ModalViewContainer.tsx +12 -6
  71. package/lib/infra/Containers/ViewContainer/ViewContainer.tsx +8 -13
  72. package/lib/infra/Containers/container-helpers.ts +47 -1
  73. package/lib/infra/DashboardFilter/DashboardFilter.tsx +3 -6
  74. package/lib/infra/DashboardFilter/filterUtils.tsx +3 -4
  75. package/lib/infra/DeferLoad/DeferLoad.tsx +26 -13
  76. package/lib/infra/ErrorBoundary/ErrorBoundary.tsx +1 -3
  77. package/lib/infra/MultiStep/MultiStep.css +48 -70
  78. package/lib/infra/MultiStep/MultiStep.tsx +27 -53
  79. package/lib/infra/NavBar/NavBar.css +1 -1
  80. package/lib/infra/NavBar/NavBar.tsx +49 -34
  81. package/lib/infra/Reference/Reference.tsx +8 -4
  82. package/lib/infra/Region/Region.tsx +1 -1
  83. package/lib/infra/RootContainer/RootContainer.tsx +6 -8
  84. package/lib/infra/Stages/Stages.tsx +3 -4
  85. package/lib/infra/View/View.tsx +9 -9
  86. package/lib/template/AdvancedSearch/AdvancedSearch.tsx +86 -0
  87. package/lib/template/AdvancedSearch/SearchGroup/persistUtils.ts +52 -0
  88. package/lib/template/AdvancedSearch/SearchGroups/SearchGroups.tsx +244 -0
  89. package/lib/template/AdvancedSearch/SearchGroups/hooks.ts +37 -0
  90. package/lib/template/AdvancedSearch/SearchGroups/index.tsx +1 -0
  91. package/lib/template/AdvancedSearch/SearchGroups/utils.ts +29 -0
  92. package/lib/template/AdvancedSearch/TemplateContext.ts +11 -0
  93. package/lib/template/AdvancedSearch/config-ext.json +9 -0
  94. package/lib/template/AdvancedSearch/index.tsx +1 -0
  95. package/lib/template/AppShell/AppShell.css +1 -5
  96. package/lib/template/AppShell/AppShell.tsx +16 -17
  97. package/lib/template/BannerPage/BannerPage.tsx +2 -2
  98. package/lib/template/CaseSummary/CaseSummary.tsx +25 -43
  99. package/lib/template/CaseView/CaseView.tsx +28 -35
  100. package/lib/template/CaseViewActionsMenu/CaseViewActionsMenu.tsx +1 -1
  101. package/lib/template/Confirmation/Confirmation.tsx +2 -3
  102. package/lib/template/DataReference/DataReference.tsx +312 -106
  103. package/lib/template/DataReference/DataReferenceAdvancedSearchContext.ts +10 -0
  104. package/lib/template/DataReference/SearchForm.tsx +149 -0
  105. package/lib/template/DataReference/utils.ts +90 -0
  106. package/lib/template/DefaultForm/DefaultForm.tsx +3 -3
  107. package/lib/template/DefaultForm/utils/index.ts +1 -3
  108. package/lib/template/DefaultPage/DefaultPage.tsx +108 -0
  109. package/lib/template/DefaultPage/index.tsx +1 -0
  110. package/lib/template/Details/Details/Details.tsx +11 -11
  111. package/lib/template/Details/DetailsSubTabs/DetailsSubTabs.tsx +2 -2
  112. package/lib/template/Details/DetailsThreeColumn/DetailsThreeColumn.tsx +11 -11
  113. package/lib/template/Details/DetailsTwoColumn/DetailsTwoColumn.tsx +11 -11
  114. package/lib/template/Details/DynamicTabs/DynamicTabs.tsx +1 -1
  115. package/lib/template/FieldGroupTemplate/FieldGroupTemplate.tsx +12 -6
  116. package/lib/template/HierarchicalForm/HierarchicalForm.tsx +58 -0
  117. package/lib/template/HierarchicalForm/hooks.ts +224 -0
  118. package/lib/template/HierarchicalForm/index.tsx +1 -0
  119. package/lib/template/InlineDashboard/InlineDashboard.tsx +14 -16
  120. package/lib/template/InlineDashboardPage/InlineDashboardPage.tsx +2 -2
  121. package/lib/template/ListPage/ListPage.tsx +1 -1
  122. package/lib/template/ListView/ListView.tsx +342 -204
  123. package/lib/template/ListView/hooks.ts +1 -5
  124. package/lib/template/ListView/utils.ts +38 -5
  125. package/lib/template/MultiReferenceReadOnly/MultiReferenceReadOnly.tsx +17 -2
  126. package/lib/template/NarrowWide/NarrowWide/NarrowWide.tsx +5 -5
  127. package/lib/template/NarrowWide/NarrowWideDetails/NarrowWideDetails.tsx +11 -11
  128. package/lib/template/NarrowWide/NarrowWideForm/NarrowWideForm.tsx +2 -2
  129. package/lib/template/NarrowWide/NarrowWidePage/NarrowWidePage.tsx +2 -2
  130. package/lib/template/ObjectPage/index.tsx +1 -0
  131. package/lib/template/OneColumn/OneColumn/OneColumn.tsx +7 -7
  132. package/lib/template/OneColumn/OneColumnPage/OneColumnPage.tsx +1 -1
  133. package/lib/template/OneColumn/OneColumnTab/OneColumnTab.tsx +2 -2
  134. package/lib/template/PromotedFilters/PromotedFilters.tsx +1 -2
  135. package/lib/template/SelfServiceCaseView/SelfServiceCaseView.tsx +153 -0
  136. package/lib/template/SelfServiceCaseView/index.tsx +1 -0
  137. package/lib/template/SimpleTable/SimpleTable/SimpleTable.tsx +2 -3
  138. package/lib/template/SimpleTable/SimpleTableManual/SimpleTableManual.tsx +45 -34
  139. package/lib/template/SimpleTable/SimpleTableSelect/SimpleTableSelect.tsx +1 -1
  140. package/lib/template/SimpleTable/SimpleTableSelectReadonly/SimpleTableSelectReadonly.tsx +179 -0
  141. package/lib/template/SimpleTable/SimpleTableSelectReadonly/index.tsx +1 -0
  142. package/lib/template/SingleReferenceReadOnly/SingleReferenceReadOnly.tsx +10 -2
  143. package/lib/template/SubTabs/SubTabs.tsx +2 -2
  144. package/lib/template/SubTabs/tabUtils.ts +118 -1
  145. package/lib/template/TwoColumn/TwoColumn/TwoColumn.tsx +9 -10
  146. package/lib/template/TwoColumn/TwoColumnPage/TwoColumnPage.tsx +1 -1
  147. package/lib/template/TwoColumn/TwoColumnTab/TwoColumnTab.tsx +9 -10
  148. package/lib/template/WideNarrow/WideNarrow/WideNarrow.tsx +5 -5
  149. package/lib/template/WideNarrow/WideNarrowDetails/WideNarrowDetails.tsx +11 -11
  150. package/lib/template/WideNarrow/WideNarrowForm/WideNarrowForm.tsx +2 -2
  151. package/lib/template/WideNarrow/WideNarrowPage/WideNarrowPage.tsx +2 -2
  152. package/lib/template/WssNavBar/WssNavBar.css +1 -1
  153. package/lib/template/WssNavBar/WssNavBar.tsx +6 -6
  154. package/lib/template/utils.tsx +58 -0
  155. package/lib/widget/AppAnnouncement/AppAnnouncement.tsx +1 -1
  156. package/lib/widget/Attachment/Attachment.css +6 -8
  157. package/lib/widget/Attachment/Attachment.tsx +303 -225
  158. package/lib/widget/Attachment/Attachment.types.ts +96 -0
  159. package/lib/widget/Attachment/AttachmentUtils.ts +316 -0
  160. package/lib/widget/CaseHistory/CaseHistory.tsx +5 -5
  161. package/lib/widget/FileUtility/ActionButtonsForFileUtil/ActionButtonsForFileUtil.css +0 -14
  162. package/lib/widget/FileUtility/ActionButtonsForFileUtil/ActionButtonsForFileUtil.tsx +3 -3
  163. package/lib/widget/FileUtility/FileUtility/FileUtility.css +7 -6
  164. package/lib/widget/FileUtility/FileUtility/FileUtility.tsx +29 -22
  165. package/lib/widget/Followers/Followers.tsx +2 -4
  166. package/lib/widget/QuickCreate/QuickCreate.tsx +1 -2
  167. package/lib/widget/SummaryItem/SummaryItem.css +9 -11
  168. package/lib/widget/SummaryItem/SummaryItem.tsx +2 -2
  169. package/lib/widget/SummaryList/SummaryList.tsx +1 -1
  170. package/lib/widget/ToDo/ToDo.css +1 -13
  171. package/lib/widget/ToDo/ToDo.tsx +37 -36
  172. package/package.json +1 -1
  173. package/lib/helpers/attachmentHelpers.ts +0 -76
@@ -48,7 +48,6 @@ export class Utils {
48
48
  // eslint-disable-next-line no-case-declarations
49
49
  const dataPage = configProps.datasource;
50
50
  if (typeof dataPage === 'string' && dataObject[dataPage]) {
51
- // eslint-disable-next-line no-alert
52
51
  alert('need to handle data page');
53
52
  } else {
54
53
  let listSourceItems = configProps.listOutput;
@@ -337,6 +336,14 @@ export class Utils {
337
336
  static isObject(objValue) {
338
337
  return objValue && typeof objValue === 'object' && objValue.constructor === Object;
339
338
  }
339
+
340
+ static getMappedKey(key) {
341
+ const mappedKey = PCore.getEnvironmentInfo().getKeyMapping(key);
342
+ if (!mappedKey) {
343
+ return key;
344
+ }
345
+ return mappedKey;
346
+ }
340
347
  }
341
348
 
342
349
  export default Utils;
@@ -10,6 +10,5 @@ export const sdkVersion = '8.7';
10
10
  export function compareSdkPCoreVersions() {
11
11
  // const theConstellationVersion = PCore.getPCoreVersion();
12
12
 
13
- // eslint-disable-next-line no-console
14
13
  console.warn(`Using Constellation version ${PCore.getPCoreVersion()}. Ensure this is the same version as your Infinity server.`);
15
14
  }
@@ -1,6 +1,6 @@
1
1
  import makeStyles from '@mui/styles/makeStyles';
2
2
  import Button from '@mui/material/Button';
3
- import { Grid, Divider } from '@mui/material';
3
+ import { Grid2, Divider } from '@mui/material';
4
4
 
5
5
  // ActionButtons does NOT have getPConnect. So, no need to extend from PConnProps
6
6
  interface ActionButtonsProps {
@@ -10,13 +10,18 @@ interface ActionButtonsProps {
10
10
  onButtonPress: any;
11
11
  }
12
12
 
13
- const useStyles = makeStyles((/* theme */) => ({
14
- button: {
15
- padding: '0px 5px'
16
- },
13
+ const useStyles = makeStyles(theme => ({
17
14
  divider: {
18
15
  marginTop: '10px',
19
16
  marginBottom: '10px'
17
+ },
18
+ secondaryButton: {
19
+ backgroundColor: theme.actionButtons.secondary.backgroundColor,
20
+ color: theme.actionButtons.secondary.color
21
+ },
22
+ primaryButton: {
23
+ backgroundColor: theme.actionButtons.primary.backgroundColor,
24
+ color: theme.actionButtons.primary.color
20
25
  }
21
26
  }));
22
27
 
@@ -33,42 +38,44 @@ export default function ActionButtons(props: ActionButtonsProps) {
33
38
  return (
34
39
  <>
35
40
  <Divider className={classes.divider} />
36
- <Grid container spacing={4} justifyContent='space-between'>
37
- <Grid item>
38
- <Grid container spacing={1}>
41
+ <Grid2 container spacing={4} justifyContent='space-between'>
42
+ <Grid2>
43
+ <Grid2 container spacing={1}>
39
44
  {arSecondaryButtons.map(sButton => (
40
- <Grid item key={sButton.name}>
45
+ <Grid2 key={sButton.name}>
41
46
  <Button
42
- variant='contained'
47
+ className={classes.secondaryButton}
43
48
  color='secondary'
49
+ variant='contained'
44
50
  onClick={() => {
45
51
  _onButtonPress(sButton.jsAction, 'secondary');
46
52
  }}
47
53
  >
48
54
  {localizedVal(sButton.name, localeCategory)}
49
55
  </Button>
50
- </Grid>
56
+ </Grid2>
51
57
  ))}
52
- </Grid>
53
- </Grid>
54
- <Grid item>
55
- <Grid container spacing={1}>
58
+ </Grid2>
59
+ </Grid2>
60
+ <Grid2>
61
+ <Grid2 container spacing={1}>
56
62
  {arMainButtons.map(mButton => (
57
- <Grid item key={mButton.name}>
63
+ <Grid2 key={mButton.name}>
58
64
  <Button
59
- variant='contained'
65
+ className={classes.primaryButton}
60
66
  color='primary'
67
+ variant='contained'
61
68
  onClick={() => {
62
69
  _onButtonPress(mButton.jsAction, 'primary');
63
70
  }}
64
71
  >
65
72
  {localizedVal(mButton.name, localeCategory)}
66
73
  </Button>
67
- </Grid>
74
+ </Grid2>
68
75
  ))}
69
- </Grid>
70
- </Grid>
71
- </Grid>
76
+ </Grid2>
77
+ </Grid2>
78
+ </Grid2>
72
79
  </>
73
80
  );
74
81
  }
@@ -1,19 +1,21 @@
1
- import React, { PropsWithChildren, useEffect, useState } from 'react';
1
+ import React, { type PropsWithChildren, useEffect, useState } from 'react';
2
2
  import Snackbar from '@mui/material/Snackbar';
3
3
  import IconButton from '@mui/material/IconButton';
4
4
  import CloseIcon from '@mui/icons-material/Close';
5
5
 
6
6
  import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
7
7
  import { useFocusFirstField, useScrolltoTop } from '@pega/react-sdk-components/lib/hooks';
8
+ import AlertBanner from '@pega/react-sdk-components/lib/components/designSystemExtension/AlertBanner/AlertBanner';
9
+ import { useValidationBanner } from './useValidationBanner';
8
10
 
9
- import { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
11
+ import type { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
10
12
 
11
13
  interface AssignmentProps extends PConnProps {
12
14
  // If any, enter additional props that only exist on this component
13
15
  itemKey: string;
14
16
  isInModal: boolean;
15
17
  banners: any[];
16
- // eslint-disable-next-line react/no-unused-prop-types
18
+
17
19
  actionButtons: any[];
18
20
  }
19
21
 
@@ -23,6 +25,7 @@ export default function Assignment(props: PropsWithChildren<AssignmentProps>) {
23
25
  const MultiStep = getComponentFromMap('MultiStep');
24
26
 
25
27
  const { getPConnect, children, itemKey = '', isInModal = false, banners = [] } = props;
28
+ const validationMessages = useValidationBanner(itemKey);
26
29
  const thePConn = getPConnect();
27
30
 
28
31
  const [bHasNavigation, setHasNavigation] = useState(false);
@@ -33,8 +36,8 @@ export default function Assignment(props: PropsWithChildren<AssignmentProps>) {
33
36
 
34
37
  const actionsAPI = thePConn.getActionsApi();
35
38
  const localizedVal = PCore.getLocaleUtils().getLocaleValue;
39
+ const localizationService = thePConn.getLocalizationService();
36
40
  const localeCategory = 'Assignment';
37
- const localeReference = `${getPConnect().getCaseInfo().getClassName()}!CASE!${getPConnect().getCaseInfo().getName()}`.toUpperCase();
38
41
 
39
42
  // store off bound functions to above pointers
40
43
  const finishAssignment = actionsAPI.finishAssignment.bind(actionsAPI);
@@ -76,7 +79,7 @@ export default function Assignment(props: PropsWithChildren<AssignmentProps>) {
76
79
  function getStepsInfo(steps, formedSteps: any = []) {
77
80
  steps.forEach(step => {
78
81
  if (step.name) {
79
- step.name = PCore.getLocaleUtils().getLocaleValue(step.name, undefined, localeReference);
82
+ step.name = localizationService.getLocalizedText(step.name);
80
83
  }
81
84
  if (step.steps) {
82
85
  formedSteps = getStepsInfo(step.steps, formedSteps);
@@ -88,8 +91,9 @@ export default function Assignment(props: PropsWithChildren<AssignmentProps>) {
88
91
  }
89
92
 
90
93
  const scrollId = window.location.href.includes('embedded') ? '#pega-part-of-page' : '#portal';
94
+ const currentAssignmentViewName = getPConnect().getCaseInfo().getCurrentAssignmentViewName();
91
95
  useScrolltoTop(scrollId, children);
92
- useFocusFirstField('Assignment', children);
96
+ useFocusFirstField('Assignment', currentAssignmentViewName);
93
97
 
94
98
  useEffect(() => {
95
99
  if (children) {
@@ -97,43 +101,50 @@ export default function Assignment(props: PropsWithChildren<AssignmentProps>) {
97
101
  const oWorkItem = firstChild.props.getPConnect();
98
102
  const oWorkData = oWorkItem.getDataObject();
99
103
  const oData: any = thePConn.getDataObject(''); // 1st arg empty string until typedefs allow it to be optional
104
+ const caseInfo = oData?.caseInfo;
105
+ if (!oWorkData?.caseInfo || oWorkData.caseInfo.assignments === null || !caseInfo) {
106
+ return;
107
+ }
100
108
 
101
- if (oWorkData?.caseInfo && oWorkData.caseInfo.assignments !== null) {
102
- const oCaseInfo = oData?.caseInfo;
109
+ // Set action buttons
110
+ if (caseInfo.actionButtons) {
111
+ setActionButtons(caseInfo.actionButtons);
112
+ }
103
113
 
104
- if (oCaseInfo && oCaseInfo.actionButtons) {
105
- setActionButtons(oCaseInfo.actionButtons);
106
- }
114
+ // Handle navigation setup
115
+ const navigation = caseInfo.navigation;
116
+ if (!navigation) {
117
+ setHasNavigation(false);
118
+ return;
119
+ }
107
120
 
108
- if (oCaseInfo?.navigation /* was oCaseInfo.navigation != null */) {
109
- setHasNavigation(true);
121
+ const isStandardTemplate = navigation.template?.toLowerCase() === 'standard';
122
+ const hasSingleStep = navigation.steps?.length === 1;
123
+ const shouldHideNavigation = isStandardTemplate || hasSingleStep;
110
124
 
111
- if (
112
- (oCaseInfo.navigation.template && oCaseInfo.navigation.template.toLowerCase() === 'standard') ||
113
- oCaseInfo?.navigation?.steps?.length === 1
114
- ) {
115
- setHasNavigation(false);
116
- } else if (oCaseInfo.navigation.template && oCaseInfo.navigation.template.toLowerCase() === 'vertical') {
117
- setIsVertical(true);
118
- } else {
119
- setIsVertical(false);
120
- }
125
+ setHasNavigation(!shouldHideNavigation);
121
126
 
122
- if (oCaseInfo?.navigation?.steps) {
123
- const steps = JSON.parse(JSON.stringify(oCaseInfo?.navigation?.steps));
124
- const formedSteps = getStepsInfo(steps);
125
- setArNavigationSteps(formedSteps);
126
- }
127
+ if (shouldHideNavigation) {
128
+ return;
129
+ }
127
130
 
128
- setArCurrentStepIndicies(findCurrentIndicies(arNavigationSteps, arCurrentStepIndicies, 0));
129
- }
131
+ // set vertical navigation
132
+ const isVerticalTemplate = navigation.template?.toLowerCase() === 'vertical';
133
+ setIsVertical(isVerticalTemplate);
134
+
135
+ if (navigation.steps) {
136
+ const steps = JSON.parse(JSON.stringify(navigation.steps));
137
+ const formedSteps = getStepsInfo(steps);
138
+ setArNavigationSteps(formedSteps);
130
139
  }
140
+
141
+ setArCurrentStepIndicies(findCurrentIndicies(arNavigationSteps, arCurrentStepIndicies, 0));
131
142
  }
132
143
  }, [children]);
133
144
 
134
145
  function showToast(message: string) {
135
146
  const theMessage = `Assignment: ${message}`;
136
- // eslint-disable-next-line no-console
147
+
137
148
  console.error(theMessage);
138
149
  setSnackbarMessage(message);
139
150
  setShowSnackbar(true);
@@ -303,6 +314,11 @@ export default function Assignment(props: PropsWithChildren<AssignmentProps>) {
303
314
 
304
315
  return (
305
316
  <div id='Assignment'>
317
+ {validationMessages.length > 0 && (
318
+ <div style={{ marginBottom: '1rem' }}>
319
+ <AlertBanner id={`validation-banner-${itemKey}`} variant='urgent' messages={validationMessages} />
320
+ </div>
321
+ )}
306
322
  {banners}
307
323
  {bHasNavigation ? (
308
324
  <>
@@ -0,0 +1,29 @@
1
+ import { useState, useEffect, useCallback } from 'react';
2
+
3
+ function formatError(error: any, localizedVal: Function): string {
4
+ if (typeof error === 'string') return localizedVal(error, 'Messages');
5
+ const label = error.label?.endsWith(':') ? error.label : `${error.label}:`;
6
+ return localizedVal(`${label} ${error.description}`, 'Messages');
7
+ }
8
+
9
+ /**
10
+ * Subscribes to the PCore store and returns formatted validation error messages
11
+ * for the given itemKey. Reacts to any ADD_MESSAGES / CLEAR_MESSAGES dispatch
12
+ * (blur, tab, submit, etc.) so the banner appears and clears in real time.
13
+ */
14
+ export function useValidationBanner(itemKey: string): string[] {
15
+ const [messages, setMessages] = useState<string[]>([]);
16
+
17
+ const readMessages = useCallback(() => {
18
+ const localizedVal = PCore.getLocaleUtils().getLocaleValue;
19
+ const errors: any[] = PCore.getMessageManager().getValidationErrorMessages(itemKey) || [];
20
+ setMessages(errors.map(error => formatError(error, localizedVal)));
21
+ }, [itemKey]);
22
+
23
+ useEffect(() => {
24
+ readMessages();
25
+ return PCore.getStore().subscribe(readMessages);
26
+ }, [readMessages]);
27
+
28
+ return messages;
29
+ }
@@ -1,6 +1,6 @@
1
- import { PropsWithChildren, useEffect, useState } from 'react';
1
+ import { type PropsWithChildren, useEffect, useState } from 'react';
2
2
 
3
- import { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
3
+ import type { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
4
4
  import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
5
5
 
6
6
  interface AssignmentCardProps extends PConnProps {
@@ -1,5 +1,3 @@
1
- /* eslint-disable no-nested-ternary */
2
-
3
1
  import { useState, useEffect, useContext } from 'react';
4
2
  import makeStyles from '@mui/styles/makeStyles';
5
3
  import { Alert, Card, CardHeader, Avatar, Typography } from '@mui/material';
@@ -11,7 +9,7 @@ import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpe
11
9
  import { withSimpleViewContainerRenderer } from '@pega/react-sdk-components/lib/components/infra/Containers/SimpleView/SimpleView';
12
10
 
13
11
  import { addContainerItem, getToDoAssignments, showBanner, hasContainerItems } from './helpers';
14
- import { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
12
+ import type { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
15
13
  import { LocalizationProvider } from '@mui/x-date-pickers';
16
14
  import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
17
15
 
@@ -24,11 +22,10 @@ interface FlowContainerProps extends PConnProps {
24
22
  activeContainerItemID: string;
25
23
  }
26
24
 
27
- //
28
- // WARNING: It is not expected that this file should be modified. It is part of infrastructure code that works with
29
- // Redux and creation/update of Redux containers and PConnect. Modifying this code could have undesireable results and
30
- // is totally at your own risk.
31
- //
25
+ /**
26
+ * WARNING: This file is part of the infrastructure component responsible for working with Redux and managing the creation and update of Redux containers and PConnect.
27
+ * You may override Material components within this component if needed, but do not modify any container-related logic. Changing this logic can lead to unexpected behavior.
28
+ */
32
29
 
33
30
  const useStyles = makeStyles(theme => ({
34
31
  root: {
@@ -58,7 +55,6 @@ export const FlowContainer = (props: FlowContainerProps) => {
58
55
  const AlertBanner = getComponentFromMap('AlertBanner');
59
56
 
60
57
  const pCoreConstants = PCore.getConstants();
61
- const PCoreVersion = PCore.getPCoreVersion();
62
58
  const { TODO } = pCoreConstants;
63
59
  const todo_headerText = 'To do';
64
60
 
@@ -78,6 +74,7 @@ export const FlowContainer = (props: FlowContainerProps) => {
78
74
  const getPConnect = getPConnectOfActiveContainerItem || getPConnectOfFlowContainer;
79
75
  const thePConn = getPConnect();
80
76
  const containerName = assignmentNames && assignmentNames.length > 0 ? assignmentNames[0] : '';
77
+ const bShowBanner = showBanner(getPConnect);
81
78
  // const [init, setInit] = useState(true);
82
79
  // const [fcState, setFCState] = useState({ hasError: false });
83
80
 
@@ -98,13 +95,12 @@ export const FlowContainer = (props: FlowContainerProps) => {
98
95
  const localizedVal = PCore.getLocaleUtils().getLocaleValue;
99
96
  const localeCategory = 'Messages';
100
97
 
101
- const key = `${thePConn.getCaseInfo().getClassName()}!CASE!${thePConn.getCaseInfo().getName()}`.toUpperCase();
98
+ const key = getPConnect()?.getCaseLocaleReference();
102
99
  const classes = useStyles();
103
100
 
104
101
  function getBuildName(): string {
105
102
  const ourPConn = getPConnect();
106
103
 
107
- // let { getPConnect, name } = this.pConn$.pConn;
108
104
  const context = ourPConn.getContextName();
109
105
  let viewContainerName = ourPConn.getContainerName();
110
106
 
@@ -113,7 +109,7 @@ export const FlowContainer = (props: FlowContainerProps) => {
113
109
  }
114
110
 
115
111
  function getTodoVisibility() {
116
- const caseViewMode = getPConnect().getValue('context_data.caseViewMode', ''); // 2nd arg empty string until typedefs properly allow optional
112
+ const caseViewMode = getPConnect().getValue('context_data.caseViewMode');
117
113
  if (caseViewMode && caseViewMode === 'review') {
118
114
  return true;
119
115
  }
@@ -123,16 +119,6 @@ export const FlowContainer = (props: FlowContainerProps) => {
123
119
  function initComponent() {
124
120
  const ourPConn = getPConnect();
125
121
 
126
- // debugging/investigation help
127
- // console.log(`${ourPConn.getComponentName()}: children update for main draw`);
128
-
129
- // const oData = ourPConn.getDataObject();
130
-
131
- // const activeActionLabel = "";
132
- // const child0_getPConnect = arNewChildren[0].getPConnect();
133
-
134
- // this.templateName$ = this.configProps$["template"];
135
-
136
122
  // debugger;
137
123
  setShowTodo(getTodoVisibility());
138
124
 
@@ -148,7 +134,7 @@ export const FlowContainer = (props: FlowContainerProps) => {
148
134
  }, []);
149
135
 
150
136
  useEffect(() => {
151
- // @ts-ignore - Property 'getMetadata' is private and only accessible within class 'C11nEnv'
137
+ // @ts-expect-error - Property 'getMetadata' is private and only accessible within class 'C11nEnv'
152
138
  if (isInitialized && pConnectOfFlowContainer.getMetadata().children && !hasItems) {
153
139
  // ensuring not to add container items, if container already has items
154
140
  // because during multi doc mode, we will have container items already in store
@@ -156,63 +142,6 @@ export const FlowContainer = (props: FlowContainerProps) => {
156
142
  }
157
143
  }, [isInitialized, hasItems]);
158
144
 
159
- function isCaseWideLocalAction() {
160
- const ourPConn = getPConnect();
161
-
162
- const actionID = ourPConn.getValue(pCoreConstants.CASE_INFO.ACTIVE_ACTION_ID, ''); // 2nd arg empty string until typedefs properly allow optional
163
- const caseActions = ourPConn.getValue(pCoreConstants.CASE_INFO.AVAILABLEACTIONS, ''); // 2nd arg empty string until typedefs properly allow optional
164
- let bCaseWideAction = false;
165
- if (caseActions && actionID) {
166
- const actionObj = caseActions.find(caseAction => caseAction.ID === actionID);
167
- if (actionObj) {
168
- bCaseWideAction = actionObj.type === 'Case';
169
- }
170
- }
171
- return bCaseWideAction;
172
- }
173
-
174
- function hasChildCaseAssignments() {
175
- const ourPConn = getPConnect();
176
-
177
- const childCases = ourPConn.getValue(pCoreConstants.CASE_INFO.CHILD_ASSIGNMENTS, ''); // 2nd arg empty string until typedefs properly allow optional
178
- // const allAssignments = [];
179
- return !!(childCases && childCases.length > 0);
180
- }
181
-
182
- function hasAssignments() {
183
- const ourPConn = getPConnect();
184
-
185
- let bHasAssignments = false;
186
- const assignmentsList: any[] = ourPConn.getValue(pCoreConstants.CASE_INFO.D_CASE_ASSIGNMENTS_RESULTS, ''); // 2nd arg empty string until typedefs properly allow optional
187
- const isEmbedded = window.location.href.includes('embedded');
188
- let bAssignmentsForThisOperator = false;
189
- // 8.7 includes assignments in Assignments List that may be assigned to
190
- // a different operator. So, see if there are any assignments for
191
- // the current operator
192
- if (PCoreVersion?.includes('8.7') || isEmbedded) {
193
- const thisOperator = PCore.getEnvironmentInfo().getOperatorIdentifier();
194
- for (const assignment of assignmentsList) {
195
- if (assignment.assigneeInfo.ID === thisOperator) {
196
- bAssignmentsForThisOperator = true;
197
- }
198
- }
199
- } else {
200
- bAssignmentsForThisOperator = true;
201
- }
202
- // Bail out if there isn't an assignmentsList
203
- if (!assignmentsList) {
204
- return bHasAssignments;
205
- }
206
-
207
- const bHasChildCaseAssignments = hasChildCaseAssignments();
208
-
209
- if (bAssignmentsForThisOperator || bHasChildCaseAssignments || isCaseWideLocalAction()) {
210
- bHasAssignments = true;
211
- }
212
-
213
- return bHasAssignments;
214
- }
215
-
216
145
  // From SDK-WC updateSelf - so do this in useEffect that's run only when the props change...
217
146
  useEffect(() => {
218
147
  setBuildName(getBuildName());
@@ -222,29 +151,21 @@ export const FlowContainer = (props: FlowContainerProps) => {
222
151
 
223
152
  let loadingInfo: any;
224
153
  try {
225
- loadingInfo = thePConn.getLoadingStatus(''); // 1st arg empty string until typedefs properly allow optional
154
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
155
+ loadingInfo = thePConn.getLoadingStatus();
156
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
226
157
  } catch (ex) {
227
- // eslint-disable-next-line no-console
228
158
  console.error(`${thePConn.getComponentName()}: loadingInfo catch block`);
229
159
  }
230
160
 
231
- // let configProps = this.thePConn.resolveConfigProps(this.thePConn.getConfigProps());
232
-
233
- if (!loadingInfo) {
234
- // turn off spinner
235
- // this.psService.sendMessage(false);
236
- }
237
-
238
- const caseViewMode = thePConn.getValue('context_data.caseViewMode', ''); // 2nd arg empty string until typedefs properly allow optional
161
+ const caseViewMode = thePConn.getValue('context_data.caseViewMode');
239
162
  const { CASE_INFO: CASE_CONSTS } = pCoreConstants;
240
163
  if (caseViewMode && caseViewMode === 'review') {
241
164
  setTimeout(() => {
242
165
  // updated for 8.7 - 30-Mar-2022
243
166
  const todoAssignments = getToDoAssignments(thePConn);
244
- if (todoAssignments && todoAssignments.length > 0) {
245
- setCaseInfoID(thePConn.getValue(CASE_CONSTS.CASE_INFO_ID, '')); // 2nd arg empty string until typedefs properly allow optional
246
- setTodoDatasource({ source: todoAssignments });
247
- }
167
+ setCaseInfoID(thePConn.getValue(CASE_CONSTS.CASE_INFO_ID));
168
+ setTodoDatasource({ source: todoAssignments });
248
169
  setShowTodo(true);
249
170
  setShowTodoList(false);
250
171
  }, 100);
@@ -255,11 +176,12 @@ export const FlowContainer = (props: FlowContainerProps) => {
255
176
  }
256
177
 
257
178
  // if have caseMessage show message and end
258
- const theCaseMessages = localizedVal(thePConn.getValue('caseMessages', ''), localeCategory); // 2nd arg empty string until typedefs properly allow optional
179
+ const theCaseMessages = localizedVal(thePConn.getValue('caseMessages'), localeCategory);
180
+
181
+ const rootInfo = PCore.getContainerUtils().getContainerItemData(getPConnect().getTarget(), itemKey);
182
+ const bConfirmView = rootInfo && bShowBanner;
259
183
 
260
- // caseMessages's behavior has changed in 24.2, and hence it doesn't let Optional Action work.
261
- // Changing the below condition for now. Was: (theCaseMessages || !hasAssignments())
262
- if (!hasAssignments()) {
184
+ if (bConfirmView) {
263
185
  // Temp fix for 8.7 change: confirmationNote no longer coming through in caseMessages$.
264
186
  // So, if we get here and caseMessages$ is empty, use default value in DX API response
265
187
  setCaseMessages(theCaseMessages || localizedVal('Thank you! The next step in this case has been routed appropriately.', localeCategory));
@@ -276,11 +198,9 @@ export const FlowContainer = (props: FlowContainerProps) => {
276
198
  }, [props]);
277
199
 
278
200
  const caseId = thePConn.getCaseSummary().content.pyID;
279
- const urgency = getPConnect().getCaseSummary().assignments ? getPConnect().getCaseSummary().assignments?.[0].urgency : '';
201
+ const urgency = getPConnect().getCaseSummary().assignments ? getPConnect().getCaseSummary().assignments?.[0]?.urgency : '';
280
202
  const operatorInitials = Utils.getInitials(PCore.getEnvironmentInfo().getOperatorName() || '');
281
203
 
282
- const bShowBanner = showBanner(getPConnect);
283
-
284
204
  const displayPageMessages = () => {
285
205
  let hasBanner = false;
286
206
  const messages = pageMessages ? pageMessages.map(msg => localizedVal(msg.message, 'Messages')) : pageMessages;
@@ -297,7 +217,7 @@ export const FlowContainer = (props: FlowContainerProps) => {
297
217
  <CardHeader
298
218
  id='assignment-header'
299
219
  title={<Typography variant='h6'>{localizedVal(containerName, undefined, key)}</Typography>}
300
- subheader={`${localizedVal('Task in', 'Todo')} ${caseId} \u2022 ${localizedVal('Priority', 'Todo')} ${urgency}`}
220
+ subheader={`${localizedVal('In', 'Todo')} ${caseId} \u2022 ${localizedVal('Priority', 'Todo')} ${urgency}`}
301
221
  avatar={<Avatar className={`${classes.avatar} psdk-avatar`}>{operatorInitials}</Avatar>}
302
222
  />
303
223
  {displayPageMessages()}
@@ -1,7 +1,7 @@
1
1
  import { useState } from 'react';
2
2
  import Button from '@mui/material/Button';
3
3
  import makeStyles from '@mui/styles/makeStyles';
4
- import { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
4
+ import type { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
5
5
 
6
6
  const useStyles = makeStyles((/* theme */) => ({
7
7
  button: {
@@ -53,7 +53,6 @@ function ListViewActionButtons(props: ListViewActionButtonsProps) {
53
53
  closeActionsDialog();
54
54
  })
55
55
  .catch(err => {
56
- // eslint-disable-next-line no-console
57
56
  console.log(err);
58
57
  })
59
58
  .finally(() => {
@@ -11,7 +11,12 @@ import createPConnectComponent from '@pega/react-sdk-components/lib/bridge/react
11
11
  // Need to get correct implementation from component map for Assignment and CancelAlert
12
12
  import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map';
13
13
  import { getBanners } from '@pega/react-sdk-components/lib/components/helpers/case-utils';
14
- import { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
14
+ import type { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
15
+
16
+ /**
17
+ * WARNING: This file is part of the infrastructure component responsible for working with Redux and managing the creation and update of Redux containers and PConnect.
18
+ * You may override Material components within this component if needed, but do not modify any container-related logic. Changing this logic can lead to unexpected behavior.
19
+ */
15
20
 
16
21
  interface ModalViewContainerProps extends PConnProps {
17
22
  // If any, enter additional props that only exist on this component
@@ -43,7 +48,7 @@ function getKeyAndLatestItem(routinginfo, pConn, options) {
43
48
  if (PCore.getContainerUtils().hasContainerItems(buildName(pConn, containerName))) {
44
49
  const { accessedOrder, items } = routinginfo;
45
50
  let key;
46
- // eslint-disable-next-line no-plusplus
51
+
47
52
  for (let i = accessedOrder.length - 1; i >= 0; i--) {
48
53
  const tempkey = accessedOrder[i];
49
54
  if ((acTertiary && items[tempkey].acTertiary) || (!acTertiary && !items[tempkey].acTertiary)) {
@@ -96,6 +101,7 @@ const useStyles = makeStyles(theme => ({
96
101
  marginBottom: theme.spacing(0)
97
102
  },
98
103
  dlgContent: {
104
+ paddingTop: `${theme.spacing(1)} !important`,
99
105
  marginLeft: theme.spacing(2),
100
106
  marginRight: theme.spacing(2),
101
107
  marginTop: theme.spacing(0),
@@ -130,7 +136,7 @@ export default function ModalViewContainer(props: ModalViewContainerProps) {
130
136
  const [cancelAlertProps, setCancelAlertProps] = useState({});
131
137
  const [isMultiRecordData, setMultiRecordData] = useState(false);
132
138
  const localizedVal = PCore.getLocaleUtils().getLocaleValue;
133
- const localeCategory = 'Data Object';
139
+ const localeCategory = 'ModalContainer';
134
140
 
135
141
  const ERROR_WHILE_RENDERING = 'ERROR_WHILE_RENDERING';
136
142
 
@@ -216,7 +222,7 @@ export default function ModalViewContainer(props: ModalViewContainerProps) {
216
222
  ERROR_WHILE_RENDERING,
217
223
  error => {
218
224
  // setError(true);
219
- // eslint-disable-next-line no-console
225
+
220
226
  console.error(error);
221
227
  },
222
228
  `${ERROR_WHILE_RENDERING}-mc-${getPConnect().getContextName()}`,
@@ -254,7 +260,7 @@ export default function ModalViewContainer(props: ModalViewContainerProps) {
254
260
  const headingValue =
255
261
  isDataObject || isMultiRecord
256
262
  ? getModalHeading(dataObjectAction)
257
- : determineModalHeaderByAction(actionName, caseTypeName, ID, `${caseInfo?.getClassName()}!CASE!${caseInfo.getName()}`.toUpperCase());
263
+ : determineModalHeaderByAction(actionName, caseTypeName, ID, pConnect?.getCaseLocaleReference());
258
264
 
259
265
  let arChildrenAsReact: any[] = [];
260
266
 
@@ -309,7 +315,7 @@ export default function ModalViewContainer(props: ModalViewContainerProps) {
309
315
 
310
316
  return (
311
317
  <>
312
- <Dialog open={bShowModal} aria-labelledby='form-dialog-title'>
318
+ <Dialog open={bShowModal} aria-labelledby='form-dialog-title' maxWidth='sm' fullWidth>
313
319
  <DialogTitle id='form-dialog-title' className={`${classes.dlgTitle} psdk-dialog-title`}>
314
320
  {title}
315
321
  </DialogTitle>