@pega/angular-sdk-overrides 0.25.15 → 0.26.2

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 (86) hide show
  1. package/lib/designSystemExtension/alert/alert.component.html +4 -1
  2. package/lib/designSystemExtension/alert/alert.component.scss +9 -10
  3. package/lib/designSystemExtension/alert/alert.component.ts +6 -2
  4. package/lib/designSystemExtension/material-details-fields/material-details-fields.component.html +30 -21
  5. package/lib/designSystemExtension/operator/operator.component.ts +2 -1
  6. package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.html +104 -10
  7. package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.scss +141 -1
  8. package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.ts +224 -72
  9. package/lib/field/auto-complete/auto-complete.component.html +2 -1
  10. package/lib/field/auto-complete/auto-complete.component.ts +2 -0
  11. package/lib/field/check-box/check-box.component.html +4 -2
  12. package/lib/field/check-box/check-box.component.ts +10 -1
  13. package/lib/field/currency/currency.component.html +2 -1
  14. package/lib/field/currency/currency.component.ts +10 -1
  15. package/lib/field/date/date.component.html +2 -1
  16. package/lib/field/date/date.component.ts +2 -0
  17. package/lib/field/date-time/date-time.component.html +2 -1
  18. package/lib/field/date-time/date-time.component.scss +46 -40
  19. package/lib/field/date-time/date-time.component.ts +2 -0
  20. package/lib/field/decimal/decimal.component.html +2 -1
  21. package/lib/field/decimal/decimal.component.ts +2 -0
  22. package/lib/field/dropdown/dropdown.component.html +2 -1
  23. package/lib/field/dropdown/dropdown.component.ts +10 -1
  24. package/lib/field/email/email.component.html +2 -1
  25. package/lib/field/email/email.component.ts +2 -2
  26. package/lib/field/embedded-data-multi/embedded-data-multi.component.html +3 -0
  27. package/lib/field/embedded-data-multi/embedded-data-multi.component.scss +0 -0
  28. package/lib/field/embedded-data-multi/embedded-data-multi.component.ts +173 -0
  29. package/lib/field/field.base.ts +27 -1
  30. package/lib/field/integer/integer.component.html +2 -1
  31. package/lib/field/integer/integer.component.ts +4 -2
  32. package/lib/field/location/location.component.html +2 -1
  33. package/lib/field/location/location.component.ts +3 -1
  34. package/lib/field/multiselect/multiselect.component.html +1 -1
  35. package/lib/field/multiselect/multiselect.component.ts +22 -3
  36. package/lib/field/multiselect/utils.ts +5 -3
  37. package/lib/field/object-reference/object-reference.component.html +30 -15
  38. package/lib/field/object-reference/object-reference.component.ts +819 -94
  39. package/lib/field/percentage/percentage.component.html +2 -1
  40. package/lib/field/percentage/percentage.component.ts +10 -1
  41. package/lib/field/phone/phone.component.html +2 -1
  42. package/lib/field/phone/phone.component.ts +2 -1
  43. package/lib/field/radio-buttons/radio-buttons.component.html +2 -1
  44. package/lib/field/radio-buttons/radio-buttons.component.ts +10 -1
  45. package/lib/field/rich-text/rich-text.component.scss +1 -166
  46. package/lib/field/rich-text/rich-text.component.ts +1 -1
  47. package/lib/field/selectable-card/selectable-card.component.html +1 -0
  48. package/lib/field/selectable-card/selectable-card.component.ts +31 -16
  49. package/lib/field/semantic-link/semantic-link.component.ts +9 -5
  50. package/lib/field/text-area/text-area.component.html +2 -1
  51. package/lib/field/text-area/text-area.component.ts +2 -1
  52. package/lib/field/text-input/text-input.component.html +2 -1
  53. package/lib/field/text-input/text-input.component.ts +2 -1
  54. package/lib/field/time/time.component.html +2 -1
  55. package/lib/field/time/time.component.ts +2 -1
  56. package/lib/field/url/url.component.html +2 -1
  57. package/lib/field/url/url.component.ts +2 -1
  58. package/lib/field/user-reference/user-reference.component.html +4 -2
  59. package/lib/field/user-reference/user-reference.component.ts +10 -5
  60. package/lib/infra/Containers/flow-container/flow-container.component.ts +35 -46
  61. package/lib/infra/Containers/modal-view-container/modal-view-container.component.ts +46 -50
  62. package/lib/infra/Containers/view-container/view-container.component.ts +32 -31
  63. package/lib/infra/navbar/navbar.component.ts +33 -35
  64. package/lib/infra/root-container/root-container.component.ts +33 -38
  65. package/lib/template/app-shell/app-shell.component.ts +12 -11
  66. package/lib/template/base/details-template-base.ts +2 -1
  67. package/lib/template/data-reference/data-reference.component.ts +18 -27
  68. package/lib/template/data-reference/search-form/search-form.component.ts +7 -1
  69. package/lib/template/default-form/default-form.component.html +19 -3
  70. package/lib/template/default-form/default-form.component.ts +13 -3
  71. package/lib/template/simple-table/simple-table.component.ts +6 -0
  72. package/lib/template/simple-table-manual/helpers.ts +5 -5
  73. package/lib/template/simple-table-manual/simple-table-manual.component.html +29 -11
  74. package/lib/template/simple-table-manual/simple-table-manual.component.scss +4 -2
  75. package/lib/template/simple-table-manual/simple-table-manual.component.ts +82 -24
  76. package/lib/template/single-reference-readonly/single-reference-readonly.component.html +1 -1
  77. package/lib/template/single-reference-readonly/single-reference-readonly.component.scss +4 -0
  78. package/lib/template/single-reference-readonly/single-reference-readonly.component.ts +4 -4
  79. package/lib/template/wss-nav-bar/wss-nav-bar.component.ts +18 -20
  80. package/lib/widget/attachment/AttachmentUtils.ts +18 -10
  81. package/lib/widget/attachment/attachment.component.html +16 -6
  82. package/lib/widget/attachment/attachment.component.ts +12 -2
  83. package/lib/widget/case-history/case-history.component.ts +6 -2
  84. package/lib/widget/file-utility/file-utility.component.ts +25 -29
  85. package/lib/widget/todo/todo.component.ts +7 -2
  86. package/package.json +1 -1
