@pega/angular-sdk-overrides 0.26.1 → 0.26.3

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 (133) hide show
  1. package/lib/designSystemExtension/alert/alert.component.html +4 -1
  2. package/lib/designSystemExtension/alert/alert.component.scss +9 -10
  3. package/lib/designSystemExtension/alert/alert.component.ts +6 -2
  4. package/lib/designSystemExtension/field-group/field-group.component.ts +11 -3
  5. package/lib/designSystemExtension/material-case-summary/material-case-summary.component.html +12 -3
  6. package/lib/designSystemExtension/operator/operator.component.ts +2 -1
  7. package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.html +104 -10
  8. package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.scss +141 -1
  9. package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.ts +224 -72
  10. package/lib/field/auto-complete/auto-complete.component.html +46 -5
  11. package/lib/field/auto-complete/auto-complete.component.scss +92 -0
  12. package/lib/field/auto-complete/auto-complete.component.ts +349 -22
  13. package/lib/field/cancel-alert/cancel-alert.component.ts +38 -15
  14. package/lib/field/check-box/check-box.component.html +3 -1
  15. package/lib/field/check-box/check-box.component.ts +10 -1
  16. package/lib/field/currency/currency.component.html +2 -1
  17. package/lib/field/currency/currency.component.ts +10 -1
  18. package/lib/field/date/date.component.html +2 -1
  19. package/lib/field/date/date.component.ts +2 -0
  20. package/lib/field/date-time/date-time.component.html +2 -1
  21. package/lib/field/date-time/date-time.component.scss +46 -40
  22. package/lib/field/date-time/date-time.component.ts +2 -0
  23. package/lib/field/decimal/decimal.component.html +2 -1
  24. package/lib/field/decimal/decimal.component.ts +2 -0
  25. package/lib/field/dropdown/dropdown.component.html +2 -1
  26. package/lib/field/dropdown/dropdown.component.ts +10 -1
  27. package/lib/field/email/email.component.html +2 -1
  28. package/lib/field/email/email.component.ts +2 -2
  29. package/lib/field/field.base.ts +27 -1
  30. package/lib/field/group/group.component.html +1 -1
  31. package/lib/field/group/group.component.ts +1 -3
  32. package/lib/field/integer/integer.component.html +2 -1
  33. package/lib/field/integer/integer.component.ts +4 -2
  34. package/lib/field/location/location.component.html +2 -1
  35. package/lib/field/location/location.component.ts +3 -1
  36. package/lib/field/object-reference/object-reference.component.html +1 -1
  37. package/lib/field/object-reference/object-reference.component.ts +3 -0
  38. package/lib/field/percentage/percentage.component.html +2 -1
  39. package/lib/field/percentage/percentage.component.ts +10 -1
  40. package/lib/field/phone/phone.component.html +2 -1
  41. package/lib/field/phone/phone.component.ts +2 -1
  42. package/lib/field/radio-buttons/radio-buttons.component.html +2 -1
  43. package/lib/field/radio-buttons/radio-buttons.component.ts +10 -1
  44. package/lib/field/rich-text/rich-text.component.scss +1 -166
  45. package/lib/field/rich-text/rich-text.component.ts +1 -1
  46. package/lib/field/semantic-link/semantic-link.component.html +1 -1
  47. package/lib/field/semantic-link/semantic-link.component.scss +4 -0
  48. package/lib/field/semantic-link/semantic-link.component.ts +9 -5
  49. package/lib/field/text-area/text-area.component.html +2 -1
  50. package/lib/field/text-area/text-area.component.ts +2 -1
  51. package/lib/field/text-input/text-input.component.html +2 -1
  52. package/lib/field/text-input/text-input.component.ts +2 -1
  53. package/lib/field/time/time.component.html +2 -1
  54. package/lib/field/time/time.component.ts +2 -1
  55. package/lib/field/url/url.component.html +2 -1
  56. package/lib/field/url/url.component.ts +2 -1
  57. package/lib/field/user-reference/user-reference.component.html +4 -2
  58. package/lib/field/user-reference/user-reference.component.ts +10 -5
  59. package/lib/infra/Containers/flow-container/flow-container.component.html +1 -1
  60. package/lib/infra/Containers/flow-container/flow-container.component.ts +33 -40
  61. package/lib/infra/Containers/modal-view-container/data-view-action-buttons/data-view-action-buttons.component.html +12 -0
  62. package/lib/infra/Containers/modal-view-container/data-view-action-buttons/data-view-action-buttons.component.spec.ts +130 -0
  63. package/lib/infra/Containers/modal-view-container/data-view-action-buttons/data-view-action-buttons.component.ts +77 -0
  64. package/lib/infra/Containers/modal-view-container/modal-view-container.component.html +35 -8
  65. package/lib/infra/Containers/modal-view-container/modal-view-container.component.spec.ts +24 -11
  66. package/lib/infra/Containers/modal-view-container/modal-view-container.component.ts +185 -194
  67. package/lib/infra/Containers/view-container/view-container.component.ts +32 -31
  68. package/lib/infra/assignment/assignment.component.html +2 -1
  69. package/lib/infra/assignment/assignment.component.ts +30 -13
  70. package/lib/infra/defer-load/defer-load.component.ts +6 -3
  71. package/lib/infra/multi-step/multi-step.component.html +25 -33
  72. package/lib/infra/multi-step/multi-step.component.scss +48 -0
  73. package/lib/infra/multi-step/multi-step.component.ts +11 -0
  74. package/lib/infra/navbar/navbar.component.ts +33 -35
  75. package/lib/infra/root-container/root-container.component.ts +33 -38
  76. package/lib/infra/view/view.component.ts +17 -39
  77. package/lib/template/app-shell/app-shell.component.ts +12 -11
  78. package/lib/template/base/details-template-base.ts +35 -53
  79. package/lib/template/case-summary/case-summary.component.ts +15 -1
  80. package/lib/template/case-view/case-view.component.html +13 -1
  81. package/lib/template/case-view/case-view.component.spec.ts +119 -10
  82. package/lib/template/case-view/case-view.component.ts +52 -3
  83. package/lib/template/data-reference/data-reference.component.ts +27 -18
  84. package/lib/template/data-reference/search-form/search-form.component.html +1 -1
  85. package/lib/template/data-reference/search-form/search-form.component.ts +2 -0
  86. package/lib/template/default-form/default-form.component.html +19 -3
  87. package/lib/template/default-form/default-form.component.ts +13 -3
  88. package/lib/template/details/details.component.html +23 -3
  89. package/lib/template/details/details.component.scss +9 -2
  90. package/lib/template/details/details.component.ts +3 -32
  91. package/lib/template/details-narrow-wide/details-narrow-wide.component.html +21 -2
  92. package/lib/template/details-narrow-wide/details-narrow-wide.component.scss +8 -1
  93. package/lib/template/details-narrow-wide/details-narrow-wide.component.ts +3 -37
  94. package/lib/template/details-one-column/details-one-column.component.html +23 -1
  95. package/lib/template/details-one-column/details-one-column.component.scss +14 -0
  96. package/lib/template/details-one-column/details-one-column.component.ts +3 -38
  97. package/lib/template/details-three-column/details-three-column.component.html +21 -2
  98. package/lib/template/details-three-column/details-three-column.component.scss +8 -1
  99. package/lib/template/details-three-column/details-three-column.component.ts +3 -46
  100. package/lib/template/details-two-column/details-two-column.component.html +21 -2
  101. package/lib/template/details-two-column/details-two-column.component.scss +8 -1
  102. package/lib/template/details-two-column/details-two-column.component.ts +3 -44
  103. package/lib/template/details-wide-narrow/details-wide-narrow.component.html +21 -2
  104. package/lib/template/details-wide-narrow/details-wide-narrow.component.scss +8 -1
  105. package/lib/template/details-wide-narrow/details-wide-narrow.component.ts +3 -41
  106. package/lib/template/field-value-list/field-value-list.component.scss +17 -0
  107. package/lib/template/list-view/list-view.component.ts +39 -0
  108. package/lib/template/self-service-case-view/self-service-case-view.component.html +13 -1
  109. package/lib/template/self-service-case-view/self-service-case-view.component.spec.ts +96 -11
  110. package/lib/template/self-service-case-view/self-service-case-view.component.ts +52 -3
  111. package/lib/template/simple-table-manual/helpers.ts +30 -9
  112. package/lib/template/simple-table-manual/simple-table-manual.component.html +30 -14
  113. package/lib/template/simple-table-manual/simple-table-manual.component.scss +4 -0
  114. package/lib/template/simple-table-manual/simple-table-manual.component.ts +118 -29
  115. package/lib/template/single-reference-readonly/single-reference-readonly.component.html +1 -1
  116. package/lib/template/single-reference-readonly/single-reference-readonly.component.scss +2 -2
  117. package/lib/template/single-reference-readonly/single-reference-readonly.component.ts +4 -4
  118. package/lib/template/wss-nav-bar/wss-nav-bar.component.ts +18 -20
  119. package/lib/widget/attachment/AttachmentUtils.ts +18 -10
  120. package/lib/widget/attachment/attachment.component.html +16 -6
  121. package/lib/widget/attachment/attachment.component.ts +12 -2
  122. package/lib/widget/case-history/case-history.component.ts +6 -2
  123. package/lib/widget/file-utility/file-utility.component.ts +25 -29
  124. package/lib/widget/todo/todo.component.ts +7 -2
  125. package/package.json +1 -1
  126. package/lib/designSystemExtension/material-details/material-details.component.html +0 -40
  127. package/lib/designSystemExtension/material-details/material-details.component.scss +0 -116
  128. package/lib/designSystemExtension/material-details/material-details.component.spec.ts +0 -24
  129. package/lib/designSystemExtension/material-details/material-details.component.ts +0 -31
  130. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.html +0 -41
  131. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.scss +0 -34
  132. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.spec.ts +0 -22
  133. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.ts +0 -61
