@pega/angular-sdk-overrides 25.1.12 → 26.1.10

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 (168) 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 +51 -36
  6. package/lib/designSystemExtension/material-case-summary/material-case-summary.component.scss +12 -0
  7. package/lib/designSystemExtension/material-case-summary/material-case-summary.component.ts +11 -0
  8. package/lib/designSystemExtension/operator/operator.component.html +5 -3
  9. package/lib/designSystemExtension/operator/operator.component.scss +7 -0
  10. package/lib/designSystemExtension/operator/operator.component.ts +2 -1
  11. package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.html +100 -10
  12. package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.scss +141 -1
  13. package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.spec.ts +1 -1
  14. package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.ts +240 -72
  15. package/lib/field/auto-complete/auto-complete.component.html +46 -5
  16. package/lib/field/auto-complete/auto-complete.component.scss +92 -0
  17. package/lib/field/auto-complete/auto-complete.component.ts +350 -23
  18. package/lib/field/cancel-alert/cancel-alert.component.ts +38 -15
  19. package/lib/field/check-box/check-box.component.html +8 -6
  20. package/lib/field/check-box/check-box.component.ts +9 -2
  21. package/lib/field/currency/currency.component.html +2 -1
  22. package/lib/field/currency/currency.component.ts +10 -1
  23. package/lib/field/date/date.component.html +2 -1
  24. package/lib/field/date/date.component.ts +2 -0
  25. package/lib/field/date-time/date-time.component.html +2 -1
  26. package/lib/field/date-time/date-time.component.scss +46 -40
  27. package/lib/field/date-time/date-time.component.ts +29 -0
  28. package/lib/field/decimal/decimal.component.html +2 -1
  29. package/lib/field/decimal/decimal.component.ts +2 -0
  30. package/lib/field/dropdown/dropdown.component.html +4 -1
  31. package/lib/field/dropdown/dropdown.component.ts +18 -19
  32. package/lib/field/email/email.component.html +2 -1
  33. package/lib/field/email/email.component.ts +2 -2
  34. package/lib/field/embedded-data-multi/embedded-data-multi.component.html +3 -0
  35. package/lib/field/embedded-data-multi/embedded-data-multi.component.scss +0 -0
  36. package/lib/field/embedded-data-multi/embedded-data-multi.component.ts +173 -0
  37. package/lib/field/field.base.ts +27 -1
  38. package/lib/field/group/group.component.html +1 -1
  39. package/lib/field/group/group.component.ts +16 -7
  40. package/lib/field/integer/integer.component.html +2 -1
  41. package/lib/field/integer/integer.component.ts +4 -2
  42. package/lib/field/location/location.component.html +2 -1
  43. package/lib/field/location/location.component.ts +3 -1
  44. package/lib/field/multiselect/multiselect.component.html +1 -1
  45. package/lib/field/multiselect/multiselect.component.ts +23 -4
  46. package/lib/field/multiselect/utils.ts +5 -3
  47. package/lib/field/object-reference/object-reference.component.html +30 -15
  48. package/lib/field/object-reference/object-reference.component.ts +818 -94
  49. package/lib/field/percentage/percentage.component.html +2 -1
  50. package/lib/field/percentage/percentage.component.ts +10 -1
  51. package/lib/field/phone/phone.component.html +2 -1
  52. package/lib/field/phone/phone.component.ts +2 -1
  53. package/lib/field/radio-buttons/radio-buttons.component.html +2 -1
  54. package/lib/field/radio-buttons/radio-buttons.component.ts +10 -1
  55. package/lib/field/rich-text/rich-text.component.scss +1 -166
  56. package/lib/field/rich-text/rich-text.component.spec.ts +1 -1
  57. package/lib/field/rich-text/rich-text.component.ts +1 -1
  58. package/lib/field/selectable-card/selectable-card.component.html +1 -0
  59. package/lib/field/selectable-card/selectable-card.component.ts +31 -16
  60. package/lib/field/semantic-link/semantic-link.component.html +1 -1
  61. package/lib/field/semantic-link/semantic-link.component.scss +4 -0
  62. package/lib/field/semantic-link/semantic-link.component.ts +13 -7
  63. package/lib/field/text-area/text-area.component.html +2 -1
  64. package/lib/field/text-area/text-area.component.ts +2 -1
  65. package/lib/field/text-input/text-input.component.html +2 -1
  66. package/lib/field/text-input/text-input.component.ts +2 -1
  67. package/lib/field/time/time.component.html +2 -1
  68. package/lib/field/time/time.component.ts +2 -1
  69. package/lib/field/url/url.component.html +2 -1
  70. package/lib/field/url/url.component.ts +2 -1
  71. package/lib/field/user-reference/user-reference.component.html +4 -2
  72. package/lib/field/user-reference/user-reference.component.ts +11 -6
  73. package/lib/infra/Containers/flow-container/flow-container.component.html +2 -2
  74. package/lib/infra/Containers/flow-container/flow-container.component.ts +34 -42
  75. package/lib/infra/Containers/modal-view-container/data-view-action-buttons/data-view-action-buttons.component.html +12 -0
  76. package/lib/infra/Containers/modal-view-container/data-view-action-buttons/data-view-action-buttons.component.spec.ts +130 -0
  77. package/lib/infra/Containers/modal-view-container/data-view-action-buttons/data-view-action-buttons.component.ts +77 -0
  78. package/lib/infra/Containers/modal-view-container/modal-view-container.component.html +35 -8
  79. package/lib/infra/Containers/modal-view-container/modal-view-container.component.ts +185 -196
  80. package/lib/infra/Containers/view-container/view-container.component.html +1 -1
  81. package/lib/infra/Containers/view-container/view-container.component.ts +36 -43
  82. package/lib/infra/assignment/assignment.component.html +2 -1
  83. package/lib/infra/assignment/assignment.component.ts +44 -22
  84. package/lib/infra/assignment-card/assignment-card.component.html +1 -0
  85. package/lib/infra/assignment-card/assignment-card.component.ts +2 -8
  86. package/lib/infra/defer-load/defer-load.component.ts +7 -5
  87. package/lib/infra/multi-step/multi-step.component.html +25 -33
  88. package/lib/infra/multi-step/multi-step.component.scss +67 -125
  89. package/lib/infra/multi-step/multi-step.component.ts +11 -0
  90. package/lib/infra/navbar/navbar.component.ts +33 -36
  91. package/lib/infra/reference/reference.component.html +7 -1
  92. package/lib/infra/reference/reference.component.ts +63 -109
  93. package/lib/infra/region/region.component.ts +1 -3
  94. package/lib/infra/root-container/root-container.component.html +1 -0
  95. package/lib/infra/root-container/root-container.component.ts +34 -42
  96. package/lib/infra/view/view.component.ts +22 -46
  97. package/lib/template/advanced-search/advanced-search.component.ts +0 -1
  98. package/lib/template/advanced-search/search-groups/search-groups.component.ts +2 -3
  99. package/lib/template/app-shell/app-shell.component.ts +13 -13
  100. package/lib/template/banner-page/banner-page.component.ts +1 -2
  101. package/lib/template/base/details-template-base.ts +41 -14
  102. package/lib/template/base/form-template-base.ts +0 -2
  103. package/lib/template/case-summary/case-summary.component.ts +15 -7
  104. package/lib/template/case-view/case-view.component.html +14 -2
  105. package/lib/template/case-view/case-view.component.spec.ts +119 -10
  106. package/lib/template/case-view/case-view.component.ts +52 -3
  107. package/lib/template/data-reference/data-reference.component.ts +29 -22
  108. package/lib/template/data-reference/search-form/search-form.component.html +1 -1
  109. package/lib/template/data-reference/search-form/search-form.component.ts +9 -1
  110. package/lib/template/data-reference/search-form/tabsData.ts +0 -1
  111. package/lib/template/default-form/default-form.component.html +20 -4
  112. package/lib/template/default-form/default-form.component.ts +14 -5
  113. package/lib/template/default-page/default-page.component.ts +1 -2
  114. package/lib/template/details/details.component.html +23 -3
  115. package/lib/template/details/details.component.scss +9 -2
  116. package/lib/template/details/details.component.ts +3 -70
  117. package/lib/template/details-narrow-wide/details-narrow-wide.component.html +21 -2
  118. package/lib/template/details-narrow-wide/details-narrow-wide.component.scss +8 -1
  119. package/lib/template/details-narrow-wide/details-narrow-wide.component.ts +3 -39
  120. package/lib/template/details-one-column/details-one-column.component.html +23 -1
  121. package/lib/template/details-one-column/details-one-column.component.scss +14 -0
  122. package/lib/template/details-one-column/details-one-column.component.ts +3 -40
  123. package/lib/template/details-three-column/details-three-column.component.html +21 -2
  124. package/lib/template/details-three-column/details-three-column.component.scss +8 -1
  125. package/lib/template/details-three-column/details-three-column.component.ts +3 -48
  126. package/lib/template/details-two-column/details-two-column.component.html +21 -2
  127. package/lib/template/details-two-column/details-two-column.component.scss +8 -1
  128. package/lib/template/details-two-column/details-two-column.component.ts +3 -46
  129. package/lib/template/details-wide-narrow/details-wide-narrow.component.html +21 -2
  130. package/lib/template/details-wide-narrow/details-wide-narrow.component.scss +8 -1
  131. package/lib/template/details-wide-narrow/details-wide-narrow.component.ts +3 -43
  132. package/lib/template/dynamic-tabs/dynamic-tabs.component.html +1 -0
  133. package/lib/template/field-group-template/field-group-template.component.ts +19 -6
  134. package/lib/template/field-value-list/field-value-list.component.scss +17 -0
  135. package/lib/template/inline-dashboard-page/inline-dashboard-page.component.ts +2 -10
  136. package/lib/template/list-view/list-view.component.ts +47 -11
  137. package/lib/template/one-column/one-column.component.html +3 -0
  138. package/lib/template/one-column-tab/one-column-tab.component.html +1 -0
  139. package/lib/template/page/page.component.html +1 -0
  140. package/lib/template/self-service-case-view/self-service-case-view.component.html +13 -1
  141. package/lib/template/self-service-case-view/self-service-case-view.component.spec.ts +96 -11
  142. package/lib/template/self-service-case-view/self-service-case-view.component.ts +52 -3
  143. package/lib/template/simple-table/simple-table.component.ts +11 -1
  144. package/lib/template/simple-table-manual/helpers.ts +84 -16
  145. package/lib/template/simple-table-manual/simple-table-manual.component.html +30 -14
  146. package/lib/template/simple-table-manual/simple-table-manual.component.scss +8 -2
  147. package/lib/template/simple-table-manual/simple-table-manual.component.ts +142 -46
  148. package/lib/template/single-reference-readonly/single-reference-readonly.component.html +0 -0
  149. package/lib/template/single-reference-readonly/single-reference-readonly.component.scss +2 -3
  150. package/lib/template/single-reference-readonly/single-reference-readonly.component.ts +7 -8
  151. package/lib/template/wide-narrow-page/wide-narrow-page.component.ts +0 -3
  152. package/lib/template/wss-nav-bar/wss-nav-bar.component.ts +19 -21
  153. package/lib/widget/attachment/AttachmentUtils.ts +19 -11
  154. package/lib/widget/attachment/attachment.component.html +16 -6
  155. package/lib/widget/attachment/attachment.component.ts +14 -4
  156. package/lib/widget/case-history/case-history.component.ts +6 -2
  157. package/lib/widget/feed-container/feed-container.component.ts +1 -199
  158. package/lib/widget/file-utility/file-utility.component.ts +26 -30
  159. package/lib/widget/todo/todo.component.ts +7 -2
  160. package/package.json +2 -2
  161. package/lib/designSystemExtension/material-details/material-details.component.html +0 -40
  162. package/lib/designSystemExtension/material-details/material-details.component.scss +0 -116
  163. package/lib/designSystemExtension/material-details/material-details.component.spec.ts +0 -24
  164. package/lib/designSystemExtension/material-details/material-details.component.ts +0 -31
  165. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.html +0 -29
  166. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.scss +0 -34
  167. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.spec.ts +0 -22
  168. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.ts +0 -37