@@ -6,6 +6,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
6
6
  import { NgxCurrencyDirective, NgxCurrencyInputMode } from 'ngx-currency';
7
7
 
8
8
  import { FieldBase } from '@pega/angular-sdk-components';
9
+ import { FieldWarningDirective } from '@pega/angular-sdk-components';
9
10
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
10
11
  import { handleEvent } from '@pega/angular-sdk-components';
11
12
  import { getCurrencyCharacters, getCurrencyOptions } from '@pega/angular-sdk-components';
@@ -31,6 +32,7 @@ interface DecimalProps extends PConnFieldProps {
31
32
  MatFormFieldModule,
32
33
  MatInputModule,
33
34
  NgxCurrencyDirective,
35
+ FieldWarningDirective,
34
36
  forwardRef(() => ComponentMapperComponent)
35
37
  ]
36
38
  })
@@ -8,7 +8,7 @@
8
8
  <ng-template #noDisplayMode>
9
9
  <div *ngIf="!bReadonly$ && bHasForm$; else noEdit">
10
10
  <div [formGroup]="formGroup$" *ngIf="bVisible$">
11
- <mat-form-field class="psdk-full-width" subscriptSizing="dynamic" [hintLabel]="helperText">
11
+ <mat-form-field class="psdk-full-width" subscriptSizing="dynamic">
12
12
  <mat-select
13
13
  [value]="value$"
14
14
  [required]="bRequired$"
@@ -22,6 +22,7 @@
22
22
  </mat-option>
23
23
  </mat-select>
24
24
  <mat-label>{{ label$ }}</mat-label>
