@pega/dx-component-builder-sdk 25.1.11 → 25.1.12

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 (38) hide show
  1. package/package.json +1 -1
  2. package/src/tasks/create/templates/SDK-Angular/field/Boolean/boolean.component.ts.mustache +18 -149
  3. package/src/tasks/create/templates/SDK-Angular/field/Date/date.component.html.mustache +1 -1
  4. package/src/tasks/create/templates/SDK-Angular/field/Date/date.component.ts.mustache +29 -150
  5. package/src/tasks/create/templates/SDK-Angular/field/DateTime/date-time.component.ts.mustache +31 -149
  6. package/src/tasks/create/templates/SDK-Angular/field/Decimal/decimal.component.ts.mustache +37 -163
  7. package/src/tasks/create/templates/SDK-Angular/field/Decimal-Currency/decimal-currency.component.ts.mustache +34 -169
  8. package/src/tasks/create/templates/SDK-Angular/field/Decimal-Percentage/decimal-percentage.component.ts.mustache +36 -154
  9. package/src/tasks/create/templates/SDK-Angular/field/Integer/integer.component.ts.mustache +18 -157
  10. package/src/tasks/create/templates/SDK-Angular/field/Picklist/picklist.component.ts.mustache +24 -148
  11. package/src/tasks/create/templates/SDK-Angular/field/Picklist-Autocomplete/demo.stories.tsx.mustache +7 -2
  12. package/src/tasks/create/templates/SDK-Angular/field/Picklist-Autocomplete/picklist-autocomplete.component.ts.mustache +28 -162
  13. package/src/tasks/create/templates/SDK-Angular/field/Picklist-RadioButtons/picklist-radio-buttons.component.ts.mustache +35 -161
  14. package/src/tasks/create/templates/SDK-Angular/field/Text/text.component.ts.mustache +29 -144
  15. package/src/tasks/create/templates/SDK-Angular/field/Text-Email/text-email.component.ts.mustache +15 -155
  16. package/src/tasks/create/templates/SDK-Angular/field/Text-Input/text.component.ts.mustache +15 -155
  17. package/src/tasks/create/templates/SDK-Angular/field/Text-Paragraph/text-paragraph.component.ts.mustache +18 -152
  18. package/src/tasks/create/templates/SDK-Angular/field/Text-Phone/text-phone.component.ts.mustache +29 -142
  19. package/src/tasks/create/templates/SDK-Angular/field/Text-URL/text-url.component.ts.mustache +16 -154
  20. package/src/tasks/create/templates/SDK-Angular/field/TimeOfDay/time-of-day.component.ts.mustache +17 -151
  21. package/src/tasks/create/templates/SDK-Angular/template/DETAILS/details.component.ts.mustache +0 -1
  22. package/src/tasks/create/templates/SDK-Angular/template/DETAILS-region/details.component.ts.mustache +0 -1
  23. package/src/tasks/create/templates/SDK-Angular/template/FORM/form.component.ts.mustache +10 -3
  24. package/src/tasks/create/templates/SDK-Angular/template/FORM-region/form.component.ts.mustache +0 -1
  25. package/src/tasks/create/templates/SDK-Angular/template/PAGE/page.component.ts.mustache +0 -1
  26. package/src/tasks/create/templates/SDK-Angular/widget/CASE/case.component.ts.mustache +0 -1
  27. package/src/tasks/create/templates/SDK-Angular/widget/PAGE/page.component.ts.mustache +0 -1
  28. package/src/tasks/create/templates/SDK-Angular/widget/PAGE-CASE/page-case.component.html.mustache +2 -2
  29. package/src/tasks/create/templates/SDK-Angular/widget/PAGE-CASE/page-case.component.ts.mustache +4 -4
  30. /package/tests/assets/sdk-a/components/createAll/custom-constellation/field/{Pega_DXIL_MyRadioButtons → Pega_DXIL_MyRadiobuttons}/PConnProps.d.ts +0 -0
  31. /package/tests/assets/sdk-a/components/createAll/custom-constellation/field/{Pega_DXIL_MyRadioButtons → Pega_DXIL_MyRadiobuttons}/create-nonce.ts +0 -0
  32. /package/tests/assets/sdk-a/components/createAll/custom-constellation/field/{Pega_DXIL_MyRadioButtons → Pega_DXIL_MyRadiobuttons}/demo.stories.tsx +0 -0
  33. /package/tests/assets/sdk-a/components/createAll/custom-constellation/field/{Pega_DXIL_MyRadioButtons → Pega_DXIL_MyRadiobuttons}/event-utils.ts +0 -0
  34. /package/tests/assets/sdk-a/components/createAll/custom-constellation/field/{Pega_DXIL_MyRadioButtons → Pega_DXIL_MyRadiobuttons}/index.tsx +0 -0
  35. /package/tests/assets/sdk-a/components/createAll/custom-constellation/field/{Pega_DXIL_MyRadioButtons → Pega_DXIL_MyRadiobuttons}/mock.ts +0 -0
  36. /package/tests/assets/sdk-a/components/createAll/custom-constellation/field/{Pega_DXIL_MyRadioButtons → Pega_DXIL_MyRadiobuttons}/styles.ts +0 -0
  37. /package/tests/assets/sdk-a/components/createAll/custom-constellation/field/{Pega_DXIL_MyRadioButtons → Pega_DXIL_MyRadiobuttons}/suggestions-handler.ts +0 -0
  38. /package/tests/assets/sdk-a/components/createAll/custom-constellation/field/{Pega_DXIL_MyRadioButtons → Pega_DXIL_MyRadiobuttons}/textformat-utils.tsx +0 -0