@@ -4,7 +4,7 @@
4
4
  <ng-template #noDisplayMode>
5
5
  <div *ngIf="!bReadonly$ && bHasForm$; else noEdit">
6
6
  <div [formGroup]="formGroup$" *ngIf="bVisible$">
7
- <mat-form-field class="psdk-full-width" subscriptSizing="dynamic" [hintLabel]="helperText">
7
+ <mat-form-field class="psdk-full-width" subscriptSizing="dynamic">
8
8
  <mat-label>{{ label$ }}</mat-label>
9
9
  <input
10
10
  matInput
@@ -21,6 +21,7 @@
21
21
  />
22
22
  <mat-datepicker-toggle matSuffix [for]="pegadate" [disabled]="bDisabled$"></mat-datepicker-toggle>
23
23
  <mat-datepicker #pegadate [startAt]="value$" xPosition="end"></mat-datepicker>
24
+ <mat-hint *ngIf="helperText" [appFieldWarning]="bFieldMessageVisible$">{{ helperText }}</mat-hint>
24
25
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
25
26
  </mat-form-field>
26
27
  </div>
@@ -9,6 +9,7 @@ import { MAT_DATE_FORMATS } from '@angular/material/core';
9
9
  import { MomentDateModule } from '@angular/material-moment-adapter';
