@pega/angular-sdk-overrides 0.26.2 → 0.26.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/designSystemExtension/field-group/field-group.component.ts +11 -3
- package/lib/designSystemExtension/material-case-summary/material-case-summary.component.html +12 -3
- package/lib/field/auto-complete/auto-complete.component.html +44 -4
- package/lib/field/auto-complete/auto-complete.component.scss +92 -0
- package/lib/field/auto-complete/auto-complete.component.ts +341 -16
- package/lib/field/cancel-alert/cancel-alert.component.ts +38 -15
- package/lib/field/group/group.component.html +1 -1
- package/lib/field/group/group.component.ts +1 -3
- package/lib/field/semantic-link/semantic-link.component.html +1 -1
- package/lib/field/semantic-link/semantic-link.component.scss +4 -0
- package/lib/infra/Containers/flow-container/flow-container.component.html +1 -1
- package/lib/infra/Containers/modal-view-container/data-view-action-buttons/data-view-action-buttons.component.html +12 -0
- package/lib/infra/Containers/modal-view-container/data-view-action-buttons/data-view-action-buttons.component.spec.ts +130 -0
- package/lib/infra/Containers/modal-view-container/data-view-action-buttons/data-view-action-buttons.component.ts +77 -0
- package/lib/infra/Containers/modal-view-container/modal-view-container.component.html +35 -8
- package/lib/infra/Containers/modal-view-container/modal-view-container.component.ts +179 -184
- package/lib/infra/assignment/assignment.component.html +2 -1
- package/lib/infra/assignment/assignment.component.ts +30 -13
- package/lib/infra/defer-load/defer-load.component.ts +6 -3
- package/lib/infra/multi-step/multi-step.component.html +25 -33
- package/lib/infra/multi-step/multi-step.component.scss +48 -0
- package/lib/infra/multi-step/multi-step.component.ts +11 -0
- package/lib/infra/view/view.component.ts +17 -39
- package/lib/template/base/details-template-base.ts +35 -54
- package/lib/template/case-summary/case-summary.component.ts +15 -1
- package/lib/template/case-view/case-view.component.html +13 -1
- package/lib/template/case-view/case-view.component.spec.ts +119 -10
- package/lib/template/case-view/case-view.component.ts +52 -3
- package/lib/template/data-reference/data-reference.component.ts +27 -18
- package/lib/template/data-reference/search-form/search-form.component.html +1 -1
- package/lib/template/data-reference/search-form/search-form.component.ts +2 -0
- package/lib/template/details/details.component.html +23 -3
- package/lib/template/details/details.component.scss +9 -2
- package/lib/template/details/details.component.ts +3 -32
- package/lib/template/details-narrow-wide/details-narrow-wide.component.html +21 -2
- package/lib/template/details-narrow-wide/details-narrow-wide.component.scss +8 -1
- package/lib/template/details-narrow-wide/details-narrow-wide.component.ts +3 -37
- package/lib/template/details-one-column/details-one-column.component.html +23 -1
- package/lib/template/details-one-column/details-one-column.component.scss +14 -0
- package/lib/template/details-one-column/details-one-column.component.ts +3 -38
- package/lib/template/details-three-column/details-three-column.component.html +21 -2
- package/lib/template/details-three-column/details-three-column.component.scss +8 -1
- package/lib/template/details-three-column/details-three-column.component.ts +3 -46
- package/lib/template/details-two-column/details-two-column.component.html +21 -2
- package/lib/template/details-two-column/details-two-column.component.scss +8 -1
- package/lib/template/details-two-column/details-two-column.component.ts +3 -44
- package/lib/template/details-wide-narrow/details-wide-narrow.component.html +21 -2
- package/lib/template/details-wide-narrow/details-wide-narrow.component.scss +8 -1
- package/lib/template/details-wide-narrow/details-wide-narrow.component.ts +3 -41
- package/lib/template/field-value-list/field-value-list.component.scss +17 -0
- package/lib/template/list-view/list-view.component.ts +39 -0
- package/lib/template/self-service-case-view/self-service-case-view.component.html +13 -1
- package/lib/template/self-service-case-view/self-service-case-view.component.spec.ts +96 -11
- package/lib/template/self-service-case-view/self-service-case-view.component.ts +52 -3
- package/lib/template/simple-table-manual/helpers.ts +27 -6
- package/lib/template/simple-table-manual/simple-table-manual.component.html +1 -3
- package/lib/template/simple-table-manual/simple-table-manual.component.scss +4 -0
- package/lib/template/simple-table-manual/simple-table-manual.component.ts +51 -20
- package/lib/template/single-reference-readonly/single-reference-readonly.component.scss +0 -4
- package/package.json +1 -1
- package/lib/designSystemExtension/material-details/material-details.component.html +0 -40
- package/lib/designSystemExtension/material-details/material-details.component.scss +0 -116
- package/lib/designSystemExtension/material-details/material-details.component.spec.ts +0 -24
- package/lib/designSystemExtension/material-details/material-details.component.ts +0 -31
- package/lib/designSystemExtension/material-details-fields/material-details-fields.component.html +0 -50
- package/lib/designSystemExtension/material-details-fields/material-details-fields.component.scss +0 -34
- package/lib/designSystemExtension/material-details-fields/material-details-fields.component.spec.ts +0 -22
- package/lib/designSystemExtension/material-details-fields/material-details-fields.component.ts +0 -61
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
import { ChangeDetectorRef, Component, OnInit, Input, Output, EventEmitter, forwardRef, OnDestroy } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
|
4
|
-
import isEqual from 'fast-deep-equal';
|
|
5
4
|
import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
|
|
6
5
|
import { ProgressSpinnerService } from '@pega/angular-sdk-components';
|
|
6
|
+
import { BannerService } from '@pega/angular-sdk-components';
|
|
7
7
|
import { ComponentMapperComponent } from '@pega/angular-sdk-components';
|
|
8
|
-
import { getBanners } from '@pega/angular-sdk-components';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* 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.
|
|
12
11
|
* 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.
|
|
13
12
|
*/
|
|
14
13
|
|
|
14
|
+
// One entry per open modal — supports stacking (e.g. "Create new" opened from within another modal)
|
|
15
|
+
interface ModalEntry {
|
|
16
|
+
key: string;
|
|
17
|
+
title: string;
|
|
18
|
+
createdViewPConn$: any;
|
|
19
|
+
arChildren$: any[];
|
|
20
|
+
isMultiRecordData: boolean;
|
|
21
|
+
isDataObjectModal: boolean;
|
|
22
|
+
dataRecordKeys: string;
|
|
23
|
+
dataObjectActionID: string;
|
|
24
|
+
dataObjectAction: string;
|
|
25
|
+
dataObjectClassId: string;
|
|
26
|
+
context: string;
|
|
27
|
+
updateToken: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
15
30
|
@Component({
|
|
16
31
|
selector: 'app-modal-view-container',
|
|
17
32
|
templateUrl: './modal-view-container.component.html',
|
|
@@ -27,41 +42,33 @@ export class ModalViewContainerComponent implements OnInit, OnDestroy {
|
|
|
27
42
|
// Used with AngularPConnect
|
|
28
43
|
angularPConnectData: AngularPConnectData = {};
|
|
29
44
|
|
|
30
|
-
arChildren$: any[];
|
|
31
45
|
stateProps$: object;
|
|
32
|
-
banners: any;
|
|
33
|
-
templateName$: string;
|
|
34
|
-
buildName$: string;
|
|
35
|
-
context$: string;
|
|
36
|
-
title$ = '';
|
|
37
|
-
bShowModal$ = false;
|
|
38
|
-
itemKey$: string;
|
|
39
46
|
formGroup$: FormGroup;
|
|
40
|
-
oCaseInfo: object = {};
|
|
41
|
-
|
|
42
|
-
// for causing a change on assignment
|
|
43
|
-
updateToken$ = 0;
|
|
44
47
|
|
|
45
48
|
routingInfoRef: any = {};
|
|
46
49
|
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
+
// Stack of open modals — supports one modal opening another (e.g. "Create new" from within a modal).
|
|
51
|
+
// Keyed the same as PCore's routingInfo.items so open/update/close can be derived from accessedOrder.
|
|
52
|
+
modalStack: ModalEntry[] = [];
|
|
53
|
+
private modalCollection: Record<string, object> = {};
|
|
50
54
|
|
|
51
55
|
bSubscribed = false;
|
|
52
56
|
cancelPConn$?: typeof PConnect;
|
|
57
|
+
cancelHideDelete$: boolean;
|
|
58
|
+
cancelIsDataObject$: boolean;
|
|
59
|
+
cancelSkipReleaseLockRequest$: any;
|
|
53
60
|
bShowCancelAlert$ = false;
|
|
54
61
|
bAlertState: boolean;
|
|
55
62
|
localizedVal: Function;
|
|
56
63
|
localeCategory = 'Data Object';
|
|
57
|
-
isMultiRecord = false;
|
|
58
64
|
actionsDialog = false;
|
|
59
65
|
|
|
60
66
|
constructor(
|
|
61
67
|
private angularPConnect: AngularPConnectService,
|
|
62
68
|
private cdRef: ChangeDetectorRef,
|
|
63
69
|
private psService: ProgressSpinnerService,
|
|
64
|
-
private fb: FormBuilder
|
|
70
|
+
private fb: FormBuilder,
|
|
71
|
+
public bannerService: BannerService
|
|
65
72
|
) {
|
|
66
73
|
// create the formGroup
|
|
67
74
|
this.formGroup$ = fb.group({ hideRequired: false });
|
|
@@ -71,22 +78,12 @@ export class ModalViewContainerComponent implements OnInit, OnDestroy {
|
|
|
71
78
|
// First thing in initialization is registering and subscribing to the AngularPConnect service
|
|
72
79
|
this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
|
|
73
80
|
|
|
74
|
-
const baseContext = this.pConn$.getContextName();
|
|
75
|
-
const acName = this.pConn$.getContainerName();
|
|
76
|
-
|
|
77
|
-
// for now, in general this should be overridden by updateSelf(), and not be blank
|
|
78
|
-
if (this.itemKey$ === '') {
|
|
79
|
-
this.itemKey$ = baseContext.concat('/').concat(acName);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
81
|
const containerMgr = this.pConn$.getContainerManager();
|
|
83
82
|
|
|
84
83
|
containerMgr.initializeContainers({
|
|
85
84
|
type: 'multiple'
|
|
86
85
|
});
|
|
87
86
|
|
|
88
|
-
// const { CONTAINER_TYPE, PUB_SUB_EVENTS } = PCore.getConstants();
|
|
89
|
-
|
|
90
87
|
this.angularPConnect.shouldComponentUpdate(this);
|
|
91
88
|
this.localizedVal = PCore.getLocaleUtils().getLocaleValue;
|
|
92
89
|
}
|
|
@@ -114,10 +111,6 @@ export class ModalViewContainerComponent implements OnInit, OnDestroy {
|
|
|
114
111
|
// ONLY call updateSelf when the component should update
|
|
115
112
|
if (bUpdateSelf) {
|
|
116
113
|
this.updateSelf();
|
|
117
|
-
} else if (this.bShowModal$) {
|
|
118
|
-
// right now onlu get one updated when initial diaplay. So, once modal is up
|
|
119
|
-
// let fall through and do a check with "compareCaseInfoIsDifferent" until fixed
|
|
120
|
-
// this.updateSelf();
|
|
121
114
|
}
|
|
122
115
|
}
|
|
123
116
|
|
|
@@ -134,141 +127,102 @@ export class ModalViewContainerComponent implements OnInit, OnDestroy {
|
|
|
134
127
|
} catch (ex) {
|
|
135
128
|
console.log(ex);
|
|
136
129
|
}
|
|
137
|
-
// const configProps = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps());
|
|
138
130
|
this.stateProps$ = this.pConn$.getStateProps();
|
|
139
|
-
this.banners = this.getBanners();
|
|
140
131
|
|
|
141
|
-
if (!loadingInfo) {
|
|
142
|
-
|
|
143
|
-
// this.psService.sendMessage(false);
|
|
132
|
+
if (!routingInfo || loadingInfo) {
|
|
133
|
+
return;
|
|
144
134
|
}
|
|
145
135
|
|
|
146
|
-
|
|
147
|
-
const currentOrder = routingInfo.accessedOrder;
|
|
136
|
+
const { accessedOrder, type } = routingInfo;
|
|
148
137
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
138
|
+
if (undefined == accessedOrder) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
152
141
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (!this.bSubscribed) {
|
|
170
|
-
this.bSubscribed = true;
|
|
171
|
-
const { PUB_SUB_EVENTS } = PCore.getConstants();
|
|
172
|
-
PCore.getPubSubUtils().subscribe(
|
|
173
|
-
PUB_SUB_EVENTS.EVENT_SHOW_CANCEL_ALERT,
|
|
174
|
-
payload => {
|
|
175
|
-
this.showAlert(payload);
|
|
176
|
-
},
|
|
177
|
-
PUB_SUB_EVENTS.EVENT_SHOW_CANCEL_ALERT
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// let configObject = PCore.createPConnect(config);
|
|
182
|
-
|
|
183
|
-
// THIS is where the ViewContainer creates a View
|
|
184
|
-
// The config has meta.config.type = "view"
|
|
185
|
-
this.createView(routingInfo, currentItem, latestItem, key);
|
|
142
|
+
const { MULTIPLE } = PCore.getConstants().CONTAINER_TYPE;
|
|
143
|
+
const { key, latestItem } = this.getKeyAndLatestItem(routingInfo);
|
|
144
|
+
|
|
145
|
+
if (latestItem && type === MULTIPLE && (this.isOpenModalAction(accessedOrder) || this.isUpdateModalAction(accessedOrder))) {
|
|
146
|
+
const currentItem = routingInfo.items[key];
|
|
147
|
+
if (currentItem?.view && Object.keys(currentItem.view).length > 0) {
|
|
148
|
+
if (!this.bSubscribed) {
|
|
149
|
+
this.bSubscribed = true;
|
|
150
|
+
const { PUB_SUB_EVENTS } = PCore.getConstants();
|
|
151
|
+
PCore.getPubSubUtils().subscribe(
|
|
152
|
+
PUB_SUB_EVENTS.EVENT_SHOW_CANCEL_ALERT,
|
|
153
|
+
payload => {
|
|
154
|
+
this.showAlert(payload);
|
|
155
|
+
},
|
|
156
|
+
PUB_SUB_EVENTS.EVENT_SHOW_CANCEL_ALERT
|
|
157
|
+
);
|
|
186
158
|
}
|
|
187
|
-
} else {
|
|
188
|
-
this.hideModal();
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
159
|
|
|
193
|
-
|
|
194
|
-
const configObject = this.getConfigObject(currentItem, null, false);
|
|
195
|
-
const newComp = configObject?.getPConnect();
|
|
196
|
-
// const newCompName = newComp.getComponentName();
|
|
197
|
-
const caseInfo = newComp && newComp.getDataObject() && newComp.getDataObject().caseInfo ? newComp.getDataObject().caseInfo : null;
|
|
198
|
-
// The metadata for pyDetails changed such that the "template": "CaseView"
|
|
199
|
-
// is no longer a child of the created View but is in the created View's
|
|
200
|
-
// config. So, we DON'T want to replace this.pConn$ since the created
|
|
201
|
-
// component is a View (and not a ViewContainer). We now look for the
|
|
202
|
-
// "template" type directly in the created component (newComp) and NOT
|
|
203
|
-
// as a child of the newly created component.
|
|
204
|
-
// console.log(`---> ModalViewContainer created new ${newCompName}`);
|
|
205
|
-
|
|
206
|
-
// Use the newly created component (View) info but DO NOT replace
|
|
207
|
-
// this ModalViewContainer's pConn$, etc.
|
|
208
|
-
// Note that we're now using the newly created View's PConnect in the
|
|
209
|
-
// ViewContainer HTML template to guide what's rendered similar to what
|
|
210
|
-
// the Nebula/Constellation return of React.Fragment does
|
|
211
|
-
|
|
212
|
-
// right now need to check caseInfo for changes, to trigger redraw, not getting
|
|
213
|
-
// changes from angularPconnect except for first draw
|
|
214
|
-
if (newComp && caseInfo && this.compareCaseInfoIsDifferent(caseInfo)) {
|
|
215
|
-
this.psService.sendMessage(false);
|
|
216
|
-
|
|
217
|
-
this.createdViewPConn$ = newComp;
|
|
218
|
-
const newConfigProps = newComp.getConfigProps();
|
|
219
|
-
this.templateName$ = 'template' in newConfigProps ? (newConfigProps.template as string) : '';
|
|
220
|
-
|
|
221
|
-
const { actionName } = latestItem;
|
|
222
|
-
const theNewCaseInfo = newComp.getCaseInfo();
|
|
223
|
-
// const caseName = theNewCaseInfo.getName();
|
|
224
|
-
const ID = theNewCaseInfo.getBusinessID() || theNewCaseInfo.getID();
|
|
225
|
-
|
|
226
|
-
const caseTypeName = theNewCaseInfo.getCaseTypeName();
|
|
227
|
-
const isDataObject = routingInfo.items[latestItem.context].resourceType === PCore.getConstants().RESOURCE_TYPES.DATA;
|
|
228
|
-
const dataObjectAction = routingInfo.items[latestItem.context].resourceStatus;
|
|
229
|
-
this.isMultiRecord = routingInfo.items[latestItem.context].isMultiRecordData;
|
|
230
|
-
this.context$ = latestItem.context;
|
|
231
|
-
this.title$ =
|
|
232
|
-
isDataObject || this.isMultiRecord
|
|
233
|
-
? this.getModalHeading(dataObjectAction)
|
|
234
|
-
: this.determineModalHeaderByAction(actionName, caseTypeName, ID, this.createdViewPConn$?.getCaseLocaleReference());
|
|
235
|
-
|
|
236
|
-
const bIsRefComponent = this.checkIfRefComponent(newComp);
|
|
237
|
-
|
|
238
|
-
if (bIsRefComponent) {
|
|
239
|
-
this.arChildren$ = [newComp.getComponent()];
|
|
240
|
-
} else {
|
|
241
|
-
// update children with new view's children
|
|
242
|
-
this.arChildren$ = newComp.getChildren();
|
|
160
|
+
this.upsertModal(routingInfo, latestItem, key, accessedOrder);
|
|
243
161
|
}
|
|
244
|
-
|
|
245
|
-
this.
|
|
246
|
-
|
|
247
|
-
// for when non modal
|
|
248
|
-
this.modalVisibleChange.emit(this.bShowModal$);
|
|
249
|
-
|
|
250
|
-
// save off itemKey to be used for finishAssignment, etc.
|
|
251
|
-
this.itemKey$ = key;
|
|
252
|
-
|
|
253
|
-
// cause a change for assignment
|
|
254
|
-
this.updateToken$ = new Date().getTime();
|
|
255
|
-
this.cdRef.markForCheck();
|
|
162
|
+
} else if (this.isCloseModalAction(accessedOrder)) {
|
|
163
|
+
this.handleModalClose(accessedOrder);
|
|
256
164
|
}
|
|
257
165
|
}
|
|
258
166
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
167
|
+
// Builds/refreshes one modal-stack entry and pushes or updates it in-place
|
|
168
|
+
upsertModal(routingInfo, latestItem, key, accessedOrder) {
|
|
169
|
+
const entry = this.buildModalEntry(routingInfo, latestItem, key);
|
|
170
|
+
|
|
171
|
+
if (this.isUpdateModalAction(accessedOrder)) {
|
|
172
|
+
this.modalStack = this.modalStack.map(modal => (modal.key === key ? entry : modal));
|
|
173
|
+
} else if (this.isOpenModalAction(accessedOrder)) {
|
|
174
|
+
this.handleModalOpen(key);
|
|
175
|
+
this.modalStack = [...this.modalStack, entry];
|
|
263
176
|
}
|
|
264
177
|
|
|
265
|
-
this.
|
|
178
|
+
this.psService.sendMessage(false);
|
|
179
|
+
this.modalVisibleChange.emit(this.modalStack.length > 0);
|
|
180
|
+
this.cdRef.markForCheck();
|
|
181
|
+
}
|
|
266
182
|
|
|
267
|
-
|
|
268
|
-
this.
|
|
183
|
+
buildModalEntry(routingInfo, latestItem, key): ModalEntry {
|
|
184
|
+
const configObject = this.getConfigObject(latestItem, null, false);
|
|
185
|
+
// latestItem is only reached once its view metadata is populated (see updateSelf), so the
|
|
186
|
+
// created component is always present here — same assumption the old single-modal code made.
|
|
187
|
+
const newComp = configObject!.getPConnect();
|
|
188
|
+
|
|
189
|
+
const { actionName } = latestItem;
|
|
190
|
+
const theCaseInfo = newComp.getCaseInfo();
|
|
191
|
+
const ID = theCaseInfo.getBusinessID() || theCaseInfo.getID();
|
|
192
|
+
const caseTypeName = theCaseInfo.getCaseTypeName();
|
|
193
|
+
|
|
194
|
+
const isDataObject = routingInfo.items[latestItem.context].resourceType === PCore.getConstants().RESOURCE_TYPES.DATA;
|
|
195
|
+
const dataObjectAction = routingInfo.items[latestItem.context].resourceStatus;
|
|
196
|
+
const isMultiRecordData = routingInfo.items[latestItem.context].isMultiRecordData;
|
|
197
|
+
|
|
198
|
+
const title = this.getHeadingValue(
|
|
199
|
+
latestItem,
|
|
200
|
+
isMultiRecordData,
|
|
201
|
+
isDataObject,
|
|
202
|
+
actionName,
|
|
203
|
+
dataObjectAction,
|
|
204
|
+
caseTypeName,
|
|
205
|
+
ID,
|
|
206
|
+
newComp?.getCaseLocaleReference()
|
|
207
|
+
);
|
|
269
208
|
|
|
270
|
-
|
|
271
|
-
|
|
209
|
+
const bIsRefComponent = this.checkIfRefComponent(newComp);
|
|
210
|
+
const arChildren$ = bIsRefComponent ? [newComp.getComponent()] : newComp.getChildren();
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
key,
|
|
214
|
+
title,
|
|
215
|
+
createdViewPConn$: newComp,
|
|
216
|
+
arChildren$,
|
|
217
|
+
isMultiRecordData,
|
|
218
|
+
isDataObjectModal: isDataObject && !isMultiRecordData,
|
|
219
|
+
dataRecordKeys: latestItem.key || '',
|
|
220
|
+
dataObjectActionID: routingInfo.items[latestItem.context].actionID || '',
|
|
221
|
+
dataObjectAction: dataObjectAction || '',
|
|
222
|
+
dataObjectClassId: newComp.getValue('.classID') || '',
|
|
223
|
+
context: latestItem.context,
|
|
224
|
+
updateToken: new Date().getTime()
|
|
225
|
+
};
|
|
272
226
|
}
|
|
273
227
|
|
|
274
228
|
getConfigObject(item, pConnect, isReverseCoexistence = false) {
|
|
@@ -315,13 +269,17 @@ export class ModalViewContainerComponent implements OnInit, OnDestroy {
|
|
|
315
269
|
this.bAlertState = bData;
|
|
316
270
|
this.bShowCancelAlert$ = false;
|
|
317
271
|
if (this.bAlertState) {
|
|
318
|
-
|
|
272
|
+
// Discard confirmed — matches react-sdk: drop the whole stack rather than just the top entry
|
|
273
|
+
this.modalCollection = {};
|
|
274
|
+
this.modalStack = [];
|
|
275
|
+
this.modalVisibleChange.emit(false);
|
|
276
|
+
this.cdRef.markForCheck();
|
|
319
277
|
}
|
|
320
278
|
}
|
|
321
279
|
|
|
322
280
|
showAlert(payload) {
|
|
323
281
|
const { latestItem } = this.getKeyAndLatestItem(this.routingInfoRef.current);
|
|
324
|
-
const { isModalAction } = payload;
|
|
282
|
+
const { isModalAction, hideDelete, isDataObject, skipReleaseLockRequest } = payload;
|
|
325
283
|
|
|
326
284
|
/*
|
|
327
285
|
If we are in create stage full page mode, created a new case and trying to click on cancel button
|
|
@@ -330,6 +288,9 @@ export class ModalViewContainerComponent implements OnInit, OnDestroy {
|
|
|
330
288
|
if (latestItem && isModalAction && !this.actionsDialog) {
|
|
331
289
|
const configObject = this.getConfigObject(latestItem, this.pConn$);
|
|
332
290
|
this.cancelPConn$ = configObject?.getPConnect();
|
|
291
|
+
this.cancelHideDelete$ = hideDelete;
|
|
292
|
+
this.cancelIsDataObject$ = isDataObject;
|
|
293
|
+
this.cancelSkipReleaseLockRequest$ = skipReleaseLockRequest;
|
|
333
294
|
this.bShowCancelAlert$ = true;
|
|
334
295
|
this.cdRef.markForCheck();
|
|
335
296
|
}
|
|
@@ -353,37 +314,62 @@ export class ModalViewContainerComponent implements OnInit, OnDestroy {
|
|
|
353
314
|
return {};
|
|
354
315
|
}
|
|
355
316
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
} else {
|
|
363
|
-
const sCurrnentCaseInfo = JSON.stringify(oCurrentCaseInfo);
|
|
364
|
-
const sOldCaseInfo = JSON.stringify(this.oCaseInfo);
|
|
365
|
-
// stringify compare version
|
|
366
|
-
if (sCurrnentCaseInfo != sOldCaseInfo) {
|
|
367
|
-
bRet = true;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
317
|
+
// Open/update/close are derived purely from how the count of known modals compares to
|
|
318
|
+
// routingInfo.accessedOrder — mirrors react-sdk's modal-stack fix so that closing one modal
|
|
319
|
+
// (removing one entry from accessedOrder) can never be mistaken for closing all of them.
|
|
320
|
+
isOpenModalAction(accessedOrder: string[]): boolean {
|
|
321
|
+
return Object.keys(this.modalCollection).length < accessedOrder.length;
|
|
322
|
+
}
|
|
370
323
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
324
|
+
isUpdateModalAction(accessedOrder: string[]): boolean {
|
|
325
|
+
return Object.keys(this.modalCollection).length === accessedOrder.length;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
isCloseModalAction(accessedOrder: string[]): boolean {
|
|
329
|
+
return Object.keys(this.modalCollection).length > accessedOrder.length;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
handleModalOpen(key: string) {
|
|
333
|
+
this.modalCollection = { ...this.modalCollection, [key]: {} };
|
|
334
|
+
}
|
|
375
335
|
|
|
376
|
-
|
|
336
|
+
handleModalClose(accessedOrder: string[]) {
|
|
337
|
+
const closedModalKey = Object.keys(this.modalCollection).find(modalKey => !accessedOrder.includes(modalKey));
|
|
338
|
+
|
|
339
|
+
if (closedModalKey) {
|
|
340
|
+
const updatedModalCollection = { ...this.modalCollection };
|
|
341
|
+
delete updatedModalCollection[closedModalKey];
|
|
342
|
+
this.modalCollection = updatedModalCollection;
|
|
343
|
+
|
|
344
|
+
this.modalStack = this.modalStack.filter(modal => modal.key !== closedModalKey);
|
|
345
|
+
this.modalVisibleChange.emit(this.modalStack.length > 0);
|
|
346
|
+
this.bannerService.clearBanners(closedModalKey);
|
|
347
|
+
this.cdRef.markForCheck();
|
|
348
|
+
}
|
|
377
349
|
}
|
|
378
350
|
|
|
379
|
-
|
|
380
|
-
|
|
351
|
+
getModalHeading(dataObjectAction, actionName) {
|
|
352
|
+
switch (dataObjectAction) {
|
|
353
|
+
case PCore.getConstants().RESOURCE_STATUS.CREATE:
|
|
354
|
+
return this.localizedVal('Add Record', this.localeCategory);
|
|
355
|
+
case PCore.getConstants().RESOURCE_STATUS.OPEN_FLOW_ACTION:
|
|
356
|
+
return this.localizedVal(actionName, this.localeCategory);
|
|
357
|
+
default:
|
|
358
|
+
return this.localizedVal('Edit Record', this.localeCategory);
|
|
359
|
+
}
|
|
381
360
|
}
|
|
382
361
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
362
|
+
getHeadingValue(latestItem, isMultiRecordData, isDataObject, actionName, dataObjectAction, caseTypeName, ID, caseLocaleRef) {
|
|
363
|
+
if (isMultiRecordData) {
|
|
364
|
+
return latestItem.heading;
|
|
365
|
+
}
|
|
366
|
+
if (isDataObject) {
|
|
367
|
+
if (actionName) {
|
|
368
|
+
return this.localizedVal(actionName, this.localeCategory);
|
|
369
|
+
}
|
|
370
|
+
return this.getModalHeading(dataObjectAction, actionName);
|
|
371
|
+
}
|
|
372
|
+
return this.determineModalHeaderByAction(actionName, caseTypeName, ID, caseLocaleRef);
|
|
387
373
|
}
|
|
388
374
|
|
|
389
375
|
determineModalHeaderByAction(actionName, caseTypeName, ID, caseLocaleRef) {
|
|
@@ -393,14 +379,23 @@ export class ModalViewContainerComponent implements OnInit, OnDestroy {
|
|
|
393
379
|
return `${this.localizedVal('Create', this.localeCategory)} ${this.localizedVal(caseTypeName, undefined, caseLocaleRef)} (${ID})`;
|
|
394
380
|
}
|
|
395
381
|
|
|
396
|
-
|
|
382
|
+
// Closes one modal by key (bound per-instance in the template), or the topmost when omitted
|
|
383
|
+
closeActionsDialog = (modalKey?: string) => {
|
|
397
384
|
this.actionsDialog = true;
|
|
398
|
-
this.bShowModal$ = false;
|
|
399
385
|
|
|
400
|
-
|
|
401
|
-
this.modalVisibleChange.emit(this.bShowModal$);
|
|
386
|
+
this.modalStack = modalKey ? this.modalStack.filter(modal => modal.key !== modalKey) : this.modalStack.slice(0, -1);
|
|
402
387
|
|
|
403
|
-
this.
|
|
388
|
+
this.modalVisibleChange.emit(this.modalStack.length > 0);
|
|
389
|
+
this.bannerService.clearBanners(modalKey ?? '');
|
|
404
390
|
this.cdRef.markForCheck();
|
|
405
391
|
};
|
|
392
|
+
|
|
393
|
+
// Binds closeActionsDialog to a specific modal's key so closing one stacked modal never affects the others
|
|
394
|
+
closeModalFor(modalKey: string) {
|
|
395
|
+
return () => this.closeActionsDialog(modalKey);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
trackByModalKey(index: number, modal: ModalEntry) {
|
|
399
|
+
return modal.key;
|
|
400
|
+
}
|
|
406
401
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<div>
|
|
2
|
-
<div><component-mapper name="AlertBanner" [props]="{ banners: bannerService.
|
|
2
|
+
<div><component-mapper name="AlertBanner" [props]="{ banners: bannerService.getBanners(itemKey$) }" [parent]="this"></component-mapper></div>
|
|
3
3
|
<div *ngIf="bHasNavigation$" class="psdk-stepper">
|
|
4
4
|
<component-mapper
|
|
5
5
|
name="MultiStep"
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
arMainButtons$,
|
|
11
11
|
arSecondaryButtons$,
|
|
12
12
|
bIsVertical$,
|
|
13
|
+
stepIndicator$,
|
|
13
14
|
arCurrentStepIndicies$,
|
|
14
15
|
arNavigationSteps$
|
|
15
16
|
}"
|
|
@@ -27,6 +27,8 @@ interface AssignmentProps {
|
|
|
27
27
|
template: string;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
type StepIndicator = 'horizontal' | 'vertical' | 'vertical-start';
|
|
31
|
+
|
|
30
32
|
@Component({
|
|
31
33
|
selector: 'app-assignment',
|
|
32
34
|
templateUrl: './assignment.component.html',
|
|
@@ -60,6 +62,7 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
60
62
|
|
|
61
63
|
bHasNavigation$ = false;
|
|
62
64
|
bIsVertical$ = false;
|
|
65
|
+
stepIndicator$: StepIndicator = 'horizontal';
|
|
63
66
|
prevNavigationSteps: any[] = [];
|
|
64
67
|
arCurrentStepIndicies$: number[] = [];
|
|
65
68
|
arNavigationSteps$: any[] = [];
|
|
@@ -108,6 +111,8 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
108
111
|
if (this.angularPConnectData.unsubscribeFn) {
|
|
109
112
|
this.angularPConnectData.unsubscribeFn();
|
|
110
113
|
}
|
|
114
|
+
|
|
115
|
+
this.bannerService.clearBanners(this.itemKey$);
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
// Callback passed when subscribing to store change
|
|
@@ -240,14 +245,22 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
240
245
|
}
|
|
241
246
|
|
|
242
247
|
createButtonsForMultiStepForm(oCaseInfo) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
248
|
+
const navigationTemplate = oCaseInfo.navigation.template?.toLowerCase();
|
|
249
|
+
const stepCount = oCaseInfo.navigation.steps?.length ?? 0;
|
|
250
|
+
const shouldHideNavigation = navigationTemplate === 'standard' || stepCount <= 1;
|
|
251
|
+
|
|
252
|
+
this.bHasNavigation$ = !shouldHideNavigation;
|
|
253
|
+
this.bIsVertical$ = false;
|
|
254
|
+
this.stepIndicator$ = 'horizontal';
|
|
255
|
+
|
|
256
|
+
if (!shouldHideNavigation) {
|
|
257
|
+
if (navigationTemplate === 'vertical') {
|
|
258
|
+
this.bIsVertical$ = true;
|
|
259
|
+
this.stepIndicator$ = 'vertical';
|
|
260
|
+
} else if (navigationTemplate === 'vertical-left') {
|
|
261
|
+
this.bIsVertical$ = true;
|
|
262
|
+
this.stepIndicator$ = 'vertical-start';
|
|
263
|
+
}
|
|
251
264
|
}
|
|
252
265
|
|
|
253
266
|
// iterate through steps to find current one(s)
|
|
@@ -304,7 +317,7 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
304
317
|
|
|
305
318
|
buttonClick(sAction, sButtonType) {
|
|
306
319
|
this.snackBarRef?.dismiss();
|
|
307
|
-
this.bannerService.clearBanners();
|
|
320
|
+
this.bannerService.clearBanners(this.itemKey$);
|
|
308
321
|
PCore.getPubSubUtils().publish('clearBannerMessages');
|
|
309
322
|
// right now, done on an individual basis, setting bReInit to true
|
|
310
323
|
// upon the next flow container state change, will cause the flow container
|
|
@@ -496,10 +509,14 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
496
509
|
refreshProps.forEach(prop => {
|
|
497
510
|
PCore.getRefreshManager().registerForRefresh(
|
|
498
511
|
'PROP_CHANGE',
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
512
|
+
// The registered prop is an authored pattern with an empty list index (ex: ".Addons().Type"),
|
|
513
|
+
// which the server rejects. The refresh manager hands back the concrete path that changed.
|
|
514
|
+
(matchedPath?: string) => {
|
|
515
|
+
this.pConn$.getActionsApi().refreshCaseView(caseKey, '', pageReference, {
|
|
516
|
+
...refreshOptions,
|
|
517
|
+
refreshFor: matchedPath || prop[0]
|
|
518
|
+
});
|
|
519
|
+
},
|
|
503
520
|
`${pageReference}.${prop[1]}`,
|
|
504
521
|
`${context}/${pageReference}`,
|
|
505
522
|
context
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component, OnInit, Input, forwardRef, OnDestroy, OnChanges, SimpleChanges } from '@angular/core';
|
|
1
|
+
import { Component, OnInit, Input, forwardRef, OnDestroy, OnChanges, SimpleChanges, ChangeDetectorRef } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import { publicConstants } from '@pega/pcore-pconnect-typedefs/constants';
|
|
4
4
|
import { ComponentMapperComponent } from '@pega/angular-sdk-components';
|
|
@@ -35,7 +35,10 @@ export class DeferLoadComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
35
35
|
PAGE: any;
|
|
36
36
|
DATA: any;
|
|
37
37
|
lastUpdateCaseTime;
|
|
38
|
-
constructor(
|
|
38
|
+
constructor(
|
|
39
|
+
private angularPConnect: AngularPConnectService,
|
|
40
|
+
private cdRef: ChangeDetectorRef
|
|
41
|
+
) {
|
|
39
42
|
this.constants = PCore.getConstants();
|
|
40
43
|
}
|
|
41
44
|
|
|
@@ -132,7 +135,7 @@ export class DeferLoadComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
132
135
|
PCore.getDeferLoadManager().stop(this.deferLoadId, this.pConn$.getContextName());
|
|
133
136
|
}
|
|
134
137
|
}
|
|
135
|
-
|
|
138
|
+
this.cdRef.detectChanges();
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
loadActiveTab() {
|