@@ -1,17 +1,15 @@
1
- import { Component, OnInit, Input, ChangeDetectorRef, forwardRef, OnDestroy } from '@angular/core';
1
+ import { Component, forwardRef } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
- import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
3
+ import { FormControl, ReactiveFormsModule } from '@angular/forms';
4
4
  import { MatInputModule } from '@angular/material/input';
5
5
  import { MatFormFieldModule } from '@angular/material/form-field';
6
- import { interval } from 'rxjs';
7
6
  import { NgxCurrencyDirective, NgxCurrencyInputMode } from 'ngx-currency';
8
- import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
9
- import { Utils } from '@pega/angular-sdk-components';
7
+ import { FieldBase } from '@pega/angular-sdk-components';
10
8
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
11
9
  import { handleEvent } from '@pega/angular-sdk-components';
12
10
  import { getCurrencyCharacters, getCurrencyOptions } from '@pega/angular-sdk-components';
13
- import { PConnFieldProps } from '@pega/angular-sdk-components';
14
11
  import { format } from '@pega/angular-sdk-components';
12
+ import { PConnFieldProps } from '@pega/angular-sdk-components';
15
13
 
16
14
  interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
17
15
  // If any, enter additional props that only exist on Currency here
@@ -26,175 +24,59 @@ interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
26
24
  styleUrls: ['./{{COMPONENT_CLASS_NAME_KEBAB}}.component.scss'],
27
25
  imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, NgxCurrencyDirective, forwardRef(() => ComponentMapperComponent)]
28
26
  })