10
10
 
11
11
  import { FieldBase } from '@pega/angular-sdk-components';
12
+ import { FieldWarningDirective } from '@pega/angular-sdk-components';
12
13
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
13
14
  import { getDateFormatInfo } from '@pega/angular-sdk-components';
14
15
  import { format } from '@pega/angular-sdk-components';
@@ -50,6 +51,7 @@ class MyFormat {
50
51
  MatDatepickerModule,
51
52
  MatNativeDateModule,
52
53
  MomentDateModule,
54
+ FieldWarningDirective,
53
55
  forwardRef(() => ComponentMapperComponent)
54
56
  ],
55
57
  providers: [{ provide: MAT_DATE_FORMATS, useClass: MyFormat }]
@@ -4,7 +4,7 @@
4
4
  <ng-template #noDisplayMode>
5
5
  <div *ngIf="!bReadonly$ && bHasForm$; else noEdit">
6
6
  <div [formGroup]="formGroup$" *ngIf="bVisible$">
7
- <mat-form-field class="psdk-full-width" subscriptSizing="dynamic" [hintLabel]="helperText">
7
+ <mat-form-field class="psdk-full-width" subscriptSizing="dynamic">
8
8
  <mat-label>{{ label$ }}</mat-label>
9
9
  <input
10
10
  matInput
@@ -18,6 +18,7 @@
18
18
  />
19
19
  <mat-datepicker-toggle matSuffix [owlDateTimeTrigger]="dtPicker"></mat-datepicker-toggle>
20
20
  <owl-date-time #dtPicker [disabled]="bDisabled$" [scrollStrategy]="scrollStrategy"></owl-date-time>
21
+ <mat-hint *ngIf="helperText" [appFieldWarning]="bFieldMessageVisible$">{{ helperText }}</mat-hint>
21
22
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
22
23
  </mat-form-field>
23
24
  </div>
@@ -20,61 +20,67 @@
20
20
  width: auto;
21
21
  }
22
22
 
