@pega/angular-sdk-overrides 23.1.10 → 24.2.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 (137) hide show
  1. package/lib/designSystemExtension/alert-banner/alert-banner.component.ts +1 -1
  2. package/lib/designSystemExtension/case-create-stage/case-create-stage.component.ts +1 -1
  3. package/lib/designSystemExtension/material-case-summary/material-case-summary.component.html +7 -4
  4. package/lib/designSystemExtension/material-case-summary/material-case-summary.component.scss +2 -1
  5. package/lib/designSystemExtension/material-case-summary/material-case-summary.component.ts +3 -1
  6. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.html +1 -1
  7. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.ts +4 -1
  8. package/lib/designSystemExtension/material-vertical-tabs/material-vertical-tabs.component.html +1 -1
  9. package/lib/designSystemExtension/operator/operator.component.ts +11 -6
  10. package/lib/designSystemExtension/pulse/pulse.component.ts +7 -7
  11. package/lib/field/auto-complete/auto-complete.component.ts +17 -14
  12. package/lib/field/cancel-alert/cancel-alert.component.ts +0 -2
  13. package/lib/field/check-box/check-box.component.html +16 -15
  14. package/lib/field/check-box/check-box.component.scss +14 -1
  15. package/lib/field/check-box/check-box.component.ts +128 -45
  16. package/lib/field/currency/currency.component.html +16 -7
  17. package/lib/field/currency/currency.component.ts +55 -20
  18. package/lib/field/date/date.component.html +1 -6
  19. package/lib/field/date/date.component.ts +22 -39
  20. package/lib/field/date-time/date-time.component.html +6 -7
  21. package/lib/field/date-time/date-time.component.ts +28 -45
  22. package/lib/field/decimal/decimal.component.html +14 -4
  23. package/lib/field/decimal/decimal.component.ts +47 -7
  24. package/lib/field/dropdown/dropdown.component.ts +132 -21
  25. package/lib/field/email/email.component.ts +14 -4
  26. package/lib/field/group/group.component.html +1 -1
  27. package/lib/field/group/group.component.ts +6 -2
  28. package/lib/field/integer/integer.component.html +1 -1
  29. package/lib/field/integer/integer.component.ts +13 -5
  30. package/lib/field/multiselect/multiselect.component.html +33 -0
  31. package/lib/field/multiselect/multiselect.component.scss +7 -0
  32. package/lib/field/multiselect/multiselect.component.spec.ts +21 -0
  33. package/lib/field/multiselect/multiselect.component.ts +369 -0
  34. package/lib/field/multiselect/utils.ts +209 -0
  35. package/lib/field/percentage/percentage.component.html +17 -6
  36. package/lib/field/percentage/percentage.component.ts +51 -12
  37. package/lib/field/phone/phone.component.html +1 -1
  38. package/lib/field/phone/phone.component.ts +11 -14
  39. package/lib/field/radio-buttons/radio-buttons.component.ts +9 -12
  40. package/lib/field/rich-text/config-ext.json +10 -0
  41. package/lib/field/rich-text/rich-text.component.html +1 -1
  42. package/lib/field/rich-text/rich-text.component.ts +8 -6
  43. package/lib/field/scalar-list/scalar-list.component.ts +4 -4
  44. package/lib/field/text/text.component.ts +2 -0
  45. package/lib/field/text-area/text-area.component.html +2 -1
  46. package/lib/field/text-area/text-area.component.ts +13 -8
  47. package/lib/field/text-input/text-input.component.html +1 -1
  48. package/lib/field/text-input/text-input.component.ts +13 -5
  49. package/lib/field/time/time.component.html +3 -2
  50. package/lib/field/time/time.component.ts +23 -7
  51. package/lib/field/url/url.component.html +2 -1
  52. package/lib/field/url/url.component.ts +15 -5
  53. package/lib/field/user-reference/user-reference.component.html +42 -45
  54. package/lib/field/user-reference/user-reference.component.ts +73 -27
  55. package/lib/infra/Containers/base-components/flow-container-base.component.ts +22 -0
  56. package/lib/infra/Containers/base-components/helper.ts +89 -0
  57. package/lib/infra/Containers/flow-container/flow-container.component.html +9 -4
  58. package/lib/infra/Containers/flow-container/flow-container.component.ts +38 -33
  59. package/lib/infra/Containers/modal-view-container/modal-view-container.component.ts +41 -9
  60. package/lib/infra/Containers/preview-view-container/preview-view-container.component.ts +1 -1
  61. package/lib/infra/Containers/view-container/helper.ts +22 -0
  62. package/lib/infra/Containers/view-container/view-container.component.ts +5 -18
  63. package/lib/infra/assignment/assignment.component.ts +37 -39
  64. package/lib/infra/dashboard-filter/dashboard-filter.component.ts +0 -1
  65. package/lib/infra/defer-load/defer-load.component.ts +9 -12
  66. package/lib/infra/multi-step/multi-step.component.html +1 -1
  67. package/lib/infra/multi-step/multi-step.component.scss +1 -0
  68. package/lib/infra/navbar/navbar.component.html +4 -4
  69. package/lib/infra/navbar/navbar.component.ts +9 -6
  70. package/lib/infra/root-container/root-container.component.ts +3 -3
  71. package/lib/infra/stages/stages.component.scss +2 -2
  72. package/lib/infra/view/view.component.html +7 -20
  73. package/lib/infra/view/view.component.ts +21 -3
  74. package/lib/template/app-shell/app-shell.component.ts +20 -2
  75. package/lib/template/banner-page/config-ext.json +9 -0
  76. package/lib/template/base/details-template-base.ts +67 -0
  77. package/lib/template/base/form-template-base.ts +10 -0
  78. package/lib/template/case-summary/case-summary.component.ts +38 -4
  79. package/lib/template/case-view/case-view.component.html +7 -7
  80. package/lib/template/case-view/case-view.component.scss +2 -0
  81. package/lib/template/case-view/case-view.component.ts +8 -19
  82. package/lib/template/confirmation/confirmation.component.ts +1 -1
  83. package/lib/template/data-reference/data-reference.component.ts +37 -43
  84. package/lib/template/default-form/default-form.component.html +0 -4
  85. package/lib/template/default-form/default-form.component.ts +7 -23
  86. package/lib/template/details/details.component.ts +7 -41
  87. package/lib/template/details-narrow-wide/details-narrow-wide.component.ts +6 -39
  88. package/lib/template/details-one-column/details-one-column.component.ts +7 -42
  89. package/lib/template/details-sub-tabs/details-sub-tabs.component.html +1 -2
  90. package/lib/template/details-sub-tabs/details-sub-tabs.component.ts +5 -37
  91. package/lib/template/details-three-column/details-three-column.component.ts +7 -43
  92. package/lib/template/details-two-column/details-two-column.component.ts +8 -44
  93. package/lib/template/details-wide-narrow/details-wide-narrow.component.ts +7 -42
  94. package/lib/template/dynamic-tabs/dynamic-tabs.component.html +3 -0
  95. package/lib/template/dynamic-tabs/dynamic-tabs.component.ts +8 -4
  96. package/lib/template/field-group-template/field-group-template.component.ts +4 -14
  97. package/lib/template/field-value-list/field-value-list.component.html +8 -3
  98. package/lib/template/field-value-list/field-value-list.component.scss +2 -1
  99. package/lib/template/field-value-list/field-value-list.component.ts +1 -0
  100. package/lib/template/inline-dashboard-page/config-ext.json +9 -0
  101. package/lib/template/inline-dashboard-page/inline-dashboard-page.component.ts +2 -2
  102. package/lib/template/list-view/list-view.component.html +9 -6
  103. package/lib/template/list-view/list-view.component.scss +11 -0
  104. package/lib/template/list-view/list-view.component.ts +60 -32
  105. package/lib/template/list-view/listViewHelpers.ts +1 -2
  106. package/lib/template/narrow-wide-form/narrow-wide-form.component.ts +1 -1
  107. package/lib/template/one-column/one-column.component.ts +4 -3
  108. package/lib/template/one-column-tab/one-column-tab.component.ts +1 -1
  109. package/lib/template/page/page.component.ts +1 -1
  110. package/lib/template/promoted-filters/promoted-filters.component.ts +1 -1
  111. package/lib/template/repeating-structures/repeating-structures.component.ts +2 -3
  112. package/lib/template/simple-table/simple-table.component.ts +0 -2
  113. package/lib/template/simple-table-manual/helpers.ts +2 -2
  114. package/lib/template/simple-table-manual/simple-table-manual.component.html +1 -1
  115. package/lib/template/simple-table-manual/simple-table-manual.component.scss +1 -0
  116. package/lib/template/simple-table-manual/simple-table-manual.component.ts +60 -28
  117. package/lib/template/simple-table-select/simple-table-select.component.ts +5 -7
  118. package/lib/template/three-column/three-column.component.ts +4 -3
  119. package/lib/template/two-column/two-column.component.ts +4 -3
  120. package/lib/template/two-column-tab/two-column-tab.component.ts +1 -1
  121. package/lib/template/wide-narrow-form/wide-narrow-form.component.ts +4 -3
  122. package/lib/template/wide-narrow-page/wide-narrow-page.component.ts +1 -1
  123. package/lib/template/wss-nav-bar/wss-nav-bar.component.html +1 -1
  124. package/lib/template/wss-nav-bar/wss-nav-bar.component.ts +5 -4
  125. package/lib/widget/attachment/attachment.component.html +50 -26
  126. package/lib/widget/attachment/attachment.component.scss +118 -0
  127. package/lib/widget/attachment/attachment.component.ts +256 -503
  128. package/lib/widget/case-history/case-history.component.ts +1 -2
  129. package/lib/widget/feed-container/feed-container.component.ts +7 -11
  130. package/lib/widget/file-utility/file-utility.component.html +2 -2
  131. package/lib/widget/file-utility/file-utility.component.ts +15 -22
  132. package/lib/widget/list-utility/list-utility.component.html +1 -1
  133. package/lib/widget/quick-create/config-ext.json +9 -0
  134. package/lib/widget/quick-create/quick-create.component.ts +1 -1
  135. package/lib/widget/todo/todo.component.html +8 -7
  136. package/lib/widget/todo/todo.component.ts +97 -86
  137. package/package.json +1 -1