25
+ <mat-hint *ngIf="helperText" [appFieldWarning]="bFieldMessageVisible$">{{ helperText }}</mat-hint>
25
26
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
26
27
  </mat-form-field>
27
28
  </div>
@@ -7,6 +7,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
7
7
  import isEqual from 'fast-deep-equal';
8
8
 
9
9
  import { FieldBase } from '@pega/angular-sdk-components';
10
+ import { FieldWarningDirective } from '@pega/angular-sdk-components';
10
11
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
11
12
  import { handleEvent } from '@pega/angular-sdk-components';
12
13
  import { PConnFieldProps } from '@pega/angular-sdk-components';
@@ -66,7 +67,15 @@ interface DropdownProps extends PConnFieldProps {
66
67
  selector: 'app-dropdown',
67
68
  templateUrl: './dropdown.component.html',
68
69
  styleUrls: ['./dropdown.component.scss'],
69
- imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatSelectModule, MatOptionModule, forwardRef(() => ComponentMapperComponent)]
70
+ imports: [
71
+ CommonModule,
72
+ ReactiveFormsModule,
73
+ MatFormFieldModule,
74
+ MatSelectModule,
75
+ MatOptionModule,
76
+ FieldWarningDirective,
77
+ forwardRef(() => ComponentMapperComponent)
78
+ ]
70
79
  })
71
80
  export class DropdownComponent extends FieldBase implements OnInit, OnDestroy {
72
81
  @Output() onRecordChange: EventEmitter<any> = new EventEmitter();
@@ -4,7 +4,7 @@
4
4
  <ng-template #noDisplayMode>
5
5
  <div *ngIf="!bReadonly$ && bHasForm$; else noEdit">
6
6
  <div [formGroup]="formGroup$" *ngIf="bVisible$">
7
- <mat-form-field class="psdk-full-width" subscriptSizing="dynamic" [hintLabel]="helperText">
7
+ <mat-form-field class="psdk-full-width" subscriptSizing="dynamic">
8
8
  <mat-label>{{ label$ }}</mat-label>
9
9
  <input
10
10
  matInput
@@ -17,6 +17,7 @@
17
17
  (change)="fieldOnChange($event)"
18
18
  (blur)="fieldOnBlur($event)"
19
19
  />
20
+ <mat-hint *ngIf="helperText" [appFieldWarning]="bFieldMessageVisible$">{{ helperText }}</mat-hint>
20
21
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
21
22
  </mat-form-field>
22
23
  </div>
@@ -5,6 +5,7 @@ import { MatInputModule } from '@angular/material/input';
5
5
  import { MatFormFieldModule } from '@angular/material/form-field';
6
6
 
7
7
  import { FieldBase } from '@pega/angular-sdk-components';
8
+ import { FieldWarningDirective } from '@pega/angular-sdk-components';
8
9
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
9
10
  import { handleEvent } from '@pega/angular-sdk-components';
10
11
  import { PConnFieldProps } from '@pega/angular-sdk-components';
@@ -17,7 +18,7 @@ interface EmailProps extends PConnFieldProps {
17
18
  selector: 'app-email',
18
19
  templateUrl: './email.component.html',
19
20
  styleUrls: ['./email.component.scss'],
20
- imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, forwardRef(() => ComponentMapperComponent)]
21
+ imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, FieldWarningDirective, forwardRef(() => ComponentMapperComponent)]
21
22
  })