23
- .mat-datepicker-content,
24
- .time-container {
25
- box-shadow:
26
- 0px 2px 4px -1px rgba(0, 0, 0, 0.2),
27
- 0px 4px 5px 0px rgba(0, 0, 0, 0.14),
28
- 0px 1px 10px 0px rgba(0, 0, 0, 0.12);
29
- display: block;
30
- border-radius: 4px;
31
- background-color: var(--mat-datepicker-calendar-container-background-color);
32
- color: var(--mat-datepicker-calendar-container-text-color);
23
+ .owl-dt-container {
24
+ background-color: var(--mat-sys-surface-container);
25
+ color: var(--mat-sys-on-surface);
33
26
  }
34
27
 
35
- .mat-calendar-body-cell-content {
36
- color: var(--mat-datepicker-calendar-date-text-color);
37
- border-color: var(--mat-datepicker-calendar-date-outline-color);
28
+ .owl-dt-container-row,
29
+ .owl-dt-container-info .owl-dt-container-range:last-child {
30
+ border-color: var(--mat-sys-outline-variant);
38
31
  }
39
32
 
40
- .mat-calendar-body-selected {
41
- background-color: var(--mat-datepicker-calendar-date-selected-state-background-color);
42
- color: var(--mat-datepicker-calendar-date-selected-state-text-color);
33
+ .owl-dt-calendar-control,
34
+ .owl-dt-calendar-table .owl-dt-calendar-cell {
35
+ color: var(--mat-sys-on-surface);
43
36
  }
44
37
 
45
- .mat-calendar-body-cell-content {
46
- border: none !important;
38
+ .owl-dt-calendar-table .owl-dt-calendar-header,
39
+ .owl-dt-calendar-table .owl-dt-calendar-cell-disabled > .owl-dt-calendar-cell-content:not(.owl-dt-calendar-cell-selected) {
40
+ color: var(--mat-sys-on-surface-variant);
47
41
  }
48
42
 
49
- .mat-calendar-body-cell:not(.mat-calendar-body-disabled):hover
50
- > .mat-calendar-body-cell-content:not(.mat-calendar-body-selected):not(.mat-calendar-body-comparison-identical) {
51
- background-color: var(--mat-datepicker-calendar-date-hover-state-background-color);
43
+ .owl-dt-calendar-table .owl-dt-calendar-header .owl-dt-calendar-table-divider::after {
44
+ background-color: var(--mat-sys-outline-variant);
52
45
  }
53
46
 
54
- .mat-calendar-arrow {
55
- fill: var(--mat-datepicker-calendar-period-button-icon-color);
47
+ .owl-dt-calendar-table .owl-dt-calendar-cell-today:not(.owl-dt-calendar-cell-selected) {
48
+ border-color: var(--mat-sys-outline);
56
49
  }
57
50
 
58
- .mat-calendar-table-header th {
59
- text-align: center;
60
- padding: 0 0 8px 0;
61
- color: var(--mat-datepicker-calendar-header-text-color);
62
- font-size: var(--mat-datepicker-calendar-header-text-size);
63
- font-weight: var(--mat-datepicker-calendar-header-text-weight);
51
+ .owl-dt-calendar-table .owl-dt-calendar-cell-selected {
52
+ background-color: var(--mat-sys-primary);
53
+ color: var(--mat-sys-on-primary);
64
54
  }
65
55
 
66
- .mat-datepicker-content .mat-calendar-previous-button,
67
- .mat-datepicker-content .mat-calendar-next-button {
68
- color: var(--mat-datepicker-calendar-navigation-button-icon-color);
56
+ .owl-dt-calendar-table .owl-dt-calendar-cell-active:focus > .owl-dt-calendar-cell-content:not(.owl-dt-calendar-cell-selected),
57
+ .owl-dt-calendar-table :not(.owl-dt-calendar-cell-disabled):hover > .owl-dt-calendar-cell-content:not(.owl-dt-calendar-cell-selected),
58
+ .owl-dt-calendar-control .owl-dt-calendar-control-content .owl-dt-calendar-control-button:hover,
59
+ .owl-dt-control-period-button:hover > .owl-dt-control-button-content,
60
+ .owl-dt-container-control-button:hover .owl-dt-control-button-content,
61
+ .owl-dt-control:focus > .owl-dt-control-content {
62
+ background-color: var(--mat-sys-surface-container-high);
69
63
  }
70
64
 
71
- .mat-calendar-table-header-divider::after {
72
- content: '';
73
- position: absolute;
74
- top: 0;
75
- left: -8px;
76
- right: -8px;
77
- height: 1px;
78
- background: var(--mat-datepicker-calendar-header-divider-color);
65
+ .owl-dt-timer-content .owl-dt-timer-input {
66
+ border-color: var(--mat-sys-outline);
67
+ background-color: var(--mat-sys-surface-container-highest);
68
+ color: var(--mat-sys-on-surface);
69
+ }
70
+
71
+ .owl-dt-container-buttons,
72
+ .owl-dt-container-info .owl-dt-container-info-active,
73
+ .owl-dt-timer-hour12 {
74
+ color: var(--mat-sys-primary);
75
+ }
76
+
77
+ .owl-dt-control-arrow-button[disabled] {
78
+ color: var(--mat-sys-on-surface-variant);
79
+ }
80
+
81
+ .owl-dt-timer-hour12 .owl-dt-timer-hour12-box:focus .owl-dt-control-button-content,
82
+ .owl-dt-timer-hour12 .owl-dt-timer-hour12-box:hover .owl-dt-control-button-content {
83
+ background-color: var(--mat-sys-primary);
84
+ color: var(--mat-sys-on-primary);
79
85
  }
80
86
  }
@@ -9,6 +9,7 @@ import { OwlDateTimeModule, OwlNativeDateTimeModule } from '@danielmoncada/angul
9
9
  import dayjs from 'dayjs';
10
10
 
11
11
  import { FieldBase } from '@pega/angular-sdk-components';
12
+ import { FieldWarningDirective } from '@pega/angular-sdk-components';
12
13
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
13
14
  import { getDateFormatInfo } from '@pega/angular-sdk-components';
14
15
  import { handleEvent } from '@pega/angular-sdk-components';
@@ -31,6 +32,7 @@ interface DateTimeProps extends PConnFieldProps {
31
32
  MatDatepickerModule,
32
33
  OwlDateTimeModule,
33
34
  OwlNativeDateTimeModule,
35
+ FieldWarningDirective,
34
36
  forwardRef(() => ComponentMapperComponent)
35
37
  ]
36
38
  })
@@ -95,6 +97,12 @@ export class DateTimeComponent extends FieldBase implements OnInit, OnDestroy {
95
97
  }
96
98
 
97
99
  fieldOnDateChange(event: any) {
100
+ // owl picker emits null when the typed text can't be parsed; clear the input instead of defaulting to now
101
+ if (!event.value) {
102
+ this.fieldControl.setValue('');
103
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, '');
104
+ return;
105
+ }
98
106
  // this comes from the date pop up
99
107
  if (typeof event.value === 'object') {
100
108
  // convert date to pega "date" format
@@ -104,4 +112,25 @@ export class DateTimeComponent extends FieldBase implements OnInit, OnDestroy {
104
112
  }
105
113
  handleEvent(this.actionsApi, 'changeNblur', this.propName, event.value);
106
114
  }
115
+
116
+ override getErrorMessage() {
117
+ // look for validation messages for json, pre-defined or just an error pushed from workitem (400)
118
+ if (this.fieldControl.hasError('message')) {
119
+ return this.angularPConnectData.validateMessage ?? '';
120
+ }
121
+
122
+ if (this.fieldControl.hasError('required')) {
123
+ return 'You must enter a value';
124
+ }
125
+
126
+ if (this.fieldControl.hasError('owlDateTimeParse')) {
127
+ return `${this.fieldControl.errors?.['owlDateTimeParse'].text} is not a valid date time value`;
128
+ }
129
+
130
+ if (this.fieldControl.errors) {
131
+ return 'Invalid date time value';
132
+ }
133
+
134
+ return '';
135
+ }
107
136
  }
@@ -4,7 +4,7 @@
4
4
  <ng-template #noDisplayMode>
5
5
  <div *ngIf="bHasForm$; else noEdit">
6
6
  <div [formGroup]="formGroup$" *ngIf="bVisible$">
7
- <mat-form-field class="psdk-full-width" subscriptSizing="dynamic" [hintLabel]="helperText">
7
+ <mat-form-field class="psdk-full-width" subscriptSizing="dynamic">
8
8
  <mat-label>{{ label$ }}</mat-label>
9
9
  <input
10
10
  type="text"
@@ -29,6 +29,7 @@
29
29
  (blur)="fieldOnBlur($event)"
30
30
  [readonly]="bReadonly$"
31
31
  />
32
+ <mat-hint *ngIf="helperText" [appFieldWarning]="bFieldMessageVisible$">{{ helperText }}</mat-hint>
32
33
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
33
34
  </mat-form-field>
34
35
  </div>
@@ -6,6 +6,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
6
6
  import { NgxCurrencyDirective, NgxCurrencyInputMode } from 'ngx-currency';
7
7
 
8
8
  import { FieldBase } from '@pega/angular-sdk-components';
9
+ import { FieldWarningDirective } from '@pega/angular-sdk-components';
9
10
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
10
11
  import { handleEvent } from '@pega/angular-sdk-components';
11
12
  import { getCurrencyCharacters, getCurrencyOptions } from '@pega/angular-sdk-components';
@@ -31,6 +32,7 @@ interface DecimalProps extends PConnFieldProps {
31
32
  MatFormFieldModule,
32
33
  MatInputModule,
33
34
  NgxCurrencyDirective,
35
+ FieldWarningDirective,
34
36
  forwardRef(() => ComponentMapperComponent)
35
37
  ]
36
38
  })
@@ -8,20 +8,23 @@
8
8
  <ng-template #noDisplayMode>
9
9
  <div *ngIf="!bReadonly$ && bHasForm$; else noEdit">
10
10
  <div [formGroup]="formGroup$" *ngIf="bVisible$">
11
- <mat-form-field class="psdk-full-width" subscriptSizing="dynamic" [hintLabel]="helperText">
11
+ <mat-form-field class="psdk-full-width" subscriptSizing="dynamic">
12
12
  <mat-select
13
13
  [value]="value$"
14
+ [placeholder]="placeholderText"
14
15
  [required]="bRequired$"
15
16
  [disabled]="bDisabled$"
16
17
  [attr.data-test-id]="testId"
17
18
  (selectionChange)="fieldOnChange($event)"
18
19
  [formControl]="fieldControl"
19
20
  >
21
+ <mat-option>{{ placeholderText }}</mat-option>
20
22
  <mat-option *ngFor="let opt of options$" [value]="opt.key">
21
23
  {{ getLocalizedOptionValue(opt) }}
22
24
  </mat-option>
23
25
  </mat-select>
24
26
  <mat-label>{{ label$ }}</mat-label>
27
+ <mat-hint *ngIf="helperText" [appFieldWarning]="bFieldMessageVisible$">{{ helperText }}</mat-hint>
25
28
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
26
29
  </mat-form-field>
27
30
  </div>
@@ -7,6 +7,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
7
7
  import isEqual from 'fast-deep-equal';
8
8
 
9
9
  import { FieldBase } from '@pega/angular-sdk-components';
10
+ import { FieldWarningDirective } from '@pega/angular-sdk-components';
10
11
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
11
12
  import { handleEvent } from '@pega/angular-sdk-components';
12
13
  import { PConnFieldProps } from '@pega/angular-sdk-components';
@@ -66,7 +67,15 @@ interface DropdownProps extends PConnFieldProps {
66
67
  selector: 'app-dropdown',
67
68
  templateUrl: './dropdown.component.html',
68
69
  styleUrls: ['./dropdown.component.scss'],
69
- imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatSelectModule, MatOptionModule, forwardRef(() => ComponentMapperComponent)]
70
+ imports: [
71
+ CommonModule,
72
+ ReactiveFormsModule,
73
+ MatFormFieldModule,
74
+ MatSelectModule,
75
+ MatOptionModule,
76
+ FieldWarningDirective,
77
+ forwardRef(() => ComponentMapperComponent)
78
+ ]
70
79
  })
71
80
  export class DropdownComponent extends FieldBase implements OnInit, OnDestroy {
72
81
  @Output() onRecordChange: EventEmitter<any> = new EventEmitter();
@@ -80,13 +89,14 @@ export class DropdownComponent extends FieldBase implements OnInit, OnDestroy {
80
89
  localeName = '';
81
90
  localePath = '';
82
91
  localizedValue = '';
92
+ placeholderText = '';
83
93
 
84
94
  set options(options: IOption[]) {
85
95
  this.options$ = options;
86
96
  if (this.displayMode$) {
87
97
  this.value$ = this.options$?.find(option => option.key === this.value$)?.value || this.value$;
88
98
  this.localizedValue = this.pConn$.getLocalizedValue(
89
- this.value$ === 'Select...' ? '' : this.value$,
99
+ this.value$,
90
100
  this.localePath,
91
101
  this.pConn$.getLocaleRuleNameFromKeys(this.localeClass, this.localeContext, this.localeName)
92
102
  );
@@ -115,20 +125,15 @@ export class DropdownComponent extends FieldBase implements OnInit, OnDestroy {
115
125
  const { value, fieldMetadata, datasource } = configProps;
116
126
 
117
127
  this.value$ = value;
128
+ this.placeholderText = this.pConn$.getLocalizedValue(this.placeholder || 'Select...', '', '');
118
129
 
119
130
  if (!isEqual(datasource, this.theDatasource)) {
120
131
  // inbound datasource is different, so update theDatasource
121
132
  this.theDatasource = datasource || null;
122
133
  }
123
134
 
124
- if (this.value$ === '' && !this.bReadonly$) {
125
- this.value$ = 'Select';
126
- }
127
-
128
135
  if (this.theDatasource) {
129
- const optionsList = [...this.utils.getOptionList(this.configProps$, this.pConn$.getDataObject())];
130
- optionsList?.unshift({ key: 'Select', value: this.pConn$.getLocalizedValue('Select...', '', '') });
131
- this.options = optionsList;
136
+ this.options = this.utils.getOptionList(this.configProps$, this.pConn$.getDataObject());
132
137
  }
133
138
 
134
139
  this.actionsApi = this.pConn$.getActionsApi();
@@ -215,27 +220,21 @@ export class DropdownComponent extends FieldBase implements OnInit, OnDestroy {
215
220
  };
216
221
  optionsData.push(obj);
217
222
  });
218
- optionsData?.unshift({ key: 'Select', value: this.pConn$.getLocalizedValue('Select...', '', '') });
219
223
  this.options = optionsData;
220
224
  });
221
225
  });