@@ -17,7 +17,7 @@ import { ComponentMapperComponent } from '@pega/angular-sdk-components';
17
17
  import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
18
18
  import { DatapageService } from '@pega/angular-sdk-components';
19
19
  import { getReferenceList } from '@pega/angular-sdk-components';
20
- import { buildFieldsForTable, filterDataByCommonFields, filterDataByDate, getContext } from './helpers';
20
+ import { buildFieldsForTable, filterDataByCommonFields, filterDataByDate, getConfigFields, getContext, isPrimaryFieldsValue } from './helpers';
21
21
  import { evaluateAllowRowAction } from '@pega/angular-sdk-components';
22
22
  import { Utils } from '@pega/angular-sdk-components';
23
23
  import { getSeconds } from '@pega/angular-sdk-components';
@@ -39,6 +39,7 @@ interface SimpleTableManualProps {
39
39
  allowActions?: any;
40
40
  allowTableEdit?: boolean;
41
41
  allowRowDelete?: any;
42
+ allowRowEdit?: any;
42
43
  editMode?: string;
43
44
  addAndEditRowsWithin?: any;
44
45
  viewForAddAndEditModal?: any;
@@ -46,7 +47,8 @@ interface SimpleTableManualProps {
46
47
  displayMode?: string;
47
48
  useSeparateViewForEdit: any;
48
49
  viewForEditModal: any;
49
- targetClassLabel: string;
50
+ targetClassLabel?: string;
51
+ uniqueField?: string;
50
52
  }
51
53
 
52
54
  class Group {
@@ -59,6 +61,12 @@ class Group {
59
61
  }
60
62
  }
61
63
 
64
+ interface RowActions {
65
+ canEdit: boolean;
66
+ canDelete: boolean;
67
+ hasAnyAction: boolean;
68
+ }
69
+
62
70
  @Component({
63
71
  selector: 'app-simple-table-manual',
64
72
  templateUrl: './simple-table-manual.component.html',
@@ -108,6 +116,9 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
108
116
  elementsData: MatTableDataSource<any>;
109
117
  originalElementsData: MatTableDataSource<any>;
110
118
  rawFields: any;
119
+ configFields: any[] = [];
120
+ uniqueField?: string;
121
+ normalizedUniqueField?: string;
111
122
  label?: string = '';
112
123
  searchIcon$: string;
113
124
 
@@ -165,9 +176,16 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
165
176
  settingsSvgIcon$: string;
166
177
 
167
178
  isInitialized = false;
168
- targetClassLabel: string;
179
+ targetClassLabel = '';
180
+ addButtonLabel$ = '';
169
181
  localizedVal = PCore.getLocaleUtils().getLocaleValue;
170
182
  localeCategory = 'SimpleTable';
183
+ hideEditRow: any;
184
+ hideDeleteRow: boolean;
185
+ showEditButton: boolean;
186
+ showDeleteButton: boolean;
187
+ showActionColumn: boolean;
188
+ rowActions: RowActions[] = [];
171
189
  constructor(
172
190
  private angularPConnect: AngularPConnectService,
173
191
  public utils: Utils,
@@ -238,7 +256,6 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
238
256
  presets,
239
257
  allowActions,
240
258
  allowTableEdit,
241
- allowRowDelete,
242
259
  label: labelProp,
243
260
  propertyLabel,
244
261
  fieldMetadata,
@@ -249,9 +266,15 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
249
266
  displayMode,
250
267
  useSeparateViewForEdit,
251
268
  viewForEditModal,
252
- targetClassLabel
269
+ targetClassLabel,
270
+ uniqueField
253
271
  } = this.configProps$;
254
272
 
273
+ // uniqueField is authored as a property reference (ex: ".EmbedListUUID__"); page instructions expect it
274
+ // with the leading dot while the inserted row payload expects the bare property name.
275
+ this.uniqueField = uniqueField;
276
+ this.normalizedUniqueField = uniqueField?.startsWith('.') ? uniqueField.substring(1) : uniqueField;
277
+
255
278
  const simpleTableManualProps: any = {};
256
279
  if (this.checkIfAllowActionsOrRowEditingExist(allowActions) && editMode) {
257
280
  simpleTableManualProps.hideAddRow = allowActions?.allowAdd === false;
@@ -267,7 +290,8 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
267
290
  this.referenceListStr = getContext(this.pConn$).referenceListStr;
268
291
  this.label = labelProp || propertyLabel;
269
292
  this.parameters = fieldMetadata?.datasource?.parameters;
270
- this.targetClassLabel = targetClassLabel;
293
+ this.targetClassLabel = targetClassLabel ?? '';
294
+ this.addButtonLabel$ = this.getAddButtonLabel();
271
295
  let { contextClass } = this.configProps$;
272
296
  this.referenceList = referenceList;
273
297
  if (!contextClass) {
@@ -304,10 +328,16 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
304
328
  this.readOnlyMode = renderMode === 'ReadOnly';
305
329
  this.editableMode = renderMode === 'Editable';
306
330
  const isDisplayModeEnabled = displayMode === 'DISPLAY_ONLY';
307
- this.showAddRowButton = !this.readOnlyMode && !simpleTableManualProps.hideAddRow;
331
+ this.showAddRowButton = this.getShowAddRowButton(simpleTableManualProps.hideAddRow);
332
+ this.hideEditRow = simpleTableManualProps.hideEditRow;
333
+ this.hideDeleteRow = simpleTableManualProps.hideDeleteRow;
308
334
  this.allowEditingInModal =
309
335
  (editMode ? editMode === 'modal' : addAndEditRowsWithin === 'modal') && !(renderMode === 'ReadOnly' || isDisplayModeEnabled);
310
- const showDeleteButton = this.editableMode && !simpleTableManualProps.hideDeleteRow && evaluateAllowRowAction(allowRowDelete, this.rowData);
336
+ this.showEditButton = this.allowEditingInModal && !this.hideEditRow;
337
+ this.showDeleteButton = this.editableMode && !this.hideDeleteRow;
338
+ this.showActionColumn = this.showEditButton || this.showDeleteButton;
339
+ const { allowRowEdit, allowRowDelete } = this.pConn$.getComponentConfig?.() ?? {};
340
+ this.rowActions = this.referenceList.map(row => this.getRowActions(row, allowRowEdit, allowRowDelete));
311
341
  this.defaultView = editModeConfig ? editModeConfig.defaultView : viewForAddAndEditModal;
312
342
  this.bUseSeparateViewForEdit = editModeConfig ? editModeConfig.useSeparateViewForEdit : useSeparateViewForEdit;
313
343
  this.editView = editModeConfig ? editModeConfig.editView : viewForEditModal;
@@ -315,9 +345,14 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
315
345
  this.defaultActionId = this.editType === 'action' ? editModeConfig?.defaultAction : undefined;
316
346
  this.editActionId =
317
347
  this.editType === 'action' && editModeConfig?.useSeparateActionForEdit ? editModeConfig?.editAction : editModeConfig?.defaultAction;
318
- const primaryFieldsViewIndex = resolvedFields.findIndex(field => field.config.value === 'pyPrimaryFields');
348
+ const primaryFieldsViewIndex = resolvedFields?.findIndex(field => isPrimaryFieldsValue(field.config.value)) ?? -1;
319
349
  // const showDeleteButton = !this.readOnlyMode && !hideDeleteRow;
320
350
 
351
+ // "pyPrimaryFields" is a single authored column that expands into several real columns, so the
352
+ // resolved/raw children can no longer be used directly - configFields is the expanded column list.
353
+ const configFields = getConfigFields(rawFields, contextClass, primaryFieldsViewIndex);
354
+ this.configFields = configFields.filter(field => !(field?.config?.hide === true));
355
+
321
356
  // Nebula has other handling for isReadOnlyMode but has Cosmos-specific code
322
357
  // so ignoring that for now...
323
358
  // fieldDefs will be an array where each entry will have a "name" which will be the
@@ -326,7 +361,7 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
326
361
  // Nebula does). It will also have the "label", and "meta" contains the original,
327
362
  // unchanged config info. For now, much of the info here is carried over from
328
363
  // Nebula and we may not end up using it all.
329
- this.fieldDefs = buildFieldsForTable(rawFields, this.pConn$, showDeleteButton, {
364
+ this.fieldDefs = buildFieldsForTable(configFields, this.pConn$, this.showActionColumn, {
330
365
  primaryFieldsViewIndex,
331
366
  fields: resolvedFields
332
367
  });
@@ -342,7 +377,7 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
342
377
  return field.name ? field.name : field.cellRenderer;
343
378
  });
344
379
 
345
- // And now we can process the resolvedFields to add in the "name"
380
+ // And now we can process the configFields to add in the "name"
346
381
  // from from the fieldDefs. This "name" is the value that
347
382
  // we'll share to connect things together in the table.
348
383
 
@@ -350,12 +385,9 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
350
385
  return { ...acc, [curr.name]: curr.label };
351
386
  }, {});
352
387
 
353
- this.processedFields = [];
354
-
355
- this.processedFields = resolvedFields.map((field, i) => {
356
- field.config.name = this.displayedColumns[i]; // .config["value"].replace(/ ./g,"_"); // replace space dot with underscore
357
- field.config.label = labelsMap[field.config.name] || field.config.label;
358
- return field;
388
+ this.processedFields = this.configFields.map((field, i) => {
389
+ const name = this.displayedColumns[i];
390
+ return { ...field, config: { ...field.config, name, label: labelsMap[name] || field.config.label } };
359
391
  });
360
392
 
361
393
  // for adding rows to table when editable and not modal view
@@ -364,7 +396,7 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
364
396
  }
365
397
 
366
398
  // for edit and adding rows in modal view and to generate readonly list
367
- if (!isEqual(this.prevReferenceList, this.referenceList) && (this.readOnlyMode || this.allowEditingInModal)) {
399
+ if (!isEqual(this.prevReferenceList, this.referenceList) && (this.readOnlyMode || this.allowEditingInModal || this.hideEditRow)) {
368
400
  this.generateRowsData();
369
401
  }
370
402
 
@@ -391,15 +423,22 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
391
423
  }
392
424
 
393
425
  initializeDefaultPageInstructions() {
426
+ if (!this.isInitialized) {
427
+ return;
428
+ }
429
+
430
+ this.isInitialized = false;
431
+
394
432
  if (this.allowEditingInModal) {
395
433
  this.pConn$.getListActions().initDefaultPageInstructions(
396
434
  this.pConn$.getReferenceList(),
397
- this.fieldDefs.filter(item => item.name).map(item => item.name)
435
+ // Temporary filter for attachments to align with constellation payload behavior.
436
+ this.fieldDefs.filter(item => item.name && item.meta?.type !== 'Attachment').map(item => item.name),
437
+ this.uniqueField
398
438
  );
399
- } else if (this.isInitialized) {
400
- this.isInitialized = false;
401
- // @ts-ignore - An argument for 'propertyNames' was not provided.
402
- this.pConn$.getListActions().initDefaultPageInstructions(this.pConn$.getReferenceList());
439
+ } else {
440
+ // @ts-ignore - 'propertyNames' is optional at runtime; uniqueField is passed as the 3rd argument.
441
+ this.pConn$.getListActions().initDefaultPageInstructions(this.pConn$.getReferenceList(), undefined, this.uniqueField);
403
442
  }
404
443
  }
405
444
 
@@ -408,6 +447,31 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
408
447
  return `${recordsCount || 0} result${recordsCount > 1 ? 's' : ''}`;
409
448
  }
410
449
 
450
+ private getRowActions(row: any, allowRowEdit: any, allowRowDelete: any): RowActions {
451
+ const canEdit = this.showEditButton && evaluateAllowRowAction(allowRowEdit, row);
452
+ const canDelete = this.showDeleteButton && this.isDeleteAllowedForRow(row, allowRowDelete);
453
+
454
+ return {
455
+ canEdit,
456
+ canDelete,
457
+ hasAnyAction: canEdit || canDelete
458
+ };
459
+ }
460
+
461
+ private isDeleteAllowedForRow(row: any, allowRowDelete: any): boolean {
462
+ if (allowRowDelete === undefined || allowRowDelete === true) return true;
463
+ if (typeof allowRowDelete === 'string' && allowRowDelete.startsWith('@E ')) {
464
+ try {
465
+ const expression = allowRowDelete.replace('@E ', '');
466
+ // @ts-expect-error - options param is optional per corejs docs
467
+ return PCore.getExpressionEngine().evaluate(expression, row);
468
+ } catch {
469
+ return true;
470
+ }
471
+ }
472
+ return false;
473
+ }
474
+
411
475
  sortCompare(a, b): number {
412
476
  let aValue = a[0][this.compareRef];
413
477
  let bValue = b[0][this.compareRef];
@@ -927,9 +991,13 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
927
991
  // See what data (if any) we have to display
928
992
  const refKeys: string[] = inColKey.split('.');
929
993
  let valBuilder = inRowData;
994
+ let index = 0;
995
+
930
996
  for (const key of refKeys) {
931
- valBuilder = valBuilder[key] ? valBuilder[key] : valBuilder;
997
+ index += 1;
998
+ valBuilder = valBuilder[key] !== undefined || index === refKeys.length ? valBuilder[key] : valBuilder;
932
999
  }
1000
+
933
1001
  return valBuilder;
934
1002
  }
935
1003
 
@@ -977,7 +1045,11 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
977
1045
  this.defaultActionId
978
1046
  );
979
1047
  } else {
980
- this.pConn$.getListActions().insert({ classID: this.contextClass }, this.referenceList.length);
1048
+ const payload: any = { classID: this.contextClass };
1049
+ if (this.normalizedUniqueField) {
1050
+ payload[this.normalizedUniqueField] = crypto.randomUUID();
1051
+ }
1052
+ this.pConn$.getListActions().insert(payload, this.referenceList.length);
981
1053
  }
982
1054
 
983
1055
  this.pConn$.clearErrorMessages({
@@ -985,8 +1057,20 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
985
1057
  });
986
1058
  }