29
- export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
30
- @Input() pConn$: typeof PConnect;
31
- @Input() formGroup$: FormGroup;
32
-
33
- // Used with AngularPConnect
34
- angularPConnectData: AngularPConnectData = {};
27
+ export class {{COMPONENT_CLASS_NAME}}Component extends FieldBase {
35
28
  configProps$: {{COMPONENT_CLASS_NAME}}Props;
29
+ override fieldControl = new FormControl<number | null>(null, { updateOn: 'blur' });
36
30
 
37
- label$ = '';
38
- value$: any;
39
- bRequired$ = false;
40
- bReadonly$ = false;
41
- bDisabled$ = false;
42
- bVisible$ = true;
43
- displayMode$?: string = '';
44
- controlName$: string;
45
- bHasForm$ = true;
46
- componentReference = '';
47
- testId: string;
48
- helperText: string;
49
- placeholder: string;
50
- currencyISOCode = 'USD';
51
31
  currencyOptions: object = {};
52
-
53
- fieldControl = new FormControl<number | null>(null, { updateOn: 'blur' });
54
32
  currencySymbol: string;
55
33
  thousandSeparator: string;
56
34
  decimalSeparator: string;
57
- inputMode: any;
58
35
  decimalPrecision: number | undefined;
59
36
  formattedValue: string;
60
37
  formatter;
38
+ inputMode = NgxCurrencyInputMode.Natural;
61
39
 
62
- constructor(
63
- private angularPConnect: AngularPConnectService,
64
- private cdRef: ChangeDetectorRef,
65
- private utils: Utils
66
- ) {}
67
-
68
- ngOnInit(): void {
69
- // First thing in initialization is registering and subscribing to the AngularPConnect service
70
- this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
71
- this.controlName$ = this.angularPConnect.getComponentID(this);
72
-
73
- // Then, continue on with other initialization
40
+ /**
41
+ * Updates the component when there are changes in the state.
42
+ */
43
+ override updateSelf(): void {
44
+ // Resolve configuration properties
45
+ this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as {{COMPONENT_CLASS_NAME}}Props;
74
46
 
75
- // call updateSelf when initializing
76
- // this.updateSelf();
77
- this.checkAndUpdate();
47
+ // Update component common properties
48
+ this.updateComponentCommonProperties(this.configProps$);
78
49
 
79
- if (this.formGroup$) {
80
- // add control to formGroup
81
- this.formGroup$.addControl(this.controlName$, this.fieldControl);
50
+ // Extract and normalize the value property
51
+ const { value } = this.configProps$;
52
+ if (value) {
53
+ this.value$ = typeof value === 'string' ? parseFloat(value) : value;
82
54
  this.fieldControl.setValue(this.value$);
83
- this.bHasForm$ = true;
84
- } else {
85
- this.bReadonly$ = true;
86
- this.bHasForm$ = false;
87
- }
88
- }
89
-
90
- ngOnDestroy(): void {
91
- if (this.formGroup$) {
92
- this.formGroup$.removeControl(this.controlName$);
93
55
  }
94
56
 
95
- if (this.angularPConnectData.unsubscribeFn) {
96
- this.angularPConnectData.unsubscribeFn();
97
- }
57
+ // update currency properties
58
+ this.updateCurrencyProperties(this.configProps$);
98
59
  }
99
60
 
100
- // Callback passed when subscribing to store change
101
- onStateChange() {
102
- this.checkAndUpdate();
103
- }
104
-
105
- checkAndUpdate() {
106
- // Should always check the bridge to see if the component should
107
- // update itself (re-render)
108
- const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
109
-
110
- // ONLY call updateSelf when the component should update
111
- if (bUpdateSelf) {
112
- this.updateSelf();
113
- }
114
- }
115
-
116
- // updateSelf
117
- updateSelf(): void {
118
- // starting very simple...
119
-
120
- // moved this from ngOnInit() and call this from there instead...
121
- this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as {{COMPONENT_CLASS_NAME}}Props;
122
- this.testId = this.configProps$.testId;
123
- this.label$ = this.configProps$.label;
124
- this.displayMode$ = this.configProps$.displayMode;
125
- this.inputMode = NgxCurrencyInputMode.Natural;
126
- let nValue: any = this.configProps$.value;
127
- if (nValue) {
128
- if (typeof nValue === 'string') {
129
- nValue = parseFloat(nValue);
130
- }
131
- this.value$ = nValue;
132
- } else {
133
- this.value$ = null;
134
- }
135
- this.fieldControl.setValue(this.value$);
136
- this.helperText = this.configProps$.helperText;
137
- this.placeholder = this.configProps$.placeholder || '';
138
- const currencyISOCode = this.configProps$?.currencyISOCode ?? '';
61
+ /**
62
+ * Updates the currency properties
63
+ *
64
+ * @param {Object} configProps - Configuration properties.
65
+ * @param {boolean} configProps.allowDecimals - Whether to allow decimal values.
66
+ * @param {string} configProps.currencyISOCode - The ISO code of the currency.
67
+ * @param {string} configProps.formatter - The formatter type (e.g., 'currency').
68
+ */
69
+ protected updateCurrencyProperties(configProps): void {
70
+ const { allowDecimals, currencyISOCode = 'USD', formatter } = configProps;
139
71
 
140
72
  const theSymbols = getCurrencyCharacters(currencyISOCode);
141
73
  this.currencySymbol = theSymbols.theCurrencySymbol;
142
74
  this.thousandSeparator = theSymbols.theDigitGroupSeparator;
143
75
  this.decimalSeparator = theSymbols.theDecimalIndicator;
144
- this.formatter = this.configProps$.formatter;
76
+ this.decimalPrecision = allowDecimals ? 2 : 0;
145
77
 
146
- if (this.displayMode$ === 'DISPLAY_ONLY' || this.displayMode$ === 'STACKED_LARGE_VAL') {
147
- const theCurrencyOptions = getCurrencyOptions(currencyISOCode);
148
- if (this.formatter) {
149
- this.formattedValue = format(this.value$, this.formatter.toLowerCase(), theCurrencyOptions);
150
- } else {
151
- this.formattedValue = format(this.value$, 'currency', theCurrencyOptions);
152
- }
153
- }
154
-
155
- // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
156
- setTimeout(() => {
157
- if (this.configProps$.required != null) {
158
- this.bRequired$ = this.utils.getBooleanValue(this.configProps$.required);
159
- }
160
- this.cdRef.detectChanges();
161
- });
162
-
163
- if (this.configProps$.visibility != null) {
164
- this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
165
- }
166
-
167
- // disabled
168
- if (this.configProps$.disabled != undefined) {
169
- this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
170
- }
171
-
172
- if (this.bDisabled$) {
173
- this.fieldControl.disable();
174
- } else {
175
- this.fieldControl.enable();
176
- }
177
-
178
- if (this.configProps$.readOnly != null) {
179
- this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
180
- }
181
-
182
- if (this.configProps$.currencyISOCode != null) {
183
- this.currencyISOCode = this.configProps$.currencyISOCode;
184
- }
185
-
186
- this.decimalPrecision = this.configProps$?.allowDecimals ? 2 : 0;
187
-
188
- this.componentReference = this.pConn$.getStateProps().value;
189
-
190
- // trigger display of error message with field control
191
- if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
192
- const timer = interval(100).subscribe(() => {
193
- this.fieldControl.setErrors({ message: true });
194
- this.fieldControl.markAsTouched();
195
-
196
- timer.unsubscribe();
197
- });
78
+ if (['DISPLAY_ONLY', 'STACKED_LARGE_VAL'].includes(this.displayMode$)) {
79
+ this.formattedValue = format(this.value$, formatter ? formatter.toLowerCase() : 'currency', getCurrencyOptions(currencyISOCode));
198
80
  }
199
81
  }
200
82
 
@@ -219,21 +101,4 @@ export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
219
101
  handleEvent(actionsApi, 'changeNblur', propName, value);
220
102
  }
221
103
  }
222
-
223
- getErrorMessage() {
224
- let errMessage = '';
225
-
226
- // look for validation messages for json, pre-defined or just an error pushed from workitem (400)
227
- if (this.fieldControl.hasError('message')) {
228
- errMessage = this.angularPConnectData.validateMessage ?? '';
229
- return errMessage;
230
- }
231
- if (this.fieldControl.hasError('required')) {
232
- errMessage = 'You must enter a value';
233
- } else if (this.fieldControl.errors) {
234
- errMessage = this.fieldControl.errors.toString();
235
- }
236
-
237
- return errMessage;
238
- }
239
104
  }
@@ -1,19 +1,18 @@
1
- import { Component, OnInit, Input, ChangeDetectorRef, forwardRef, OnDestroy } from '@angular/core';
1
+ import { Component, forwardRef } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
- import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
3
+ import { FormControl, ReactiveFormsModule } from '@angular/forms';
4
4
  import { MatInputModule } from '@angular/material/input';
5
5
  import { MatFormFieldModule } from '@angular/material/form-field';
6
- import { interval } from 'rxjs';
7
6
  import { NgxCurrencyDirective, NgxCurrencyInputMode } from 'ngx-currency';
8
- import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
9
- import { Utils } from '@pega/angular-sdk-components';
7
+ import { FieldBase } from '@pega/angular-sdk-components';
10
8
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
11
9
  import { handleEvent } from '@pega/angular-sdk-components';
12
10
  import { getCurrencyCharacters } from '@pega/angular-sdk-components';
13
- import { PConnFieldProps } from '@pega/angular-sdk-components';
14
11
  import { format } from '@pega/angular-sdk-components';
12
+ import { PConnFieldProps } from '@pega/angular-sdk-components';
15
13
 
16
- interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
14
+ interface {{COMPONENT_CLASS_NAME}}Props extends Omit<PConnFieldProps, 'value'> {
15
+ value?: number;
17
16
  showGroupSeparators?: string;
18
17
  decimalPrecision?: number;
19
18
  currencyISOCode?: string;
@@ -26,155 +25,54 @@ interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
26
25
  styleUrls: ['./{{COMPONENT_CLASS_NAME_KEBAB}}.component.scss'],
27
26
  imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, NgxCurrencyDirective, forwardRef(() => ComponentMapperComponent)]
28
27
  })