222
226
  }
223
227
 
224
- isSelected(buttonValue: string): boolean {
225
- return this.value$ === buttonValue;
226
- }
227
-
228
228
  fieldOnChange(event: any) {
229
- if (event?.value === 'Select') {
230
- event.value = '';
231
- }
232
- handleEvent(this.actionsApi, 'changeNblur', this.propName, event.value);
229
+ // The reset option has no value; Pega expects '' for a cleared field
230
+ const value = event.value ?? '';
231
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
233
232
 
234
233
  this.pConn$.clearErrorMessages({
235
234
  property: this.propName
236
235
  });
237
236
  if (this.onRecordChange) {
238
- this.onRecordChange.emit(event.value);
237
+ this.onRecordChange.emit(value);
239
238
  }
240
239
  }
241
240
 
@@ -4,7 +4,7 @@
4
4
  <ng-template #noDisplayMode>
5
5
  <div *ngIf="!bReadonly$ && bHasForm$; else noEdit">
6
6
  <div [formGroup]="formGroup$" *ngIf="bVisible$">
7
- <mat-form-field class="psdk-full-width" subscriptSizing="dynamic" [hintLabel]="helperText">
7
+ <mat-form-field class="psdk-full-width" subscriptSizing="dynamic">
8
8
  <mat-label>{{ label$ }}</mat-label>
