@pega/angular-sdk-overrides 0.242.5 → 0.242.7

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 (31) hide show
  1. package/lib/field/email/email.component.ts +17 -7
  2. package/lib/field/integer/integer.component.html +1 -1
  3. package/lib/field/integer/integer.component.ts +16 -6
  4. package/lib/field/text-area/text-area.component.html +1 -1
  5. package/lib/field/text-area/text-area.component.ts +16 -6
  6. package/lib/field/text-input/text-input.component.html +1 -1
  7. package/lib/field/text-input/text-input.component.ts +16 -6
  8. package/lib/field/url/url.component.html +1 -1
  9. package/lib/field/url/url.component.ts +16 -6
  10. package/lib/field/user-reference/user-reference.component.html +2 -10
  11. package/lib/field/user-reference/user-reference.component.ts +34 -12
  12. package/lib/infra/Containers/flow-container/flow-container.component.ts +17 -48
  13. package/lib/infra/Containers/flow-container/helpers.ts +1 -1
  14. package/lib/infra/Containers/modal-view-container/modal-view-container.component.ts +0 -6
  15. package/lib/infra/assignment/assignment.component.html +1 -1
  16. package/lib/infra/assignment/assignment.component.ts +84 -39
  17. package/lib/infra/assignment-card/assignment-card.component.html +1 -0
  18. package/lib/infra/assignment-card/assignment-card.component.ts +32 -4
  19. package/lib/infra/reference/reference.component.ts +15 -12
  20. package/lib/infra/root-container/root-container.component.html +2 -15
  21. package/lib/infra/root-container/root-container.component.ts +0 -10
  22. package/lib/infra/view/view.component.ts +15 -1
  23. package/lib/template/base/form-template-base.ts +6 -0
  24. package/lib/template/default-form/default-form.component.ts +39 -4
  25. package/lib/template/field-group-template/field-group-template.component.ts +1 -1
  26. package/lib/template/simple-table-manual/helpers.ts +7 -5
  27. package/lib/template/simple-table-manual/simple-table-manual.component.ts +0 -1
  28. package/lib/widget/todo/todo.component.html +4 -4
  29. package/lib/widget/todo/todo.component.scss +7 -0
  30. package/lib/widget/todo/todo.component.ts +4 -3
  31. package/package.json +1 -1
@@ -159,16 +159,26 @@ export class EmailComponent implements OnInit, OnDestroy {
159
159
  }
160
160
 
161
161
  fieldOnChange(event: any) {
162
- const value = event?.target?.value;
163
- handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
164
- this.pConn$.clearErrorMessages({
165
- property: this.propName
166
- });
162
+ const oldVal = this.value$ ?? '';
163
+ const isValueChanged = event.target.value.toString() !== oldVal.toString();
164
+
165
+ if (isValueChanged) {
166
+ const value = event?.target?.value;
167
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
168
+ this.pConn$.clearErrorMessages({
169
+ property: this.propName
170
+ });
171
+ }
167
172
  }
168
173
 
169
174
  fieldOnBlur(event: any) {
170
- const value = event?.target?.value;
171
- handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
175
+ const oldVal = this.value$ ?? '';
176
+ const isValueChanged = event.target.value.toString() !== oldVal.toString();
177
+
178
+ if (isValueChanged) {
179
+ const value = event?.target?.value;
180
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
181
+ }
172
182
  }
173
183
 
174
184
  getErrorMessage() {
@@ -15,7 +15,7 @@
15
15
  [required]="bRequired$"
16
16
  [formControl]="fieldControl"
17
17
  [attr.data-test-id]="testId"
18
- (change)="fieldOnChange()"
18
+ (change)="fieldOnChange($event)"
19
19
  (blur)="fieldOnBlur($event)"
20
20
  />
21
21
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
@@ -161,15 +161,25 @@ export class IntegerComponent implements OnInit, OnDestroy {
161
161
  }
162
162
  }
163
163
 