22
23
  export class EmailComponent extends FieldBase implements OnInit, OnDestroy {
23
24
  configProps$: EmailProps;
@@ -28,7 +29,6 @@ export class EmailComponent extends FieldBase implements OnInit, OnDestroy {
28
29
  override updateSelf(): void {
29
30
  // Resolve configuration properties
30
31
  this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as EmailProps;
31
-
32
32
  // Update component common properties
33
33
  this.updateComponentCommonProperties(this.configProps$);
34
34
 
@@ -0,0 +1,3 @@
1
+ <div *ngIf="bVisible$ && simpleTableComponentName">
2
+ <component-mapper [name]="simpleTableComponentName" [props]="{ pConn$: simpleTablePConn, formGroup$ }"></component-mapper>
3
+ </div>
@@ -0,0 +1,173 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, Input, OnInit, OnDestroy, forwardRef } from '@angular/core';
3
+ import { FormGroup } from '@angular/forms';
4
+
5
+ import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
6
+ import { ComponentMapperComponent } from '@pega/angular-sdk-components';
7
+
8
+ interface EmbeddedDataMultiProps {
9
+ addEditAction?: string;
10
+ addEditView?: string;
11
+ displayAs?: string;
12
+ editAction?: string;
13
+ editMode?: string;
14
+ editType?: string;
15
+ editView?: string;
16
+ readOnly?: boolean;
17
+ repeatingView?: string;
18
+ targetObjectClass?: string;
19
+ useSeparateActionForEdit?: boolean;
20
+ useSeparateViewForEdit?: boolean;
21
+ visibility?: boolean;
22
+ }
23
+
24
+ @Component({
25
+ selector: 'app-embedded-data-multi',
26
+ templateUrl: './embedded-data-multi.component.html',
27
+ styleUrls: ['./embedded-data-multi.component.scss'],
28
+ imports: [CommonModule, forwardRef(() => ComponentMapperComponent)]
29
+ })
30
+ export class EmbeddedDataMultiComponent implements OnInit, OnDestroy {
31
+ @Input() pConn$: typeof PConnect;
32
+ @Input() formGroup$: FormGroup;
33
+
34
+ angularPConnectData: AngularPConnectData = {};
35
+ simpleTablePConn: typeof PConnect;
36
+ simpleTableComponentName = '';
37
+ bVisible$ = true;
38
+
39
+ constructor(private angularPConnect: AngularPConnectService) {}
40
+
41
+ ngOnInit(): void {
42
+ this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
43
+ this.checkAndUpdate();
44
+ }
45
+
46
+ ngOnDestroy(): void {
47
+ if (this.angularPConnectData.unsubscribeFn) {
48
+ this.angularPConnectData.unsubscribeFn();
49
+ }
50
+ }
51
+
52
+ onStateChange = () => {
53
+ this.checkAndUpdate();
54
+ };
55
+
56
+ checkAndUpdate() {
57
+ const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
58
+ if (bUpdateSelf) {
59
+ this.updateSelf();
60
+ }
61
+ }
62
+
63
+ updateSelf() {
64
+ const configProps = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as EmbeddedDataMultiProps;
65
+ const {
66
+ addEditAction,
67
+ addEditView,
68
+ displayAs,
69
+ editAction,
70
+ editMode,
71
+ editType,
72
+ editView,
73
+ readOnly = false,
74
+ repeatingView,
75
+ targetObjectClass,
76
+ useSeparateActionForEdit,
77
+ useSeparateViewForEdit,
78
+ visibility = true
79
+ } = configProps;
80
+
81
+ this.bVisible$ = visibility !== false;
82
+
83
+ const rawMetadata = this.pConn$.getRawMetadata();
84
+ const rawMetadataConfig = rawMetadata?.config as any;
85
+
86
+ if (!rawMetadataConfig) {
87
+ return;
88
+ }
89
+
90
+ const renderMode = readOnly ? 'ReadOnly' : 'Editable';
91
+
92
+ let columnsChildren;
93
+ if (displayAs === 'table' || displayAs === 'simpleTable') {
94
+ columnsChildren = [
95
+ {
96
+ children: rawMetadataConfig.columns || [],
97
+ name: 'Columns',
98
+ type: 'Region'
99
+ }
100
+ ];
101
+ }
102
+
103
+ let regionWithView: any[] = [];
104
+ if (displayAs === 'repeatingView') {
105
+ regionWithView = [
106
+ {
107
+ children: [
108
+ {
109
+ type: 'reference',
110
+ config: {
111
+ type: 'view',
112
+ name: repeatingView
113
+ }
114
+ }
115
+ ],
116
+ name: 'view',
117
+ type: 'Region'
118
+ }
119
+ ];
120
+ }
121
+
122
+ const { pagelistValue } = rawMetadataConfig;
123
+ const authorContext = pagelistValue?.startsWith('@P') ? pagelistValue?.substring(3) : pagelistValue;
124
+
125
+ const componentConfig = {
126
+ type: 'View',
127
+ config: {
128
+ template: 'SimpleTable',
129
+ type: 'multirecordlist',
130
+ authorContext,
131
+ name: authorContext?.substring(1),
132
+ renderMode,
133
+ multiRecordDisplayAs: displayAs === 'repeatingView' ? 'fieldGroup' : displayAs,
134
+ referenceList: pagelistValue,
135
+ contextClass: targetObjectClass,
136
+ editMode,
137
+ editModeConfig: {
138
+ editType,
139
+ defaultView: addEditView,
140
+ defaultAction: addEditAction,
141
+ useSeparateViewForEdit,
142
+ useSeparateActionForEdit,
143
+ editView,
144
+ editAction
145
+ },
146
+ label: rawMetadataConfig.label,
147
+ hideLabel: rawMetadataConfig.hideLabel,
148
+ children: columnsChildren,
149
+ displayField: rawMetadataConfig.displayField,
150
+ uniqueField: rawMetadataConfig.uniqueField,
151
+ targetClassLabel: rawMetadataConfig.targetClassLabel,
152
+ targetClassLabelOption: rawMetadataConfig.targetClassLabelOption,
153
+ fieldHeader: rawMetadataConfig.repeatingViewHeadingSource,
154
+ heading: rawMetadataConfig.repeatingViewHeading,
155
+ allowActions: {
156
+ allowAdd: rawMetadataConfig.allowAdd ?? true,
157
+ allowEdit: rawMetadataConfig.allowEdit ?? true,
158
+ allowDelete: rawMetadataConfig.allowDelete ?? true,
159
+ allowDragDrop: rawMetadataConfig.allowDragDrop ?? true
160
+ },
161
+ allowRowDelete: rawMetadataConfig.allowRowDelete ?? true,
162
+ allowRowEdit: rawMetadataConfig.allowRowEdit ?? true
163
+ },
164
+ children: regionWithView
165
+ };
166
+
167
+ const component = this.pConn$.createComponent(componentConfig as any, '', 0, {});
168
+ if (component) {
169
+ this.simpleTablePConn = component.getPConnect();
170
+ this.simpleTableComponentName = this.simpleTablePConn.getComponentName() ?? '';
171
+ }
172
+ }
173
+ }
@@ -3,6 +3,7 @@ import { FormControl, FormGroup } from '@angular/forms';
3
3
 
4
4
  import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
5
5
  import { Utils } from '@pega/angular-sdk-components';
6
+ import type { PConnFieldProps } from '../../_types/PConnProps.interface';
6
7
 
7
8
  @Directive()
8
9
  export class FieldBase implements OnInit, OnDestroy {
@@ -31,6 +32,10 @@ export class FieldBase implements OnInit, OnDestroy {
31
32
  bDisabled$ = false;
32
33
  bVisible$ = true;
33
34
  displayMode$ = '';
35
+ bFieldMessageVisible$ = false;
36
+ fieldMessage = '';
37
+
38
+ private defaultHelperText = '';
34
39
 
35
40
  /**
36
41
  * Initializes the component, registers with AngularPConnect, and sets up form control.
@@ -101,7 +106,7 @@ export class FieldBase implements OnInit, OnDestroy {
101
106
  this.label$ = label;
102
107
  this.hideLabel = hideLabel;
103
108
  this.displayMode$ = displayMode;
104
- this.helperText = helperText;
109
+ this.defaultHelperText = helperText ?? '';
105
110
  this.placeholder = placeholder || '';
106
111
 
107
112
  // Convert boolean properties
@@ -113,10 +118,27 @@ export class FieldBase implements OnInit, OnDestroy {
113
118
  // Enable or disable field control
114
119
  this.fieldControl[this.bDisabled$ ? 'disable' : 'enable']();
115
120
 
121
+ this.updateFieldMessage(configProps);
122
+
116
123
  // Display error message if validation message exists
117
124
  this.displayValidationMessage();
118
125
  }
119
126
 
127
+ /**
128
+ * Updates the contextual field message state for fields that support it.
129
+ *
130
+ * @param configProps The resolved field configuration.
131
+ */
132
+ protected updateFieldMessage(configProps: Pick<PConnFieldProps, 'messageConfig' | 'showFieldMessage'>): void {
133
+ const { messageConfig = {}, showFieldMessage } = configProps;
134
+ const isVisible = this.utils.getBooleanValue(messageConfig.visibility);
135
+ const shouldShowFieldMessage = this.utils.getBooleanValue(showFieldMessage) && isVisible && !this.bReadonly$;
136
+
137
+ this.bFieldMessageVisible$ = shouldShowFieldMessage;
138
+ this.fieldMessage = shouldShowFieldMessage ? (messageConfig.content ?? '') : '';
139
+ this.updateHelperText();
140
+ }
141
+
120
142
  /**
121
143
  * Displays the validation message if it exists.
122
144
  */
@@ -129,6 +151,10 @@ export class FieldBase implements OnInit, OnDestroy {
129
151
  }
130
152
  }
131
153
 
154
+ private updateHelperText(): void {
155
+ this.helperText = this.bFieldMessageVisible$ ? this.fieldMessage : this.defaultHelperText;
156
+ }
157
+
132
158
  /**
133
159
  * Retrieves the error message for the current field control.
134
160
  *
@@ -4,7 +4,7 @@
4
4
  <ng-template #noDisplayMode>
5
5
  <div *ngIf="!bReadonly$ && bHasForm$; else noEdit">
6
6
  <div [formGroup]="formGroup$" *ngIf="bVisible$">
7
- <mat-form-field class="psdk-full-width" subscriptSizing="dynamic" [hintLabel]="helperText">
7
+ <mat-form-field class="psdk-full-width" subscriptSizing="dynamic">
8
8
  <mat-label>{{ label$ }}</mat-label>
9
9
  <input
10
10
  matInput
@@ -18,6 +18,7 @@
18
18
  (change)="fieldOnChange($event)"
19
19
  (blur)="fieldOnBlur($event)"
20
20
  />
21
+ <mat-hint *ngIf="helperText" [appFieldWarning]="bFieldMessageVisible$">{{ helperText }}</mat-hint>
21
22
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
22
23
  </mat-form-field>
23
24
  </div>
@@ -5,6 +5,7 @@ import { MatInputModule } from '@angular/material/input';
5
5
  import { MatFormFieldModule } from '@angular/material/form-field';
6
6
 
7
7
  import { FieldBase } from '@pega/angular-sdk-components';
8
+ import { FieldWarningDirective } from '@pega/angular-sdk-components';
8
9
  import { ComponentMapperComponent } from '@pega/angular-sdk-components';
9
10
  import { handleEvent } from '@pega/angular-sdk-components';
10
11
  import { PConnFieldProps } from '@pega/angular-sdk-components';
@@ -17,7 +18,7 @@ interface IntegerProps extends PConnFieldProps {
17
18
  selector: 'app-integer',
18
19
  templateUrl: './integer.component.html',
19
20
  styleUrls: ['./integer.component.scss'],
20
- imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, forwardRef(() => ComponentMapperComponent)]
21
+ imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, FieldWarningDirective, forwardRef(() => ComponentMapperComponent)]
21
22
  })
22
23
  export class IntegerComponent extends FieldBase {
23
24
  configProps$: IntegerProps;
@@ -57,7 +58,8 @@ export class IntegerComponent extends FieldBase {
57
58
 
58
59
  if (isValueChanged) {
59
60
  const value = event?.target?.value;
60
- handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
61
+ const normalizedValue = value === '' ? '' : Number(value);
62
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, normalizedValue);
61
63
  }
62
64
  }
63
65
  }
@@ -1,6 +1,6 @@
1
1
  <div *ngIf="mapReady && bVisible$">
2
2
  <!-- Google suggestions -->
3
- <mat-form-field class="psdk-full-width" [hintLabel]="helperText">
3
+ <mat-form-field class="psdk-full-width">
4
4
  <mat-label>{{ label$ }}</mat-label>
5
5
  <input
6
6
  matInput
@@ -14,6 +14,7 @@
14
14
  (blur)="fieldOnBlur()"
15
15
  />
16
16
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
17
+ <mat-hint *ngIf="helperText" [appFieldWarning]="bFieldMessageVisible$">{{ helperText }}</mat-hint>
17
18
  <button
18
19
  mat-icon-button
19
20
  matSuffix
@@ -11,6 +11,7 @@ import { GoogleMapsModule } from '@angular/google-maps';
11
11
  import { debounceTime, from, of, switchMap } from 'rxjs';
12
12
 
13
13
  import { FieldBase } from '@pega/angular-sdk-components';
14
+ import { FieldWarningDirective } from '@pega/angular-sdk-components';
14
15
  import { GoogleMapsLoaderService } from '@pega/angular-sdk-components';
15
16
  import { handleEvent } from '@pega/angular-sdk-components';
16
17
 
@@ -34,7 +35,8 @@ interface LocationProps extends PConnFieldProps {
34
35
  MatIconModule,
35
36
  MatInputModule,
36
37
  MatProgressSpinnerModule,
37
- ReactiveFormsModule
38
+ ReactiveFormsModule,
39
+ FieldWarningDirective
38
40
  ],
39
41
  templateUrl: './location.component.html',
40
42
  styleUrl: './location.component.scss'
@@ -1,7 +1,7 @@
1
1
  <div [formGroup]="formGroup$">
2
2
  <mat-form-field class="psdk-full-width" subscriptSizing="dynamic">
3
3
  <mat-label>{{ label$ }}</mat-label>
4
- <mat-chip-grid #chipGrid [required]="bRequired$">
4
+ <mat-chip-grid #chipGrid>
5
5
  <ng-container *ngFor="let select of selectedItems">
6
6
  <mat-chip-row (removed)="removeChip(select)">
7
7
  {{ select.primary }}
@@ -91,13 +91,32 @@ export class MultiselectComponent extends FieldBase {
91
91
  }
92
92
  ];
93
93
  let secondaryColumns: any = [];
94
- if (secondaryFields) {
95
- secondaryColumns = secondaryFields.map(secondaryField => ({
96
- value: secondaryField,
94
+ // Read columnsFormatter from raw (unresolved) metadata to get field property paths
95
+ // (e.g. "@P .pyLabel") instead of resolved data values (e.g. "New Complex Fields").
96
+ // This matches Constellation's approach: pConn.getRawMetadata()?.config?.columnsFormatter
97
+ const columnsFormatter = (this.pConn$.getRawMetadata()?.config as any)?.columnsFormatter;
98
+ const secondaryFieldsFromFormatter = columnsFormatter
99
+ ? columnsFormatter
100
+ .map(item => {
101
+ const property = item?.config?.value;
102
+ if (typeof property === 'string') {
103
+ if (property.startsWith('@USER ')) return property.substring(6);
104
+ if (property.startsWith('@P ')) return property.substring(3);
105
+ return property;
106
+ }
107
+ return undefined;
108
+ })
109
+ .filter(Boolean)
110
+ : undefined;
111
+ const updatedSecondaryFields = secondaryFieldsFromFormatter || secondaryFields;
112
+ if (updatedSecondaryFields) {
113
+ secondaryColumns = updatedSecondaryFields.map(secondaryField => ({
114
+ value: typeof secondaryField === 'string' ? secondaryField : undefined,
97
115
  display: 'true',
98
116
  secondary: 'true',
99
117
  useForSearch: 'true'
100
118
  }));
119
+ secondaryColumns = secondaryColumns.filter(col => col.value);
101
120
  } else {
102
121
  secondaryColumns = [
103
122
  {
@@ -11,9 +11,11 @@ export function setVisibilityForList(c11nEnv, visibility) {
11
11
  function preProcessColumns(columns) {
12
12
  return columns?.map(col => {
13
13
  const tempColObj = { ...col };
14
- tempColObj.value = col.value && col.value.startsWith('.') ? col.value.substring(1) : col.value;
15
- if (tempColObj.setProperty) {
16
- tempColObj.setProperty = col.setProperty && col.setProperty.startsWith('.') ? col.setProperty.substring(1) : col.setProperty;
14
+ if (typeof col.value === 'string') {
15
+ tempColObj.value = col.value.startsWith('.') ? col.value.substring(1) : col.value;
16
+ }
17
+ if (typeof col.setProperty === 'string') {
18
+ tempColObj.setProperty = col.setProperty.startsWith('.') ? col.setProperty.substring(1) : col.setProperty;
17
19
  }
18
20
  return tempColObj;
19
21
  });
@@ -1,17 +1,32 @@
1
- <div *ngIf="isDisplayModeEnabled && !canBeChangedInReviewMode; else semanticLinkCheck">
2
- <component-mapper name="SingleReferenceReadOnly" [props]="{ pConn$ }"></component-mapper>
3
- </div>
4
- <ng-template #semanticLinkCheck>
5
- <div *ngIf="type === 'SemanticLink' && !canBeChangedInReviewMode; else loadDynamicComp">
1
+ <ng-container *ngIf="bVisible$" [ngSwitch]="renderMode">
2
+ <!-- SingleReferenceReadOnly mode -->
3
+ <div *ngSwitchCase="'singleReferenceReadonly'">
4
+ <component-mapper name="SingleReferenceReadOnly" [props]="{ pConn$, isDetails$, dataRelationshipContext }"></component-mapper>
5
+ </div>
6
+
7
+ <!-- MultiReferenceReadonly mode -->
8
+ <div *ngSwitchCase="'multiReferenceReadonly'">
9
+ <component-mapper name="MultiReferenceReadOnly" [props]="{ pConn$ }"></component-mapper>
10
+ </div>
11
+
12
+ <!-- SemanticLink mode -->
13
+ <div *ngSwitchCase="'semanticLink'">
6
14
  <component-mapper name="SemanticLink" [props]="{ pConn$: newPconn }"></component-mapper>
7
15
  </div>
8
- </ng-template>
9
- <ng-template #loadDynamicComp>
10
- <component-mapper
11
- *ngIf="newComponentName"
12
- [name]="newComponentName"
13
- [props]="{ pConn$: newPconn, formGroup$ }"
14
- [parent]="this"
15
- [outputEvents]="{ onRecordChange: onRecordChange }"
16
- ></component-mapper>
17
- </ng-template>
16
+
17
+ <!-- SearchAndSelect mode -->
18
+ <div *ngSwitchCase="'searchAndSelect'">
19
+ <component-mapper name="SearchForm" [props]="{ pConn$, formGroup$, searchSelectCacheKey, type: 'ObjectReference' }"></component-mapper>
20
+ </div>
21
+
22
+ <!-- Dynamic component mode (Cards, Map, CheckboxGroup, Table, Multiselect, Dropdown, AutoComplete, etc.) -->
23
+ <div *ngSwitchCase="'dynamicComponent'">
24
+ <component-mapper
25
+ *ngIf="newComponentName"
26
+ [name]="newComponentName"
27
+ [props]="{ pConn$: newPconn, formGroup$ }"
28
+ [parent]="this"
29
+ [outputEvents]="useOutputEvents ? { onRecordChange: onRecordChange } : undefined"
30
+ ></component-mapper>
31
+ </div>
32
+ </ng-container>