9
9
  <input
10
10
  matInput
@@ -17,6 +17,7 @@
17
17
  (change)="fieldOnChange($event)"
18
18
  (blur)="fieldOnBlur($event)"
19
19
  />
20
+ <mat-hint *ngIf="helperText" [appFieldWarning]="bFieldMessageVisible$">{{ helperText }}</mat-hint>
20
21
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
21
22
  </mat-form-field>
22
23
  </div>
@@ -5,6 +5,7 @@ import { MatInputModule } from '@angular/material/input';
5
5
  import { MatFormFieldModule } from '@angular/material/form-field';
6
6
 
7
7
  import { FieldBase } from '@pega/angular-sdk-components';
8
+ import { FieldWarningDirective } from '@pega/angular-sdk-components';
8
9
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
9
10
  import { handleEvent } from '@pega/angular-sdk-components';
10
11
  import { PConnFieldProps } from '@pega/angular-sdk-components';
@@ -17,7 +18,7 @@ interface EmailProps extends PConnFieldProps {
17
18
  selector: 'app-email',
18
19
  templateUrl: './email.component.html',
19
20
  styleUrls: ['./email.component.scss'],
20
- imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, forwardRef(() => ComponentMapperComponent)]
21
+ imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, FieldWarningDirective, forwardRef(() => ComponentMapperComponent)]
21
22
  })
