@pega/react-sdk-overrides 0.23.28 → 0.23.30

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.
@@ -19,6 +19,7 @@ interface OperatorProps extends PConnProps {
19
19
  updateDateTime: string;
20
20
  updateLabel: string;
21
21
  updateOperator: { userName: string; userId: string };
22
+ displayLabel?: any;
22
23
  }
23
24
 
24
25
  const useStyles = makeStyles(theme => ({
@@ -36,18 +37,19 @@ export default function Operator(props: OperatorProps) {
36
37
  // const componentName = "Operator";
37
38
  const classes = useStyles();
38
39
 
39
- const fieldLabel = props.label.toLowerCase();
40
+ const fieldLabel = props?.label?.toLowerCase();
41
+ const displayLabel = props?.displayLabel?.toLowerCase();
40
42
  let caseOpLabel = '---';
41
43
  let caseOpName = '---';
42
44
  let caseOpId = '';
43
45
  let caseTime = '';
44
46
 
45
- if (fieldLabel === 'create operator') {
47
+ if (fieldLabel === 'create operator' || displayLabel === 'create operator') {
46
48
  caseOpLabel = props.createLabel;
47
49
  caseOpName = props.createOperator.userName;
48
50
  caseTime = props.createDateTime;
49
51
  caseOpId = props.createOperator.userId;
50
- } else if (fieldLabel === 'update operator') {
52
+ } else if (fieldLabel === 'update operator' || displayLabel === 'update operator') {
51
53
  caseOpLabel = props.updateLabel;
52
54
  caseOpName = props.updateOperator.userName;
53
55
  caseTime = props.updateDateTime;
@@ -70,6 +70,20 @@ export default function Assignment(props: PropsWithChildren<AssignmentProps>) {
70
70
  return arIndicies;
71
71
  }
72
72
 
73
+ function getStepsInfo(steps, formedSteps: any = []) {
74
+ steps.forEach(step => {
75
+ if (step.name) {
76
+ step.name = PCore.getLocaleUtils().getLocaleValue(step.name, undefined, localeReference);
77
+ }
78
+ if (step.steps) {
79
+ formedSteps = getStepsInfo(step.steps, formedSteps);
80
+ } else {
81
+ formedSteps.push(step);
82
+ }
83
+ });
84
+ return formedSteps;
85
+ }
86
+
73
87
  useEffect(() => {
74
88
  if (children) {
75
89
  const firstChild = Array.isArray(children) ? children[0] : children;
@@ -97,13 +111,13 @@ export default function Assignment(props: PropsWithChildren<AssignmentProps>) {
97
111
  } else {
98
112
  setIsVertical(false);
99
113
  }
100
- const steps = JSON.parse(JSON.stringify(oCaseInfo?.navigation?.steps));
101
- steps.forEach(step => {
102
- if (step.name) {
103
- step.name = PCore.getLocaleUtils().getLocaleValue(step.name, undefined, localeReference);
104
- }
105
- });
106
- setArNavigationSteps(steps);
114
+
115
+ if (oCaseInfo?.navigation?.steps) {
116
+ const steps = JSON.parse(JSON.stringify(oCaseInfo?.navigation?.steps));
117
+ const formedSteps = getStepsInfo(steps);
118
+ setArNavigationSteps(formedSteps);
119
+ }
120
+
107
121
  setArCurrentStepIndicies(findCurrentIndicies(arNavigationSteps, arCurrentStepIndicies, 0));
108
122
  }
109
123
  }
@@ -0,0 +1,149 @@
1
+ import React, { useState } from 'react';
2
+ import { Button, Grid, IconButton, Snackbar } from '@material-ui/core';
3
+ import CloseIcon from '@material-ui/icons/Close';
4
+
5
+ import { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
6
+ import './CancelAlert.css';
7
+
8
+ interface CancelAlertProps extends PConnFieldProps {
9
+ // If any, enter additional props that only exist on CancelAlert here
10
+ heading: string;
11
+ content: string;
12
+ itemKey: string;
13
+ hideDelete: boolean;
14
+ isDataObject: boolean;
15
+ skipReleaseLockRequest: any;
16
+ dismiss: Function;
17
+ }
18
+
19
+ export default function CancelAlert(props: CancelAlertProps) {
20
+ const { heading, content, getPConnect, itemKey: containerItemID, hideDelete, isDataObject, skipReleaseLockRequest, dismiss } = props;
21
+ const actionsAPI = getPConnect().getActionsApi();
22
+ const containerManagerAPI = getPConnect().getContainerManager();
23
+ const isLocalAction = getPConnect().getValue(PCore.getConstants().CASE_INFO.IS_LOCAL_ACTION);
24
+ const isBulkAction = getPConnect()?.options?.isBulkAction;
25
+ const localizedVal = PCore.getLocaleUtils().getLocaleValue;
26
+ const broadCastUtils: any = PCore.getCoexistenceManager().getBroadcastUtils();
27
+ const isReverseCoexistence = broadCastUtils.isReverseCoexistenceCaseLoaded();
28
+ const localeCategory = 'ModalContainer';
29
+ const btnIds = {
30
+ SAVE_AND_CLOSE: 'saveAndClose',
31
+ CONTINUE_WORKING: 'continueWorking',
32
+ DELETE: 'delete'
33
+ };
34
+
35
+ const [buttonsState, setButtonsState] = useState({
36
+ [btnIds.SAVE_AND_CLOSE]: false,
37
+ [btnIds.DELETE]: false
38
+ });
39
+
40
+ const [showSnackbar, setShowSnackbar] = useState(false);
41
+ const [snackbarMessage, setSnackbarMessage] = useState('');
42
+
43
+ function disableButton(id) {
44
+ setButtonsState(prevState => ({
45
+ ...prevState,
46
+ [id]: true
47
+ }));
48
+ }
49
+
50
+ function enableButton(id) {
51
+ setButtonsState(prevState => ({
52
+ ...prevState,
53
+ [id]: false
54
+ }));
55
+ }
56
+
57
+ function cancelHandler() {
58
+ if (isReverseCoexistence) {
59
+ dismiss(true);
60
+ // @ts-ignore - An argument for 'payload' was not provided.
61
+ PCore.getPubSubUtils().publish(PCore.getConstants().PUB_SUB_EVENTS.REVERSE_COEXISTENCE_EVENTS.HANDLE_DISCARD);
62
+ } else if (!isDataObject && !isLocalAction && !isBulkAction) {
63
+ disableButton(btnIds.DELETE);
64
+ actionsAPI
65
+ .deleteCaseInCreateStage(containerItemID, hideDelete)
66
+ .then(() => {
67
+ // @ts-ignore - An argument for 'payload' was not provided.
68
+ PCore.getPubSubUtils().publish(PCore.getConstants().PUB_SUB_EVENTS.EVENT_CANCEL);
69
+ })
70
+ .catch(() => {
71
+ setSnackbarMessage(localizedVal('Delete failed.', localeCategory));
72
+ setShowSnackbar(true);
73
+ })
74
+ .finally(() => {
75
+ enableButton(btnIds.DELETE);
76
+ dismiss(true);
77
+ });
78
+ } else if (isLocalAction) {
79
+ dismiss(true);
80
+ actionsAPI.cancelAssignment(containerItemID);
81
+ } else if (isBulkAction) {
82
+ dismiss(true);
83
+ actionsAPI.cancelBulkAction(containerItemID);
84
+ } else {
85
+ dismiss(true);
86
+ containerManagerAPI.removeContainerItem({ containerItemID, skipReleaseLockRequest });
87
+ }
88
+ }
89
+
90
+ function handleSnackbarClose(event: React.SyntheticEvent | React.MouseEvent, reason?: string) {
91
+ if (reason === 'clickaway') {
92
+ return;
93
+ }
94
+ setShowSnackbar(false);
95
+ }
96
+
97
+ const leftButton = (
98
+ <Button
99
+ name={btnIds.CONTINUE_WORKING}
100
+ variant='contained'
101
+ color='secondary'
102
+ onClick={() => {
103
+ dismiss();
104
+ if (isReverseCoexistence) {
105
+ broadCastUtils.setCallBackFunction(null);
106
+ broadCastUtils.setIsDirtyDialogActive(false);
107
+ }
108
+ }}
109
+ >
110
+ {localizedVal('Go back', localeCategory)}
111
+ </Button>
112
+ );
113
+
114
+ const rightButton = (
115
+ <Button name={btnIds.DELETE} variant='contained' color='primary' disabled={buttonsState[btnIds.DELETE]} onClick={cancelHandler}>
116
+ {localizedVal('Discard', localeCategory)}
117
+ </Button>
118
+ );
119
+
120
+ return (
121
+ <>
122
+ <div className='cancel-alert-background'>
123
+ <div className='cancel-alert-top'>
124
+ <h3>{localizedVal(heading, localeCategory)}</h3>
125
+ <div>
126
+ <p>{localizedVal(content, localeCategory)}</p>
127
+ </div>
128
+ <div className='action-controls'>
129
+ <Grid container spacing={4} justifyContent='space-between'>
130
+ <Grid item>{leftButton}</Grid>
131
+ <Grid item>{rightButton}</Grid>
132
+ </Grid>
133
+ </div>
134
+ </div>
135
+ </div>
136
+ <Snackbar
137
+ open={showSnackbar}
138
+ autoHideDuration={3000}
139
+ onClose={handleSnackbarClose}
140
+ message={snackbarMessage}
141
+ action={
142
+ <IconButton size='small' aria-label='close' color='inherit' onClick={handleSnackbarClose}>
143
+ <CloseIcon fontSize='small' />
144
+ </IconButton>
145
+ }
146
+ />
147
+ </>
148
+ );
149
+ }
@@ -34,7 +34,6 @@ function ListViewActionButtons(props: ListViewActionButtonsProps) {
34
34
  variant='contained'
35
35
  color='secondary'
36
36
  onClick={() => {
37
- closeActionsDialog();
38
37
  getPConnect().getActionsApi().cancelDataObject(context);
39
38
  }}
40
39
  >
@@ -1,17 +1,16 @@
1
1
  import { createElement, useEffect, useRef, useState } from 'react';
2
- import isEqual from 'fast-deep-equal';
3
2
  import Dialog from '@material-ui/core/Dialog';
4
3
  import DialogContent from '@material-ui/core/DialogContent';
5
4
  import DialogTitle from '@material-ui/core/DialogTitle';
6
5
  import { makeStyles } from '@material-ui/core/styles';
7
6
  import { MuiPickersUtilsProvider } from '@material-ui/pickers';
8
7
  import DayjsUtils from '@date-io/dayjs';
8
+ import difference from 'lodash.difference';
9
9
 
10
10
  import createPConnectComponent from '@pega/react-sdk-components/lib/bridge/react_pconnect';
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 { isEmptyObject } from '@pega/react-sdk-components/lib/components/helpers/common-utils';
15
14
  import { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
16
15
 
17
16
  interface ModalViewContainerProps extends PConnProps {
@@ -21,31 +20,67 @@ interface ModalViewContainerProps extends PConnProps {
21
20
  pageMessages?: string[];
22
21
  }
23
22
 
23
+ function isOpenModalAction(prevModalCollection, currentModalList) {
24
+ return prevModalCollection && currentModalList ? Object.keys(prevModalCollection).length < currentModalList.length : false;
25
+ }
26
+
27
+ function isUpdateModalAction(prevModalCollection, currentModalList) {
28
+ return prevModalCollection && currentModalList ? Object.keys(prevModalCollection).length === currentModalList.length : false;
29
+ }
30
+
31
+ function isCloseModalAction(prevModalCollection, currentModalList) {
32
+ return prevModalCollection && currentModalList ? Object.keys(prevModalCollection).length > currentModalList.length : false;
33
+ }
34
+
24
35
  function buildName(pConnect, name = '') {
25
36
  const context = pConnect.getContextName();
26
37
  return `${context}/${name}`;
27
38
  }
28
39
 
29
- function getKeyAndLatestItem(routinginfo, pConn) {
40
+ function getKeyAndLatestItem(routinginfo, pConn, options) {
30
41
  const containerName = pConn.getContainerName();
42
+ const { acTertiary = false } = options || {};
31
43
  if (PCore.getContainerUtils().hasContainerItems(buildName(pConn, containerName))) {
32
44
  const { accessedOrder, items } = routinginfo;
33
- const key = accessedOrder[accessedOrder.length - 1];
45
+ let key;
46
+ // eslint-disable-next-line no-plusplus
47
+ for (let i = accessedOrder.length - 1; i >= 0; i--) {
48
+ const tempkey = accessedOrder[i];
49
+ if ((acTertiary && items[tempkey].acTertiary) || (!acTertiary && !items[tempkey].acTertiary)) {
50
+ key = tempkey;
51
+ break;
52
+ }
53
+ }
34
54
  const latestItem = items[key];
35
55
  return { key, latestItem };
36
56
  }
37
57
  return {};
38
58
  }
39
59
 
40
- function getConfigObject(item, pConnect) {
60
+ function getConfigObject(item, pConnect, isReverseCoexistence = false) {
61
+ let config;
62
+ if (isReverseCoexistence) {
63
+ config = {
64
+ options: {
65
+ pageReference: pConnect?.getPageReference(),
66
+ hasForm: true,
67
+ containerName: pConnect?.getContainerName() || PCore.getConstants().MODAL
68
+ }
69
+ };
70
+ return PCore.createPConnect(config);
71
+ }
41
72
  if (item) {
42
- const { context, view } = item;
43
- const config = {
73
+ const { context, view, isBulkAction } = item;
74
+ const target = PCore.getContainerUtils().getTargetFromContainerItemID(context);
75
+ config = {
44
76
  meta: view,
45
77
  options: {
46
78
  context,
47
79
  pageReference: view.config.context || pConnect.getPageReference(),
48
- hasForm: true
80
+ hasForm: true,
81
+ ...(isBulkAction && { isBulkAction }),
82
+ containerName: pConnect?.getContainerName() || PCore.getConstants().MODAL,
83
+ target
49
84
  }
50
85
  };
51
86
  return PCore.createPConnect(config);
@@ -59,20 +94,12 @@ const useStyles = makeStyles(theme => ({
59
94
  marginRight: theme.spacing(2),
60
95
  marginTop: theme.spacing(2),
61
96
  marginBottom: theme.spacing(0)
62
- // paddingLeft: theme.spacing(0),
63
- // paddingRight: theme.spacing(0),
64
- // paddingTop: theme.spacing(0),
65
- // paddingBottom: theme.spacing(0),
66
97
  },
67
98
  dlgContent: {
68
99
  marginLeft: theme.spacing(2),
69
100
  marginRight: theme.spacing(2),
70
101
  marginTop: theme.spacing(0),
71
102
  marginBottom: theme.spacing(2)
72
- // paddingLeft: theme.spacing(0),
73
- // paddingRight: theme.spacing(0),
74
- // paddingTop: theme.spacing(0),
75
- // paddingBottom: theme.spacing(0),
76
103
  }
77
104
  }));
78
105
 
@@ -84,70 +111,79 @@ export default function ModalViewContainer(props: ModalViewContainerProps) {
84
111
 
85
112
  const classes = useStyles();
86
113
 
114
+ const modalCollection = useRef({});
87
115
  const routingInfoRef = useRef({});
88
- const { getPConnect, routingInfo = null, loadingInfo = '', pageMessages = [] } = props;
116
+ const { getPConnect, routingInfo = null, pageMessages = [] } = props;
89
117
  const pConn = getPConnect();
118
+ const { acTertiary } = pConn.getConfigProps() as any;
90
119
  const {
91
120
  CONTAINER_TYPE: { MULTIPLE },
92
121
  PUB_SUB_EVENTS: { EVENT_SHOW_CANCEL_ALERT }
93
122
  } = PCore.getConstants();
94
- const { subscribe } = PCore.getPubSubUtils();
123
+ const { subscribe, unsubscribe } = PCore.getPubSubUtils();
95
124
  const [bShowModal, setShowModal] = useState(false);
96
- const [bSubscribed, setSubscribed] = useState(false);
97
125
  const [bShowCancelAlert, setShowCancelAlert] = useState(false);
98
- const [oCaseInfo, setOCaseInfo] = useState({});
99
126
  const [createdView, setCreatedView] = useState<any>(null);
100
127
  const [title, setTitle] = useState('');
101
128
  const [arNewChildrenAsReact, setArNewChildrenAsReact] = useState<any[]>([]);
102
129
  const [itemKey, setItemKey] = useState('');
103
- const [cancelPConn, setCancelPConn] = useState(null);
130
+ const [cancelAlertProps, setCancelAlertProps] = useState({});
104
131
  const [isMultiRecordData, setMultiRecordData] = useState(false);
105
132
  const localizedVal = PCore.getLocaleUtils().getLocaleValue;
106
133
  const localeCategory = 'Data Object';
107
134
 
108
- const actionsDialog = useRef(false);
135
+ const ERROR_WHILE_RENDERING = 'ERROR_WHILE_RENDERING';
109
136
 
110
137
  function showAlert(payload) {
111
- const { latestItem } = getKeyAndLatestItem(routingInfoRef.current, pConn);
112
- const { isModalAction } = payload;
138
+ const { latestItem } = getKeyAndLatestItem(routingInfoRef.current, pConn, { acTertiary });
139
+ const isReverseCoexistence = (PCore.getCoexistenceManager().getBroadcastUtils() as any).isReverseCoexistenceCaseLoaded();
140
+ const { isModalAction, hideDelete, isDataObject, skipReleaseLockRequest } = payload;
113
141
 
114
142
  /*
115
143
  If we are in create stage full page mode, created a new case and trying to click on cancel button
116
144
  it will show two alert dialogs which is not expected. Hence isModalAction flag to avoid that.
117
145
  */
118
- if (latestItem && isModalAction && !actionsDialog.current) {
119
- const configObject = getConfigObject(latestItem, pConn);
120
- setCancelPConn(configObject?.getPConnect() as any);
146
+ if (latestItem && isModalAction) {
147
+ const configObject = getConfigObject(latestItem, pConn, isReverseCoexistence);
148
+ const contextName = configObject?.getPConnect().getContextName();
149
+ setCancelAlertProps({
150
+ heading: 'Discard unsaved changes?',
151
+ content: 'You have unsaved changes. You can discard them or go back to keep working.',
152
+ getPConnect: configObject?.getPConnect,
153
+ itemKey: contextName,
154
+ hideDelete,
155
+ isDataObject,
156
+ skipReleaseLockRequest
157
+ });
121
158
  setShowCancelAlert(true);
122
159
  }
123
160
  }
124
161
 
125
- function compareCaseInfoIsDifferent(oCurrentCaseInfo: Object): boolean {
126
- let bRet = false;
127
-
128
- // fast-deep-equal version
129
- if (isEqual !== undefined) {
130
- bRet = !isEqual(oCaseInfo, oCurrentCaseInfo);
131
- } else {
132
- const sCurrentCaseInfo = JSON.stringify(oCurrentCaseInfo);
133
- const sOldCaseInfo = JSON.stringify(oCaseInfo);
134
- // stringify compare version
135
- if (sCurrentCaseInfo !== sOldCaseInfo) {
136
- bRet = true;
137
- }
138
- }
162
+ function handleModalOpen(key) {
163
+ modalCollection.current = {
164
+ ...modalCollection.current,
165
+ [key]: {}
166
+ };
167
+ }
139
168
 
140
- // if different, save off new case info
141
- if (bRet) {
142
- setOCaseInfo(JSON.parse(JSON.stringify(oCurrentCaseInfo)));
143
- }
169
+ function handleModalClose(accessedOrder) {
170
+ const tempModalCollection = modalCollection.current;
171
+ const [closedModalKey] = difference(Object.keys(tempModalCollection), accessedOrder);
144
172
 
145
- return bRet;
173
+ if (closedModalKey && tempModalCollection[closedModalKey]) {
174
+ const modifiedModalCollection = { ...tempModalCollection };
175
+ delete modifiedModalCollection[closedModalKey];
176
+ modalCollection.current = modifiedModalCollection;
177
+ setShowModal(false);
178
+ }
146
179
  }
147
180
 
148
- const updateAlertState = modalFlag => {
181
+ const dismissCancelAlert = dismissAllModals => {
149
182
  setShowCancelAlert(false);
150
- setShowModal(modalFlag);
183
+
184
+ if (dismissAllModals) {
185
+ setShowModal(false);
186
+ }
151
187
  };
152
188
 
153
189
  function getModalHeading(dataObjectAction) {
@@ -170,151 +206,104 @@ export default function ModalViewContainer(props: ModalViewContainerProps) {
170
206
  }, [MULTIPLE, pConn]);
171
207
 
172
208
  useEffect(() => {
173
- // Update routingInfoRef.current whenever routingInfo changes
209
+ // Persisting routing information between the renders in showAlert
174
210
  routingInfoRef.current = routingInfo;
175
- if (routingInfoRef.current && !loadingInfo) {
176
- const currentOrder = routingInfo.accessedOrder;
211
+ });
177
212
 
178
- if (undefined === currentOrder) {
179
- return;
180
- }
213
+ useEffect(() => {
214
+ subscribe(EVENT_SHOW_CANCEL_ALERT, showAlert, EVENT_SHOW_CANCEL_ALERT /* Unique string for subscription */);
215
+ subscribe(
216
+ ERROR_WHILE_RENDERING,
217
+ error => {
218
+ // setError(true);
219
+ // eslint-disable-next-line no-console
220
+ console.error(error);
221
+ },
222
+ `${ERROR_WHILE_RENDERING}-mc-${getPConnect().getContextName()}`,
223
+ false,
224
+ getPConnect().getContextName()
225
+ );
226
+
227
+ // Unsubscribe on component unmount
228
+ return () => {
229
+ unsubscribe(EVENT_SHOW_CANCEL_ALERT, EVENT_SHOW_CANCEL_ALERT /* Should be same unique string passed during subscription */);
230
+ };
231
+ });
181
232
 
182
- const currentItems = routingInfo.items;
183
-
184
- const { key, latestItem } = getKeyAndLatestItem(routingInfoRef.current, pConn);
185
- // console.log(`ModalViewContainer: key: ${key} latestItem: ${JSON.stringify(latestItem)}`);
186
-
187
- if (currentOrder.length > 0) {
188
- if (currentItems[key] && currentItems[key].view && !isEmptyObject(currentItems[key].view)) {
189
- const currentItem = currentItems[key];
190
- const rootView = currentItem.view;
191
- const { context } = rootView.config;
192
- const config: any = { meta: rootView };
193
- config.options = {
194
- context: currentItem.context,
195
- hasForm: true,
196
- pageReference: context || pConn.getPageReference()
197
- };
198
-
199
- if (!bSubscribed) {
200
- setSubscribed(true);
201
- subscribe(EVENT_SHOW_CANCEL_ALERT, showAlert, EVENT_SHOW_CANCEL_ALERT /* Unique string for subscription */);
202
- }
203
-
204
- const configObject = PCore.createPConnect(config);
205
-
206
- // THIS is where the ViewContainer creates a View
207
- // The config has meta.config.type = "view"
208
- const newComp = configObject.getPConnect();
209
- // const newCompName = newComp.getComponentName();
210
- // @ts-ignore - parameter “contextName” for getDataObject method should be optional
211
- const caseInfo = newComp && newComp.getDataObject() && newComp.getDataObject().caseInfo ? newComp.getDataObject().caseInfo : null;
212
-
213
- // console.log(`ModalViewContainer just created newComp: ${newCompName}`);
214
-
215
- // The metadata for pyDetails changed such that the "template": "CaseView"
216
- // is no longer a child of the created View but is in the created View's
217
- // config. So, we DON'T want to replace this.pConn$ since the created
218
- // component is a View (and not a ViewContainer). We now look for the
219
- // "template" type directly in the created component (newComp) and NOT
220
- // as a child of the newly created component.
221
- // console.log(`---> ModalViewContainer created new ${newCompName}`);
222
-
223
- // Use the newly created component (View) info but DO NOT replace
224
- // this ModalViewContainer's pConn$, etc.
225
- // Note that we're now using the newly created View's PConnect in the
226
- // ViewContainer HTML template to guide what's rendered similar to what
227
- // the React return of React.Fragment does
228
-
229
- // right now need to check caseInfo for changes, to trigger redraw, not getting
230
- // changes from angularPconnect except for first draw
231
- if (newComp && caseInfo && compareCaseInfoIsDifferent(caseInfo)) {
232
- setCreatedView({ configObject, latestItem });
233
-
234
- const { actionName } = latestItem;
235
- const theNewCaseInfo = newComp.getCaseInfo();
236
- const caseName = theNewCaseInfo.getName();
237
- const ID = theNewCaseInfo.getBusinessID() || theNewCaseInfo.getID();
238
- const caseTypeName = theNewCaseInfo.getCaseTypeName();
239
- const isDataObject = routingInfo.items[latestItem.context].resourceType === PCore.getConstants().RESOURCE_TYPES.DATA;
240
- const dataObjectAction = routingInfo.items[latestItem.context].resourceStatus;
241
- const isMultiRecord = routingInfo.items[latestItem.context].isMultiRecordData;
242
- setMultiRecordData(isMultiRecord);
243
- const headingValue =
244
- isDataObject || isMultiRecord
245
- ? getModalHeading(dataObjectAction)
246
- : determineModalHeaderByAction(
247
- actionName,
248
- caseTypeName,
249
- ID,
250
- `${theNewCaseInfo?.getClassName()}!CASE!${theNewCaseInfo.getName()}`.toUpperCase()
251
- );
252
-
253
- setTitle(headingValue);
254
-
255
- let arChildrenAsReact: any[] = [];
256
-
257
- if (newComp.getComponentName() === 'reference') {
258
- // Reference component doesn't have children. It can build the View we want.
259
- // The Reference component getPConnect is in configObject
260
-
261
- arChildrenAsReact.push(
262
- createElement(createPConnectComponent(), {
263
- ...configObject,
264
- key: `${caseName}-${ID}`
265
- })
266
- );
267
- } else {
268
- // This is the 8.6 implementation. Leaving it in for reference for now.
269
- // And create a similar array of the children as React components
270
- // passed to Assignment component when rendered
271
- arChildrenAsReact = (newComp.getChildren() as []).map((child: any) => {
272
- // Use Case Summary ID as the React element's key
273
- const caseSummaryID = child.getPConnect().getCaseSummary().ID;
274
- return createElement(createPConnectComponent(), {
275
- ...child,
276
- key: caseSummaryID
277
- });
278
- });
279
- }
280
-
281
- if (arChildrenAsReact.length > 0) setArNewChildrenAsReact(arChildrenAsReact);
282
-
283
- setShowModal(true);
284
-
285
- // save off itemKey to be used for finishAssignment, etc.
286
- setItemKey(key);
287
- }
288
- }
289
- } else {
290
- if (bShowModal) {
291
- setShowModal(false);
233
+ useEffect(() => {
234
+ if (routingInfo) {
235
+ const { accessedOrder, type } = routingInfo;
236
+ const { key, latestItem } = getKeyAndLatestItem(routingInfo, pConn, { acTertiary });
237
+
238
+ if (
239
+ latestItem &&
240
+ type === MULTIPLE &&
241
+ (isOpenModalAction(modalCollection.current, accessedOrder) || isUpdateModalAction(modalCollection.current, accessedOrder))
242
+ ) {
243
+ const { actionName } = latestItem;
244
+ // const { isDockable = false } = latestItem?.modalOptions || {};
245
+ const configObject: any = getConfigObject(latestItem, null, false);
246
+ const pConnect = configObject.getPConnect();
247
+ const caseInfo: any = pConnect.getCaseInfo();
248
+ const caseName = caseInfo.getName();
249
+ const caseTypeName = caseInfo.getCaseTypeName();
250
+ const ID = caseInfo.getBusinessID() || caseInfo.getID();
251
+ const isDataObject = routingInfo.items[latestItem.context].resourceType === PCore.getConstants().RESOURCE_TYPES.DATA;
252
+ const dataObjectAction = routingInfo.items[latestItem.context].resourceStatus;
253
+ const isMultiRecord = routingInfo.items[latestItem.context].isMultiRecordData;
254
+ const headingValue =
255
+ isDataObject || isMultiRecord
256
+ ? getModalHeading(dataObjectAction)
257
+ : determineModalHeaderByAction(actionName, caseTypeName, ID, `${caseInfo?.getClassName()}!CASE!${caseInfo.getName()}`.toUpperCase());
258
+
259
+ let arChildrenAsReact: any[] = [];
260
+
261
+ if (pConnect.getComponentName() === 'reference') {
262
+ // Reference component doesn't have children. It can build the View we want.
263
+ // The Reference component getPConnect is in configObject
264
+
265
+ arChildrenAsReact.push(
266
+ createElement(createPConnectComponent(), {
267
+ ...configObject,
268
+ key: `${caseName}-${ID}`
269
+ })
270
+ );
271
+ } else {
272
+ // This is the 8.6 implementation. Leaving it in for reference for now.
273
+ // And create a similar array of the children as React components
274
+ // passed to Assignment component when rendered
275
+ arChildrenAsReact = (pConnect.getChildren() as []).map((child: any) => {
276
+ // Use Case Summary ID as the React element's key
277
+ const caseSummaryID = child.getPConnect().getCaseSummary().ID;
278
+ return createElement(createPConnectComponent(), {
279
+ ...child,
280
+ key: caseSummaryID
281
+ });
282
+ });
292
283
  }
293
- if (!isEmptyObject(oCaseInfo)) {
294
- setOCaseInfo({});
284
+
285
+ if (arChildrenAsReact.length > 0) setArNewChildrenAsReact(arChildrenAsReact);
286
+ setMultiRecordData(isMultiRecord);
287
+ setTitle(headingValue);
288
+ setCreatedView({ configObject, latestItem });
289
+ setItemKey(key);
290
+ setShowModal(true);
291
+
292
+ // Update modal use case which happens when assignment in submitted in modal.
293
+ if (isUpdateModalAction(modalCollection.current, accessedOrder)) {
294
+ // handleModalUpdate(key);
295
+ } else if (isOpenModalAction(modalCollection.current, accessedOrder)) {
296
+ // New modal open scenario
297
+ handleModalOpen(key);
295
298
  }
299
+ } else if (isCloseModalAction(modalCollection.current, accessedOrder)) {
300
+ handleModalClose(accessedOrder);
296
301
  }
297
302
  }
298
303
  }, [routingInfo]);
299
304
 
300
- // function placeholderModalClose() {
301
- // // Intentionally a no-op. Similar behavior in other SDKs.
302
- // // Does NOT close the window. This forces the user to use
303
- // // the cancel or submit button to close the modal (which, in turn, gets the right
304
- // // Constellation code to run to clean up the containers, data, etc.)
305
-
306
- // // console.log(`ModalViewContainer: placeholderModalClose setting bShowModal to false`) setShowModal(false);
307
- // }
308
-
309
- // if (bShowModal) {
310
- // console.log(`ModalViewContainer about to show modal with`);
311
- // console.log(`--> createdView: ${createdView} createdView.getPConnect: ${typeof createdView.getPConnect}`);
312
- // console.log(`--> itemKey: ${itemKey}`);
313
- // console.log(`--> arNewChildrenAsReact: ${JSON.stringify(arNewChildrenAsReact)}`);
314
- // }
315
-
316
305
  function closeActionsDialog() {
317
- actionsDialog.current = true;
306
+ // actionsDialog.current = true;
318
307
  setShowModal(false);
319
308
  }
320
309
 
@@ -341,6 +330,7 @@ export default function ModalViewContainer(props: ModalViewContainerProps) {
341
330
  </MuiPickersUtilsProvider>
342
331
  ) : null}
343
332
  </DialogContent>
333
+
344
334
  {isMultiRecordData && (
345
335
  <ListViewActionButtons
346
336
  getPConnect={createdView.configObject.getPConnect}
@@ -349,7 +339,7 @@ export default function ModalViewContainer(props: ModalViewContainerProps) {
349
339
  />
350
340
  )}
351
341
  </Dialog>
352
- {bShowCancelAlert && <CancelAlert pConn={cancelPConn} showAlert={bShowCancelAlert} updateAlertState={updateAlertState} />}
342
+ {bShowCancelAlert && <CancelAlert {...cancelAlertProps} dismiss={dismissCancelAlert} />}
353
343
  </>
354
344
  );
355
345
  }
@@ -116,6 +116,8 @@ export default function NavBar(props: NavBarProps) {
116
116
  const [bShowCaseTypes, setBShowCaseTypes] = useState(true);
117
117
  const [bShowOperatorButtons, setBShowOperatorButtons] = useState(false);
118
118
  const [anchorEl, setAnchorEl] = useState(null);
119
+ const localeUtils = PCore.getLocaleUtils();
120
+ const localeReference = pConn.getValue('.pyLocaleReference');
119
121
 
120
122
  const localizedVal = PCore.getLocaleUtils().getLocaleValue;
121
123
  const localeCategory = 'AppShell';
@@ -231,7 +233,7 @@ export default function NavBar(props: NavBarProps) {
231
233
  <ListItemIcon>
232
234
  <WorkOutlineIcon fontSize='large' />
233
235
  </ListItemIcon>
234
- <ListItemText primary={caseType.pyLabel} />
236
+ <ListItemText primary={localeUtils.getLocaleValue(caseType.pyLabel, '', localeReference)} />
235
237
  </ListItem>
236
238
  ))}
237
239
  </List>
@@ -240,7 +242,7 @@ export default function NavBar(props: NavBarProps) {
240
242
  {navPages.map(page => (
241
243
  <ListItem button onClick={() => navPanelButtonClick(page)} key={page.pyLabel}>
242
244
  <ListItemIcon>{iconMap[page.pxPageViewIcon]}</ListItemIcon>
243
- <ListItemText primary={page.pyLabel} />
245
+ <ListItemText primary={localeUtils.getLocaleValue(page.pyLabel, '', localeReference)} />
244
246
  </ListItem>
245
247
  ))}
246
248
  </List>
@@ -278,7 +280,7 @@ export default function NavBar(props: NavBarProps) {
278
280
  <ListItemIcon>
279
281
  <ArrowBackIcon fontSize='large' />
280
282
  </ListItemIcon>
281
- <Typography variant='inherit'>{localizedVal('Logout', localeCategory)}</Typography>
283
+ <Typography variant='inherit'>{localizedVal('Log off', localeCategory)}</Typography>
282
284
  </MenuItem>
283
285
  </Menu>
284
286
  </>
@@ -17,7 +17,8 @@ export default function CaseSummary(props: PropsWithChildren<CaseSummaryProps>)
17
17
  // const { status, showStatus } = theConfigProps;
18
18
  const status = theConfigProps.status;
19
19
  const showStatus = theConfigProps.showStatus;
20
-
20
+ const localizedVal = PCore.getLocaleUtils().getLocaleValue;
21
+ const localeCategory = 'ModalContainer';
21
22
  // from Constellation DX Components
22
23
  // get the primary and secondary fields with the raw data (which has the non-resolved property values)
23
24
  // const regionsRaw = getPConnect().getRawMetadata().children;
@@ -29,13 +30,54 @@ export default function CaseSummary(props: PropsWithChildren<CaseSummaryProps>)
29
30
  let arPrimaryFields: any[] = [];
30
31
  let arSecondaryFields: any[] = [];
31
32
 
33
+ /* eslint-disable @typescript-eslint/no-shadow */
34
+ function prepareComponentInCaseSummary(pConnectMeta, getPConnect) {
35
+ const { config, children } = pConnectMeta;
36
+ const pConnect = getPConnect();
37
+
38
+ const caseSummaryComponentObject: any = {};
39
+
40
+ const { type } = pConnectMeta;
41
+ const createdComponent = pConnect.createComponent({
42
+ type,
43
+ children: children ? [...children] : [],
44
+ config: {
45
+ ...config
46
+ }
47
+ });
48
+
49
+ caseSummaryComponentObject.value = createdComponent;
50
+ return caseSummaryComponentObject;
51
+ }
52
+
53
+ function prepareCaseSummaryData(summaryFieldChildren) {
54
+ const convertChildrenToSummaryData = kid => {
55
+ return kid?.map((childItem, index) => {
56
+ const childMeta = childItem.getPConnect().meta;
57
+ const caseSummaryComponentObject = prepareComponentInCaseSummary(childMeta, childItem.getPConnect);
58
+ caseSummaryComponentObject.id = index + 1;
59
+ return caseSummaryComponentObject;
60
+ });
61
+ };
62
+ return summaryFieldChildren ? convertChildrenToSummaryData(summaryFieldChildren?.getChildren()) : undefined;
63
+ }
64
+
32
65
  for (const child of children as ReactElement[]) {
33
66
  const childPConn = (child as ReactElement).props.getPConnect();
34
67
  const childPConnData = childPConn.resolveConfigProps(childPConn.getRawMetadata());
35
68
  if (childPConnData.name.toLowerCase() === 'primary fields') {
36
69
  arPrimaryFields = childPConnData.children;
70
+ arPrimaryFields.forEach(field => {
71
+ if (field.config?.value && typeof field.config?.value === 'string') {
72
+ field.config.value = localizedVal(field.config.value, localeCategory);
73
+ }
74
+ });
37
75
  } else if (childPConnData.name.toLowerCase() === 'secondary fields') {
76
+ const secondarySummaryFields = prepareCaseSummaryData(childPConn);
38
77
  arSecondaryFields = childPConnData.children;
78
+ arSecondaryFields.forEach((field, index) => {
79
+ field.config.displayLabel = secondarySummaryFields[index]?.value?.props?.label;
80
+ });
39
81
  }
40
82
  }
41
83
 
@@ -4,6 +4,9 @@ import Menu from '@material-ui/core/Menu';
4
4
  import MenuItem from '@material-ui/core/MenuItem';
5
5
 
6
6
  import { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps';
7
+ import Snackbar from '@material-ui/core/Snackbar';
8
+ import IconButton from '@material-ui/core/IconButton';
9
+ import CloseIcon from '@material-ui/icons/Close';
7
10
 
8
11
  interface CaseViewActionsMenuProps extends PConnProps {
9
12
  // If any, enter additional props that only exist on this component
@@ -23,6 +26,9 @@ export default function CaseViewActionsMenu(props: CaseViewActionsMenuProps) {
23
26
 
24
27
  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
25
28
 
29
+ const [showSnackbar, setShowSnackbar] = useState(false);
30
+ const [snackbarMessage, setSnackbarMessage]: any = useState('');
31
+
26
32
  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
27
33
  setAnchorEl(event.currentTarget);
28
34
  };
@@ -33,6 +39,18 @@ export default function CaseViewActionsMenu(props: CaseViewActionsMenuProps) {
33
39
 
34
40
  const arMenuItems: any[] = [];
35
41
 
42
+ function showToast(message: string) {
43
+ setSnackbarMessage(message);
44
+ setShowSnackbar(true);
45
+ }
46
+
47
+ function handleSnackbarClose(event: React.SyntheticEvent | React.MouseEvent, reason?: string) {
48
+ if (reason === 'clickaway') {
49
+ return;
50
+ }
51
+ setShowSnackbar(false);
52
+ }
53
+
36
54
  function _actionMenuActionsClick(data) {
37
55
  const actionsAPI = thePConn.getActionsApi();
38
56
  const openLocalAction = actionsAPI.openLocalAction.bind(actionsAPI);
@@ -51,7 +69,11 @@ export default function CaseViewActionsMenu(props: CaseViewActionsMenuProps) {
51
69
  const openProcessAction = actionsAPI.openProcessAction.bind(actionsAPI);
52
70
  openProcessAction(process.ID, {
53
71
  ...process
54
- });
72
+ })
73
+ .then(() => {})
74
+ .catch(() => {
75
+ showToast(`${process.name} Submit failed!`);
76
+ });
55
77
  handleClose();
56
78
  }
57
79
 
@@ -79,6 +101,17 @@ export default function CaseViewActionsMenu(props: CaseViewActionsMenuProps) {
79
101
  <Menu id='simple-menu' anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleClose}>
80
102
  {arMenuItems}
81
103
  </Menu>
104
+ <Snackbar
105
+ open={showSnackbar}
106
+ autoHideDuration={3000}
107
+ onClose={handleSnackbarClose}
108
+ message={snackbarMessage}
109
+ action={
110
+ <IconButton size='small' aria-label='close' color='inherit' onClick={handleSnackbarClose}>
111
+ <CloseIcon fontSize='small' />
112
+ </IconButton>
113
+ }
114
+ />
82
115
  </>
83
116
  );
84
117
  }
@@ -141,7 +141,6 @@ export default function SimpleTableManual(props: PropsWithChildren<SimpleTableMa
141
141
  // Getting current context
142
142
  const context = getPConnect().getContextName();
143
143
  const resolvedList = getReferenceList(pConn);
144
- const pageReference = `${pConn.getPageReference()}${resolvedList}`;
145
144
  pConn.setReferenceList(resolvedList);
146
145
  const menuIconOverride$ = Utils.getImageSrc('trash', Utils.getSDKStaticConentUrl());
147
146
 
@@ -288,10 +287,8 @@ export default function SimpleTableManual(props: PropsWithChildren<SimpleTableMa
288
287
  pConn
289
288
  .getActionsApi()
290
289
  .openEmbeddedDataModal(defaultView, pConn, referenceListStr, referenceList.length, PCore.getConstants().RESOURCE_STATUS.CREATE);
291
- } else if (PCore.getPCoreVersion()?.includes('8.7')) {
292
- pConn.getListActions().insert({ classID: contextClass }, referenceList.length, pageReference);
293
290
  } else {
294
- pConn.getListActions().insert({ classID: contextClass }, referenceList.length, ''); // 3rd arg null until typedef marked correctly as optional
291
+ pConn.getListActions().insert({ classID: contextClass }, referenceList.length);
295
292
  }
296
293
  };
297
294
 
@@ -312,11 +309,11 @@ export default function SimpleTableManual(props: PropsWithChildren<SimpleTableMa
312
309
 
313
310
  const deleteRecord = () => {
314
311
  setEditAnchorEl(null);
315
- if (PCore.getPCoreVersion()?.includes('8.7')) {
316
- pConn.getListActions().deleteEntry(selectedRowIndex.current, pageReference);
317
- } else {
318
- pConn.getListActions().deleteEntry(selectedRowIndex.current, ''); // 2nd arg empty string until typedef marked correctly as optional
319
- }
312
+ pConn.getListActions().deleteEntry(selectedRowIndex.current);
313
+ };
314
+
315
+ const deleteRecordFromInlineEditable = (index: number) => {
316
+ pConn.getListActions().deleteEntry(index);
320
317
  };
321
318
 
322
319
  function buildElementsForTable() {
@@ -616,7 +613,7 @@ export default function SimpleTableManual(props: PropsWithChildren<SimpleTableMa
616
613
  className='psdk-utility-button'
617
614
  id='delete-button'
618
615
  aria-label='Delete Cell'
619
- onClick={() => deleteRecord()}
616
+ onClick={() => deleteRecordFromInlineEditable(index)}
620
617
  >
621
618
  <img className='psdk-utility-card-action-svg-icon' src={menuIconOverride$} />
622
619
  </button>
@@ -632,7 +629,8 @@ export default function SimpleTableManual(props: PropsWithChildren<SimpleTableMa
632
629
  .slice(0)
633
630
  .map((row, index) => {
634
631
  return (
635
- <TableRow key={row[displayedColumns[0]]}>
632
+ // eslint-disable-next-line react/no-array-index-key
633
+ <TableRow key={index}>
636
634
  {displayedColumns.map(colKey => {
637
635
  return (
638
636
  <TableCell key={colKey} className={classes.tableCell}>
@@ -54,6 +54,9 @@ export default function WssNavBar(props: WssNavBarProps) {
54
54
  const [anchorElNav, setAnchorElNav] = useState<null | HTMLElement>(null);
55
55
  const [anchorElUser, setAnchorElUser] = useState<null | HTMLElement>(null);
56
56
 
57
+ const localizedVal = PCore.getLocaleUtils().getLocaleValue;
58
+ const localeCategory = 'AppShell';
59
+
57
60
  const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => {
58
61
  setAnchorElNav(event.currentTarget);
59
62
  };
@@ -144,7 +147,7 @@ export default function WssNavBar(props: WssNavBarProps) {
144
147
  onClose={handleCloseUserMenu}
145
148
  >
146
149
  <MenuItem onClick={logout}>
147
- <Typography>Logout</Typography>
150
+ <Typography>{localizedVal('Log off', localeCategory)}</Typography>
148
151
  </MenuItem>
149
152
  </Menu>
150
153
  </Box>
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable react/jsx-boolean-value */
2
2
  /* eslint-disable react/no-array-index-key */
3
+ /* eslint-disable no-nested-ternary */
3
4
  import { useState, useEffect, useCallback } from 'react';
4
5
  import { CircularProgress, IconButton, Menu, MenuItem, Button } from '@material-ui/core';
5
6
  import MoreVertIcon from '@material-ui/icons/MoreVert';
@@ -39,7 +40,10 @@ export default function Attachment(props: AttachmentProps) {
39
40
  [required, disabled] = [required, disabled].map(prop => prop === true || (typeof prop === 'string' && prop === 'true'));
40
41
  const pConn = getPConnect();
41
42
  const caseID = PCore.getStoreValue('.pyID', 'caseInfo.content', pConn.getContextName());
42
-
43
+ const localizedVal = PCore.getLocaleUtils().getLocaleValue;
44
+ const localeCategory = 'CosmosFields';
45
+ const uploadMultipleFilesLabel = localizedVal('file_upload_text_multiple', localeCategory);
46
+ const uploadSingleFileLabel = localizedVal('file_upload_text_one', localeCategory);
43
47
  let categoryName = '';
44
48
  if (value && value.pyCategoryName) {
45
49
  categoryName = value.pyCategoryName;
@@ -379,7 +383,13 @@ export default function Attachment(props: AttachmentProps) {
379
383
  onChange={onFileAdded}
380
384
  />
381
385
  <Button style={{ textTransform: 'none' }} variant='outlined' color='primary' component='span'>
382
- {allowMultiple === 'true' ? 'Upload files' : 'Upload a file'}
386
+ {allowMultiple === 'true'
387
+ ? uploadMultipleFilesLabel === 'file_upload_text_multiple'
388
+ ? 'Choose files'
389
+ : uploadMultipleFilesLabel
390
+ : uploadSingleFileLabel === 'file_upload_text_one'
391
+ ? 'Choose a file'
392
+ : uploadSingleFileLabel}
383
393
  </Button>
384
394
  </label>
385
395
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pega/react-sdk-overrides",
3
- "version": "0.23.28",
3
+ "version": "0.23.30",
4
4
  "description": "React SDK - Code for overriding components",
5
5
  "_filesComment": "During packing, npm ignores everything NOT in the files list",
6
6
  "files": [
@@ -1,132 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { Button, Grid, IconButton, Snackbar } from '@material-ui/core';
3
- import CloseIcon from '@material-ui/icons/Close';
4
-
5
- import { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
6
- import './CancelAlert.css';
7
-
8
- interface CancelAlertProps extends PConnFieldProps {
9
- // If any, enter additional props that only exist on CancelAlert here
10
- pConn: any;
11
- updateAlertState: any;
12
- }
13
-
14
- export default function CancelAlert(props: CancelAlertProps) {
15
- const { pConn, updateAlertState } = props;
16
- const [showSnackbar, setShowSnackbar] = useState(false);
17
- const [snackbarMessage, setSnackbarMessage] = useState('');
18
-
19
- const itemKey = pConn.getContextName();
20
- const caseInfo = pConn.getCaseInfo();
21
- const caseName = caseInfo.getName();
22
- const ID = caseInfo.getID();
23
- const localizedVal = PCore.getLocaleUtils().getLocaleValue;
24
- const localeCategory = 'ModalContainer';
25
-
26
- function showToast(message: string) {
27
- setSnackbarMessage(message);
28
- setShowSnackbar(true);
29
- }
30
-
31
- const dismissCancelAlertOnly = () => {
32
- updateAlertState(true);
33
- };
34
-
35
- const dismissModal = () => {
36
- updateAlertState(false);
37
- };
38
-
39
- function handleSnackbarClose(event: React.SyntheticEvent | React.MouseEvent, reason?: string) {
40
- if (reason === 'clickaway') {
41
- return;
42
- }
43
- setShowSnackbar(false);
44
- }
45
-
46
- const buttonClick = action => {
47
- const actionsAPI = pConn.getActionsApi();
48
-
49
- switch (action) {
50
- case 'save':
51
- // eslint-disable-next-line no-case-declarations
52
- const savePromise = actionsAPI.saveAndClose(itemKey);
53
-
54
- savePromise
55
- .then(() => {
56
- dismissModal();
57
-
58
- // @ts-ignore - second parameter “payload” for publish method should be optional
59
- PCore.getPubSubUtils().publish(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.CASE_CREATED);
60
- })
61
- .catch(() => {
62
- showToast(localizedVal('Save failed', localeCategory));
63
- });
64
- break;
65
-
66
- case 'continue':
67
- dismissCancelAlertOnly();
68
- break;
69
-
70
- case 'delete':
71
- // eslint-disable-next-line no-case-declarations
72
- const deletePromise = actionsAPI.deleteCaseInCreateStage(itemKey);
73
-
74
- deletePromise
75
- .then(() => {
76
- dismissModal();
77
-
78
- // @ts-ignore - second parameter “payload” for publish method should be optional
79
- PCore.getPubSubUtils().publish(PCore.getConstants().PUB_SUB_EVENTS.EVENT_CANCEL);
80
- })
81
- .catch(() => {
82
- showToast(localizedVal('Delete failed.', localeCategory));
83
- });
84
- break;
85
-
86
- default:
87
- break;
88
- }
89
- };
90
-
91
- return (
92
- <>
93
- <div className='cancel-alert-background'>
94
- <div className='cancel-alert-top'>
95
- <h3>{`Delete ${caseName}(${ID})`}</h3>
96
- <div>
97
- <p>{`${localizedVal('Are you sure you want to delete', localeCategory)} ${caseName} (${ID})?`}</p>
98
- <p>{localizedVal('Alternatively, you can continue working or save your work for later.', localeCategory)}</p>
99
- </div>
100
- <div className='action-controls'>
101
- <Grid container spacing={4} justifyContent='space-between'>
102
- <Grid item>
103
- <Button variant='outlined' color='primary' onClick={() => buttonClick('save')}>
104
- {localizedVal('Save for later', localeCategory)}
105
- </Button>
106
- </Grid>
107
- <Grid item>
108
- <Button variant='outlined' color='primary' onClick={() => buttonClick('continue')}>
109
- {localizedVal('Continue Working', localeCategory)}
110
- </Button>
111
- <Button variant='contained' color='primary' onClick={() => buttonClick('delete')}>
112
- {localizedVal('Delete', localeCategory)}
113
- </Button>
114
- </Grid>
115
- </Grid>
116
- </div>
117
- </div>
118
- </div>
119
- <Snackbar
120
- open={showSnackbar}
121
- autoHideDuration={3000}
122
- onClose={handleSnackbarClose}
123
- message={snackbarMessage}
124
- action={
125
- <IconButton size='small' aria-label='close' color='inherit' onClick={handleSnackbarClose}>
126
- <CloseIcon fontSize='small' />
127
- </IconButton>
128
- }
129
- />
130
- </>
131
- );
132
- }