@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,15 +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 { ReactiveFormsModule } from '@angular/forms';
4
4
  import { MatRadioModule } from '@angular/material/radio';
5
5
  import { MatInputModule } from '@angular/material/input';
6
6
  import { MatFormFieldModule } from '@angular/material/form-field';
7
- import { interval } from 'rxjs';
8
- import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
9
- import { Utils } from '@pega/angular-sdk-components';
7
+
8
+ import { FieldBase } from '@pega/angular-sdk-components';
10
9
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
11
- import { PConnFieldProps } from '@pega/angular-sdk-components';
10
+ import { Utils } from '@pega/angular-sdk-components';
12
11
  import { handleEvent } from '@pega/angular-sdk-components';
12
+ import { PConnFieldProps } from '@pega/angular-sdk-components';
13
13
 
14
14
  interface IOption {
15
15
  key: string;
@@ -30,159 +30,58 @@ interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
30
30
  providers: [Utils],
31
31
  imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatRadioModule, forwardRef(() => ComponentMapperComponent)]
32
32
  })
33
- export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
34
- @Input() pConn$: typeof PConnect;
35
- @Input() formGroup$: FormGroup;
36
-
37
- // Used with AngularPConnect
38
- angularPConnectData: AngularPConnectData = {};
33
+ export class {{COMPONENT_CLASS_NAME}}Component extends FieldBase {
39
34
  configProps$: {{COMPONENT_CLASS_NAME}}Props;
40
35
 
41
- label$ = '';
42
- value$ = '';
43
- bRequired$ = false;
44
- bReadonly$ = false;
45
- bDisabled$ = false;
46
- bVisible$ = true;
47
36
  bInline$ = false;
48
- displayMode$?: string = '';
49
- controlName$: string;
50
- bHasForm$ = true;
37
+
51
38
  options$: IOption[];
52
39
  componentReference = '';
53
- testId: string;
54
- helperText: string;
55
- placeholder: string;
56
-
57
- fieldControl = new FormControl('', null);
58
40
  fieldMetadata: any[];
59
41
  localeContext = '';
60
42
  localeClass = '';
61
43
  localeName = '';
62
44
  localePath = '';
63
45
  localizedValue = '';
64
- actionsApi: object;
65
- propName: string;
66
46
  variant?: string;
67
47
 
68
- constructor(
69
- private angularPConnect: AngularPConnectService,
70
- private cdRef: ChangeDetectorRef,
71
- private utils: Utils
72
- ) {}
73
-
74
- ngOnInit(): void {
75
- // First thing in initialization is registering and subscribing to the AngularPConnect service
76
- this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
77
- this.controlName$ = this.angularPConnect.getComponentID(this);
78
-
79
- // Then, continue on with other initialization
80
-
81
- // call updateSelf when initializing
82
- // this.updateSelf();
83
- this.checkAndUpdate();
84
-
85
- if (this.formGroup$) {
86
- // add control to formGroup
87
- this.formGroup$.addControl(this.controlName$, this.fieldControl);
88
- this.fieldControl.setValue(this.value$);
89
- this.bHasForm$ = true;
90
- } else {
91
- this.bReadonly$ = true;
92
- this.bHasForm$ = false;
93
- }
94
- }
95
-
96
- ngOnDestroy(): void {
97
- if (this.formGroup$) {
98
- this.formGroup$.removeControl(this.controlName$);
99
- }
100
-
101
- if (this.angularPConnectData.unsubscribeFn) {
102
- this.angularPConnectData.unsubscribeFn();
103
- }
104
- }
105
-
106
- // Callback passed when subscribing to store change
107
- onStateChange() {
108
- this.checkAndUpdate();
109
- }
110
-
111
- checkAndUpdate() {
112
- // Should always check the bridge to see if the component should
113
- // update itself (re-render)
114
- const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
115
-
116
- // ONLY call updateSelf when the component should update
117
- if (bUpdateSelf) {
118
- this.updateSelf();
119
- }
120
- }
121
-
122
- // updateSelf
123
- updateSelf(): void {
124
- // moved this from ngOnInit() and call this from there instead...
48
+ /**
49
+ * Updates the component when there are changes in the state.
50
+ */
51
+ override updateSelf(): void {
52
+ // Resolve config properties
125
53
  this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as {{COMPONENT_CLASS_NAME}}Props;
126
54
 
127
- if (this.configProps$.value != undefined) {
128
- this.value$ = this.configProps$.value;
129
- }
130
-
131
- this.testId = this.configProps$.testId;
132
- this.label$ = this.configProps$.label;
133
- this.displayMode$ = this.configProps$.displayMode;
134
- this.helperText = this.configProps$.helperText;
135
- this.placeholder = this.configProps$.placeholder || '';
136
-
137
- this.variant = this.configProps$.variant;
138
-
139
- // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
140
- setTimeout(() => {
141
- if (this.configProps$.required != null) {
142
- this.bRequired$ = this.utils.getBooleanValue(this.configProps$.required);
143
- }
144
- this.cdRef.detectChanges();
145
- });
146
-
147
- if (this.configProps$.visibility != null) {
148
- this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
149
- }
55
+ // Update component common properties
56
+ this.updateComponentCommonProperties(this.configProps$);
150
57
 
151
- if (this.configProps$.inline != null) {
152
- this.bInline$ = this.utils.getBooleanValue(this.configProps$.inline);
153
- }
58
+ // Extract and normalize the value property
59
+ const { value } = this.configProps$;
60
+ this.value$ = value;
154
61
 
155
- if (this.configProps$.disabled != undefined) {
156
- this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
157
- }
158
-
159
- if (this.configProps$.inline != null) {
160
- this.bInline$ = this.utils.getBooleanValue(this.configProps$.inline);
161
- }
162
-
163
- if (this.bDisabled$) {
164
- this.fieldControl.disable();
165
- } else {
166
- this.fieldControl.enable();
167
- }
168
-
169
- if (this.configProps$.readOnly != null) {
170
- this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
171
- }
62
+ // Set component specific properties
63
+ this.updateRadioButtonsProperties(this.configProps$);
64
+ }
172
65
 
173
- this.componentReference = this.pConn$.getStateProps().value;
66
+ /**
67
+ * Updates radio buttons properties based on the provided config props.
68
+ * @param configProps Configuration properties.
69
+ */
70
+ protected updateRadioButtonsProperties(configProps) {
71
+ const { inline, fieldMetadata, variant } = configProps;
174
72
 
175
- this.options$ = this.utils.getOptionList(this.configProps$, this.pConn$.getDataObject());
73
+ this.variant = variant;
74
+ this.bInline$ = this.utils.getBooleanValue(inline);
176
75
 
177
- this.actionsApi = this.pConn$.getActionsApi();
178
- this.propName = this.pConn$.getStateProps().value;
76
+ // Get options from config props and data object
77
+ this.options$ = this.utils.getOptionList(configProps, this.pConn$.getDataObject());
179
78
 
79
+ // Extract metadata and locale information
180
80
  const className = this.pConn$.getCaseInfo().getClassName();
181
81
  const refName = this.propName?.slice(this.propName.lastIndexOf('.') + 1);
82
+ const metaData = Array.isArray(fieldMetadata) ? fieldMetadata.filter(field => field?.classID === className)[0] : fieldMetadata;
182
83
 
183
- this.fieldMetadata = this.configProps$.fieldMetadata;
184
- const metaData = Array.isArray(this.fieldMetadata) ? this.fieldMetadata.filter(field => field?.classID === className)[0] : this.fieldMetadata;
185
-
84
+ // Determine display name and locale context
186
85
  let displayName = metaData?.datasource?.propertyForDisplayText;
187
86
  displayName = displayName?.slice(displayName.lastIndexOf('.') + 1);
188
87
  this.localeContext = metaData?.datasource?.tableType === 'DataPage' ? 'datapage' : 'associated';
@@ -190,20 +89,12 @@ export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
190
89
  this.localeName = this.localeContext === 'datapage' ? metaData?.datasource?.name : refName;
191
90
  this.localePath = this.localeContext === 'datapage' ? displayName : this.localeName;
192
91
 
92
+ // Get localized value
193
93
  this.localizedValue = this.pConn$.getLocalizedValue(
194
94
  this.value$,
195
95
  this.localePath,
196
96
  this.pConn$.getLocaleRuleNameFromKeys(this.localeClass, this.localeContext, this.localeName)
197
97
  );
198
- // trigger display of error message with field control
199
- if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
200
- const timer = interval(100).subscribe(() => {
201
- this.fieldControl.setErrors({ message: true });
202
- this.fieldControl.markAsTouched();
203
-
204
- timer.unsubscribe();
205
- });
206
- }
207
98
  }
208
99
 
209
100
  isSelected(buttonValue: string): boolean {
@@ -221,21 +112,4 @@ export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
221
112
  this.pConn$.getLocaleRuleNameFromKeys(this.localeClass, this.localeContext, this.localeName)
222
113
  );
223
114
  }
