@pega/angular-sdk-overrides 23.1.10 → 24.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 (85) hide show
  1. package/lib/designSystemExtension/material-case-summary/material-case-summary.component.html +7 -4
  2. package/lib/designSystemExtension/material-case-summary/material-case-summary.component.ts +3 -1
  3. package/lib/designSystemExtension/material-vertical-tabs/material-vertical-tabs.component.html +1 -1
  4. package/lib/designSystemExtension/operator/operator.component.ts +10 -5
  5. package/lib/field/auto-complete/auto-complete.component.ts +1 -1
  6. package/lib/field/cancel-alert/cancel-alert.component.ts +0 -2
  7. package/lib/field/check-box/check-box.component.html +16 -15
  8. package/lib/field/check-box/check-box.component.scss +14 -1
  9. package/lib/field/check-box/check-box.component.ts +126 -44
  10. package/lib/field/currency/currency.component.html +15 -6
  11. package/lib/field/currency/currency.component.ts +36 -18
  12. package/lib/field/date-time/date-time.component.html +5 -5
  13. package/lib/field/date-time/date-time.component.ts +15 -37
  14. package/lib/field/decimal/decimal.component.html +14 -4
  15. package/lib/field/decimal/decimal.component.ts +42 -5
  16. package/lib/field/dropdown/dropdown.component.ts +0 -3
  17. package/lib/field/group/group.component.html +1 -1
  18. package/lib/field/group/group.component.ts +4 -0
  19. package/lib/field/multiselect/multiselect.component.html +33 -0
  20. package/lib/field/multiselect/multiselect.component.scss +7 -0
  21. package/lib/field/multiselect/multiselect.component.spec.ts +21 -0
  22. package/lib/field/multiselect/multiselect.component.ts +359 -0
  23. package/lib/field/multiselect/utils.ts +209 -0
  24. package/lib/field/percentage/percentage.component.html +15 -4
  25. package/lib/field/percentage/percentage.component.ts +29 -5
  26. package/lib/field/radio-buttons/radio-buttons.component.ts +0 -3
  27. package/lib/field/rich-text/config-ext.json +10 -0
  28. package/lib/field/rich-text/rich-text.component.html +1 -1
  29. package/lib/field/scalar-list/scalar-list.component.ts +2 -1
  30. package/lib/field/text-area/text-area.component.ts +0 -2
  31. package/lib/field/time/time.component.html +1 -0
  32. package/lib/field/time/time.component.ts +2 -0
  33. package/lib/field/url/url.component.html +1 -0
  34. package/lib/field/url/url.component.ts +2 -0
  35. package/lib/field/user-reference/user-reference.component.html +50 -45
  36. package/lib/field/user-reference/user-reference.component.ts +33 -15
  37. package/lib/infra/Containers/base-components/flow-container-base.component.ts +22 -0
  38. package/lib/infra/Containers/base-components/helper.ts +89 -0
  39. package/lib/infra/Containers/flow-container/flow-container.component.html +8 -3
  40. package/lib/infra/Containers/flow-container/flow-container.component.ts +30 -29
  41. package/lib/infra/Containers/modal-view-container/modal-view-container.component.ts +40 -8
  42. package/lib/infra/Containers/view-container/view-container.component.ts +0 -1
  43. package/lib/infra/assignment/assignment.component.ts +38 -39
  44. package/lib/infra/dashboard-filter/dashboard-filter.component.ts +0 -1
  45. package/lib/infra/defer-load/defer-load.component.ts +5 -8
  46. package/lib/infra/multi-step/multi-step.component.html +1 -1
  47. package/lib/infra/multi-step/multi-step.component.scss +1 -0
  48. package/lib/infra/navbar/navbar.component.html +4 -4
  49. package/lib/infra/navbar/navbar.component.ts +6 -3
  50. package/lib/infra/view/view.component.ts +1 -1
  51. package/lib/template/banner-page/config-ext.json +9 -0
  52. package/lib/template/case-summary/case-summary.component.ts +37 -3
  53. package/lib/template/case-view/case-view.component.html +3 -3
  54. package/lib/template/case-view/case-view.component.scss +2 -0
  55. package/lib/template/case-view/case-view.component.ts +0 -6
  56. package/lib/template/data-reference/data-reference.component.ts +1 -3
  57. package/lib/template/dynamic-tabs/dynamic-tabs.component.ts +0 -1
  58. package/lib/template/field-group-template/field-group-template.component.ts +4 -12
  59. package/lib/template/field-value-list/field-value-list.component.html +7 -2
  60. package/lib/template/field-value-list/field-value-list.component.ts +1 -0
  61. package/lib/template/inline-dashboard-page/config-ext.json +9 -0
  62. package/lib/template/list-view/list-view.component.html +6 -6
  63. package/lib/template/list-view/list-view.component.ts +36 -28
  64. package/lib/template/list-view/listViewHelpers.ts +0 -1
  65. package/lib/template/repeating-structures/repeating-structures.component.ts +1 -2
  66. package/lib/template/simple-table/simple-table.component.ts +0 -2
  67. package/lib/template/simple-table-manual/helpers.ts +1 -1
  68. package/lib/template/simple-table-manual/simple-table-manual.component.html +1 -1
  69. package/lib/template/simple-table-manual/simple-table-manual.component.ts +49 -19
  70. package/lib/template/simple-table-select/simple-table-select.component.ts +2 -4
  71. package/lib/template/wss-nav-bar/wss-nav-bar.component.html +1 -1
  72. package/lib/template/wss-nav-bar/wss-nav-bar.component.ts +2 -1
  73. package/lib/widget/attachment/attachment.component.html +50 -26
  74. package/lib/widget/attachment/attachment.component.scss +118 -0
  75. package/lib/widget/attachment/attachment.component.ts +256 -501
  76. package/lib/widget/case-history/case-history.component.ts +1 -2
  77. package/lib/widget/feed-container/feed-container.component.ts +0 -4
  78. package/lib/widget/file-utility/file-utility.component.html +2 -2
  79. package/lib/widget/file-utility/file-utility.component.ts +13 -17
  80. package/lib/widget/list-utility/list-utility.component.html +1 -1
  81. package/lib/widget/quick-create/config-ext.json +9 -0
  82. package/lib/widget/quick-create/quick-create.component.ts +1 -1
  83. package/lib/widget/todo/todo.component.html +6 -5
  84. package/lib/widget/todo/todo.component.ts +7 -6
  85. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
  <dl class="psdk-case-summary-fields-primary">