29
- export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
30
- @Input() pConn$: typeof PConnect;
31
- @Input() formGroup$: FormGroup;
32
-
33
- // Used with AngularPConnect
34
- angularPConnectData: AngularPConnectData = {};
28
+ export class {{COMPONENT_CLASS_NAME}}Component extends FieldBase {
35
29
  configProps$: {{COMPONENT_CLASS_NAME}}Props;
30
+ override fieldControl = new FormControl<number | null>(null, null);
36
31
 
37
- label$ = '';
38
- value$: number;
39
- bRequired$ = false;
40
- bReadonly$ = false;
41
- bDisabled$ = false;
42
- bVisible$ = true;
43
- displayMode$?: string = '';
44
- controlName$: string;
45
- bHasForm$ = true;
46
- componentReference = '';
47
- testId: string;
48
- helperText: string;
49
- placeholder: string;
50
32
  decimalSeparator: string;
51
33
  thousandSeparator: string;
52
- inputMode: any;
34
+ inputMode: any = NgxCurrencyInputMode.Natural;
53
35
  decimalPrecision: number | undefined;
54
- fieldControl = new FormControl<number | null>(null, null);
55
- actionsApi: object;
56
- propName: string;
57
36
  formattedValue: string;
58
37
 
59
- constructor(
60
- private angularPConnect: AngularPConnectService,
61
- private cdRef: ChangeDetectorRef,
62
- private utils: Utils
63
- ) {}
64
-
65
- ngOnInit(): void {
66
- // First thing in initialization is registering and subscribing to the AngularPConnect service
67
- this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
68
- this.controlName$ = this.angularPConnect.getComponentID(this);
69
-
70
- // Then, continue on with other initialization
71
- // call updateSelf when initializing
72
- // this.updateSelf();
73
- this.checkAndUpdate();
38
+ /**
39
+ * Updates the component when there are changes in the state.
40
+ */
41
+ override updateSelf(): void {
42
+ // Resolve configuration properties
43
+ this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as {{COMPONENT_CLASS_NAME}}Props;
74
44
 
75
- if (this.formGroup$) {
76
- // add control to formGroup
77
- this.formGroup$.addControl(this.controlName$, this.fieldControl);
78
- this.fieldControl.setValue(this.value$);
79
- this.bHasForm$ = true;
80
- } else {
81
- this.bReadonly$ = true;
82
- this.bHasForm$ = false;
83
- }
84
- }
45
+ // Update component common properties
46
+ this.updateComponentCommonProperties(this.configProps$);
85
47
 
86
- ngOnDestroy(): void {
87
- if (this.formGroup$) {
88
- this.formGroup$.removeControl(this.controlName$);
48
+ // Set component specific properties
49
+ const { value } = this.configProps$;
50
+ if (value) {
51
+ this.value$ = value;
52
+ this.fieldControl.setValue(value);
89
53
  }
90
54
 
91
- if (this.angularPConnectData.unsubscribeFn) {
92
- this.angularPConnectData.unsubscribeFn();
93
- }
55
+ // update percentage properties
56
+ this.updatePercentageProperties(this.configProps$);
94
57
  }
95
58
 
96
- // Callback passed when subscribing to store change
97
- onStateChange() {
98
- this.checkAndUpdate();
99
- }
100
-
101
- checkAndUpdate() {
102
- // Should always check the bridge to see if the component should
103
- // update itself (re-render)
104
- const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
105
-
106
- // ONLY call updateSelf when the component should update
107
- if (bUpdateSelf) {
108
- this.updateSelf();
109
- }
110
- }
111
-
112
- // updateSelf
113
- updateSelf(): void {
114
- // moved this from ngOnInit() and call this from there instead...
115
- this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as {{COMPONENT_CLASS_NAME}}Props;
116
- this.testId = this.configProps$.testId;
117
- this.label$ = this.configProps$.label;
118
- this.displayMode$ = this.configProps$.displayMode;
119
- this.inputMode = NgxCurrencyInputMode.Natural;
120
- const nValue: any = this.configProps$.value;
121
- if (nValue) {
122
- this.value$ = nValue;
123
- this.fieldControl.setValue(nValue);
124
- }
125
- this.helperText = this.configProps$.helperText;
126
- this.placeholder = this.configProps$.placeholder || '';
127
- const showGroupSeparators = this.configProps$.showGroupSeparators;
59
+ /**
60
+ * Updates the percentage properties
61
+ *
62
+ * @param {Object} configProps - Configuration properties.
63
+ * @param {boolean} configProps.showGroupSeparators - Whether to show group separators.
64
+ * @param {number} configProps.decimalPrecision - The number of decimal places to display.
65
+ */
66
+ updatePercentageProperties(configProps): void {
67
+ const { showGroupSeparators, decimalPrecision } = configProps;
128
68
 
129
69
  const theSymbols = getCurrencyCharacters('');
130
70
  this.decimalSeparator = theSymbols.theDecimalIndicator;
131
71
  this.thousandSeparator = showGroupSeparators ? theSymbols.theDigitGroupSeparator : '';
72
+ this.decimalPrecision = decimalPrecision ?? 2;
132
73
 
133
- this.actionsApi = this.pConn$.getActionsApi();
134
- this.propName = this.pConn$.getStateProps().value;
135
-
136
- if (this.displayMode$ === 'DISPLAY_ONLY' || this.displayMode$ === 'STACKED_LARGE_VAL') {
137
- this.formattedValue = nValue ? format(nValue, 'percentage') : '';
138
- }
139
-
140
- // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
141
- setTimeout(() => {
142
- if (this.configProps$.required != null) {
143
- this.bRequired$ = this.utils.getBooleanValue(this.configProps$.required);
144
- }
145
- this.cdRef.detectChanges();
146
- });
147
-
148
- if (this.configProps$.visibility != null) {
149
- this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
150
- }
151
-
152
- // disabled
153
- if (this.configProps$.disabled != undefined) {
154
- this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
155
- }
156
-
157
- if (this.bDisabled$) {
158
- this.fieldControl.disable();
159
- } else {
160
- this.fieldControl.enable();
161
- }
162
-
163
- if (this.configProps$.readOnly != null) {
164
- this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
165
- }
166
-
167
- this.decimalPrecision = this.configProps$?.decimalPrecision ?? 2;
168
-
169
- this.componentReference = this.pConn$.getStateProps().value;
170
-
171
- // trigger display of error message with field control
172
- if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
173
- const timer = interval(100).subscribe(() => {
174
- this.fieldControl.setErrors({ message: true });
175
- this.fieldControl.markAsTouched();
176
- timer.unsubscribe();
177
- });
74
+ if (['DISPLAY_ONLY', 'STACKED_LARGE_VAL'].includes(this.displayMode$)) {
75
+ this.formattedValue = this.value$ ? format(this.value$, 'percentage') : '';
178
76
  }
179
77
  }
180
78
 
@@ -210,20 +108,4 @@ export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
210
108
  handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
211
109
  }
212
110
  }
213
-
214
- getErrorMessage() {
215
- // field control gets error message from here
216
- let errMessage = '';
217
- // look for validation messages for json, pre-defined or just an error pushed from workitem (400)
218
- if (this.fieldControl.hasError('message')) {
219
- errMessage = this.angularPConnectData.validateMessage ?? '';
220
- return errMessage;
221
- }
222
- if (this.fieldControl.hasError('required')) {
223
- errMessage = 'You must enter a value';
224
- } else if (this.fieldControl.errors) {
225
- errMessage = this.fieldControl.errors.toString();
226
- }
227
- return errMessage;
228
- }
229
111
  }
@@ -1,14 +1,13 @@
1
- import { Component, OnInit, Input, ChangeDetectorRef, forwardRef, OnDestroy } from '@angular/core';
1
+ import { Component, forwardRef } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
- import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
3
+ import { FormControl, ReactiveFormsModule } from '@angular/forms';
4
4
  import { MatInputModule } from '@angular/material/input';
5
5
  import { MatFormFieldModule } from '@angular/material/form-field';
6
- import { interval } from 'rxjs';
7
- import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
8
- import { Utils } from '@pega/angular-sdk-components';
6
+
7
+ import { FieldBase } from '@pega/angular-sdk-components';
9
8
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
10
- import { PConnFieldProps } from '@pega/angular-sdk-components';
11
9
  import { handleEvent } from '@pega/angular-sdk-components';
10
+ import { PConnFieldProps } from '@pega/angular-sdk-components';
12
11
 
13
12
  interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
14
13
  // If any, enter additional props that only exist on Integer here
@@ -20,143 +19,24 @@ interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
20
19
  styleUrls: ['./{{COMPONENT_CLASS_NAME_KEBAB}}.component.scss'],
21
20
  imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, forwardRef(() => ComponentMapperComponent)]