22
23
  export class EmailComponent extends FieldBase implements OnInit, OnDestroy {
23
24
  configProps$: EmailProps;
@@ -28,7 +29,6 @@ export class EmailComponent extends FieldBase implements OnInit, OnDestroy {
28
29
  override updateSelf(): void {
29
30
  // Resolve configuration properties
30
31
  this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as EmailProps;
31
-
32
32
  // Update component common properties
33
33
  this.updateComponentCommonProperties(this.configProps$);
34
34
 
@@ -0,0 +1,3 @@
1
+ <div *ngIf="bVisible$ && simpleTableComponentName">
2
+ <component-mapper [name]="simpleTableComponentName" [props]="{ pConn$: simpleTablePConn, formGroup$ }"></component-mapper>
3
+ </div>
@@ -0,0 +1,173 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, Input, OnInit, OnDestroy, forwardRef } from '@angular/core';
3
+ import { FormGroup } from '@angular/forms';
4
+
5
+ import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
6
+ import { ComponentMapperComponent } from '@pega/angular-sdk-components';
7
+
8
+ interface EmbeddedDataMultiProps {
9
+ addEditAction?: string;
10
+ addEditView?: string;
11
+ displayAs?: string;
12
+ editAction?: string;
13
+ editMode?: string;
14
+ editType?: string;
15
+ editView?: string;
16
+ readOnly?: boolean;
17
+ repeatingView?: string;
18
+ targetObjectClass?: string;
19
+ useSeparateActionForEdit?: boolean;
20
+ useSeparateViewForEdit?: boolean;
21
+ visibility?: boolean;
22
+ }
23
+
24
+ @Component({
25
+ selector: 'app-embedded-data-multi',
26
+ templateUrl: './embedded-data-multi.component.html',
27
+ styleUrls: ['./embedded-data-multi.component.scss'],
28
+ imports: [CommonModule, forwardRef(() => ComponentMapperComponent)]
29
+ })
30
+ export class EmbeddedDataMultiComponent implements OnInit, OnDestroy {
31
+ @Input() pConn$: typeof PConnect;
32
+ @Input() formGroup$: FormGroup;
33
+
34
+ angularPConnectData: AngularPConnectData = {};
35
+ simpleTablePConn: typeof PConnect;
36
+ simpleTableComponentName = '';
37
+ bVisible$ = true;
38
+
39
+ constructor(private angularPConnect: AngularPConnectService) {}
40
+
41
+ ngOnInit(): void {
42
+ this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
43
+ this.checkAndUpdate();
44
+ }
45
+
46
+ ngOnDestroy(): void {
47
+ if (this.angularPConnectData.unsubscribeFn) {
48
+ this.angularPConnectData.unsubscribeFn();
49
+ }
50
+ }
51
+
52
+ onStateChange = () => {
53
+ this.checkAndUpdate();
54
+ };
55
+
56
+ checkAndUpdate() {
57
+ const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
58
+ if (bUpdateSelf) {
59
+ this.updateSelf();
60
+ }
61
+ }
62
+
63
+ updateSelf() {
64
+ const configProps = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as EmbeddedDataMultiProps;
65
+ const {
66
+ addEditAction,
67
+ addEditView,
68
+ displayAs,
69
+ editAction,
70
+ editMode,
71
+ editType,
72
+ editView,
73
+ readOnly = false,
74
+ repeatingView,
75
+ targetObjectClass,
76
+ useSeparateActionForEdit,
77
+ useSeparateViewForEdit,
78
+ visibility = true
79
+ } = configProps;
80
+
81
+ this.bVisible$ = visibility !== false;
82
+
83
+ const rawMetadata = this.pConn$.getRawMetadata();
84
+ const rawMetadataConfig = rawMetadata?.config as any;
85
+
86
+ if (!rawMetadataConfig) {
87
+ return;
88
+ }
89
+
90
+ const renderMode = readOnly ? 'ReadOnly' : 'Editable';
91
+
92
+ let columnsChildren;
93
+ if (displayAs === 'table' || displayAs === 'simpleTable') {
94
+ columnsChildren = [
95
+ {
96
+ children: rawMetadataConfig.columns || [],
97
+ name: 'Columns',
98
+ type: 'Region'
99
+ }
100
+ ];
101
+ }
102
+
103
+ let regionWithView: any[] = [];
104
+ if (displayAs === 'repeatingView') {
105
+ regionWithView = [
106
+ {
107
+ children: [
108
+ {
109
+ type: 'reference',
110
+ config: {
111
+ type: 'view',
112
+ name: repeatingView
113
+ }
114
+ }
115
+ ],
116
+ name: 'view',
117
+ type: 'Region'
118
+ }
119
+ ];
120
+ }
121
+
122
+ const { pagelistValue } = rawMetadataConfig;
123
+ const authorContext = pagelistValue?.startsWith('@P') ? pagelistValue?.substring(3) : pagelistValue;
124
+
125
+ const componentConfig = {
126
+ type: 'View',
127
+ config: {
128
+ template: 'SimpleTable',
129
+ type: 'multirecordlist',
130
+ authorContext,
131
+ name: authorContext?.substring(1),
132
+ renderMode,
133
+ multiRecordDisplayAs: displayAs === 'repeatingView' ? 'fieldGroup' : displayAs,
134
+ referenceList: pagelistValue,
135
+ contextClass: targetObjectClass,
136
+ editMode,
137
+ editModeConfig: {
138
+ editType,
139
+ defaultView: addEditView,
140
+ defaultAction: addEditAction,
141
+ useSeparateViewForEdit,
142
+ useSeparateActionForEdit,
143
+ editView,
144
+ editAction
145
+ },
146
+ label: rawMetadataConfig.label,
147
+ hideLabel: rawMetadataConfig.hideLabel,
148
+ children: columnsChildren,
149
+ displayField: rawMetadataConfig.displayField,
150
+ uniqueField: rawMetadataConfig.uniqueField,
151
+ targetClassLabel: rawMetadataConfig.targetClassLabel,
152
+ targetClassLabelOption: rawMetadataConfig.targetClassLabelOption,
153
+ fieldHeader: rawMetadataConfig.repeatingViewHeadingSource,
154
+ heading: rawMetadataConfig.repeatingViewHeading,
155
+ allowActions: {
156
+ allowAdd: rawMetadataConfig.allowAdd ?? true,
157
+ allowEdit: rawMetadataConfig.allowEdit ?? true,
158
+ allowDelete: rawMetadataConfig.allowDelete ?? true,
159
+ allowDragDrop: rawMetadataConfig.allowDragDrop ?? true
160
+ },
161
+ allowRowDelete: rawMetadataConfig.allowRowDelete ?? true,
162
+ allowRowEdit: rawMetadataConfig.allowRowEdit ?? true
163
+ },
164
+ children: regionWithView
165
+ };
166
+
167
+ const component = this.pConn$.createComponent(componentConfig as any, '', 0, {});
168
+ if (component) {
169
+ this.simpleTablePConn = component.getPConnect();
170
+ this.simpleTableComponentName = this.simpleTablePConn.getComponentName() ?? '';
171
+ }
172
+ }
173
+ }
@@ -3,6 +3,7 @@ import { FormControl, FormGroup } from '@angular/forms';
3
3
 
4
4
  import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
5
5
  import { Utils } from '@pega/angular-sdk-components';
6
+ import type { PConnFieldProps } from '@pega/angular-sdk-components';
6
7
 
7
8
  @Directive()
8
9
  export class FieldBase implements OnInit, OnDestroy {
@@ -31,6 +32,10 @@ export class FieldBase implements OnInit, OnDestroy {
31
32
  bDisabled$ = false;
32
33
  bVisible$ = true;
33
34
  displayMode$ = '';
35
+ bFieldMessageVisible$ = false;
36
+ fieldMessage = '';
37
+
38
+ private defaultHelperText = '';
34
39
 
35
40
  /**
36
41
  * Initializes the component, registers with AngularPConnect, and sets up form control.
@@ -101,7 +106,7 @@ export class FieldBase implements OnInit, OnDestroy {
101
106
  this.label$ = label;
102
107
  this.hideLabel = hideLabel;
103
108
  this.displayMode$ = displayMode;
104
- this.helperText = helperText;
109
+ this.defaultHelperText = helperText ?? '';
105
110
  this.placeholder = placeholder || '';
106
111
 
107
112
  // Convert boolean properties
@@ -113,10 +118,27 @@ export class FieldBase implements OnInit, OnDestroy {
113
118
  // Enable or disable field control
114
119
  this.fieldControl[this.bDisabled$ ? 'disable' : 'enable']();
115
120
 
121
+ this.updateFieldMessage(configProps);
122
+
116
123
  // Display error message if validation message exists
117
124
  this.displayValidationMessage();
118
125
  }
119
126
 
127
+ /**
128
+ * Updates the contextual field message state for fields that support it.
129
+ *
130
+ * @param configProps The resolved field configuration.
131
+ */
132
+ protected updateFieldMessage(configProps: Pick<PConnFieldProps, 'messageConfig' | 'showFieldMessage'>): void {
133
+ const { messageConfig = {}, showFieldMessage } = configProps;
134
+ const isVisible = this.utils.getBooleanValue(messageConfig.visibility);
135
+ const shouldShowFieldMessage = this.utils.getBooleanValue(showFieldMessage) && isVisible && !this.bReadonly$;
136
+
137
+ this.bFieldMessageVisible$ = shouldShowFieldMessage;
138
+ this.fieldMessage = shouldShowFieldMessage ? (messageConfig.content ?? '') : '';
139
+ this.updateHelperText();
140
+ }
141
+
120
142
  /**
121
143
  * Displays the validation message if it exists.
122
144
  */
@@ -129,6 +151,10 @@ export class FieldBase implements OnInit, OnDestroy {
129
151
  }
130
152
  }
131
153
 
154
+ private updateHelperText(): void {
155
+ this.helperText = this.bFieldMessageVisible$ ? this.fieldMessage : this.defaultHelperText;
156
+ }
157
+
132
158
  /**
133
159
  * Retrieves the error message for the current field control.
134
160
  *
@@ -3,7 +3,7 @@
3
3
  name="FieldGroup"
4
4
  [props]="{
5
5
  name: showHeading$ ? heading$ : undefined,
6
- collapsible: collapsible$,
6
+ collapseOnLoad: configProps$.collapseOnLoad,
7
7
  instructions: instructions$,
8
8
  childrenTemplate: childrenTemplate
9
9
  }"