3
3
  <div *ngFor="let field of primaryFieldsWithStatus$" class="psdk-csf-primary-field">
4
4
  <dt class="psdk-csf-primary-field-header">
5
- {{ field.config.label }}
5
+ {{ field.config?.label }}
6
6
  </dt>
7
7
  <dd *ngIf="field.config.value === ''; else hasValue" class="psdk-csf-primary-field-data">
8
8
  <ng-container [ngSwitch]="field.type.toLowerCase()">
@@ -28,16 +28,19 @@
28
28
  <dl *ngFor="let field of secondaryFields$" class="psdk-case-summary-fields-secondary">
29
29
  <div
30
30
  *ngIf="
31
- field.config?.label?.toLowerCase() == 'create operator' || field.config?.label?.toLowerCase() == 'update operator';
31
+ field?.config?.label?.toLowerCase() == 'create operator' ||
32
+ field?.displayLabel?.toLowerCase() == 'create operator' ||
33
+ field?.config?.label?.toLowerCase() == 'update operator' ||
34
+ field?.displayLabel?.toLowerCase() == 'update operator';
32
35
  else hasSecondaryValue
33
36
  "
34
37
  >
35
- <component-mapper name="Operator" [props]="{ pConn$: field?.kid }"></component-mapper>
38
+ <component-mapper name="Operator" [props]="{ pConn$: field?.kid, displayLabel: field?.displayLabel }"></component-mapper>
36
39
  </div>
37
40
  <ng-template #hasSecondaryValue>
38
41
  <div class="psdk-csf-secondary-field">
39
42
  <dt class="psdk-csf-secondary-field-header">
40
- {{ field.config.displayLabel || field.config.label }}
43
+ {{ field.config?.displayLabel || field.config?.label }}
41
44
  </dt>
42
45
  <dd class="psdk-csf-secondary-field-data">
43
46
  <div [ngSwitch]="field.type">