@@ -1,24 +1,33 @@
1
1
  <div *ngIf="displayMode$; else noDisplayMode">
2
- <component-mapper *ngIf="bVisible$ !== false" name="FieldValueList" [props]="{ label$, value$, displayMode$ }"></component-mapper>
2
+ <component-mapper *ngIf="bVisible$ !== false" name="FieldValueList" [props]="{ label$, value$: formattedValue, 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: currencySymbol,
17
+ thousands: thousandSeparator,
18
+ decimal: decimalSeparator,
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,20 @@ 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';
10
- import { getCurrencyCharacters } from '@pega/angular-sdk-components';
11
+ import { handleEvent } from '@pega/angular-sdk-components';
12
+ import { getCurrencyCharacters, getCurrencyOptions } from '@pega/angular-sdk-components';
11
13
  import { PConnFieldProps } from '@pega/angular-sdk-components';
14
+ import { format } from '@pega/angular-sdk-components';
12
15
 
13
16
  interface CurrrencyProps extends PConnFieldProps {
14
17
  // If any, enter additional props that only exist on Currency here
15
18
  currencyISOCode?: string;
19
+ allowDecimals: boolean;
20
+ formatter?: string;
16
21
  }
17
22
 
18
23
  @Component({
@@ -20,7 +25,7 @@ interface CurrrencyProps extends PConnFieldProps {
20
25
  templateUrl: './currency.component.html',
21
26
  styleUrls: ['./currency.component.scss'],
22
27
  standalone: true,
23
- imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, forwardRef(() => ComponentMapperComponent)]
28
+ imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, NgxCurrencyDirective, forwardRef(() => ComponentMapperComponent)]
24
29
  })