164
- fieldOnChange() {
165
- this.pConn$.clearErrorMessages({
166
- property: this.propName
167
- });
164
+ fieldOnChange(event: any) {
165
+ const oldVal = this.value$ ?? '';
166
+ const isValueChanged = event.target.value.toString() !== oldVal.toString();
167
+
168
+ if (isValueChanged) {
169
+ this.pConn$.clearErrorMessages({
170
+ property: this.propName
171
+ });
172
+ }
168
173
  }
169
174
 
170
175
  fieldOnBlur(event: any) {
171
- const value = event?.target?.value;
172
- handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
176
+ const oldVal = this.value$ ?? '';
177
+ const isValueChanged = event.target.value.toString() !== oldVal.toString();
178
+
179
+ if (isValueChanged) {
180
+ const value = event?.target?.value;
181
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
182
+ }
173
183
  }
174
184
 
175
185
  getErrorMessage() {
@@ -16,7 +16,7 @@
16
16
  [required]="bRequired$"
17
17
  [disabled]="bDisabled$"
18
18
  [formControl]="fieldControl"
19
- (change)="fieldOnChange()"
19
+ (change)="fieldOnChange($event)"
20
20
  (blur)="fieldOnBlur($event)"
21
21
  ></textarea>
22
22
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
@@ -159,15 +159,25 @@ export class TextAreaComponent implements OnInit, OnDestroy {
159
159
  }
160
160
  }
161
161
 
162
- fieldOnChange() {
163
- this.pConn$.clearErrorMessages({
164
- property: this.propName
165
- });
162
+ fieldOnChange(event: any) {
163
+ const oldVal = this.value$ ?? '';
164
+ const isValueChanged = event.target.value.toString() !== oldVal.toString();
165
+
166
+ if (isValueChanged) {
167
+ this.pConn$.clearErrorMessages({
168
+ property: this.propName
169
+ });
170
+ }
166
171
  }
167
172
 
168
173
  fieldOnBlur(event: any) {
169
- const value = event?.target?.value;
170
- handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
174
+ const oldVal = this.value$ ?? '';
175
+ const isValueChanged = event.target.value.toString() !== oldVal.toString();
176
+
177
+ if (isValueChanged) {
178
+ const value = event?.target?.value;
179
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
180
+ }
171
181
  }
172
182
 
173
183
  getErrorMessage() {
@@ -14,7 +14,7 @@
14
14
  [required]="bRequired$"
15
15
  [attr.data-test-id]="testId"
16
16
  [formControl]="fieldControl"
17
- (change)="fieldOnChange()"
17
+ (change)="fieldOnChange($event)"
18
18
  (blur)="fieldOnBlur($event)"
19
19
  />
20
20
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
@@ -161,15 +161,25 @@ export class TextInputComponent implements OnInit, OnDestroy {
161
161
  }
162
162
  }
163
163
 
164
- fieldOnChange() {
165
- this.pConn$.clearErrorMessages({
166
- property: this.propName
167
- });
164
+ fieldOnChange(event) {
165
+ const oldVal = this.value$ ?? '';
166
+ const isValueChanged = event.target.value.toString() !== oldVal.toString();
167
+
168
+ if (isValueChanged) {
169
+ this.pConn$.clearErrorMessages({
170
+ property: this.propName
171
+ });
172
+ }
168
173
  }
169
174
 
170
175
  fieldOnBlur(event: any) {
171
- const value = event?.target?.value;
172
- handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
176
+ const oldVal = this.value$ ?? '';
177
+ const isValueChanged = event.target.value.toString() !== oldVal.toString();
178
+
179
+ if (isValueChanged) {
180
+ const value = event?.target?.value;
181
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
182
+ }
173
183
  }
174
184
 
175
185
  getErrorMessage() {
@@ -14,7 +14,7 @@
14
14
  [required]="bRequired$"
15
15
  [attr.data-test-id]="testId"
16
16
  [formControl]="fieldControl"
17
- (change)="fieldOnChange()"
17
+ (change)="fieldOnChange($event)"
18
18
  (blur)="fieldOnBlur($event)"
19
19
  />
20
20
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
@@ -159,15 +159,25 @@ export class UrlComponent implements OnInit, OnDestroy {
159
159
  }
160
160
  }
161
161
 
162
- fieldOnChange() {
163
- this.pConn$.clearErrorMessages({
164
- property: this.propName
165
- });
162
+ fieldOnChange(event: any) {
163
+ const oldVal = this.value$ ?? '';
164
+ const isValueChanged = event.target.value.toString() !== oldVal.toString();
165
+
166
+ if (isValueChanged) {
167
+ this.pConn$.clearErrorMessages({
168
+ property: this.propName
169
+ });
170
+ }
166
171
  }
167
172
 
168
173
  fieldOnBlur(event: any) {
169
- const value = event?.target?.value;
170
- handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
174
+ const oldVal = this.value$ ?? '';
175
+ const isValueChanged = event.target.value.toString() !== oldVal.toString();
176
+
177
+ if (isValueChanged) {
178
+ const value = event?.target?.value;
179
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
180
+ }
171
181
  }
172
182
 
173
183
  getErrorMessage() {
@@ -8,13 +8,7 @@
8
8
  </div>
9
9
  <div [formGroup]="formGroup$" *ngIf="type === 'dropdown'">
10
10
  <mat-form-field class="psdk-full-width" subscriptSizing="dynamic" [hintLabel]="helperText">
11
- <mat-select
12
- [value]="value$"
13
- [required]="bRequired$"
14
- [formControl]="fieldControl"
15
- [attr.data-test-id]="testId"
16
- (selectionChange)="fieldOnChange($event)"
17
- >
11
+ <mat-select [required]="bRequired$" [formControl]="fieldControl" [attr.data-test-id]="testId" (selectionChange)="fieldOnChange($event)">
18
12
  <mat-option *ngFor="let opt of options$" [value]="opt.key">
19
13
  {{ opt.value }}
20
14
  </mat-option>
@@ -32,14 +26,12 @@
32
26
  matInput
33
27
  [placeholder]="placeholder"
34
28
  [formControl]="fieldControl"
35
- [value]="value$"
36
29
  [required]="bRequired$"
37
30
  [matAutocomplete]="auto"
38
31
  [attr.data-test-id]="testId"
39
- (change)="fieldOnChange($event)"
40
32
  (blur)="fieldOnBlur($event)"
41
33
  />
42
- <mat-autocomplete #auto="matAutocomplete">
34
+ <mat-autocomplete #auto="matAutocomplete" autoActiveFirstOption (optionSelected)="optionChanged($event)">
43
35
  <mat-option *ngFor="let opt of filteredOptions | async" [value]="opt.value">
44
36
  <span>{{ opt.value }}</span>
45
37
  </mat-option>
@@ -23,6 +23,7 @@ interface UserReferenceProps extends Omit<PConnFieldProps, 'value'> {
23
23
  value?: any;
24
24
  showAsFormattedText?: boolean;
25
25
  additionalProps?: object;
26
+ onRecordChange?: any;
26
27
  }
27
28
 
28
29
  @Component({
@@ -66,6 +67,7 @@ export class UserReferenceComponent implements OnInit, OnDestroy {
66
67
  fieldControl = new FormControl('', null);
67
68
  actionsApi: Object;
68
69
  propName: string;
70
+ onRecordChange: any;
69
71
 
70
72
  constructor(
71
73
  private angularPConnect: AngularPConnectService,
@@ -83,11 +85,11 @@ export class UserReferenceComponent implements OnInit, OnDestroy {
83
85
  if (this.formGroup$) {
84
86
  // add control to formGroup
85
87
  this.formGroup$.addControl(this.controlName$, this.fieldControl);
86
- this.fieldControl.setValue(this.value$);
88
+ this.fieldControl.setValue(this.getValue(this.value$));
87
89
  }
88
90
 
89
91
  this.filteredOptions = this.fieldControl.valueChanges.pipe(
90
- startWith(''),
92
+ startWith(this.getValue(this.value$) || ''),
91
93
  map(value => this._filter(value || ''))
92
94
  );
93
95
  }
@@ -126,6 +128,21 @@ export class UserReferenceComponent implements OnInit, OnDestroy {
126
128
  return this.options$?.filter(option => option.value?.toLowerCase().includes(filterVal));
127
129
  }
128
130
 
131
+ isUserNameAvailable = user => {
132
+ return typeof user === 'object' && user !== null && user.userName;
133
+ };
134
+
135
+ getUserName = user => {
136
+ return user.userName;
137
+ };
138
+
139
+ getValue = user => {
140
+ if (this.displayAs$ === DROPDOWN_LIST) {
141
+ return this.utils.getUserId(user) || this.getUserName(user);
142
+ }
143
+ return this.isUserNameAvailable(user) ? this.getUserName(user) : this.utils.getUserId(user);
144
+ };
145
+
129
146
  async checkAndUpdate() {
130
147
  // Should always check the bridge to see if the component should
131
148
  // update itself (re-render)
@@ -140,6 +157,7 @@ export class UserReferenceComponent implements OnInit, OnDestroy {
140
157
  async updateSelf() {
141
158
  const props = this.pConn$.getConfigProps() as UserReferenceProps;
142
159
  this.testId = props.testId;
160
+ this.onRecordChange = props?.onRecordChange;
143
161
 
144
162
  const { label, displayAs, value, showAsFormattedText, helperText, placeholder, displayMode } = props;
145
163
 
@@ -150,20 +168,18 @@ export class UserReferenceComponent implements OnInit, OnDestroy {
150
168
  this.placeholder = placeholder || '';
151
169
  this.displayMode$ = displayMode;
152
170
 
171
+ this.value$ = this.pConn$.getConfigProps()?.value;
172
+
153
173
  const { readOnly, required } = props;
154
174
  [this.bReadonly$, this.bRequired$] = [readOnly, required].map(prop => prop === true || (typeof prop === 'string' && prop === 'true'));
155
175
 
156
176
  this.actionsApi = this.pConn$.getActionsApi();
157
177
  this.propName = this.pConn$.getStateProps().value;
158
178
 
159
- const isUserNameAvailable = user => {
160
- return typeof user === 'object' && user !== null && user.userName;
161
- };
162
-
163
179
  this.userID$ = this.utils.getUserId(value);
164
180
 
165
181
  if (this.userID$ && this.bReadonly$ && this.showAsFormattedText$) {
166
- if (isUserNameAvailable(value)) {
182
+ if (this.isUserNameAvailable(value)) {
167
183
  this.userName$ = value.userName;
168
184
  } else {
169
185
  // if same user ref field is referred in view as editable & readonly formatted text
@@ -201,7 +217,12 @@ export class UserReferenceComponent implements OnInit, OnDestroy {
201
217
  if (event?.target) {
202
218
  this.filterValue = (event.target as HTMLInputElement).value;
203
219
  }
204
- const value = event?.target?.value;
220
+ const value = event?.value;
221
+ handleEvent(this.actionsApi, 'change', this.propName, value);
222
+ }
223
+
224
+ optionChanged(event: any) {
225
+ const value = event?.option?.value;
205
226
  handleEvent(this.actionsApi, 'change', this.propName, value);
206
227
  }
207
228
 
@@ -211,11 +232,12 @@ export class UserReferenceComponent implements OnInit, OnDestroy {
211
232
  const index = this.options$?.findIndex(element => element.value === event.target.value);
212
233
  key = index > -1 ? (key = this.options$[index].key) : event.target.value;
213
234
  }
214
-
215
- const value = {
216
- value: key
217
- };
235
+ const value = key;
218
236
  handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
237
+ if (this.onRecordChange) {
238
+ event.target.value = value;
239
+ this.onRecordChange(event);
240
+ }
219
241
  }
220
242
 
221
243
  getErrorMessage() {
@@ -6,7 +6,7 @@ import { publicConstants } from '@pega/pcore-pconnect-typedefs/constants';
6
6
  import { ProgressSpinnerService } from '@pega/angular-sdk-components';
7
7
  import { ReferenceComponent } from '@pega/angular-sdk-components';
8
8
  import { Utils } from '@pega/angular-sdk-components';
9
- import { getToDoAssignments, showBanner } from './helpers';
9
+ import { getToDoAssignments, hasAssignments, showBanner } from './helpers';
10
10
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
11
11
  import { FlowContainerBaseComponent } from '@pega/angular-sdk-components';
12
12
 
@@ -121,6 +121,14 @@ export class FlowContainerComponent extends FlowContainerBaseComponent implement
121
121
  },
122
122
  'cancelPressed'
123
123
  );
124
+
125
+ PCore.getPubSubUtils().subscribe(
126
+ 'clearBannerMessages',
127
+ () => {
128
+ this.banners = [];
129
+ },
130
+ 'CLEAR_BANNER_MESSAGES'
131
+ );
124
132
  }
125
133
 
126
134
  ngOnDestroy() {
@@ -131,6 +139,8 @@ export class FlowContainerComponent extends FlowContainerBaseComponent implement
131
139
  PCore.getPubSubUtils().unsubscribe(PCore.getConstants().PUB_SUB_EVENTS.EVENT_CANCEL, 'cancelAssignment');
132
140
 
133
141
  PCore.getPubSubUtils().unsubscribe('cancelPressed', 'cancelPressed');
142
+
143
+ PCore.getPubSubUtils().unsubscribe('clearBannerMessages', 'CLEAR_BANNER_MESSAGES');
134
144
  }
135
145
 
136
146
  handleCancel() {
@@ -155,13 +165,15 @@ export class FlowContainerComponent extends FlowContainerBaseComponent implement
155
165
  const caseViewModeFromProps = this.angularPConnect.getComponentProp(this, 'caseViewMode');
156
166
  const caseViewModeFromRedux = pConn.getValue('context_data.caseViewMode', '');
157
167
 
168
+ const completeProps = this.angularPConnect.getCurrentCompleteProps(this) as FlowContainerProps;
169
+
158
170
  // ONLY call updateSelf when the component should update
159
171
  // AND removing the "gate" that was put there since shouldComponentUpdate
160
172
  // should be the real "gate"
173
+ // eslint-disable-next-line sonarjs/no-collapsible-if
161
174
  if (bUpdateSelf || caseViewModeFromProps !== caseViewModeFromRedux) {
162
175
  // don't want to redraw the flow container when there are page messages, because
163
176
  // the redraw causes us to loose the errors on the elements
164
- const completeProps = this.angularPConnect.getCurrentCompleteProps(this) as FlowContainerProps;
165
177
  if (!completeProps.pageMessages || completeProps.pageMessages.length == 0) {
166
178
  // with a cancel, need to timeout so todo will update correctly
167
179
  if (this.bHasCancel) {
@@ -172,10 +184,10 @@ export class FlowContainerComponent extends FlowContainerBaseComponent implement
172
184
  } else {
173
185
  this.updateSelf();
174
186
  }
175
- } else {
176
- this.showPageMessages(completeProps);
177
187
  }
178
188
  }
189
+
190
+ this.showPageMessages(completeProps);
179
191
  }
180
192
 
181
193
  showPageMessages(completeProps: FlowContainerProps) {
@@ -277,41 +289,6 @@ export class FlowContainerComponent extends FlowContainerBaseComponent implement
277
289
  this.psService.sendMessage(false);
278
290
  }
279
291
 
280
- hasAssignments() {
281
- let hasAssignments = false;
282
- const assignmentsList = this.pConn$.getValue(this.pCoreConstants.CASE_INFO.D_CASE_ASSIGNMENTS_RESULTS);
283
- // const thisOperator = PCore.getEnvironmentInfo().getOperatorIdentifier();
284
- // 8.7 includes assignments in Assignments List that may be assigned to
285
- // a different operator. So, see if there are any assignments for
286
- // the current operator
287
- const isEmbedded = window.location.href.includes('embedded');
288
- let bAssignmentsForThisOperator = false;
289
-
290
- if (isEmbedded) {
291
- const thisOperator = PCore.getEnvironmentInfo().getOperatorIdentifier();
292
- for (const assignment of assignmentsList) {
293
- if (assignment.assigneeInfo.ID === thisOperator) {
294
- bAssignmentsForThisOperator = true;
295
- }
296
- }
297
- } else {
298
- bAssignmentsForThisOperator = true;
299
- }
300
-
301
- // Bail if there is no assignmentsList
302
- if (!assignmentsList) {
303
- return hasAssignments;
304
- }
305
-
306
- const hasChildCaseAssignments = this.hasChildCaseAssignments();
307
-
308
- if (bAssignmentsForThisOperator || hasChildCaseAssignments || this.isCaseWideLocalAction()) {
309
- hasAssignments = true;
310
- }
311
-
312
- return hasAssignments;
313
- }
314
-
315
292
  isCaseWideLocalAction() {
316
293
  const actionID = this.pConn$.getValue(this.pCoreConstants.CASE_INFO.ACTIVE_ACTION_ID);
317
294
  const caseActions = this.pConn$.getValue(this.pCoreConstants.CASE_INFO.AVAILABLEACTIONS);
@@ -461,18 +438,10 @@ export class FlowContainerComponent extends FlowContainerBaseComponent implement
461
438
  this.caseMessages$ = this.localizedVal(this.pConn$.getValue('caseMessages'), this.localeCategory);
462
439
  // caseMessages's behavior has changed in 24.2, and hence it doesn't let Optional Action work.
463
440
  // Changing the below condition for now. Was: (theCaseMessages || !hasAssignments())
464
- if (!this.hasAssignments()) {
441
+ if (!hasAssignments(this.pConn$)) {
465
442
  this.bHasCaseMessages$ = true;
466
443
  this.bShowConfirm = true;
467
444
  this.checkSvg$ = this.utils.getImageSrc('check', this.utils.getSDKStaticContentUrl());
468
- // Temp fix for 8.7 change: confirmationNote no longer coming through in caseMessages$.
469
- // So, if we get here and caseMessages$ is empty, use default value in DX API response
470
- if (!this.caseMessages$) {
471
- this.caseMessages$ = this.localizedVal('Thank you! The next step in this case has been routed appropriately.', this.localeCategory);
472
- }
473
-
474
- // publish this "assignmentFinished" for mashup, need to get approved as a standard
475
- PCore.getPubSubUtils().publish('assignmentFinished');
476
445
 
477
446
  this.psService.sendMessage(false);
478
447
  } else {
@@ -28,7 +28,7 @@ function getChildCaseAssignments(pConnect) {
28
28
  return allAssignments;
29
29
  }
30
30
 
31
- function hasAssignments(pConnect) {
31
+ export function hasAssignments(pConnect) {
32
32
  const { CASE_INFO } = PCore.getConstants();
33
33
  const assignments = pConnect.getValue(CASE_INFO.D_CASE_ASSIGNMENTS_RESULTS);
34
34
  const childCasesAssignments = getChildCaseAssignments(pConnect);
@@ -23,7 +23,6 @@ import { ReferenceComponent } from '@pega/angular-sdk-components';
23
23
  })
24
24
  export class ModalViewContainerComponent implements OnInit, OnDestroy {
25
25
  @Input() pConn$: typeof PConnect;
26
- @Input() displayOnlyFA$: boolean;
27
26
 
28
27
  // for when non modal
29
28
  @Output() modalVisibleChange = new EventEmitter<boolean>();
@@ -73,11 +72,6 @@ export class ModalViewContainerComponent implements OnInit, OnDestroy {
73
72
  }
74
73
 
75
74
  ngOnInit(): void {
76
- if (this.displayOnlyFA$) {
77
- // for when non modal
78
- this.bShowAsModal$ = false;
79
- }
80
-
81
75
  // First thing in initialization is registering and subscribing to the AngularPConnect service
82
76
  this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
83
77
 
@@ -1,5 +1,5 @@
1
1
  <div>
2
- <div><component-mapper name="AlertBanner" [props]="{ banners }" [parent]="this"></component-mapper></div>
2
+ <div><component-mapper name="AlertBanner" [props]="{ banners: bannerService.banners }" [parent]="this"></component-mapper></div>
3
3
  <div *ngIf="bHasNavigation$" class="psdk-stepper">
4
4
  <component-mapper
5
5
  name="MultiStep"
@@ -6,9 +6,18 @@ import { FormGroup } from '@angular/forms';
6
6
  import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
7
7
  import { ErrorMessagesService } from '@pega/angular-sdk-components';
8
8
  import { ProgressSpinnerService } from '@pega/angular-sdk-components';
9
+ import { BannerService } from '@pega/angular-sdk-components';
9
10
  import { ReferenceComponent } from '@pega/angular-sdk-components';
10
11
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
11
12
 
13
+ function getRefreshProps(refreshConditions) {
14
+ // refreshConditions cuurently supports only "Changes" event
15
+ if (!refreshConditions) {
16
+ return [];
17
+ }
18
+ return refreshConditions.filter(item => item.event && item.event === 'Changes').map(item => [item.field, item.field?.substring(1)]) || [];
19
+ }
20
+
12
21
  interface AssignmentProps {
13
22
  // If any, enter additional props that only exist on this component
14
23
  template: string;
@@ -29,7 +38,6 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
29
38
  @Input() isCreateStage$: boolean;
30
39
  @Input() updateToken$: number;
31
40
  @Input() isInModal$ = false;
32
- @Input() banners;
33
41
 
34
42
  // For interaction with AngularPConnect
35
43
  angularPConnectData: AngularPConnectData = {};
@@ -69,12 +77,15 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
69
77
  localeCategory = 'Assignment';
70
78
  localeReference;
71
79
 
80
+ snackBarRef;
81
+
72
82
  constructor(
73
83
  private angularPConnect: AngularPConnectService,
74
84
  private psService: ProgressSpinnerService,
75
85
  private erService: ErrorMessagesService,
76
86
  private ngZone: NgZone,
77
- private snackBar: MatSnackBar
87
+ private snackBar: MatSnackBar,
88
+ public bannerService: BannerService
78
89
  ) {}
79
90
 
80
91
  ngOnInit(): void {
@@ -105,6 +116,8 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
105
116
  // Should always check the bridge to see if the component should update itself (re-render)
106
117
  const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
107
118
 
119
+ this.bannerService.updateBanners(this.itemKey$);
120
+
108
121
  // ONLY call updateSelf when the component should update
109
122
  // AND removing the "gate" that was put there since shouldComponentUpdate
110
123
  // should be the real "gate"
@@ -128,6 +141,8 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
128
141
  }
129
142
 
130
143
  updateChanges() {
144
+ this.registerForRefresh();
145
+
131
146
  // pConn$ may be a 'reference' component, so normalize it
132
147
  this.newPConn$ = ReferenceComponent.normalizePConn(this.pConn$);
133
148
 
@@ -285,6 +300,9 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
285
300
  }
286
301
 
287
302
  buttonClick(sAction, sButtonType) {
303
+ this.snackBarRef?.dismiss();
304
+ this.bannerService.clearBanners();
305
+ PCore.getPubSubUtils().publish('clearBannerMessages');
288
306
  // right now, done on an individual basis, setting bReInit to true
289
307
  // upon the next flow container state change, will cause the flow container
290
308
  // to re-initialize
@@ -308,21 +326,21 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
308
326
  switch (sAction) {
309
327
  case 'navigateToStep':
310
328
  this.erService.sendMessage('publish', '');
311
- if (this.formValid()) {
312
- this.bReInit = true;
313
- this.psService.sendMessage(true);
329
+ // if (this.formValid()) {
330
+ this.bReInit = true;
331
+ this.psService.sendMessage(true);
314
332
 
315
- const navigatePromise = this.navigateToStep('previous', this.itemKey$);
316
- navigatePromise
317
- .then(() => {
318
- this.updateChanges();
319
- this.psService.sendMessage(false);
320
- })
321
- .catch(() => {
322
- this.psService.sendMessage(false);
323
- this.snackBar.open(`${this.localizedVal('Navigation failed!', this.localeCategory)}`, 'Ok');
324
- });
325
- }
333
+ const navigatePromise = this.navigateToStep('previous', this.itemKey$);
334
+ navigatePromise
335
+ .then(() => {
336
+ this.updateChanges();
337
+ this.psService.sendMessage(false);
338
+ })
339
+ .catch(() => {
340
+ this.psService.sendMessage(false);
341
+ this.snackBarRef = this.snackBar.open(`${this.localizedVal('Navigation failed!', this.localeCategory)}`, 'Ok');
342
+ });
343
+ // }
326
344
  break;
327
345
 
328
346
  case 'saveAssignment': {
@@ -338,7 +356,7 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
338
356
  })
339
357
  .catch(() => {
340
358
  this.psService.sendMessage(false);
341
- this.snackBar.open(`${this.localizedVal('Save failed', this.localeCategory)}`, 'Ok');
359
+ this.snackBarRef = this.snackBar.open(`${this.localizedVal('Save failed', this.localeCategory)}`, 'Ok');
342
360
  });
343
361
 
344
362
  break;
@@ -362,7 +380,7 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
362
380
  })
363
381
  .catch(() => {
364
382
  this.psService.sendMessage(false);
365
- this.snackBar.open(`${this.localizedVal('Cancel failed!', this.localeCategory)}`, 'Ok');
383
+ this.snackBarRef = this.snackBar.open(`${this.localizedVal('Cancel failed!', this.localeCategory)}`, 'Ok');
366
384
  });
367
385
  } else {
368
386
  this.psService.sendMessage(true);
@@ -379,7 +397,7 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
379
397
  })
380
398
  .catch(() => {
381
399
  this.psService.sendMessage(false);
382
- this.snackBar.open(`${this.localizedVal('Cancel failed!', this.localeCategory)}`, 'Ok');
400
+ this.snackBarRef = this.snackBar.open(`${this.localizedVal('Cancel failed!', this.localeCategory)}`, 'Ok');
383
401
  });
384
402
  }
385
403
  break;
@@ -391,7 +409,7 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
391
409
  .then(() => {})
392
410
  .catch(() => {
393
411
  this.psService.sendMessage(false);
394
- this.snackBar.open(`${this.localizedVal('Rejection failed!', this.localeCategory)}`, 'Ok');
412
+ this.snackBarRef = this.snackBar.open(`${this.localizedVal('Rejection failed!', this.localeCategory)}`, 'Ok');
395
413
  });
396
414
 
397
415
  break;
@@ -404,23 +422,19 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
404
422
  switch (sAction) {
405
423
  case 'finishAssignment':
406
424
  this.erService.sendMessage('publish', '');
407
- if (this.formValid()) {
408
- this.bReInit = true;
409
- this.psService.sendMessage(true);
410
- const finishPromise = this.finishAssignment(this.itemKey$); // JA - was itemID but Nebula/Constellation uses itemKey
411
- finishPromise
412
- .then(() => {
413
- this.psService.sendMessage(false);
414
- this.updateChanges();
415
- })
416
- .catch(() => {
417
- this.psService.sendMessage(false);
418
- this.snackBar.open(`${this.localizedVal('Submit failed!', this.localeCategory)}`, 'Ok');
419
- });
420
- } else {
421
- // let snackBarRef = this.snackBar.open("Please fix errors on form.", "Ok");
422
- this.erService.sendMessage('show', this.localizedVal('Please fix errors on form.', this.localeCategory));
423
- }
425
+ this.bReInit = true;
426
+ this.psService.sendMessage(true);
427
+ const finishPromise = this.finishAssignment(this.itemKey$); // JA - was itemID but Nebula/Constellation uses itemKey
428
+ finishPromise
429
+ .then(() => {
430
+ this.psService.sendMessage(false);
431
+ this.updateChanges();
432
+ })
433
+ .catch(() => {
434
+ this.psService.sendMessage(false);
435
+ this.snackBarRef = this.snackBar.open(`${this.localizedVal('Submit failed!', this.localeCategory)}`, 'Ok');
436
+ });
437
+
424
438
  break;
425
439
 
426
440
  case 'approveCase': {
@@ -430,7 +444,7 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
430
444
  .then(() => {})
431
445
  .catch(() => {
432
446
  this.psService.sendMessage(false);
433
- this.snackBar.open(`${this.localizedVal('Approve failed!', this.localeCategory)}`, 'Ok');
447
+ this.snackBarRef = this.snackBar.open(`${this.localizedVal('Approve failed!', this.localeCategory)}`, 'Ok');
434
448
  });
435
449
 
436
450
  break;
@@ -452,10 +466,41 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
452
466
  });
453
467
  }
454
468
 
455
- // eslint-disable-next-line sonarjs/no-identical-functions
456
469
  topViewRefresh(): void {
457
470
  Object.values(this.formGroup$.controls).forEach((control: any) => {
458
471
  control.markAsTouched();
459
472
  });
460
473
  }
474
+
475
+ registerForRefresh() {
476
+ // @ts-ignore - Property 'getActionRefreshConditions' is private and only accessible within class 'CaseInfo'
477
+ const refreshConditions = this.pConn$.getCaseInfo()?.getActionRefreshConditions();
478
+ const pageReference = this.pConn$.getPageReference();
479
+ const context = this.pConn$.getContextName();
480
+
481
+ // refresh api de-registration
482
+ PCore.getRefreshManager().deRegisterForRefresh(context);
483
+
484
+ // refresh api registration
485
+ const refreshProps = getRefreshProps(refreshConditions);
486
+ const caseKey = this.pConn$.getCaseInfo().getKey();
487
+ const refreshOptions = {
488
+ autoDetectRefresh: true,
489
+ preserveClientChanges: false
490
+ };
491
+ if (refreshProps.length > 0) {
492
+ refreshProps.forEach(prop => {
493
+ PCore.getRefreshManager().registerForRefresh(
494
+ 'PROP_CHANGE',
495
+ this.pConn$.getActionsApi().refreshCaseView.bind(this.pConn$.getActionsApi(), caseKey, '', pageReference, {
496
+ ...refreshOptions,
497
+ refreshFor: prop[0]
498
+ }),
499
+ `${pageReference}.${prop[1]}`,
500
+ `${context}/${pageReference}`,
501
+ context
502
+ );
503
+ });
504
+ }
505
+ }
461
506
  }
@@ -18,6 +18,7 @@
18
18
  <div class="psdk-case-view-divider"></div>
19
19
 
20
20
  <component-mapper
21
+ *ngIf="arMainButtons$ && arSecondaryButtons$"
21
22
  name="ActionButtons"
22
23
  [props]="{ arMainButtons$, arSecondaryButtons$ }"
23
24
  [parent]="this"
@@ -1,8 +1,10 @@
1
- import { Component, OnInit, Input, Output, EventEmitter, forwardRef, OnChanges } from '@angular/core';
1
+ import { Component, OnInit, Input, Output, EventEmitter, forwardRef, OnChanges, OnDestroy } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { FormGroup, ReactiveFormsModule } from '@angular/forms';
4
4
  import { ReferenceComponent } from '@pega/angular-sdk-components';
5
5
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
6
+ import { IdleDetectionService } from '@pega/angular-sdk-components';
7
+ import { ServerConfigService } from '@pega/angular-sdk-components';
6
8
 
7
9
  @Component({
8
10
  selector: 'app-assignment-card',
@@ -11,7 +13,7 @@ import { ComponentMapperComponent } from '@pega/angular-sdk-components';
11
13
  standalone: true,
12
14
  imports: [CommonModule, ReactiveFormsModule, forwardRef(() => ComponentMapperComponent)]
13
15
  })
14
- export class AssignmentCardComponent implements OnInit, OnChanges {
16
+ export class AssignmentCardComponent implements OnInit, OnChanges, OnDestroy {
15
17
  @Input() pConn$: typeof PConnect;
16
18
  @Input() formGroup$: FormGroup;
17
19
  @Input() arMainButtons$: any[];
@@ -21,10 +23,16 @@ export class AssignmentCardComponent implements OnInit, OnChanges {
21
23
 
22
24
  @Output() actionButtonClick: EventEmitter<any> = new EventEmitter();
23
25
 
26
+ constructor(
27
+ private idleService: IdleDetectionService,
28
+ private scservice: ServerConfigService
29
+ ) {}
30
+
24
31
  ngOnInit(): void {
25
- // Children may contain 'reference' component, so we need to
26
- // normalize them
32
+ // Children may contain 'reference' component, so we need to normalize them
27
33
  this.arChildren$ = ReferenceComponent.normalizePConnArray(this.arChildren$);
34
+
35
+ this.checkAndEnableAutoSave();
28
36
  }
29
37
 
30
38
  ngOnChanges() {
@@ -33,7 +41,27 @@ export class AssignmentCardComponent implements OnInit, OnChanges {
33
41
  this.arChildren$ = ReferenceComponent.normalizePConnArray(this.arChildren$);
34
42
  }
35
43
 
44
+ ngOnDestroy() {
45
+ this.idleService.stopWatching();
46
+ }
47
+
48
+ async checkAndEnableAutoSave() {
49
+ const sdkConfig = await this.scservice.getSdkConfig();
50
+ const autoSave = sdkConfig.serverConfig.autoSave;
51
+
52
+ if (autoSave) {
53
+ this.idleService.startWatching(() => this.autoSave(), autoSave);
54
+ }
55
+ }
56
+
36
57
  onActionButtonClick(oData: any) {
37
58
  this.actionButtonClick.emit(oData);
38
59
  }
60
+
61
+ autoSave() {
62
+ const context = this.pConn$.getContextName();
63
+ if (PCore.getFormUtils().isStateModified(context)) {
64
+ this.pConn$.getActionsApi().saveAssignment(context);
65
+ }
66
+ }
39
67
  }
@@ -33,13 +33,9 @@ export class ReferenceComponent {
33
33
  static createFullReferencedViewFromRef(inPConn: any) {
34
34
  // BAIL and ERROR if inPConn is NOT a reference!
35
35
  if (inPConn.getComponentName() !== 'reference') {
36
- // debugger;
37
-
38
36
  console.error(`Reference component: createFullReferencedViewFromRef inPConn is NOT a reference! ${inPConn.getComponentName()}`);
39
37
  }
40
38
 
41
- const theResolvedConfigProps = inPConn.resolveConfigProps(inPConn.getConfigProps());
42
-
43
39
  const referenceConfig = { ...inPConn.getComponentConfig() } || {};
44
40
 
45
41
  // Since SDK-A implements Reference as static methods and we don't rely on
@@ -47,8 +43,8 @@ export class ReferenceComponent {
47
43
  // (and also leaving the others in for now) so the referenced View can act on
48
44
  // the visibility prop. (The following 3 lines were carried over from React SDK)
49
45
  delete referenceConfig?.name;
50
- // delete referenceConfig?.type;
51
- // delete referenceConfig?.visibility;
46
+ delete referenceConfig?.type;
47
+ delete referenceConfig?.visibility;
52
48
 
53
49
  const viewMetadata = inPConn.getReferencedView();
54
50
 
@@ -68,12 +64,15 @@ export class ReferenceComponent {
68
64
  }
69
65
  };
70
66
 
67
+ const theResolvedConfigProps = inPConn.resolveConfigProps(inPConn.getConfigProps());
68
+ const { visibility = true, context, readOnly = false, displayMode = '' } = theResolvedConfigProps;
69
+
71
70
  if (ReferenceComponent.bLogging) {
72
- console.log(`Reference: about to call createComponent with pageReference: context: ${theResolvedConfigProps.context}`);
71
+ console.log(`Reference: about to call createComponent with pageReference: context: ${inPConn.getContextName()}`);
73
72
  }
74
73
 
75
74
  const viewComponent = inPConn.createComponent(viewObject, null, null, {
76
- pageReference: theResolvedConfigProps.context
75
+ pageReference: context && context.startsWith('@CLASS') ? '' : context
77
76
  });
78
77
 
79
78
  // updating the referencedComponent should trigger a render
@@ -81,8 +80,8 @@ export class ReferenceComponent {
81
80
 
82
81
  newCompPConnect.setInheritedConfig({
83
82
  ...referenceConfig,
84
- readOnly: theResolvedConfigProps.readOnly ? theResolvedConfigProps.readOnly : false,
85
- displayMode: theResolvedConfigProps.displayMode ? theResolvedConfigProps.displayMode : null
83
+ readOnly,
84
+ displayMode
86
85
  });
87
86
 
88
87
  if (ReferenceComponent.bLogging) {
@@ -93,7 +92,11 @@ export class ReferenceComponent {
93
92
  );
94
93
  }
95
94
 
96
- return newCompPConnect;
95
+ if (visibility !== false) {
96
+ return newCompPConnect;
97
+ }
98
+
99
+ return null;
97
100
  }
98
101
 
99
102
  // STATIC method that other components can call to normalize
@@ -130,7 +133,7 @@ export class ReferenceComponent {
130
133
  // debugger;
131
134
  let theRefViewPConn = this.createFullReferencedViewFromRef(inPConn.getPConnect());
132
135
  // now return its PConnect
133
- theRefViewPConn = theRefViewPConn.getComponent();
136
+ theRefViewPConn = theRefViewPConn?.getComponent();
134
137
 
135
138
  // const theFullReference = theRefViewPConn.getPConnect().getFullReference();
136
139
  // console.log(`theFullReference: ${theFullReference}`);
@@ -5,20 +5,11 @@
5
5
  <div *ngIf="bShowRoot$">
6
6
  <div [ngSwitch]="componentName$">
7
7
  <component-mapper *ngSwitchCase="'View'" name="View" [props]="{ pConn$, displayOnlyFA$ }"></component-mapper>
8
- <!-- <app-reference *ngSwitchCase="'reference'" [pConn$]="pConn$" [displayOnlyFA$]="displayOnlyFA$"></app-reference> -->
9
8
  <component-mapper
10
9
  *ngSwitchCase="'ViewContainer'"
11
10
  name="ViewContainer"
12
- [props]="{ pConn$: displayOnlyFA$ ? viewContainerPConn$ : pConn$, displayOnlyFA$ }"
11
+ [props]="{ pConn$: viewContainerPConn$, displayOnlyFA$ }"
13
12
  ></component-mapper>
14
- <app-hybrid-view-container *ngSwitchCase="'HybridViewContainer'" [pConn$]="pConn$" [displayOnlyFA$]="displayOnlyFA$"></app-hybrid-view-container>
15
- <app-modal-view-container
16
- *ngSwitchCase="'ModalViewContainer'"
17
- [pConn$]="pConn$"
18
- [displayOnlyFA$]="displayOnlyFA$"
19
- (modalVisibleChange)="modalVisibleChanged($event)"
20
- ></app-modal-view-container>
21
- <div *ngSwitchCase="''"></div>
22
13
  <div *ngSwitchDefault>{{ localizedVal('RootContainer Missing: ' + componentName$, localeCategory) }}.</div>
23
14
  </div>
24
15
  </div>
@@ -28,9 +19,5 @@
28
19
  </div>
29
20
 
30
21
  <div *ngIf="mConn$ != null">
31
- <app-modal-view-container
32
- [pConn$]="mConn$"
33
- [displayOnlyFA$]="displayOnlyFA$"
34
- (modalVisibleChange)="modalVisibleChanged($event)"
35
- ></app-modal-view-container>
22
+ <app-modal-view-container [pConn$]="mConn$"></app-modal-view-container>
36
23
  </div>
@@ -128,16 +128,6 @@ export class RootContainerComponent implements OnInit, OnDestroy {
128
128
  }
129
129
  }
130
130
 
131
- modalVisibleChanged(isVisible) {
132
- if (this.displayOnlyFA$) {
133
- if (isVisible) {
134
- this.bShowRoot$ = false;
135
- } else {
136
- this.bShowRoot$ = true;
137
- }
138
- }
139
- }
140
-
141
131
  updateSelf() {
142
132
  // need to call this.getCurrentCompleteProps (not this.thePConn.getConfigProps)
143
133
  // to get full set of props that affect this component in Redux
@@ -8,6 +8,20 @@ import { ReferenceComponent } from '@pega/angular-sdk-components';
8
8
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
9
9
 
10
10
  const NO_HEADER_TEMPLATES = ['SubTabs', 'SimpleTable', 'Confirmation', 'DynamicTabs', 'DetailsSubTabs'];
11
+ const DETAILS_TEMPLATES = [
12
+ 'Details',
13
+ 'DetailsFields',
14
+ 'DetailsOneColumn',
15
+ 'DetailsSubTabs',
16
+ 'DetailsThreeColumn',
17
+ 'DetailsTwoColumn',
18
+ 'NarrowWideDetails',
19
+ 'WideNarrowDetails'
20
+ ];
21
+
22
+ function isDetailsTemplate(template) {
23
+ return DETAILS_TEMPLATES.includes(template);
24
+ }
11
25
 
12
26
  /**
13
27
  * WARNING: It is not expected that this file should be modified. It is part of infrastructure code that works with
@@ -146,7 +160,7 @@ export class ViewComponent implements OnInit, OnDestroy, OnChanges {
146
160
  this.templateName$ = this.configProps$.template || '';
147
161
  this.title$ = this.configProps$.title || '';
148
162
  this.label$ = this.configProps$.label || '';
149
- this.showLabel$ = this.configProps$.showLabel || this.showLabel$;
163
+ this.showLabel$ = this.configProps$.showLabel || isDetailsTemplate(this.templateName$) || this.showLabel$;
150
164
  // label & showLabel within inheritedProps takes precedence over configProps
151
165
  this.label$ = this.inheritedProps$.label || this.label$;
152
166
  this.showLabel$ = this.inheritedProps$.showLabel || this.showLabel$;
@@ -1,10 +1,16 @@
1
1
  import { Directive, OnDestroy } from '@angular/core';
2
+ import { AngularPConnectData } from '@pega/angular-sdk-components';
2
3
 
3
4
  @Directive()
4
5
  export class FormTemplateBase implements OnDestroy {
5
6
  pConn$: any;
7
+ angularPConnectData: AngularPConnectData;
6
8
 
7
9
  ngOnDestroy(): void {
8
10
  PCore.getContextTreeManager().removeContextTreeNode(this.pConn$.getContextName());
11
+
12
+ if (this.angularPConnectData?.unsubscribeFn) {
13
+ this.angularPConnectData.unsubscribeFn();
14
+ }
9
15
  }
10
16
  }
@@ -1,11 +1,23 @@
1
- import { Component, OnInit, Input, forwardRef } from '@angular/core';
1
+ import { Component, OnInit, Input, forwardRef, OnDestroy } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { FormGroup } from '@angular/forms';
4
4
  import { ReferenceComponent } from '@pega/angular-sdk-components';
5
+ import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
5
6
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
6
7
  import { TemplateUtils } from '@pega/angular-sdk-components';
7
8
  import { FormTemplateBase } from '@pega/angular-sdk-components';
8
9
 
10
+ function areViewsChanged(oldViews: any[], newViews: any[]): boolean {
11
+ if (oldViews?.length !== newViews?.length) {
12
+ return true;
13
+ }
14
+
15
+ return !oldViews?.every((oldView, index) => {
16
+ const newView = newViews[index];
17
+ return oldView.getPConnect().viewName === newView.getPConnect().viewName;
18
+ });
19
+ }
20
+
9
21
  interface DefaultFormProps {
10
22
  // If any, enter additional props that only exist on this component
11
23
  NumCols: string;
@@ -19,19 +31,36 @@ interface DefaultFormProps {
19
31
  standalone: true,
20
32
  imports: [CommonModule, forwardRef(() => ComponentMapperComponent)]
21
33
  })
22
- export class DefaultFormComponent extends FormTemplateBase implements OnInit {
34
+ export class DefaultFormComponent extends FormTemplateBase implements OnInit, OnDestroy {
23
35
  @Input() override pConn$: typeof PConnect;
24
36
  @Input() formGroup$: FormGroup;
25
37
 
38
+ // Used with AngularPConnect
39
+ override angularPConnectData: AngularPConnectData = {};
40
+
26
41
  arChildren$: any[];
27
42
  divClass$: string;
28
43
  instructions: string;
29
44
 
30
- constructor(private templateUtils: TemplateUtils) {
45
+ constructor(
46
+ private angularPConnect: AngularPConnectService,
47
+ private templateUtils: TemplateUtils
48
+ ) {
31
49
  super();
32
50
  }
33
51
 
34
52
  ngOnInit(): void {
53
+ // First thing in initialization is registering and subscribing to the AngularPConnect service
54
+ this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
55
+
56
+ this.updateSelf();
57
+ }
58
+
59
+ onStateChange() {
60
+ this.updateSelf();
61
+ }
62
+
63
+ updateSelf() {
35
64
  const configProps = this.pConn$.getConfigProps() as DefaultFormProps;
36
65
  const kids = this.pConn$.getChildren();
37
66
  this.instructions = this.templateUtils.getInstructions(this.pConn$, configProps?.instructions);
@@ -55,6 +84,12 @@ export class DefaultFormComponent extends FormTemplateBase implements OnInit {
55
84
  // repoint children before getting templateArray
56
85
  // Children may contain 'reference' component, so we need to
57
86
  // normalize them
58
- this.arChildren$ = ReferenceComponent.normalizePConnArray(kids[0].getPConnect().getChildren());
87
+ const children = ReferenceComponent.normalizePConnArray(kids[0].getPConnect().getChildren());
88
+
89
+ const visibleChildren = children?.filter(child => child !== undefined) || [];
90
+
91
+ if (areViewsChanged(this.arChildren$, visibleChildren)) {
92
+ this.arChildren$ = visibleChildren;
93
+ }
59
94
  }
60
95
  }
@@ -117,7 +117,7 @@ export class FieldGroupTemplateComponent implements OnInit, OnDestroy, OnChanges
117
117
  this.pConn$.setInheritedProp('displayMode', 'DISPLAY_ONLY');
118
118
  }
119
119
  this.referenceList = this.configProps$.referenceList;
120
- if (this.prevRefLength != this.referenceList.length) {
120
+ if (this.prevRefLength != this.referenceList?.length) {
121
121
  // eslint-disable-next-line sonarjs/no-collapsible-if
122
122
  if (!this.readonlyMode) {
123
123
  if (this.referenceList?.length === 0 && this.allowAddEdit !== false) {
@@ -44,18 +44,20 @@ function getFieldWidth(field, label) {
44
44
  export const getContext = thePConn => {
45
45
  const contextName = thePConn.getContextName();
46
46
  const pageReference = thePConn.getPageReference();
47
- // 8.7 change = referenceList may now be in top-level of state props,
48
- // not always in config of state props
49
- let { referenceList } = thePConn.getStateProps()?.config || thePConn.getStateProps();
47
+ const { readonlyContextList, referenceList = readonlyContextList } = thePConn.getStateProps()?.config || thePConn.getStateProps();
48
+
50
49
  const pageReferenceForRows = referenceList.startsWith('.') ? `${pageReference}.${referenceList.substring(1)}` : referenceList;
50
+ const viewName = thePConn.viewName;
51
51
 
52
52
  // removing "caseInfo.content" prefix to avoid setting it as a target while preparing pageInstructions
53
- referenceList = pageReferenceForRows.replace(PCore.getConstants().CASE_INFO.CASE_INFO_CONTENT, '');
53
+ // skipping the removal as StateMachine itself is removing this case info prefix while preparing pageInstructions
54
+ // referenceList = pageReferenceForRows.replace(PCore.getConstants().CASE_INFO.CASE_INFO_CONTENT, '');
54
55
 
55
56
  return {
56
57
  contextName,
57
58
  referenceListStr: referenceList,
58
- pageReferenceForRows
59
+ pageReferenceForRows,
60
+ viewName
59
61
  };
60
62
  };
61
63
 
@@ -1,4 +1,3 @@
1
- /* eslint-disable max-classes-per-file */
2
1
  import { Component, OnInit, Input, ViewChild, forwardRef, OnDestroy } from '@angular/core';
3
2
  import { CommonModule } from '@angular/common';
4
3
  import { FormGroup } from '@angular/forms';
@@ -1,8 +1,8 @@
1
1
  <div class="psdk-todo">
2
- <div class="psdk-todo-header">
3
- <div *ngIf="showTodoList$" class="psdk-avatar">{{ this.currentUserInitials$ }}</div>
2
+ <div *ngIf="showTodoList$" class="psdk-todo-header">
3
+ <div class="psdk-avatar">{{ this.currentUserInitials$ }}</div>
4
4
  <div id="worklist" class="psdk-todo-text">{{ headerText$ }}</div>
5
- <div *ngIf="showTodoList$" class="psdk-assignment-count">{{ count }}</div>
5
+ <div class="psdk-assignment-count">{{ count }}</div>
6
6
  </div>
7
7
  <br /><br />
8
8
  <div *ngIf="showTodoList$" class="psdk-display-divider"></div>
@@ -27,7 +27,7 @@
27
27
  </div>
28
28
  </div>
29
29
  </div>
30
- <div class="psdk-todo-assignment-action" *ngIf="!isConfirm || canPerform">
30
+ <div *ngIf="!isConfirm || canPerform" class="psdk-todo-assignment-action">
31
31
  <button mat-flat-button color="primary" (click)="clickGo(assignment)">{{ localizedVal('Go', localeCategory) }}</button>
32
32
  </div>
33
33
  </div>
@@ -1,5 +1,12 @@
1
+ .psdk-todo-assignments > *:last-child {
2
+ .psdk-display-divider {
3
+ display: none;
4
+ }
5
+ }
6
+
1
7
  .psdk-display-divider {
2
8
  border-bottom: 0.0625rem solid var(--app-neutral-light-color);
9
+ margin-block: 0.5rem;
3
10
  }
4
11
 
5
12
  .psdk-todo {
@@ -91,7 +91,6 @@ export class TodoComponent implements OnInit, OnDestroy {
91
91
  localeCategory = 'Todo';
92
92
  showlessLocalizedValue = this.localizedVal('show_less', 'CosmosFields');
93
93
  showMoreLocalizedValue = this.localizedVal('show_more', 'CosmosFields');
94
- canPerform: boolean;
95
94
  count: number;
96
95
 
97
96
  constructor(
@@ -119,6 +118,10 @@ export class TodoComponent implements OnInit, OnDestroy {
119
118
  PCore.getPubSubUtils().unsubscribe(CREATE_STAGE_DELETED, CREATE_STAGE_DELETED);
120
119
  }
121
120
 
121
+ get canPerform() {
122
+ return this.assignmentsSource$?.[0]?.canPerform === 'true' || this.assignmentsSource$?.[0]?.canPerform === true;
123
+ }
124
+
122
125
  updateList() {
123
126
  const {
124
127
  WORK_BASKET: {
@@ -156,8 +159,6 @@ export class TodoComponent implements OnInit, OnDestroy {
156
159
  }
157
160
  }
158
161
 
159
- this.canPerform = this.arAssignments$?.[0]?.canPerform === 'true' || this.arAssignments$?.[0]?.canPerform === true;
160
-
161
162
  this.currentUser$ = PCore.getEnvironmentInfo().getOperatorName();
162
163
  this.currentUserInitials$ = this.utils.getInitials(this.currentUser$ ?? '');
163
164
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pega/angular-sdk-overrides",
3
- "version": "0.242.5",
3
+ "version": "0.242.7",
4
4
  "description": "Angular SDK - Code for overriding components",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"