22
21
  })
23
- export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
24
- @Input() pConn$: typeof PConnect;
25
- @Input() formGroup$: FormGroup;
26
-
27
- // Used with AngularPConnect
28
- angularPConnectData: AngularPConnectData = {};
22
+ export class {{COMPONENT_CLASS_NAME}}Component extends FieldBase {
29
23
  configProps$: {{COMPONENT_CLASS_NAME}}Props;
24
+ override fieldControl = new FormControl<number | null>(null, null);
30
25
 
31
- label$ = '';
32
- value$: number;
33
- bRequired$ = false;
34
- bReadonly$ = false;
35
- bDisabled$ = false;
36
- bVisible$ = true;
37
- displayMode$?: string = '';
38
- controlName$: string;
39
- bHasForm$ = true;
40
- componentReference = '';
41
- testId: string;
42
- helperText: string;
43
- placeholder: string;
44
-
45
- fieldControl = new FormControl<number | null>(null, null);
46
- actionsApi: object;
47
- propName: string;
48
-
49
- constructor(
50
- private angularPConnect: AngularPConnectService,
51
- private cdRef: ChangeDetectorRef,
52
- private utils: Utils
53
- ) {}
54
-
55
- ngOnInit(): void {
56
- // First thing in initialization is registering and subscribing to the AngularPConnect service
57
- this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
58
- this.controlName$ = this.angularPConnect.getComponentID(this);
59
-
60
- // Then, continue on with other initialization
61
-
62
- // call updateSelf when initializing
63
- // this.updateSelf();
64
- this.checkAndUpdate();
65
-
66
- if (this.formGroup$) {
67
- // add control to formGroup
68
- this.formGroup$.addControl(this.controlName$, this.fieldControl);
69
- this.fieldControl.setValue(this.value$);
70
- this.bHasForm$ = true;
71
- } else {
72
- this.bReadonly$ = true;
73
- this.bHasForm$ = false;
74
- }
75
- }
76
-
77
- ngOnDestroy(): void {
78
- if (this.formGroup$) {
79
- this.formGroup$.removeControl(this.controlName$);
80
- }
81
-
82
- if (this.angularPConnectData.unsubscribeFn) {
83
- this.angularPConnectData.unsubscribeFn();
84
- }
85
- }
86
-
87
- // Callback passed when subscribing to store change
88
- onStateChange() {
89
- this.checkAndUpdate();
90
- }
91
-
92
- checkAndUpdate() {
93
- // Should always check the bridge to see if the component should
94
- // update itself (re-render)
95
- const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
96
-
97
- // ONLY call updateSelf when the component should update
98
- if (bUpdateSelf) {
99
- this.updateSelf();
100
- }
101
- }
102
-
103
- // updateSelf
104
- updateSelf(): void {
105
- // moved this from ngOnInit() and call this from there instead...
26
+ /**
27
+ * Updates the component when there are changes in the state.
28
+ */
29
+ override updateSelf(): void {
30
+ // Resolve configuration properties
106
31
  this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as {{COMPONENT_CLASS_NAME}}Props;
107
- this.testId = this.configProps$.testId;
108
- this.label$ = this.configProps$.label;
109
- this.displayMode$ = this.configProps$.displayMode;
110
- let nValue: any = this.configProps$.value;
111
- if (nValue) {
112
- if (typeof nValue === 'string') {
113
- nValue = parseInt(nValue, 10);
114
- }
115
- this.value$ = nValue;
116
- }
117
- this.helperText = this.configProps$.helperText;
118
- this.placeholder = this.configProps$.placeholder || '';
119
-
120
- this.actionsApi = this.pConn$.getActionsApi();
121
- this.propName = this.pConn$.getStateProps().value;
122
-
123
- // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
124
- setTimeout(() => {
125
- if (this.configProps$.required != null) {
126
- this.bRequired$ = this.utils.getBooleanValue(this.configProps$.required);
127
- }
128
- this.cdRef.detectChanges();
129
- });
130
-
131
- if (this.configProps$.visibility != null) {
132
- this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
133
- }
134
-
135
- // disabled
136
- if (this.configProps$.disabled != undefined) {
137
- this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
138
- }
139
-
140
- if (this.bDisabled$) {
141
- this.fieldControl.disable();
142
- } else {
143
- this.fieldControl.enable();
144
- }
145
32
 
146
- if (this.configProps$.readOnly != null) {
147
- this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
148
- }
149
-
150
- this.componentReference = this.pConn$.getStateProps().value;
151
-
152
- // trigger display of error message with field control
153
- if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
154
- const timer = interval(100).subscribe(() => {
155
- this.fieldControl.setErrors({ message: true });
156
- this.fieldControl.markAsTouched();
33
+ // Update component common properties
34
+ this.updateComponentCommonProperties(this.configProps$);
157
35
 
158
- timer.unsubscribe();
159
- });
36
+ // Extract and normalize the value property
37
+ const { value } = this.configProps$;
38
+ if (value) {
39
+ this.value$ = typeof value === 'string' ? parseInt(value, 10) : value;
160
40
  }
161
41
  }
162
42
 
@@ -180,23 +60,4 @@ export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
180
60
  handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
181
61
  }
182
62
  }
183
-
184
- getErrorMessage() {
185
- // field control gets error message from here
186
-
187
- let errMessage = '';
188
-
189
- // look for validation messages for json, pre-defined or just an error pushed from workitem (400)
190
- if (this.fieldControl.hasError('message')) {
191
- errMessage = this.angularPConnectData.validateMessage ?? '';
192
- return errMessage;
193
- }
194
- if (this.fieldControl.hasError('required')) {
195
- errMessage = 'You must enter a value';
196
- } else if (this.fieldControl.errors) {
197
- errMessage = this.fieldControl.errors.toString();
198
- }
199
-
200
- return errMessage;
201
- }
202
63
  }