25
30
  export class CurrencyComponent implements OnInit, OnDestroy {
26
31
  @Input() pConn$: typeof PConnect;
@@ -31,7 +36,7 @@ export class CurrencyComponent implements OnInit, OnDestroy {
31
36
  configProps$: CurrrencyProps;
32
37
 
33
38
  label$ = '';
34
- value$: number | null;
39
+ value$: any;
35
40
  bRequired$ = false;
36
41
  bReadonly$ = false;
37
42
  bDisabled$ = false;
@@ -47,9 +52,13 @@ export class CurrencyComponent implements OnInit, OnDestroy {
47
52
  currencyOptions: Object = {};
48
53
 
49
54
  fieldControl = new FormControl<number | null>(null, { updateOn: 'blur' });
50
- symbol: string;
51
- thousandsSep: string;
52
- decimalSep: string;
55
+ currencySymbol: string;
56
+ thousandSeparator: string;
57
+ decimalSeparator: string;
58
+ inputMode: any;
59
+ decimalPrecision: number | undefined;
60
+ formattedValue: string;
61
+ formatter;
53
62
 
54
63
  constructor(
55
64
  private angularPConnect: AngularPConnectService,
@@ -114,10 +123,32 @@ export class CurrencyComponent implements OnInit, OnDestroy {
114
123
  this.testId = this.configProps$.testId;
115
124
  this.label$ = this.configProps$.label;
116
125
  this.displayMode$ = this.configProps$.displayMode;
117
- const nValue: any = this.configProps$.value;
118
- this.value$ = nValue && typeof nValue === 'string' ? parseFloat(nValue) : nValue;
126
+ this.inputMode = NgxCurrencyInputMode.Natural;
127
+ let nValue: any = this.configProps$.value;
128
+ if (nValue) {
129
+ if (typeof nValue === 'string') {
130
+ nValue = parseFloat(nValue);
131
+ }
132
+ this.value$ = nValue;
133
+ }
119
134
  this.helperText = this.configProps$.helperText;
120
135
  this.placeholder = this.configProps$.placeholder || '';
136
+ const currencyISOCode = this.configProps$?.currencyISOCode ?? '';
137
+
138
+ const theSymbols = getCurrencyCharacters(currencyISOCode);
139
+ this.currencySymbol = theSymbols.theCurrencySymbol;
140
+ this.thousandSeparator = theSymbols.theDigitGroupSeparator;
141
+ this.decimalSeparator = theSymbols.theDecimalIndicator;
142
+ this.formatter = this.configProps$.formatter;
143
+
144
+ if (this.displayMode$ === 'DISPLAY_ONLY' || this.displayMode$ === 'STACKED_LARGE_VAL') {
145
+ const theCurrencyOptions = getCurrencyOptions(currencyISOCode);
146
+ if (this.formatter) {
147
+ this.formattedValue = format(this.value$, this.formatter.toLowerCase(), theCurrencyOptions);
148
+ } else {
149
+ this.formattedValue = format(this.value$, 'currency', theCurrencyOptions);
150
+ }
151
+ }
121
152
 
122
153
  // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
123
154
  setTimeout(() => {
@@ -150,12 +181,9 @@ export class CurrencyComponent implements OnInit, OnDestroy {
150
181
  this.currencyISOCode = this.configProps$.currencyISOCode;
151
182
  }
152
183
 
153
- const theSymbols = getCurrencyCharacters(this.currencyISOCode);
154
- this.symbol = theSymbols.theCurrencySymbol;
155
- this.thousandsSep = theSymbols.theDigitGroupSeparator;
156
- this.decimalSep = theSymbols.theDecimalIndicator;
184
+ this.decimalPrecision = this.configProps$?.allowDecimals ? 2 : 0;
157
185
 
158
- this.componentReference = (this.pConn$.getStateProps() as any).value;
186
+ this.componentReference = this.pConn$.getStateProps().value;
159
187
 
160
188
  // trigger display of error message with field control
161
189
  if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
@@ -168,14 +196,21 @@ export class CurrencyComponent implements OnInit, OnDestroy {
168
196
  }
169
197
  }
170
198
 
171
- fieldOnChange(event: any) {
172
- this.angularPConnectData.actions?.onChange(this, event);
173
- }
174
-
175
199
  fieldOnBlur(event: any) {
176
- // PConnect wants to use eventHandler for onBlur
177
-
178
- this.angularPConnectData.actions?.onBlur(this, event);
200
+ const actionsApi = this.pConn$?.getActionsApi();
201
+ const propName = this.pConn$?.getStateProps().value;
202
+ let value = event?.target?.value;
203
+ value = value?.substring(1);
204
+ // replacing thousand separator with empty string as not required in api call
205
+ const thousandSep = this.thousandSeparator === '.' ? '\\.' : this.thousandSeparator;
206
+ let regExp = new RegExp(String.raw`${thousandSep}`, 'g');
207
+ value = value?.replace(regExp, '');
208
+ // replacing decimal separator with '.'
209
+ if (this.decimalSeparator !== '.') {
210
+ regExp = new RegExp(String.raw`${this.decimalSeparator}`, 'g');
211
+ value = value.replace(regExp, '.');
212
+ }
213
+ handleEvent(actionsApi, 'changeNblur', propName, value);
179
214
  }
180
215
 
181
216
  getErrorMessage() {
@@ -1,9 +1,5 @@
1
1
  <div *ngIf="displayMode$; else noDisplayMode">
2
- <component-mapper
3
- *ngIf="bVisible$ !== false"
4
- name="FieldValueList"
5
- [props]="{ label$, value$: getFormattedValue(), displayMode$ }"
6
- ></component-mapper>
2
+ <component-mapper *ngIf="bVisible$ !== false" name="FieldValueList" [props]="{ label$, value$: formattedValue$, displayMode$ }"></component-mapper>
7
3
  </div>
8
4
  <ng-template #noDisplayMode>
9
5
  <div *ngIf="!bReadonly$ && bHasForm$; else noEdit">
@@ -21,7 +17,6 @@
21
17
  [required]="bRequired$"
22
18
  [formControl]="fieldControl"
23
19
  (dateChange)="fieldOnDateChange($event)"
24
- (blur)="fieldOnBlur($event)"
25
20
  />
26
21
  <mat-datepicker-toggle matSuffix [for]="pegadate"></mat-datepicker-toggle>
27
22
  <mat-datepicker #pegadate [startAt]="value$"></mat-datepicker>
@@ -1,4 +1,3 @@
1
- /* eslint-disable max-classes-per-file */
2
1
  import { Component, OnInit, Input, ChangeDetectorRef, forwardRef, Inject, OnDestroy } from '@angular/core';
3
2
  import { CommonModule } from '@angular/common';
4
3
  import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
@@ -15,13 +14,14 @@ import { ComponentMapperComponent } from '@pega/angular-sdk-components';
15
14
  import { dateFormatInfoDefault, getDateFormatInfo } from '@pega/angular-sdk-components';
16
15
  import { PConnFieldProps } from '@pega/angular-sdk-components';
17
16
  import { format } from '@pega/angular-sdk-components';
17
+ import { handleEvent } from '@pega/angular-sdk-components';
18
18
 
19
19
  interface DateProps extends PConnFieldProps {
20
20
  // If any, enter additional props that only exist on Date here
21
21
  }
22
22
 
23
23
  class MyFormat {
24
- theDateFormat: any = getDateFormatInfo();
24
+ theDateFormat = getDateFormatInfo();
25
25
 
26
26
  get display() {
27
27
  return {
@@ -83,7 +83,10 @@ export class DateComponent implements OnInit, OnDestroy {
83
83
  // Start with default dateFormatInfo
84
84
  dateFormatInfo = dateFormatInfoDefault;
85
85
  // and then update, as needed, based on locale, etc.
86
- theDateFormat: any = getDateFormatInfo();
86
+ theDateFormat = getDateFormatInfo();
87
+ actionsApi: Object;
88
+ propName: string;
89
+ formattedValue$: any;
87
90
 
88
91
  constructor(
89
92
  private angularPConnect: AngularPConnectService,
@@ -146,27 +149,16 @@ export class DateComponent implements OnInit, OnDestroy {
146
149
  // moved this from ngOnInit() and call this from there instead...
147
150
  this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as DateProps;
148
151
 
149
- if (this.configProps$.value != undefined) {
150
- let sDateValue: any = '';
151
- sDateValue = this.configProps$.value;
152
-
153
- if (sDateValue != '') {
154
- if (typeof sDateValue === 'object') {
155
- sDateValue = sDateValue.toISOString();
156
- } else if (sDateValue.indexOf('/') < 0) {
157
- // if we have the "pega" format, then for display, convert to standard format (US)
158
- // sDateValue = this.formatDate(sDateValue);
159
- sDateValue = this.utils.generateDate(sDateValue, 'Date-Long-Custom-YYYY');
160
- }
161
- this.value$ = new Date(sDateValue);
162
- }
163
- }
152
+ this.value$ = this.configProps$.value;
164
153
  this.testId = this.configProps$.testId;
165
154
  this.label$ = this.configProps$.label;
166
155
  this.displayMode$ = this.configProps$.displayMode;
167
156
  this.helperText = this.configProps$.helperText;
168
157
  this.placeholder = this.configProps$.placeholder || '';
169
158
 
159
+ this.actionsApi = this.pConn$.getActionsApi();
160
+ this.propName = this.pConn$.getStateProps().value;
161
+
170
162
  // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
171
163
  setTimeout(() => {
172
164
  if (this.configProps$.required != null) {
@@ -175,6 +167,12 @@ export class DateComponent implements OnInit, OnDestroy {
175
167
  this.cdRef.detectChanges();
176
168
  });
177
169
 
170
+ if (this.displayMode$ === 'DISPLAY_ONLY' || this.displayMode$ === 'STACKED_LARGE_VAL') {
171
+ this.formattedValue$ = format(this.value$, 'date', {
172
+ format: this.theDateFormat.dateFormatString
173
+ });
174
+ }
175
+
178
176
  if (this.configProps$.visibility != null) {
179
177
  this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
180
178
  }
@@ -194,7 +192,7 @@ export class DateComponent implements OnInit, OnDestroy {
194
192
  this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
195
193
  }
196
194
 
197
- this.componentReference = (this.pConn$.getStateProps() as any).value;
195
+ this.componentReference = this.pConn$.getStateProps().value;
198
196
 
199
197
  // trigger display of error message with field control
200
198
  if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
@@ -209,20 +207,11 @@ export class DateComponent implements OnInit, OnDestroy {
209
207
 
210
208
  fieldOnDateChange(event: any) {
211
209
  // this comes from the date pop up
212
- if (typeof event.value === 'object') {
213
- // convert date to pega "date" format
214
- event.value = event.value?.toISOString();
215
- }
216
- this.angularPConnectData.actions?.onChange(this, { value: event.value });
217
- }
218
-
219
- fieldOnBlur(event: any) {
220
- // PConnect wants to use eventHandler for onBlur
221
- if (typeof event.value === 'object') {
222
- // convert date to pega "date" format
223
- event.value = event.value?.toISOString();
224
- }
225
- this.angularPConnectData.actions?.onBlur(this, { value: event.value });
210
+ const value = event?.target?.value.format('YYYY-MM-DD');
211
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
212
+ this.pConn$.clearErrorMessages({
213
+ property: this.propName
214
+ });
226
215
  }
227
216
 
228
217
  hasErrors() {
@@ -243,10 +232,4 @@ export class DateComponent implements OnInit, OnDestroy {
243
232
  }
244
233
  return errMessage;
245
234
  }
246
-
247
- getFormattedValue() {
248
- return format(this.value$, 'date', {
249
- format: this.theDateFormat.dateFormatString
250
- });
251
- }
252
235
  }
@@ -1,5 +1,5 @@
1
1
  <div *ngIf="displayMode$; else noDisplayMode">
2
- <component-mapper *ngIf="bVisible$ !== false" name="FieldValueList" [props]="{ label$, value$, displayMode$ }"></component-mapper>
2
+ <component-mapper *ngIf="bVisible$ !== false" name="FieldValueList" [props]="{ label$, value$: formattedValue$, displayMode$ }"></component-mapper>
3
3
  </div>
4
4
  <ng-template #noDisplayMode>
5
5
  <div *ngIf="!bReadonly$ && bHasForm$; else noEdit">
@@ -8,18 +8,17 @@
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
- (blur)="fieldOnBlur($event)"
15
+ (dateTimeChange)="fieldOnDateChange($event)"
17
16
  [value]="value$"
18
17
  [required]="bRequired$"
19
18
  />
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>
19
+ <mat-datepicker-toggle matSuffix [owlDateTimeTrigger]="dtPicker"></mat-datepicker-toggle>
20
+ <owl-date-time #dtPicker></owl-date-time>
21
+ <mat-error *ngIf="fieldControl?.invalid">{{ getErrorMessage() }}</mat-error>
23
22
  </mat-form-field>
24
23
  </div>
25
24
  </div>
@@ -1,44 +1,23 @@
1
- /* eslint-disable max-classes-per-file */
2
1
  import { Component, OnInit, Input, ChangeDetectorRef, forwardRef, OnDestroy } from '@angular/core';
3
2
  import { CommonModule } from '@angular/common';
4
3
  import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
5
- import { NgxMatDatetimePickerModule, NgxMatTimepickerModule, NGX_MAT_DATE_FORMATS } from '@angular-material-components/datetime-picker';
6
- import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
7
- import { MomentDateModule } from '@angular/material-moment-adapter';
8
4
  import { MatDatepickerModule } from '@angular/material/datepicker';
9
5
  import { MatInputModule } from '@angular/material/input';
10
6
  import { MatFormFieldModule } from '@angular/material/form-field';
7
+ import { OwlDateTimeModule, OwlNativeDateTimeModule } from '@danielmoncada/angular-datetime-picker';
11
8
  import { interval } from 'rxjs';
12
9
  import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
13
10
  import { Utils } from '@pega/angular-sdk-components';
14
11
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
15
12
  import { dateFormatInfoDefault, getDateFormatInfo } from '@pega/angular-sdk-components';
16
- import { handleEvent } from '@pega/angular-sdk-components';
17
13
  import { PConnFieldProps } from '@pega/angular-sdk-components';
14
+ import { handleEvent } from '@pega/angular-sdk-components';
15
+ import { format } from '@pega/angular-sdk-components';
18
16
 
19
17
  interface DateTimeProps extends PConnFieldProps {
20
18
  // If any, enter additional props that only exist on DateTime here
21
19
  }
22
20
 
23
- class MyFormat {
24
- theDateFormat: any = getDateFormatInfo();
25
-
26
- get display() {
27
- return {
28
- dateInput: `${this.theDateFormat.dateFormatString}, LT`,
29
- monthYearLabel: 'MMM YYYY',
30
- dateA11yLabel: 'LL',
31
- monthYearA11yLabel: 'MMMM YYYY'
32
- };
33
- }
34
-
35
- get parse() {
36
- return {
37
- dateInput: `${this.theDateFormat.dateFormatString}, LT`
38
- };
39
- }
40
- }
41
-
42
21
  @Component({
43
22
  selector: 'app-date-time',
44
23
  templateUrl: './date-time.component.html',
@@ -50,13 +29,10 @@ class MyFormat {
50
29
  MatFormFieldModule,
51
30
  MatInputModule,
52
31
  MatDatepickerModule,
53
- NgxMatMomentModule,
54
- NgxMatDatetimePickerModule,
55
- NgxMatTimepickerModule,
56
- MomentDateModule,
32
+ OwlDateTimeModule,
33
+ OwlNativeDateTimeModule,
57
34
  forwardRef(() => ComponentMapperComponent)
58
- ],
59
- providers: [{ provide: NGX_MAT_DATE_FORMATS, useClass: MyFormat }]
35
+ ]
60
36
  })
61
37
  export class DateTimeComponent implements OnInit, OnDestroy {
62
38
  @Input() pConn$: typeof PConnect;
@@ -87,8 +63,11 @@ export class DateTimeComponent implements OnInit, OnDestroy {
87
63
  // Start with default dateFormatInfo
88
64
  dateFormatInfo = dateFormatInfoDefault;
89
65
  // and then update, as needed, based on locale, etc.
90
- theDateFormat: any = getDateFormatInfo();
66
+ theDateFormat = getDateFormatInfo();
91
67
  placeholder: string;
68
+ actionsApi: Object;
69
+ propName: string;
70
+ formattedValue$: any;
92
71
 
93
72
  constructor(
94
73
  private angularPConnect: AngularPConnectService,
@@ -97,7 +76,7 @@ export class DateTimeComponent implements OnInit, OnDestroy {
97
76
  ) {}
98
77
 
99
78
  ngOnInit(): void {
100
- this.placeholder = `${this.theDateFormat.dateFormatStringLC}, hh:mm a`;
79
+ this.placeholder = `${this.theDateFormat.dateFormatStringLC}, hh:mm A`;
101
80
  // First thing in initialization is registering and subscribing to the AngularPConnect service
102
81
  this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
103
82
  this.controlName$ = this.angularPConnect.getComponentID(this);
@@ -162,6 +141,12 @@ export class DateTimeComponent implements OnInit, OnDestroy {
162
141
  this.cdRef.detectChanges();
163
142
  });
164
143
 
144
+ if (this.displayMode$ === 'DISPLAY_ONLY' || this.displayMode$ === 'STACKED_LARGE_VAL') {
145
+ this.formattedValue$ = format(this.value$, 'datetime', {
146
+ format: `${this.theDateFormat.dateFormatString} hh:mm A`
147
+ });
148
+ }
149
+
165
150
  if (this.configProps$.visibility != null) {
166
151
  this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
167
152
  }
@@ -181,7 +166,10 @@ export class DateTimeComponent implements OnInit, OnDestroy {
181
166
  this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
182
167
  }
183
168
 
184
- this.componentReference = (this.pConn$.getStateProps() as any).value;
169
+ this.componentReference = this.pConn$.getStateProps().value;
170
+
171
+ this.actionsApi = this.pConn$.getActionsApi();
172
+ this.propName = this.pConn$.getStateProps().value;
185
173
 
186
174
  // trigger display of error message with field control
187
175
  if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
@@ -194,18 +182,13 @@ export class DateTimeComponent implements OnInit, OnDestroy {
194
182
  }
195
183
  }
196
184
 
197
- fieldOnChange(event: any) {
198
- const value = event.value && event.value.isValid() ? event.value : null;
199
- const actionsApi = this.pConn$?.getActionsApi();
200
- const propName = (this.pConn$?.getStateProps() as any).value;
201
- handleEvent(actionsApi, 'changeNblur', propName, value?.toISOString());
202
- }
203
-
204
- fieldOnBlur(event: any) {
205
- // PConnect wants to use eventHandler for onBlur
206
- if (event.target.value) event.value = event.target.value;
207
-
208
- this.angularPConnectData.actions?.onBlur(this, event);
185
+ fieldOnDateChange(event: any) {
186
+ // this comes from the date pop up
187
+ if (typeof event.value === 'object') {
188
+ // convert date to pega "date" format
189
+ event.value = event.value?.toISOString();
190
+ }
191
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, event.value);
209
192
  }
210
193
 
211
194
  getErrorMessage() {
@@ -1,22 +1,32 @@
1
1
  <div *ngIf="displayMode$; else noDisplayMode">
2
- <component-mapper *ngIf="bVisible$ !== false" name="FieldValueList" [props]="{ label$, value$, displayMode$ }"></component-mapper>
2
+ <component-mapper *ngIf="bVisible$ !== false" name="FieldValueList" [props]="{ label$, value$: formattedValue, 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$">
7
7
  <mat-form-field class="psdk-full-width" subscriptSizing="dynamic" [hintLabel]="helperText">
8
8
  <mat-label>{{ label$ }}</mat-label>
9
9
  <input
10
10
  type="text"
11
11
  matInput
12
- appThousandSeparator
12
+ currencyMask
13
+ [options]="{
14
+ prefix: currencySymbol,
15
+ thousands: thousandSeparator,
16
+ decimal: decimalSeparator,
17
+ align: 'left',
18
+ nullable: true,
19
+ precision: decimalPrecision,
20
+ inputMode: inputMode
21
+ }"
13
22
  [placeholder]="placeholder"
14
23
  step="0.01"
15
- [value]="value$"
24
+ [formControlName]="controlName$"
16
25
  [required]="bRequired$"
17
26
  [formControl]="fieldControl"
18
27
  [attr.data-test-id]="testId"
19
28
  (blur)="fieldOnBlur($event)"
29
+ [readonly]="bReadonly$"
20
30
  />
21
31
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
22
32
  </mat-form-field>
@@ -3,18 +3,21 @@ import { CommonModule } from '@angular/common';
3
3
  import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
4
4
  import { MatInputModule } from '@angular/material/input';
5
5
  import { MatFormFieldModule } from '@angular/material/form-field';
6
+ import { NgxCurrencyDirective, NgxCurrencyInputMode } from 'ngx-currency';
6
7
  import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
7
8
  import { Utils } from '@pega/angular-sdk-components';
8
9
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
9
10
  import { handleEvent } from '@pega/angular-sdk-components';
10
- import { ThousandSeparatorDirective } from '@pega/angular-sdk-components';
11
+ import { getCurrencyCharacters, getCurrencyOptions } from '@pega/angular-sdk-components';
11
12
  import { PConnFieldProps } from '@pega/angular-sdk-components';
13
+ import { format } from '@pega/angular-sdk-components';
12
14
 
13
15
  interface DecimalProps extends PConnFieldProps {
14
16
  // If any, enter additional props that only exist on Decimal here
15
17
  currencyISOCode?: string;
16
18
  decimalPrecision?: number;
17
19
  showGroupSeparators?: string;
20
+ formatter?: string;
18
21
  }
19
22
 
20
23
  @Component({
@@ -28,7 +31,7 @@ interface DecimalProps extends PConnFieldProps {
28
31
  FormsModule,
29
32
  MatFormFieldModule,
30
33
  MatInputModule,
31
- ThousandSeparatorDirective,
34
+ NgxCurrencyDirective,
32
35
  forwardRef(() => ComponentMapperComponent)
33
36
  ]
34
37
  })
@@ -41,7 +44,7 @@ export class DecimalComponent implements OnInit, OnDestroy {
41
44
  configProps$: DecimalProps;
42
45
 
43
46
  label$ = '';
44
- value$: number;
47
+ value$: any;
45
48
  bRequired$ = false;
46
49
  bReadonly$ = false;
47
50
  bDisabled$ = false;
@@ -55,6 +58,13 @@ export class DecimalComponent implements OnInit, OnDestroy {
55
58
  placeholder: string;
56
59
 
57
60
  fieldControl = new FormControl<number | null>(null, null);
61
+ decimalSeparator: string;
62
+ thousandSeparator: string;
63
+ currencySymbol = '';
64
+ decimalPrecision: number | undefined;
65
+ formatter;
66
+ formattedValue: any;
67
+ inputMode: any;
58
68
 
59
69
  constructor(
60
70
  private angularPConnect: AngularPConnectService,
@@ -119,6 +129,7 @@ export class DecimalComponent implements OnInit, OnDestroy {
119
129
  this.testId = this.configProps$.testId;
120
130
  this.label$ = this.configProps$.label;
121
131
  this.displayMode$ = this.configProps$.displayMode;
132
+ this.inputMode = NgxCurrencyInputMode.Natural;
122
133
  let nValue: any = this.configProps$.value;
123
134
  if (nValue) {
124
135
  if (typeof nValue === 'string') {
@@ -128,6 +139,21 @@ export class DecimalComponent implements OnInit, OnDestroy {
128
139
  }
129
140
  this.helperText = this.configProps$.helperText;
130
141
  this.placeholder = this.configProps$.placeholder || '';
142
+ const showGroupSeparators = this.configProps$.showGroupSeparators;
143
+ const currencyISOCode = this.configProps$?.currencyISOCode ?? '';
144
+
145
+ const theSymbols = getCurrencyCharacters(currencyISOCode);
146
+ this.decimalSeparator = theSymbols.theDecimalIndicator;
147
+ this.thousandSeparator = showGroupSeparators ? theSymbols.theDigitGroupSeparator : '';
148
+
149
+ const theCurrencyOptions = getCurrencyOptions(currencyISOCode);
150
+ this.formatter = this.configProps$.formatter;
151
+
152
+ if (this.formatter) {
153
+ this.formattedValue = format(this.value$, this.formatter.toLowerCase(), theCurrencyOptions);
154
+ } else {
155
+ this.formattedValue = format(this.value$, 'decimal', theCurrencyOptions);
156
+ }
131
157
 
132
158
  // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
133
159
  setTimeout(() => {
@@ -156,15 +182,29 @@ export class DecimalComponent implements OnInit, OnDestroy {
156
182
  this.fieldControl.enable();
157
183
  }
158
184
 
159
- this.componentReference = (this.pConn$.getStateProps() as any).value;
185
+ if (this.bReadonly$ && this.formatter === 'Currency') {
186
+ this.currencySymbol = theSymbols.theCurrencySymbol;
187
+ }
188
+ this.decimalPrecision = this.configProps$?.decimalPrecision ?? 2;
189
+
190
+ this.componentReference = this.pConn$.getStateProps().value;
160
191
  }
161
192
 
162
193
  fieldOnBlur(event: any) {
163
194
  const actionsApi = this.pConn$?.getActionsApi();
164
- const propName = (this.pConn$?.getStateProps() as any).value;
195
+ const propName = this.pConn$?.getStateProps().value;
165
196
  let value = event?.target?.value;
166
- value = value.replace(/,/g, '');
167
- value = value !== '' ? Number(value) : value;
197
+ // replacing thousand separator with empty string as not required in api call
198
+ if (this.configProps$.showGroupSeparators) {
199
+ const thousandSep = this.thousandSeparator === '.' ? '\\.' : this.thousandSeparator;
200
+ const regExp = new RegExp(String.raw`${thousandSep}`, 'g');
201
+ value = value?.replace(regExp, '');
202
+ }
203
+ // replacing decimal separator with '.'
204
+ if (this.decimalSeparator !== '.') {
205
+ const regExp = new RegExp(String.raw`${this.decimalSeparator}`, 'g');
206
+ value = value.replace(regExp, '.');
207
+ }
168
208
  handleEvent(actionsApi, 'changeNblur', propName, value);
169
209
  }
170
210