224
-
225
- getErrorMessage() {
226
- let errMessage = '';
227
-
228
- // look for validation messages for json, pre-defined or just an error pushed from workitem (400)
229
- if (this.fieldControl.hasError('message')) {
230
- errMessage = this.angularPConnectData.validateMessage ?? '';
231
- return errMessage;
232
- }
233
- if (this.fieldControl.hasError('required')) {
234
- errMessage = 'You must enter a value';
235
- } else if (this.fieldControl.errors) {
236
- errMessage = this.fieldControl.errors.toString();
237
- }
238
-
239
- return errMessage;
240
- }
241
115
  }
@@ -1,175 +1,60 @@
1
- import { Component, OnInit, Input, 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 { 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
+ import { FieldBase } from '@pega/angular-sdk-components';
9
7
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
8
+ import { handleEvent } from '@pega/angular-sdk-components';
10
9
  import { PConnFieldProps } from '@pega/angular-sdk-components';
11
10
 
12
11
  interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
13
12
  // If any, enter additional props that only exist on Text here
13
+ fieldMetadata?: any;
14
14
  }
15
15
 
16
16
  @Component({
17
17
  selector: 'app-{{COMPONENT_CLASS_NAME_KEBAB}}',
18
18
  templateUrl: './{{COMPONENT_CLASS_NAME_KEBAB}}.component.html',
19
19
  styleUrls: ['./{{COMPONENT_CLASS_NAME_KEBAB}}.component.scss'],
20
- imports: [CommonModule, MatInputModule, MatFormFieldModule, ReactiveFormsModule, forwardRef(() => ComponentMapperComponent)]
20
+ imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, forwardRef(() => ComponentMapperComponent)]
21
21
  })