@@ -19,7 +19,8 @@ export class MaterialCaseSummaryComponent implements OnInit, OnChanges {
19
19
  primaryFieldsWithStatus$: any[];
20
20
 
21
21
  constructor(private utils: Utils) {}
22
-
22
+ localizedVal = PCore.getLocaleUtils().getLocaleValue;
23
+ localeCategory = 'ModalContainer';
23
24
  ngOnInit(): void {
24
25
  this.updatePrimaryWithStatus();
25
26
  this.updateLabelAndDate(this.primaryFieldsWithStatus$);
@@ -63,6 +64,7 @@ export class MaterialCaseSummaryComponent implements OnInit, OnChanges {
63
64
  updatePrimaryWithStatus() {
64
65
  this.primaryFieldsWithStatus$ = [];
65
66
  for (const prim of this.primaryFields$) {
67
+ prim.config.value = this.localizedVal(prim.config.value, this.localeCategory);
66
68
  this.primaryFieldsWithStatus$.push(prim);
67
69
  }
68
70
 
@@ -1,5 +1,5 @@
1
1
  <div>
2
- <mat-button-toggle-group vertical (change)="onChange($event.value)" [value]="selectedTabId$" aria-label="Tabs">
2
+ <mat-button-toggle-group vertical hideSingleSelectionIndicator (change)="onChange($event.value)" [value]="selectedTabId$" aria-label="Tabs">
3
3
  <mat-button-toggle *ngFor="let tab of tabConfig$" [value]="tab.id" style="text-align: left">
4
4
  <div style="display: flex">
5
5
  <div style="flex-grow: 10">{{ tab.name }}</div>
@@ -12,7 +12,7 @@ import { Utils } from '@pega/angular-sdk-components';
12
12
  })
13
13
  export class OperatorComponent implements OnInit, OnChanges, OnDestroy {
14
14
  @Input() pConn$: typeof PConnect;
15
-
15
+ @Input() displayLabel;
16
16
  fields$: any[] = [];
17
17
  bShowPopover$: boolean;
18
18
  date$: string;
@@ -45,21 +45,26 @@ export class OperatorComponent implements OnInit, OnChanges, OnDestroy {
45
45
  }
46
46
  }
47
47
 
48
+ // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method
48
49
  ngOnDestroy(): void {
49
- this.renderer.destroy();
50
+ // Ref: https://medium.com/@kamil.galek/mythical-angular-component-styles-cleanup-in-angular-17-f799a08b2abc
51
+ // Commenting the below line as it is causing the Operator component's styles not getting applied.
52
+ // this.renderer.destroy();
50
53
  }
51
54
 
52
55
  updateSelf(): void {
53
56
  const configProps$ = this.pConn$.getConfigProps() as any;
54
- if (configProps$?.label?.toLowerCase() == 'create operator') {
57
+ this.displayLabel = this.displayLabel?.toLowerCase();
58
+ const label = configProps$?.label?.toLowerCase();
59
+ if (label === 'create operator' || this.displayLabel === 'create operator') {
55
60
  this.name$ = configProps$.createOperator.userName;
56
61
  this.id$ = configProps$.createOperator.userId;
57
62
  this.label$ = configProps$.createLabel;
58
- } else if (configProps$?.label?.toLowerCase() == 'update operator') {
63
+ } else if (label === 'update operator' || this.displayLabel === 'update operator') {
59
64
  this.name$ = configProps$.updateOperator.userName;
60
65
  this.id$ = configProps$.updateOperator.userId;
61
66
  this.label$ = configProps$.updateLabel;
62
- } else if (configProps$?.label?.toLowerCase() == 'resolve operator') {
67
+ } else if (label === 'resolve operator' || this.displayLabel === 'resolve operator') {
63
68
  this.name$ = configProps$.resolveOperator.userName;
64
69
  this.id$ = configProps$.resolveOperator.userId;
65
70
  this.label$ = configProps$.resolveLabel;
@@ -118,7 +118,7 @@ export class AutoCompleteComponent implements OnInit, OnDestroy {
118
118
 
119
119
  private _filter(value: string): string[] {
120
120
  const filterVal = (value || this.filterValue).toLowerCase();
121
- return this.options$?.filter(option => option.value.toLowerCase().includes(filterVal));
121
+ return this.options$?.filter(option => option.value?.toLowerCase().includes(filterVal));
122
122
  }
123
123
 
124
124
  // Callback passed when subscribing to store change
@@ -71,7 +71,6 @@ export class CancelAlertComponent implements OnChanges {
71
71
  this.psService.sendMessage(false);
72
72
  this.dismissAlert();
73
73
 
74
- // @ts-ignore - second parameter “payload” for publish method should be optional
75
74
  PCore.getPubSubUtils().publish(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.CASE_CREATED);
76
75
  })
77
76
  .catch(() => {
@@ -92,7 +91,6 @@ export class CancelAlertComponent implements OnChanges {
92
91
  .then(() => {
93
92
  this.psService.sendMessage(false);
94
93
  this.dismissAlert();
95
- // @ts-ignore - second parameter “payload” for publish method should be optional
96
94
  PCore.getPubSubUtils().publish(PCore.getConstants().PUB_SUB_EVENTS.EVENT_CANCEL);
97
95
  })
98
96
  .catch(() => {
@@ -6,36 +6,37 @@
6
6
  ></component-mapper>
7
7
  </div>
8
8
  <ng-template #noDisplayMode>
9
- <div *ngIf="!bReadonly$ && bHasForm$; else noEdit">
9
+ <div *ngIf="bHasForm$; else noEdit">
10
10
  <div [formGroup]="formGroup$" *ngIf="bVisible$">
11
11
  <div class="mat-form-field-infix" *ngIf="showLabel$">
12
12
  <span>
13
13
  <label class="mat-form-field-label psdk-label-readonly">{{ label$ }}</label>
14
14
  </span>
15
- <mat-checkbox
16
- [labelPosition]="'after'"
17
- [checked]="isChecked$"
18
- [disabled]="bDisabled$"
19
- [attr.data-test-id]="testId"
20
- [formControl]="fieldControl"
21
- (change)="fieldOnChange($event)"
22
- (blur)="fieldOnBlur($event)"
23
- >{{ caption$ }}</mat-checkbox
24
- >
25
15
  </div>
26
- <div class="mat-form-field-infix" *ngIf="!bReadonly$ && !showLabel$">
16
+ <div *ngIf="selectionMode === 'multi'; else single">
17
+ <mat-option *ngFor="let item of listOfCheckboxes" (click)="handleChangeMultiMode($event, item)">
18
+ <mat-checkbox
19
+ [labelPosition]="'after'"
20
+ [checked]="item.selected"
21
+ [attr.data-test-id]="testId + ':' + item.value"
22
+ (change)="handleChangeMultiMode($event, item)"
23
+ (blur)="fieldOnBlur($event)"
24
+ >{{ item.text ?? item.value }}
25
+ </mat-checkbox>
26
+ </mat-option>
27
+ </div>
28
+ <ng-template #single>
27
29
  <mat-checkbox
28
30
  [labelPosition]="'after'"
29
31
  [checked]="isChecked$"
30
- [disabled]="bDisabled$"
31
32
  [attr.data-test-id]="testId"
32
33
  [formControl]="fieldControl"
33
34
  (change)="fieldOnChange($event)"
34
35
  (blur)="fieldOnBlur($event)"
35
36
  >{{ caption$ }}</mat-checkbox
36
37
  >
37
- </div>
38
- <mat-hint *ngIf="helperText">{{ helperText }}</mat-hint>
38
+ <p *ngIf="helperText">{{ helperText }}</p>
39
+ </ng-template>
39
40
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
40
41
  </div>
41
42
  </div>
@@ -8,10 +8,10 @@
8
8
  top: 0rem;
9
9
  margin-top: 0.625rem;
10
10
  font-size: 0.875rem;
11
- display: block;
12
11
  transform: translateY(-1.28125em) scale(0.75) perspective(100px) translateZ(0.001px);
13
12
  -ms-transform: translateY(-1.28125em) scale(0.75);
14
13
  width: 133.33333%;
14
+ color: rgba(0, 0, 0, 0.6);
15
15
  }
16
16
 
17
17
  .psdk-data-readonly {
@@ -22,3 +22,16 @@
22
22
  ::ng-deep .mat-mdc-form-field-infix {
23
23
  width: auto;
24
24
  }
25
+
26
+ p {
27
+ font-size: 0.75rem;
28
+ color: rgba(0, 0, 0, 0.58);
29
+ }
30
+
31
+ mat-checkbox {
32
+ margin-left: -11px;
33
+ }
34
+
35
+ .mat-mdc-option {
36
+ margin-left: -16px;
37
+ }
@@ -3,10 +3,14 @@ import { CommonModule } from '@angular/common';
3
3
  import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
4
4
  import { MatCheckboxModule } from '@angular/material/checkbox';
5
5
  import { MatFormFieldModule } from '@angular/material/form-field';
6
+ import { MatOptionModule } from '@angular/material/core';
7
+ import { interval } from 'rxjs';
6
8
  import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
7
9
  import { Utils } from '@pega/angular-sdk-components';
8
10
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
9
11
  import { PConnFieldProps } from '@pega/angular-sdk-components';
12
+ import { deleteInstruction, insertInstruction, updateNewInstructions } from '@pega/angular-sdk-components';
13
+ import { handleEvent } from '@pega/angular-sdk-components';
10
14
 
11
15
  interface CheckboxProps extends Omit<PConnFieldProps, 'value'> {
12
16
  // If any, enter additional props that only exist on Checkbox here
@@ -15,6 +19,13 @@ interface CheckboxProps extends Omit<PConnFieldProps, 'value'> {
15
19
  caption?: string;
16
20
  trueLabel?: string;
17
21
  falseLabel?: string;
22
+ selectionMode?: string;
23
+ datasource?: any;
24
+ selectionKey?: string;
25
+ selectionList?: any;
26
+ primaryField: string;
27
+ readonlyContextList: any;
28
+ referenceList: string;
18
29
  }
19
30
 
20
31
  @Component({
@@ -22,7 +33,7 @@ interface CheckboxProps extends Omit<PConnFieldProps, 'value'> {
22
33
  templateUrl: './check-box.component.html',
23
34
  styleUrls: ['./check-box.component.scss'],
24
35
  standalone: true,
25
- imports: [CommonModule, ReactiveFormsModule, MatCheckboxModule, MatFormFieldModule, forwardRef(() => ComponentMapperComponent)]
36
+ imports: [CommonModule, ReactiveFormsModule, MatCheckboxModule, MatFormFieldModule, MatOptionModule, forwardRef(() => ComponentMapperComponent)]
26
37
  })
27
38
  export class CheckBoxComponent implements OnInit, OnDestroy {
28
39
  @Input() pConn$: typeof PConnect;
@@ -50,6 +61,17 @@ export class CheckBoxComponent implements OnInit, OnDestroy {
50
61
  trueLabel$?: string;
51
62
  falseLabel$?: string;
52
63
 
64
+ selectionMode?: string;
65
+ datasource?: any;
66
+ selectionKey?: string;
67
+ selectionList?: any;
68
+ primaryField: string;
69
+ selectedvalues: any;
70
+ referenceList: string;
71
+ listOfCheckboxes: any[] = [];
72
+ actionsApi: any;
73
+ propName: any;
74
+
53
75
  fieldControl = new FormControl('', null);
54
76
 
55
77
  constructor(
@@ -69,6 +91,11 @@ export class CheckBoxComponent implements OnInit, OnDestroy {
69
91
  // this.updateSelf();
70
92
  this.checkAndUpdate();
71
93
 
94
+ if (this.selectionMode === 'multi' && this.referenceList?.length > 0) {
95
+ this.pConn$.setReferenceList(this.selectionList);
96
+ updateNewInstructions(this.pConn$, this.selectionList);
97
+ }
98
+
72
99
  if (this.formGroup$) {
73
100
  // add control to formGroup
74
101
  this.formGroup$.addControl(this.controlName$, this.fieldControl);
@@ -111,68 +138,123 @@ export class CheckBoxComponent implements OnInit, OnDestroy {
111
138
  // moved this from ngOnInit() and call this from there instead...
112
139
  this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as CheckboxProps;
113
140
 
114
- if (this.configProps$.value != undefined) {
115
- this.value$ = this.configProps$.value;
116
- }
117
141
  this.testId = this.configProps$.testId;
118
- this.label$ = this.configProps$.label;
119
142
  this.displayMode$ = this.configProps$.displayMode;
143
+ this.label$ = this.configProps$.label;
144
+ if (this.label$ != '') {
145
+ this.showLabel$ = true;
146
+ }
120
147
 
121
- this.caption$ = this.configProps$.caption;
122
- this.helperText = this.configProps$.helperText;
123
- this.trueLabel$ = this.configProps$.trueLabel;
124
- this.falseLabel$ = this.configProps$.falseLabel;
125
-
126
- // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
127
- setTimeout(() => {
128
- if (this.configProps$.required != null) {
129
- this.bRequired$ = this.utils.getBooleanValue(this.configProps$.required);
148
+ this.actionsApi = this.pConn$.getActionsApi();
149
+ this.propName = (this.pConn$.getStateProps() as any).value;
150
+
151
+ // multi case
152
+ this.selectionMode = this.configProps$.selectionMode;
153
+ if (this.selectionMode === 'multi') {
154
+ this.referenceList = this.configProps$.referenceList;
155
+ this.selectionList = this.configProps$.selectionList;
156
+ this.selectedvalues = this.configProps$.readonlyContextList;
157
+ this.primaryField = this.configProps$.primaryField;
158
+
159
+ this.datasource = this.configProps$.datasource;
160
+ this.selectionKey = this.configProps$.selectionKey;
161
+ const listSourceItems = this.datasource?.source ?? [];
162
+ const dataField: any = this.selectionKey?.split?.('.')[1];
163
+ const listToDisplay: any[] = [];
164
+ listSourceItems.forEach(element => {
165
+ element.selected = this.selectedvalues?.some?.(data => data[dataField] === element.key);
166
+ listToDisplay.push(element);
167
+ });
168
+ this.listOfCheckboxes = listToDisplay;
169
+ } else {
170
+ if (this.configProps$.value != undefined) {
171
+ this.value$ = this.configProps$.value;
130
172
  }
131
- this.cdRef.detectChanges();
132
- });
133
-
134
- if (this.configProps$.visibility != null) {
135
- this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
136
- }
137
173
 
138
- // disabled
139
- if (this.configProps$.disabled != undefined) {
140
- this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
141
- }
174
+ this.caption$ = this.configProps$.caption;
175
+ this.helperText = this.configProps$.helperText;
176
+ this.trueLabel$ = this.configProps$.trueLabel;
177
+ this.falseLabel$ = this.configProps$.falseLabel;
178
+
179
+ // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
180
+ setTimeout(() => {
181
+ if (this.configProps$.required != null) {
182
+ this.bRequired$ = this.utils.getBooleanValue(this.configProps$.required);
183
+ }
184
+ this.cdRef.detectChanges();
185
+ });
186
+
187
+ if (this.configProps$.visibility != null) {
188
+ this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
189
+ }
142
190
 
143
- if (this.bDisabled$) {
144
- this.fieldControl.disable();
145
- } else {
146
- this.fieldControl.enable();
147
- }
191
+ // disabled
192
+ if (this.configProps$.disabled != undefined) {
193
+ this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
194
+ }
148
195
 
149
- if (this.configProps$.readOnly != null) {
150
- this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
151
- }
196
+ if (this.configProps$.readOnly != null) {
197
+ this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
198
+ }
152
199
 
153
- this.componentReference = (this.pConn$.getStateProps() as any).value;
200
+ if (this.bDisabled$ || this.bReadonly$) {
201
+ this.fieldControl.disable();
202
+ } else {
203
+ this.fieldControl.enable();
204
+ }
154
205
 
155
- if (this.label$ != '') {
156
- this.showLabel$ = true;
157
- }
206
+ this.componentReference = (this.pConn$.getStateProps() as any).value;
158
207
 
159
- // eslint-disable-next-line sonarjs/no-redundant-boolean
160
- if (this.value$ === 'true' || this.value$ == true) {
161
- this.isChecked$ = true;
162
- } else {
163
- this.isChecked$ = false;
208
+ // eslint-disable-next-line sonarjs/no-redundant-boolean
209
+ if (this.value$ === 'true' || this.value$ == true) {
210
+ this.isChecked$ = true;
211
+ } else {
212
+ this.isChecked$ = false;
213
+ }
214
+ // trigger display of error message with field control
215
+ if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
216
+ const timer = interval(100).subscribe(() => {
217
+ this.fieldControl.setErrors({ message: true });
218
+ this.fieldControl.markAsTouched();
219
+
220
+ timer.unsubscribe();
221
+ });
222
+ }
164
223
  }
165
224
  }
166
225
 
167
226
  fieldOnChange(event: any) {
168
227
  event.value = event.checked;
169
228
 
170
- this.angularPConnectData.actions?.onChange(this, event);
229
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, event.checked);
171
230
  }
172
231
 
173
232
  fieldOnBlur(event: any) {
174
- event.value = event.checked;
175
- this.angularPConnectData.actions?.onBlur(this, event);
233
+ if (this.selectionMode === 'multi') {
234
+ this.pConn$.getValidationApi().validate(this.selectedvalues, this.selectionList);
235
+ } else {
236
+ event.value = event.checked;
237
+ this.angularPConnectData.actions?.onBlur(this, event);
238
+ }
239
+ }
240
+
241
+ handleChangeMultiMode(event, element) {
242
+ if (!element.selected) {
243
+ insertInstruction(this.pConn$, this.selectionList, this.selectionKey, this.primaryField, {
244
+ id: element.key,
245
+ primary: element.text ?? element.value
246
+ });
247
+ } else {
248
+ deleteInstruction(this.pConn$, this.selectionList, this.selectionKey, {
249
+ id: element.key,
250
+ primary: element.text ?? element.value
251
+ });
252
+ }
253
+ this.pConn$.clearErrorMessages({
254
+ property: this.selectionList,
255
+ category: '',
256
+ context: ''
257
+ });
176
258
  }
177
259
 
178
260
  getErrorMessage() {
@@ -2,23 +2,32 @@
2
2
  <component-mapper *ngIf="bVisible$ !== false" name="FieldValueList" [props]="{ label$, value$, displayMode$ }"></component-mapper>
3
3
  </div>
4
4
  <ng-template #noDisplayMode>
5
- <div *ngIf="!bReadonly$ && bHasForm$; else noEdit">
5
+ <div *ngIf="bHasForm$; else noEdit">
6
6
  <div [formGroup]="formGroup$" *ngIf="bVisible$" class="psdk-currency-field">
7
7
  <mat-form-field class="psdk-full-width" subscriptSizing="dynamic" [hintLabel]="helperText">
8
8
  <mat-label>{{ label$ }}</mat-label>
9
9
  <div class="psdk-currency-input">
10
- <span>{{ symbol }}</span>
11
10
  <input
12
- style="margin-left: 5px"
13
- type="float"
11
+ style="margin-left: 5px; margin-top: -1rem"
12
+ type="text"
14
13
  matInput
14
+ currencyMask
15
+ [options]="{
16
+ prefix: currSym,
17
+ thousands: currSep,
18
+ decimal: currDec,
19
+ align: 'left',
20
+ nullable: true,
21
+ precision: decimalPrecision,
22
+ inputMode: inputMode
23
+ }"
15
24
  [placeholder]="placeholder"
16
- [value]="value$ | number: '1.2-2'"
25
+ [formControlName]="controlName$"
17
26
  [required]="bRequired$"
18
27
  [formControl]="fieldControl"
19
28
  [attr.data-test-id]="testId"
20
- (change)="fieldOnChange($event)"
21
29
  (blur)="fieldOnBlur($event)"
30
+ [readonly]="bReadonly$"
22
31
  />
23
32
  </div>
24
33
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
@@ -4,15 +4,18 @@ import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
4
4
  import { MatInputModule } from '@angular/material/input';
5
5
  import { MatFormFieldModule } from '@angular/material/form-field';
6
6
  import { interval } from 'rxjs';
7
+ import { NgxCurrencyDirective, NgxCurrencyInputMode } from 'ngx-currency';
7
8
  import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
8
9
  import { Utils } from '@pega/angular-sdk-components';
9
10
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
11
+ import { handleEvent } from '@pega/angular-sdk-components';
10
12
  import { getCurrencyCharacters } from '@pega/angular-sdk-components';
11
13
  import { PConnFieldProps } from '@pega/angular-sdk-components';
12
14
 
13
15
  interface CurrrencyProps extends PConnFieldProps {
14
16
  // If any, enter additional props that only exist on Currency here
15
17
  currencyISOCode?: string;
18
+ allowDecimals: boolean;
16
19
  }
17
20
 
18
21
  @Component({
@@ -20,7 +23,7 @@ interface CurrrencyProps extends PConnFieldProps {
20
23
  templateUrl: './currency.component.html',
21
24
  styleUrls: ['./currency.component.scss'],
22
25
  standalone: true,
23
- imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, forwardRef(() => ComponentMapperComponent)]
26
+ imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, NgxCurrencyDirective, forwardRef(() => ComponentMapperComponent)]
24
27
  })
25
28
  export class CurrencyComponent implements OnInit, OnDestroy {
26
29
  @Input() pConn$: typeof PConnect;
@@ -31,7 +34,7 @@ export class CurrencyComponent implements OnInit, OnDestroy {
31
34
  configProps$: CurrrencyProps;
32
35
 
33
36
  label$ = '';
34
- value$: number | null;
37
+ value$: any;
35
38
  bRequired$ = false;
36
39
  bReadonly$ = false;
37
40
  bDisabled$ = false;
@@ -47,9 +50,11 @@ export class CurrencyComponent implements OnInit, OnDestroy {
47
50
  currencyOptions: Object = {};
48
51
 
49
52
  fieldControl = new FormControl<number | null>(null, { updateOn: 'blur' });
50
- symbol: string;
51
- thousandsSep: string;
52
- decimalSep: string;
53
+ currSym: string;
54
+ currSep: string;
55
+ currDec: string;
56
+ inputMode: any;
57
+ decimalPrecision: number | undefined;
53
58
 
54
59
  constructor(
55
60
  private angularPConnect: AngularPConnectService,
@@ -114,10 +119,22 @@ export class CurrencyComponent implements OnInit, OnDestroy {
114
119
  this.testId = this.configProps$.testId;
115
120
  this.label$ = this.configProps$.label;
116
121
  this.displayMode$ = this.configProps$.displayMode;
117
- const nValue: any = this.configProps$.value;
118
- this.value$ = nValue && typeof nValue === 'string' ? parseFloat(nValue) : nValue;
122
+ this.inputMode = NgxCurrencyInputMode.Natural;
123
+ let nValue: any = this.configProps$.value;
124
+ if (nValue) {
125
+ if (typeof nValue === 'string') {
126
+ nValue = parseFloat(nValue);
127
+ }
128
+ this.value$ = nValue;
129
+ }
119
130
  this.helperText = this.configProps$.helperText;
120
131
  this.placeholder = this.configProps$.placeholder || '';
132
+ const currencyISOCode: any = this.configProps$?.currencyISOCode;
133
+
134
+ const theSymbols = getCurrencyCharacters(currencyISOCode);
135
+ this.currSym = theSymbols.theCurrencySymbol;
136
+ this.currSep = theSymbols.theDigitGroupSeparator;
137
+ this.currDec = theSymbols.theDecimalIndicator;
121
138
 
122
139
  // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
123
140
  setTimeout(() => {
@@ -150,10 +167,7 @@ export class CurrencyComponent implements OnInit, OnDestroy {
150
167
  this.currencyISOCode = this.configProps$.currencyISOCode;
151
168
  }
152
169
 
153
- const theSymbols = getCurrencyCharacters(this.currencyISOCode);
154
- this.symbol = theSymbols.theCurrencySymbol;
155
- this.thousandsSep = theSymbols.theDigitGroupSeparator;
156
- this.decimalSep = theSymbols.theDecimalIndicator;
170
+ this.decimalPrecision = this.configProps$?.allowDecimals ? 2 : 0;
157
171
 
158
172
  this.componentReference = (this.pConn$.getStateProps() as any).value;
159
173
 
@@ -168,14 +182,18 @@ export class CurrencyComponent implements OnInit, OnDestroy {
168
182
  }
169
183
  }
170
184
 
171
- fieldOnChange(event: any) {
172
- this.angularPConnectData.actions?.onChange(this, event);
173
- }
174
-
175
185
  fieldOnBlur(event: any) {
176
- // PConnect wants to use eventHandler for onBlur
177
-
178
- this.angularPConnectData.actions?.onBlur(this, event);
186
+ const actionsApi = this.pConn$?.getActionsApi();
187
+ const propName = (this.pConn$?.getStateProps() as any).value;
188
+ let value = event?.target?.value;
189
+ value = value?.substring(1);
190
+ if (this.currSep === ',') {
191
+ value = value.replace(/,/g, '');
192
+ } else {
193
+ value = value?.replace(/\./g, '');
194
+ value = value?.replace(/,/g, '.');
195
+ }
196
+ handleEvent(actionsApi, 'changeNblur', propName, value);
179
197
  }
180
198
 
181
199
  getErrorMessage() {
@@ -8,18 +8,18 @@
8
8
  <mat-label>{{ label$ }}</mat-label>
9
9
  <input
10
10
  matInput
11
+ [owlDateTime]="dtPicker"
11
12
  [attr.data-test-id]="testId"
12
- [ngxMatDatetimePicker]="picker"
13
13
  [placeholder]="placeholder"
14
14
  [formControl]="fieldControl"
15
- (dateChange)="fieldOnChange($event)"
16
15
  (blur)="fieldOnBlur($event)"
16
+ (dateTimeChange)="fieldOnDateChange($event)"
17
17
  [value]="value$"
18
18
  [required]="bRequired$"
19
19
  />
20
- <mat-datepicker-toggle matSuffix [for]="$any(picker)"></mat-datepicker-toggle>
21
- <ngx-mat-datetime-picker #picker [stepHour]="stepHour" [stepMinute]="stepMinute" [stepSecond]="stepSecond"> </ngx-mat-datetime-picker>
22
- <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
20
+ <mat-datepicker-toggle matSuffix [owlDateTimeTrigger]="dtPicker"></mat-datepicker-toggle>
21
+ <owl-date-time #dtPicker></owl-date-time>
22
+ <mat-error *ngIf="fieldControl?.invalid">{{ getErrorMessage() }}</mat-error>
23
23
  </mat-form-field>
24
24
  </div>
25
25
  </div>