987
1059
 
1060
+ getAddButtonLabel(): string {
1061
+ const addLabel = this.targetClassLabel
1062
+ ? this.localizedVal('Add {0}', this.localeCategory).replace('{0}', this.targetClassLabel)
1063
+ : this.localizedVal('Add', this.localeCategory);
1064
+
1065
+ return this.localizedVal(addLabel, this.localeCategory);
1066
+ }
1067
+
1068
+ getShowAddRowButton(hideAddRow?: boolean): boolean {
1069
+ return !this.readOnlyMode && !hideAddRow;
1070
+ }
1071
+
988
1072
  editRecord(data, index) {
989
- if (data) {
1073
+ if (data && Number.isInteger(index) && index >= 0 && index < this.referenceList.length) {
990
1074
  const viewForEdit = this.bUseSeparateViewForEdit ? this.editView : this.defaultView;
991
1075
  this.pConn$
992
1076
  .getActionsApi()
@@ -1004,22 +1088,27 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
1004
1088
  }
1005
1089
 
1006
1090
  deleteRecord(index) {
1007
- this.pConn$.getListActions().deleteEntry(index);
1091
+ if (Number.isInteger(index) && index >= 0 && index < this.referenceList.length) {
1092
+ this.pConn$.getListActions().deleteEntry(index);
1093
+ }
1008
1094
  }
1009
1095
 
1010
1096
  buildElementsForTable() {
1011
1097
  const context = this.pConn$.getContextName();
1098
+ const { allowRowEdit } = this.pConn$.getComponentConfig?.() ?? {};
1012
1099
  const eleData: any = [];
1013
1100
  this.referenceList.forEach((element, index) => {
1101
+ const isRowEditable = evaluateAllowRowAction(allowRowEdit, element);
1014
1102
  const data: any = [];
1015
- this.rawFields?.forEach(item => {
1103
+ data.__originalIndex = index;
1104
+ this.configFields?.forEach(item => {
1016
1105
  if (!item?.config?.hide) {
1017
1106
  item = {
1018
1107
  ...item,
1019
1108
  config: {
1020
1109
  ...item.config,
1021
1110
  label: '',
1022
- displayMode: this.readOnlyMode || this.allowEditingInModal ? 'DISPLAY_ONLY' : undefined
1111
+ displayMode: this.readOnlyMode || this.allowEditingInModal || this.hideEditRow || !isRowEditable ? 'DISPLAY_ONLY' : undefined
1023
1112
  }
1024
1113
  };
1025
1114
  const referenceListData = getReferenceList(this.pConn$);
@@ -1,4 +1,4 @@
1
- <div [ngClass]="displayMode ? 'psdk-grid-display' : 'psdk-grid-nondisplay'">
1
+ <div [ngClass]="displayMode ? 'psdk-grid-display' : 'psdk-grid-nondisplay'" [class.psdk-details-reference-value]="isDetails$">
2
2
  <div *ngIf="label" class="psdk-grid-label">{{ label }}</div>
3
3
  <component-mapper name="SemanticLink" [props]="{ pConn$: newPconn, formGroup$ }"></component-mapper>
4
4
  </div>
@@ -7,8 +7,8 @@
7
7
  margin-top: 1rem;
8
8
  }
9
9
 
10
- .psdk-grid-nondisplay {
11
- margin-top: 1rem;
10
+ .psdk-details-reference-value {
11
+ margin-top: 0;
12
12
  }
13
13
 
14
14
  .psdk-label {
@@ -14,7 +14,8 @@ import { getDataRelationshipContextFromKey } from '@pega/angular-sdk-components'
14
14
  export class SingleReferenceReadonlyComponent implements OnInit, OnDestroy {
15
15
  @Input() pConn$: typeof PConnect;
16
16
  @Input() formGroup$: FormGroup;
17
- @Input() dataRelationshipContext?: any;
17
+ @Input() dataRelationshipContext: any = null;
18
+ @Input() isDetails$ = false;
18
19
 
19
20
  angularPConnectData: AngularPConnectData = {};
20
21
  configProps: any;
@@ -66,9 +67,8 @@ export class SingleReferenceReadonlyComponent implements OnInit, OnDestroy {
66
67
  const hideLabel = this.configProps.hideLabel;
67
68
  // const additionalFields = this.configProps.additionalFields;
68
69
  const displayAs = this.configProps.displayAs ?? 'readonly';
69
- const dataRelationshipContext = (rawViewMetadata?.config as any)?.displayField
70
- ? getDataRelationshipContextFromKey((rawViewMetadata?.config as any)?.displayField)
71
- : this.dataRelationshipContext;
70
+ const dataRelationshipContext =
71
+ this.dataRelationshipContext ?? getDataRelationshipContextFromKey((rawViewMetadata?.config as any)?.displayField ?? '');
72
72
  if (propsToUse.showLabel === false) {
73
73
  propsToUse.label = '';
74
74
  }
@@ -1,4 +1,4 @@
1
- import { ChangeDetectorRef, Component, Input, NgZone, OnDestroy, OnInit } from '@angular/core';
1
+ import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { MatMenuModule } from '@angular/material/menu';
4
4
  import { MatListModule } from '@angular/material/list';
@@ -52,7 +52,6 @@ export class WssNavBarComponent implements OnInit, OnDestroy {
52
52
  private angularPConnect: AngularPConnectService,
53
53
  private cdRef: ChangeDetectorRef,
54
54
  private psService: ProgressSpinnerService,
55
- private ngZone: NgZone,
56
55
  private utils: Utils
57
56
  ) {}
58
57
 
@@ -102,30 +101,29 @@ export class WssNavBarComponent implements OnInit, OnDestroy {
102
101
  }
103
102
 
104
103
  initComponent() {
105
- this.ngZone.run(() => {
106
- this.navIcon$ = this.utils.getSDKStaticContentUrl().concat('assets/pzpega-logo-mark.svg');
107
- this.navExpandCollapse$ = this.utils.getImageSrc('plus', this.utils.getSDKStaticContentUrl());
104
+ this.navIcon$ = this.utils.getSDKStaticContentUrl().concat('assets/pzpega-logo-mark.svg');
105
+ this.navExpandCollapse$ = this.utils.getImageSrc('plus', this.utils.getSDKStaticContentUrl());
108
106
 
109
- // Then, continue on with other initialization
107
+ // Then, continue on with other initialization
110
108
 
111
- // making a copy, so can add info
112
- this.navPages$ = JSON.parse(JSON.stringify(this.pages$));
109
+ // making a copy, so can add info
110
+ this.navPages$ = JSON.parse(JSON.stringify(this.pages$));
113
111
 
114
- this.navPages$.forEach(page => {
115
- page.iconName = this.utils.getImageSrc(page.pxPageViewIcon, this.utils.getSDKStaticContentUrl());
116
- });
112
+ this.navPages$.forEach(page => {
113
+ page.iconName = this.utils.getImageSrc(page.pxPageViewIcon, this.utils.getSDKStaticContentUrl());
114
+ });
117
115
 
118
- this.actionsAPI = this.pConn$.getActionsApi();
119
- this.createWork = this.actionsAPI.createWork.bind(this.actionsAPI);
120
- this.showPage = this.actionsAPI.showPage.bind(this.actionsAPI);
121
- this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as WssNavBarProps;
122
- this.logout = this.actionsAPI.logout.bind(this.actionsAPI);
116
+ this.actionsAPI = this.pConn$.getActionsApi();
117
+ this.createWork = this.actionsAPI.createWork.bind(this.actionsAPI);
118
+ this.showPage = this.actionsAPI.showPage.bind(this.actionsAPI);
119
+ this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as WssNavBarProps;
120
+ this.logout = this.actionsAPI.logout.bind(this.actionsAPI);
123
121
 
124
- // const oData = this.pConn$.getDataObject();
122
+ // const oData = this.pConn$.getDataObject();
125
123
 
126
- this.portalOperator$ = PCore.getEnvironmentInfo().getOperatorName();
127
- this.portalOperatorInitials$ = this.utils.getInitials(this.portalOperator$ ?? '');
128
- });
124
+ this.portalOperator$ = PCore.getEnvironmentInfo().getOperatorName();
125
+ this.portalOperatorInitials$ = this.utils.getInitials(this.portalOperator$ ?? '');
126
+ this.cdRef.markForCheck();
129
127
  }
130
128
 
131
129
  navPanelButtonClick(oPageData: any) {
@@ -270,18 +270,26 @@ export const onFileDownload = (responseProps, context) => {
270
270
 
271
271
  // Prepares new structure as per Cosmos component
272
272
  export const transformAttachments = attachments => {
273
- const transformedFiles = [...attachments];
274
273
  let deleteIndex = -1;
275
- transformedFiles.forEach(attachment => {
276
- attachment.props.id = attachment.responseProps.ID;
277
- attachment.props.format = attachment.props.name.split('.').pop();
278
- if (attachment.props.error) {
279
- attachment.responseProps.deleteIndex = deleteIndex;
280
- } else {
274
+
275
+ return attachments.map(attachment => {
276
+ const props = {
277
+ ...attachment.props,
278
+ id: attachment.responseProps.ID,
279
+ format: attachment.props.name.split('.').pop()
280
+ };
281
+
282
+ if (!props.error) {
281
283
  deleteIndex += 1;
282
- attachment.responseProps.deleteIndex = deleteIndex;
283
284
  }
284
- });
285
285
 
286
- return transformedFiles;
286
+ return {
287
+ ...attachment,
288
+ props,
289
+ responseProps: {
290
+ ...attachment.responseProps,
291
+ deleteIndex
292
+ }
293
+ };
294
+ });
287
295
  };
@@ -1,6 +1,6 @@
1
1
  <div class="file-upload-container" *ngIf="bVisible$">
2
2
  <span class="attachment-label" [ngClass]="{ 'file-label': bRequired$ }">{{ label$ }}</span>
3
- <div *ngIf="(files.length === 0 && !allowMultiple$) || allowMultiple$">
3
+ <div *ngIf="displayMode !== 'DISPLAY_ONLY' && ((files.length === 0 && !allowMultiple$) || allowMultiple$)">
4
4
  <div
5
5
  style="margin-bottom: 10px"
6
6
  id="attachment-container"
@@ -36,18 +36,28 @@
36
36
  <div *ngIf="file.props.meta" [ngStyle]="{ color: file.props.error ? 'red' : null }">{{ file.props.meta }}</div>
37
37
  </div>
38
38
  <div class="psdk-attachment-action">
39
- <button id="delete-attachment" *ngIf="file.ID" class="psdk-utility-button" (click)="deleteFile(file, i)">
40
- <img class="psdk-utility-card-action-svg-icon" src="{{ deleteIcon }}" />
41
- </button>
42
- <div *ngIf="!file.ID">
39
+ <div *ngIf="displayMode === 'DISPLAY_ONLY'; else editableActions">
43
40
  <button id="setting-button" mat-icon-button [matMenuTriggerFor]="actionMenu">
44
41
  <mat-icon>more_vert</mat-icon>
45
42
  </button>
46
43
  <mat-menu #actionMenu="matMenu">
47
44
  <button mat-menu-item (click)="downloadFile(file.responseProps ? file.responseProps : {})">Download</button>
48
- <button mat-menu-item (click)="deleteFile(file, i)">Delete</button>
49
45
  </mat-menu>
50
46
  </div>
47
+ <ng-template #editableActions>
48
+ <button id="delete-attachment" *ngIf="file.ID" class="psdk-utility-button" (click)="deleteFile(file, i)">
49
+ <img class="psdk-utility-card-action-svg-icon" src="{{ deleteIcon }}" />
50
+ </button>
51
+ <div *ngIf="!file.ID">
52
+ <button id="setting-button" mat-icon-button [matMenuTriggerFor]="actionMenu">
53
+ <mat-icon>more_vert</mat-icon>
54
+ </button>
55
+ <mat-menu #actionMenu="matMenu">
56
+ <button mat-menu-item (click)="downloadFile(file.responseProps ? file.responseProps : {})">Download</button>
57
+ <button mat-menu-item (click)="deleteFile(file, i)">Delete</button>
58
+ </mat-menu>
59
+ </div>
60
+ </ng-template>
51
61
  </div>
52
62
  </div>
53
63
  </div>
@@ -1,4 +1,4 @@
1
- import { Component, OnInit, Input, OnDestroy, ViewChild, ElementRef } from '@angular/core';
1
+ import { ChangeDetectorRef, Component, OnInit, Input, OnDestroy, ViewChild, ElementRef } from '@angular/core';
2
2
  import { FormGroup } from '@angular/forms';
3
3
  import { CommonModule } from '@angular/common';
4
4
  import { MatButtonModule } from '@angular/material/button';
@@ -76,7 +76,8 @@ export class AttachmentComponent implements OnInit, OnDestroy {
76
76
 
77
77
  constructor(
78
78
  private angularPConnect: AngularPConnectService,
79
- private utils: Utils
79
+ private utils: Utils,
80
+ private cdRef: ChangeDetectorRef
80
81
  ) {}
81
82
 
82
83
  ngOnInit(): void {
@@ -96,6 +97,7 @@ export class AttachmentComponent implements OnInit, OnDestroy {
96
97
  PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION,
97
98
  () => {
98
99
  this.overrideLocalState = true;
100
+ this.cdRef.markForCheck();
99
101
  },
100
102
  this.caseID
101
103
  );
@@ -207,6 +209,13 @@ export class AttachmentComponent implements OnInit, OnDestroy {
207
209
  isArrayDeepMerge: false,
208
210
  removePropertyFromChangedList: true
209
211
  });
212
+ } else if (this.filesWithError.length === 0) {
213
+ const hasActiveUpload = this.files.some(file => file.inProgress);
214
+ if (!hasActiveUpload) {
215
+ this.files = transformAttachments(this.attachments);
216
+ this.attachmentCount = this.attachments.length;
217
+ this.filesWithError = [];
218
+ }
210
219
  }
211
220
  }
212
221
  }
@@ -336,6 +345,7 @@ export class AttachmentComponent implements OnInit, OnDestroy {
336
345
  }
337
346
  return localFile;
338
347
  });
348
+ this.cdRef.markForCheck();
339
349
  }
340
350
 
341
351
  populateErrorAndUpdateRedux(file) {
@@ -1,4 +1,4 @@
1
- import { Component, OnInit, Input } from '@angular/core';
1
+ import { ChangeDetectorRef, Component, OnInit, Input } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { MatTableDataSource, MatTableModule } from '@angular/material/table';
4
4
  import { Utils } from '@pega/angular-sdk-components';
@@ -23,7 +23,10 @@ export class CaseHistoryComponent implements OnInit {
23
23
  displayedColumns$ = Array<any>();
24
24
  waitingForData = false;
25
25
 
26
- constructor(private utils: Utils) {}
26
+ constructor(
27
+ private utils: Utils,
28
+ private cdRef: ChangeDetectorRef
29
+ ) {}
27
30
 
28
31
  ngOnInit(): void {
29
32
  this.configProps$ = this.pConn$.getConfigProps();
@@ -54,6 +57,7 @@ export class CaseHistoryComponent implements OnInit {
54
57
  this.repeatList$ = new MatTableDataSource(tableDataResults);
55
58
 
56
59
  this.waitingForData = false;
60
+ this.cdRef.markForCheck();
57
61
  });
58
62
  }
59
63
  // This method isn't being used anywhere, keeping it as a reference for now