22
- export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
23
- @Input() pConn$: typeof PConnect;
24
- @Input() formGroup$: FormGroup;
25
-
26
- // For interaction with AngularPConnect
27
- angularPConnectData: AngularPConnectData = {};
22
+ export class {{COMPONENT_CLASS_NAME}}Component extends FieldBase {
28
23
  configProps$: {{COMPONENT_CLASS_NAME}}Props;
29
24
 
30
- value$ = '';
31
- placeholder: string;
32
- bVisible$ = true;
33
- bDisabled$ = false;
34
- bReadonly$ = false;
35
- bRequired$ = false;
36
- label$ = '';
37
- bHideLabel$ = false;
38
- testId = '';
39
- helperText: string;
40
- displayMode$?: string = '';
41
-
42
- controlName$: string;
43
- bHasForm$ = true;
44
- componentReference = '';
45
-
46
- fieldControl = new FormControl('', null);
47
-
48
- constructor(
49
- private angularPConnect: AngularPConnectService,
50
- private utils: Utils
51
- ) {}
52
-
53
- ngOnInit(): void {
54
- // First thing in initialization is registering and subscribing to the AngularPConnect service
55
- this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
56
- this.controlName$ = this.angularPConnect.getComponentID(this);
57
-
58
- // Then, continue on with other initialization
59
-
60
- // call updateSelf when initializing
61
- // this.updateSelf();
62
- this.checkAndUpdate();
63
-
64
- if (this.formGroup$) {
65
- // add control to formGroup
66
- this.formGroup$.addControl(this.controlName$, this.fieldControl);
67
- this.fieldControl.setValue(this.value$);
68
- this.bHasForm$ = true;
69
- } else {
70
- this.bReadonly$ = true;
71
- this.bHasForm$ = false;
72
- }
73
- }
74
-
75
- ngOnDestroy(): void {
76
- if (this.formGroup$) {
77
- this.formGroup$.removeControl(this.controlName$);
78
- }
79
-
80
- if (this.angularPConnectData.unsubscribeFn) {
81
- this.angularPConnectData.unsubscribeFn();
82
- }
83
- }
84
-
85
- // Callback passed when subscribing to store change
86
- onStateChange() {
87
- this.checkAndUpdate();
88
- }
89
-
90
- checkAndUpdate() {
91
- // Should always check the bridge to see if the component should
92
- // update itself (re-render)
93
- const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
94
-
95
- // ONLY call updateSelf when the component should update
96
- if (bUpdateSelf) {
97
- this.updateSelf();
98
- }
99
- }
100
-
101
- // updateSelf
102
- updateSelf(): void {
103
- this.componentReference = this.pConn$.getStateProps().value;
104
- // moved this from ngOnInit() and call this from there instead...
25
+ /**
26
+ * Updates the component when there are changes in the state.
27
+ */
28
+ override updateSelf(): void {
29
+ // Resolve configuration properties
105
30
  this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as {{COMPONENT_CLASS_NAME}}Props;
106
31
 
107
- if (this.configProps$.value != undefined) {
108
- this.value$ = this.configProps$.value;
109
- }
110
- this.testId = this.configProps$.testId;
111
- this.label$ = this.configProps$.label;
112
- this.helperText = this.configProps$.helperText;
113
- this.placeholder = this.configProps$.placeholder || '';
114
- this.displayMode$ = this.configProps$.displayMode;
115
-
116
- if (this.configProps$.visibility != null) {
117
- this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
118
- }
119
-
120
- if (this.configProps$.required != null) {
121
- this.bRequired$ = this.utils.getBooleanValue(this.configProps$.required);
122
- }
123
-
124
- // disabled
125
- if (this.configProps$.disabled != null) {
126
- this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
127
- }
128
-
129
- if (this.bDisabled$) {
130
- this.fieldControl.disable();
131
- } else {
132
- this.fieldControl.enable();
133
- }
32
+ // Update component common properties
33
+ this.updateComponentCommonProperties(this.configProps$);
134
34
 
135
- if (this.configProps$.readOnly != null) {
136
- this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
137
- }
35
+ // Get and set component specific properties
36
+ const { value } = this.configProps$;
37
+ this.value$ = value;
38
+ }
138
39
 
139
- // trigger display of error message with field control
140
- if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
141
- const timer = interval(100).subscribe(() => {
142
- this.fieldControl.setErrors({ message: true });
143
- this.fieldControl.markAsTouched();
40
+ fieldOnChange(event: any) {
41
+ const oldVal = this.value$ ?? '';
42
+ const isValueChanged = event.target.value.toString() !== oldVal.toString();
144
43
 
145
- timer.unsubscribe();
44
+ if (isValueChanged) {
45
+ this.pConn$.clearErrorMessages({
46
+ property: this.propName
146
47
  });
147
48
  }
148
49
  }
149
50
 
150
- fieldOnChange(event: any) {
151
- this.angularPConnectData.actions?.onChange(this, event);
152
- }
153
-
154
51
  fieldOnBlur(event: any) {
155
- // PConnect wants to use eventHandler for onBlur
156
- this.angularPConnectData.actions?.onBlur(this, event);
157
- }
158
-
159
- getErrorMessage() {
160
- let errMessage = '';
52
+ const oldVal = this.value$ ?? '';
53
+ const isValueChanged = event.target.value.toString() !== oldVal.toString();
161
54
 
162
- // look for validation messages for json, pre-defined or just an error pushed from workitem (400)
163
- if (this.fieldControl.hasError('message')) {
164
- errMessage = this.angularPConnectData.validateMessage ?? '';
165
- return errMessage;
55
+ if (isValueChanged) {
56
+ const value = event?.target?.value;
57
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
166
58
  }
167
- if (this.fieldControl.hasError('required')) {
168
- errMessage = 'You must enter a value';
169
- } else if (this.fieldControl.errors) {
170
- errMessage = this.fieldControl.errors.toString();
171
- }
172
-
173
- return errMessage;
174
59
  }
175
60
  }
@@ -1,14 +1,12 @@
1
- import { Component, OnInit, Input, ChangeDetectorRef, forwardRef, OnDestroy } from '@angular/core';
1
+ import { Component, OnInit, forwardRef, OnDestroy } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
- import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
3
+ import { 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
+ import { FieldBase } from '@pega/angular-sdk-components';
9
7
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
10
- import { PConnFieldProps } from '@pega/angular-sdk-components';
11
8
  import { handleEvent } from '@pega/angular-sdk-components';
9
+ import { PConnFieldProps } from '@pega/angular-sdk-components';
12
10
 
13
11
  interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
14
12
  // If any, enter additional props that only exist on Email here
@@ -20,141 +18,22 @@ interface {{COMPONENT_CLASS_NAME}}Props extends PConnFieldProps {
20
18
  styleUrls: ['./{{COMPONENT_CLASS_NAME_KEBAB}}.component.scss'],
21
19
  imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, forwardRef(() => ComponentMapperComponent)]
22
20
  })
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 = {};
21
+ export class {{COMPONENT_CLASS_NAME}}Component extends FieldBase implements OnInit, OnDestroy {
29
22
  configProps$: {{COMPONENT_CLASS_NAME}}Props;
30
23
 
31
- label$ = '';
32
- value$: string;
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('', 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...
24
+ /**
25
+ * Updates the component when there are changes in the state.
26
+ */
27
+ override updateSelf(): void {
28
+ // Resolve configuration properties
106
29
  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
30
 
111
- if (this.configProps$.value != undefined) {
112
- this.value$ = this.configProps$.value;
113
- }
114
- this.helperText = this.configProps$.helperText;
115
- this.placeholder = this.configProps$.placeholder || '';
116
-
117
- // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
118
- setTimeout(() => {
119
- if (this.configProps$.required != null) {
120
- this.bRequired$ = this.utils.getBooleanValue(this.configProps$.required);
121
- }
122
- this.cdRef.detectChanges();
123
- });
124
-
125
- if (this.configProps$.visibility != null) {
126
- this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
127
- }
128
-
129
- // disabled
130
- if (this.configProps$.disabled != undefined) {
131
- this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
132
- }
133
-
134
- if (this.bDisabled$) {
135
- this.fieldControl.disable();
136
- } else {
137
- this.fieldControl.enable();
138
- }
139
-
140
- if (this.configProps$.readOnly != null) {
141
- this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
142
- }
143
-
144
- this.actionsApi = this.pConn$.getActionsApi();
145
- this.propName = this.pConn$.getStateProps().value;
146
-
147
- this.componentReference = this.pConn$.getStateProps().value;
31
+ // Update component common properties
32
+ this.updateComponentCommonProperties(this.configProps$);
148
33
 
149
- // trigger display of error message with field control
150
- if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
151
- const timer = interval(100).subscribe(() => {
152
- this.fieldControl.setErrors({ message: true });
153
- this.fieldControl.markAsTouched();
154
-
155
- timer.unsubscribe();
156
- });
157
- }
34
+ // Set component specific properties
35
+ const { value } = this.configProps$;
36
+ this.value$ = value;
158
37
  }
159
38
 
160
39
  fieldOnChange(event: any) {
@@ -162,8 +41,6 @@ export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
162
41
  const isValueChanged = event.target.value.toString() !== oldVal.toString();
163
42
 
164
43
  if (isValueChanged) {
165
- const value = event?.target?.value;
166
- handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
167
44
  this.pConn$.clearErrorMessages({
168
45
  property: this.propName
169
46
  });
@@ -179,21 +56,4 @@ export class {{COMPONENT_CLASS_NAME}}Component implements OnInit, OnDestroy {
179
56
  handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
180
57
  }
181
58
  }
182
-
183
- getErrorMessage() {
184
- let errMessage = '';
185
-
186
- // look for validation messages for json, pre-defined or just an error pushed from workitem (400)
187
- if (this.fieldControl.hasError('message')) {
188
- errMessage = this.angularPConnectData.validateMessage ?? '';
189
- return errMessage;
190
- }
191
- if (this.fieldControl.hasError('required')) {
192
- errMessage = 'You must enter a value';
193
- } else if (this.fieldControl.errors) {
194
- errMessage = this.fieldControl.errors.toString();
195
- }
196
-
197
- return errMessage;
198
- }
199
59
  }