@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
@@ -0,0 +1,369 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core';
3
+ import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
4
+ import { MatAutocompleteModule } from '@angular/material/autocomplete';
5
+ import { MatChipsModule } from '@angular/material/chips';
6
+ import { MatCheckboxModule } from '@angular/material/checkbox';
7
+ import { MatOptionModule } from '@angular/material/core';
8
+ import { MatFormFieldModule } from '@angular/material/form-field';
9
+ import { MatInputModule } from '@angular/material/input';
10
+ import { MatIconModule } from '@angular/material/icon';
11
+ import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
12
+ import { ComponentMapperComponent } from '@pega/angular-sdk-components';
13
+ import { Utils } from '@pega/angular-sdk-components';
14
+ import { doSearch, getDisplayFieldsMetaData, getGroupDataForItemsTree, preProcessColumns } from './utils';
15
+ import { deleteInstruction, insertInstruction } from '@pega/angular-sdk-components';
16
+ import { handleEvent } from '@pega/angular-sdk-components';
17
+
18
+ @Component({
19
+ selector: 'app-multiselect',
20
+ templateUrl: './multiselect.component.html',
21
+ styleUrls: ['./multiselect.component.scss'],
22
+ standalone: true,
23
+ imports: [
24
+ CommonModule,
25
+ ReactiveFormsModule,
26
+ MatFormFieldModule,
27
+ MatInputModule,
28
+ MatAutocompleteModule,
29
+ MatOptionModule,
30
+ MatCheckboxModule,
31
+ MatIconModule,
32
+ MatChipsModule,
33
+ forwardRef(() => ComponentMapperComponent)
34
+ ]
35
+ })
36
+ export class MultiselectComponent implements OnInit, OnDestroy {
37
+ @Input() pConn$: typeof PConnect;
38
+ @Input() formGroup$: FormGroup;
39
+
40
+ // Used with AngularPConnect
41
+ angularPConnectData: AngularPConnectData = {};
42
+
43
+ label$ = '';
44
+ value$ = '';
45
+ bRequired$ = false;
46
+ bDisabled$ = false;
47
+ bVisible$ = true;
48
+ controlName$: string;
49
+ bHasForm$ = true;
50
+ listType: string;
51
+ placeholder: string;
52
+ fieldControl = new FormControl('', null);
53
+ parameters: {};
54
+ hideLabel: boolean;
55
+ configProps$: any;
56
+
57
+ referenceList: any;
58
+ selectionKey: string;
59
+ primaryField: string;
60
+ initialCaseClass: any;
61
+ showSecondaryInSearchOnly = false;
62
+ isGroupData = false;
63
+ referenceType;
64
+ secondaryFields;
65
+ groupDataSource = [];
66
+ matchPosition = 'contains';
67
+ maxResultsDisplay;
68
+ groupColumnsConfig = [{}];
69
+ selectionList;
70
+ listActions: any;
71
+ selectedItems: any[] = [];
72
+ itemsTreeBaseData = [];
73
+ displayFieldMeta: any;
74
+ dataApiObj: any;
75
+ itemsTree: any[] = [];
76
+ trigger: any;
77
+ actionsApi: Object;
78
+ propName: string;
79
+
80
+ constructor(
81
+ private angularPConnect: AngularPConnectService,
82
+ private utils: Utils
83
+ ) {}
84
+
85
+ ngOnInit(): void {
86
+ // First thing in initialization is registering and subscribing to the AngularPConnect service
87
+ this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
88
+ this.controlName$ = this.angularPConnect.getComponentID(this);
89
+
90
+ // Then, continue on with other initialization
91
+ this.checkAndUpdate();
92
+
93
+ if (this.formGroup$) {
94
+ // add control to formGroup
95
+ this.formGroup$.addControl(this.controlName$, this.fieldControl);
96
+ this.fieldControl.setValue(this.value$);
97
+ this.bHasForm$ = true;
98
+ } else {
99
+ this.bHasForm$ = false;
100
+ }
101
+ }
102
+
103
+ ngOnDestroy(): void {
104
+ if (this.formGroup$) {
105
+ this.formGroup$.removeControl(this.controlName$);
106
+ }
107
+
108
+ if (this.angularPConnectData.unsubscribeFn) {
109
+ this.angularPConnectData.unsubscribeFn();
110
+ }
111
+ }
112
+
113
+ // Callback passed when subscribing to store change
114
+ onStateChange() {
115
+ this.checkAndUpdate();
116
+ }
117
+
118
+ checkAndUpdate() {
119
+ // Should always check the bridge to see if the component should
120
+ // update itself (re-render)
121
+ const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
122
+
123
+ // ONLY call updateSelf when the component should update
124
+ if (bUpdateSelf) {
125
+ this.updateSelf();
126
+ }
127
+ }
128
+
129
+ // updateSelf
130
+ updateSelf() {
131
+ this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps());
132
+
133
+ let { datasource = [], columns = [{}] } = this.configProps$;
134
+ this.setPropertyValuesFromProps();
135
+
136
+ if (this.referenceList.length > 0) {
137
+ datasource = this.referenceList;
138
+ columns = [
139
+ {
140
+ value: this.primaryField,
141
+ display: 'true',
142
+ useForSearch: true,
143
+ primary: 'true'
144
+ },
145
+ {
146
+ value: this.selectionKey,
147
+ setProperty: this.selectionKey,
148
+ key: 'true'
149
+ }
150
+ ];
151
+ let secondaryColumns: any = [];
152
+ if (this.secondaryFields) {
153
+ secondaryColumns = this.secondaryFields.map(secondaryField => ({
154
+ value: secondaryField,
155
+ display: 'true',
156
+ secondary: 'true',
157
+ useForSearch: 'true'
158
+ }));
159
+ } else {
160
+ secondaryColumns = [
161
+ {
162
+ value: this.selectionKey,
163
+ display: 'true',
164
+ secondary: 'true',
165
+ useForSearch: 'true'
166
+ }
167
+ ];
168
+ }
169
+ if (this.referenceType === 'Case') {
170
+ columns = [...columns, ...secondaryColumns];
171
+ }
172
+ }
173
+
174
+ this.value$ = this.value$ ? this.value$ : '';
175
+ const contextName = this.pConn$.getContextName();
176
+
177
+ const dataConfig = {
178
+ dataSource: datasource,
179
+ groupDataSource: this.groupDataSource,
180
+ isGroupData: this.isGroupData,
181
+ showSecondaryInSearchOnly: this.showSecondaryInSearchOnly,
182
+ parameters: this.parameters,
183
+ matchPosition: this.matchPosition,
184
+ listType: this.listType,
185
+ maxResultsDisplay: this.maxResultsDisplay || '100',
186
+ columns: preProcessColumns(columns),
187
+ groupColumnsConfig: preProcessColumns(this.groupColumnsConfig),
188
+ associationFilter: undefined,
189
+ ignoreCase: undefined
190
+ };
191
+
192
+ const groupsDisplayFieldMeta = this.listType !== 'associated' ? getDisplayFieldsMetaData(dataConfig.groupColumnsConfig) : null;
193
+
194
+ this.itemsTreeBaseData = getGroupDataForItemsTree(this.groupDataSource, groupsDisplayFieldMeta, this.showSecondaryInSearchOnly) || [];
195
+
196
+ this.itemsTree = this.isGroupData ? getGroupDataForItemsTree(this.groupDataSource, groupsDisplayFieldMeta, this.showSecondaryInSearchOnly) : [];
197
+
198
+ this.displayFieldMeta = this.listType !== 'associated' ? getDisplayFieldsMetaData(dataConfig.columns) : null;
199
+
200
+ this.listActions = this.pConn$.getListActions();
201
+ this.pConn$.setReferenceList(this.selectionList);
202
+
203
+ if (this.configProps$.visibility != null) {
204
+ this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
205
+ }
206
+
207
+ // disabled
208
+ if (this.configProps$.disabled != undefined) {
209
+ this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
210
+ }
211
+
212
+ if (this.bDisabled$) {
213
+ this.fieldControl.disable();
214
+ } else {
215
+ this.fieldControl.enable();
216
+ }
217
+
218
+ this.actionsApi = this.pConn$.getActionsApi();
219
+ this.propName = this.pConn$.getStateProps().value;
220
+
221
+ if (this.listType !== 'associated') {
222
+ PCore.getDataApi()
223
+ ?.init(dataConfig, contextName)
224
+ .then(async dataObj => {
225
+ this.dataApiObj = dataObj;
226
+ if (!this.isGroupData) {
227
+ this.getCaseListBasedOnParams(this.value$ ?? '', '', [...this.selectedItems], [...this.itemsTree]);
228
+ }
229
+ });
230
+ }
231
+ }
232
+
233
+ setPropertyValuesFromProps() {
234
+ this.label$ = this.configProps$.label;
235
+ this.placeholder = this.configProps$.placeholder || '';
236
+ this.listType = this.configProps$.listType ? this.configProps$.listType : '';
237
+ this.hideLabel = this.configProps$.hideLabel;
238
+ this.parameters = this.configProps$?.parameters ? this.configProps$?.parameters : {};
239
+ this.referenceList = this.configProps$?.referenceList;
240
+ this.selectionKey = this.configProps$?.selectionKey;
241
+ this.primaryField = this.configProps$?.primaryField;
242
+ this.initialCaseClass = this.configProps$?.initialCaseClass;
243
+ this.showSecondaryInSearchOnly = this.configProps$?.showSecondaryInSearchOnly ? this.configProps$?.showSecondaryInSearchOnly : false;
244
+ this.isGroupData = this.configProps$?.isGroupData ? this.configProps$.isGroupData : false;
245
+ this.referenceType = this.configProps$?.referenceType;
246
+ this.secondaryFields = this.configProps$?.secondaryFields;
247
+ this.groupDataSource = this.configProps$?.groupDataSource ? this.configProps$?.groupDataSource : [];
248
+ this.matchPosition = this.configProps$?.matchPosition ? this.configProps$?.matchPosition : 'contains';
249
+ this.maxResultsDisplay = this.configProps$?.maxResultsDisplay;
250
+ this.groupColumnsConfig = this.configProps$?.groupColumnsConfig ? this.configProps$?.groupColumnsConfig : [{}];
251
+ this.selectionList = this.configProps$?.selectionList;
252
+ this.value$ = this.configProps$?.value;
253
+ }
254
+
255
+ // main search function trigger
256
+ getCaseListBasedOnParams(searchText, group, selectedRows, currentItemsTree, isTriggeredFromSearch = false) {
257
+ if (this.referenceList && this.referenceList.length > 0) {
258
+ this.listActions.getSelectedRows(true).then(result => {
259
+ selectedRows =
260
+ result.length > 0
261
+ ? result.map(item => {
262
+ return {
263
+ id: item[this.selectionKey.startsWith('.') ? this.selectionKey.substring(1) : this.selectionKey],
264
+ primary: item[this.primaryField.startsWith('.') ? this.primaryField.substring(1) : this.primaryField]
265
+ };
266
+ })
267
+ : [];
268
+ this.selectedItems = selectedRows;
269
+
270
+ const initalItemsTree = isTriggeredFromSearch || !currentItemsTree ? [...this.itemsTreeBaseData] : [...currentItemsTree];
271
+
272
+ doSearch(
273
+ searchText,
274
+ group,
275
+ this.initialCaseClass,
276
+ this.displayFieldMeta,
277
+ this.dataApiObj,
278
+ initalItemsTree,
279
+ this.isGroupData,
280
+ this.showSecondaryInSearchOnly,
281
+ selectedRows || []
282
+ ).then(res => {
283
+ this.itemsTree = res || [];
284
+ });
285
+ });
286
+ }
287
+ }
288
+
289
+ fieldOnChange(event: Event) {
290
+ this.value$ = (event.target as HTMLInputElement).value;
291
+ this.getCaseListBasedOnParams(this.value$, '', [...this.selectedItems], [...this.itemsTree], true);
292
+ }
293
+
294
+ optionChanged(event: any) {
295
+ let value = event?.target?.value;
296
+ value = value?.substring(1);
297
+ handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
298
+ }
299
+
300
+ optionClicked = (event: Event, data: any): void => {
301
+ event.stopPropagation();
302
+ this.toggleSelection(data);
303
+ };
304
+
305
+ toggleSelection = (data: any): void => {
306
+ data.selected = !data.selected;
307
+ this.itemsTree.map((ele: any) => {
308
+ if (ele.id === data.id) {
309
+ ele.selected = data.selected;
310
+ }
311
+ return ele;
312
+ });
313
+
314
+ if (data.selected === true) {
315
+ this.selectedItems.push(data);
316
+ } else {
317
+ const index = this.selectedItems.findIndex(value => value.id === data.id);
318
+ this.selectedItems.splice(index, 1);
319
+ }
320
+
321
+ this.value$ = '';
322
+ // if this is a referenceList case
323
+ if (this.referenceList) this.setSelectedItemsForReferenceList(data);
324
+
325
+ this.getCaseListBasedOnParams(this.value$, '', [...this.selectedItems], [...this.itemsTree], true);
326
+ };
327
+
328
+ removeChip = (data: any): void => {
329
+ if (data) {
330
+ data = this.itemsTree.filter((ele: any) => {
331
+ return ele.id === data.id;
332
+ });
333
+ this.toggleSelection(data[0]);
334
+ }
335
+ };
336
+
337
+ setSelectedItemsForReferenceList(data: any) {
338
+ // Clear error messages if any
339
+ const propName = this.pConn$.getStateProps().selectionList;
340
+ this.pConn$.clearErrorMessages({
341
+ property: propName,
342
+ category: '',
343
+ context: ''
344
+ });
345
+ const { selected } = data;
346
+ if (selected) {
347
+ insertInstruction(this.pConn$, this.selectionList, this.selectionKey, this.primaryField, data);
348
+ } else {
349
+ deleteInstruction(this.pConn$, this.selectionList, this.selectionKey, data);
350
+ }
351
+ }
352
+
353
+ getErrorMessage() {
354
+ let errMessage = '';
355
+
356
+ // look for validation messages for json, pre-defined or just an error pushed from workitem (400)
357
+ if (this.fieldControl.hasError('message')) {
358
+ errMessage = this.angularPConnectData.validateMessage ?? '';
359
+ return errMessage;
360
+ }
361
+ if (this.fieldControl.hasError('required')) {
362
+ errMessage = 'You must enter a value';
363
+ } else if (this.fieldControl.errors) {
364
+ errMessage = this.fieldControl.errors.toString();
365
+ }
366
+
367
+ return errMessage;
368
+ }
369
+ }
@@ -0,0 +1,209 @@
1
+ import cloneDeep from 'lodash.clonedeep';
2
+
3
+ export function setVisibilityForList(c11nEnv, visibility) {
4
+ const { selectionMode, selectionList, renderMode, referenceList } = c11nEnv.getComponentConfig();
5
+ // usecase:multiselect, fieldgroup, editable table
6
+ if ((selectionMode === PCore.getConstants().LIST_SELECTION_MODE.MULTI && selectionList) || (renderMode === 'Editable' && referenceList)) {
7
+ c11nEnv.getListActions().setVisibility(visibility);
8
+ }
9
+ }
10
+
11
+ function preProcessColumns(columns) {
12
+ return columns?.map(col => {
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;
17
+ }
18
+ return tempColObj;
19
+ });
20
+ }
21
+
22
+ function getDisplayFieldsMetaData(columns) {
23
+ const displayColumns = columns?.filter(col => col.display === 'true');
24
+ const metaDataObj: any = {
25
+ key: '',
26
+ primary: '',
27
+ secondary: []
28
+ };
29
+ const keyCol = columns?.filter(col => col.key === 'true');
30
+ metaDataObj.key = keyCol?.length > 0 ? keyCol[0].value : 'auto';
31
+ const itemsRecordsColumn = columns?.filter(col => col.itemsRecordsColumn === 'true');
32
+ if (itemsRecordsColumn?.length > 0) {
33
+ metaDataObj.itemsRecordsColumn = itemsRecordsColumn[0].value;
34
+ }
35
+ const itemsGroupKeyColumn = columns?.filter(col => col.itemsGroupKeyColumn === 'true');
36
+ if (itemsGroupKeyColumn?.length > 0) {
37
+ metaDataObj.itemsGroupKeyColumn = itemsGroupKeyColumn[0].value;
38
+ }
39
+ for (let index = 0; index < displayColumns?.length; index += 1) {
40
+ if (displayColumns[index].secondary === 'true') {
41
+ metaDataObj.secondary.push(displayColumns[index].value);
42
+ } else if (displayColumns[index].primary === 'true') {
43
+ metaDataObj.primary = displayColumns[index].value;
44
+ }
45
+ }
46
+ return metaDataObj;
47
+ }
48
+
49
+ function createSingleTreeObejct(entry, displayFieldMeta, showSecondaryData, selected) {
50
+ const secondaryArr: any = [];
51
+ displayFieldMeta.secondary.forEach(col => {
52
+ secondaryArr.push(entry[col]);
53
+ });
54
+ const isSelected = selected.some(item => item.id === entry[displayFieldMeta.key]);
55
+
56
+ return {
57
+ id: entry[displayFieldMeta.key],
58
+ primary: entry[displayFieldMeta.primary],
59
+ secondary: showSecondaryData ? secondaryArr : [],
60
+ selected: isSelected
61
+ };
62
+ }
63
+
64
+ function putItemsDataInItemsTree(listObjData, displayFieldMeta, itemsTree, showSecondaryInSearchOnly, selected) {
65
+ let newTreeItems = itemsTree.slice();
66
+ const showSecondaryData = !showSecondaryInSearchOnly;
67
+ for (const obj of listObjData) {
68
+ const items = obj[displayFieldMeta.itemsRecordsColumn].map(entry => createSingleTreeObejct(entry, displayFieldMeta, showSecondaryData, selected));
69
+
70
+ newTreeItems = newTreeItems.map(caseObject => {
71
+ if (caseObject.id === obj[displayFieldMeta.itemsGroupKeyColumn]) {
72
+ caseObject.items = [...items];
73
+ }
74
+ return caseObject;
75
+ });
76
+ }
77
+ return newTreeItems;
78
+ }
79
+
80
+ function prepareSearchResults(listObjData, displayFieldMeta) {
81
+ const searchResults: any = [];
82
+ for (const obj of listObjData) {
83
+ searchResults.push(...obj[displayFieldMeta.itemsRecordsColumn]);
84
+ }
85
+ return searchResults;
86
+ }
87
+
88
+ async function doSearch(
89
+ searchText,
90
+ clickedGroup,
91
+ initialCaseClass,
92
+ displayFieldMeta,
93
+ dataApiObj, // deep clone of the dataApiObj
94
+ itemsTree,
95
+ isGroupData,
96
+ showSecondaryInSearchOnly,
97
+ selected
98
+ ) {
99
+ let searchTextForUngroupedData = '';
100
+ if (dataApiObj) {
101
+ // creating dataApiObject in grouped data cases
102
+ if (isGroupData) {
103
+ dataApiObj = cloneDeep(dataApiObj);
104
+ dataApiObj.fetchedNQData = false;
105
+ dataApiObj.cache = {};
106
+
107
+ // if we have no search text and no group selected, return the original tree
108
+ if (searchText === '' && clickedGroup === '') {
109
+ return itemsTree;
110
+ }
111
+
112
+ // setting the inital search text & search classes in ApiObject
113
+ dataApiObj.parameters[Object.keys(dataApiObj.parameters)[1]] = searchText;
114
+ dataApiObj.parameters[Object.keys(dataApiObj.parameters)[0]] = initialCaseClass;
115
+
116
+ // if we have a selected group
117
+ if (clickedGroup) {
118
+ // check if the data for this group is already present and no search text
119
+ if (searchText === '') {
120
+ const containsData = itemsTree.find(item => item.id === clickedGroup);
121
+ // do not make API call when items of respective group are already fetched
122
+ if (containsData?.items?.length) return itemsTree;
123
+ }
124
+
125
+ dataApiObj.parameters[Object.keys(dataApiObj.parameters)[0]] = JSON.stringify([clickedGroup]);
126
+ }
127
+ } else {
128
+ searchTextForUngroupedData = searchText;
129
+ }
130
+
131
+ // search API call
132
+ const response = await dataApiObj.fetchData(searchTextForUngroupedData).catch(() => {
133
+ return itemsTree;
134
+ });
135
+
136
+ let listObjData = response.data;
137
+ let newItemsTree = [];
138
+ if (isGroupData) {
139
+ if (searchText) {
140
+ listObjData = prepareSearchResults(listObjData, displayFieldMeta);
141
+ } else {
142
+ newItemsTree = putItemsDataInItemsTree(listObjData, displayFieldMeta, itemsTree, showSecondaryInSearchOnly, selected);
143
+ return newItemsTree;
144
+ }
145
+ }
146
+ const showSecondaryData = showSecondaryInSearchOnly ? !!searchText : true;
147
+ if (listObjData !== undefined && listObjData.length > 0) {
148
+ newItemsTree = listObjData.map(entry => createSingleTreeObejct(entry, displayFieldMeta, showSecondaryData, selected));
149
+ }
150
+ return newItemsTree;
151
+ }
152
+
153
+ return itemsTree;
154
+ }
155
+
156
+ function setValuesToPropertyList(searchText, assocProp, items, columns, actions, updatePropertyInRedux = true) {
157
+ const setPropertyList = columns
158
+ ?.filter(col => col.setProperty)
159
+ .map(col => {
160
+ return {
161
+ source: col.value,
162
+ target: col.setProperty,
163
+ key: col.key,
164
+ primary: col.primary
165
+ };
166
+ });
167
+ const valueToSet: any = [];
168
+ if (setPropertyList.length > 0) {
169
+ setPropertyList.forEach(prop => {
170
+ items.forEach(item => {
171
+ if (prop.key === 'true' && item) {
172
+ valueToSet.push(item.id);
173
+ } else if (prop.primary === 'true' || !item) {
174
+ valueToSet.push(searchText);
175
+ }
176
+ });
177
+
178
+ if (updatePropertyInRedux) {
179
+ // BUG-666851 setting options so that the store values are replaced and not merged
180
+ const options = {
181
+ isArrayDeepMerge: false
182
+ };
183
+ if (prop.target === 'Associated property') {
184
+ actions.updateFieldValue(assocProp, valueToSet, options);
185
+ } else {
186
+ actions.updateFieldValue(`.${prop.target}`, valueToSet, options);
187
+ }
188
+ }
189
+ });
190
+ }
191
+ return valueToSet;
192
+ }
193
+
194
+ function getGroupDataForItemsTree(groupDataSource, groupsDisplayFieldMeta, showSecondaryInSearchOnly) {
195
+ return groupDataSource?.map(group => {
196
+ const secondaryArr: any = [];
197
+ groupsDisplayFieldMeta.secondary.forEach(col => {
198
+ secondaryArr.push(group[col]);
199
+ });
200
+ return {
201
+ id: group[groupsDisplayFieldMeta.key],
202
+ primary: group[groupsDisplayFieldMeta.primary],
203
+ secondary: showSecondaryInSearchOnly ? [] : secondaryArr,
204
+ items: []
205
+ };
206
+ });
207
+ }
208
+
209
+ export { preProcessColumns, getDisplayFieldsMetaData, doSearch, setValuesToPropertyList, getGroupDataForItemsTree };
@@ -1,23 +1,34 @@
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
- <!-- <span matPrefix>% &nbsp;</span> -->
10
9
  <input
10
+ type="text"
11
11
  matInput
12
+ currencyMask
13
+ [options]="{
14
+ prefix: '',
15
+ suffix: '%',
16
+ thousands: thousandSeparator,
17
+ decimal: decimalSeparator,
18
+ align: 'left',
19
+ nullable: true,
20
+ precision: decimalPrecision,
21
+ inputMode: inputMode
22
+ }"
12
23
  [placeholder]="placeholder"
13
- type="number"
14
24
  step=".01"
15
- [value]="value$"
25
+ [formControlName]="controlName$"
16
26
  [required]="bRequired$"
17
27
  [formControl]="fieldControl"
18
28
  [attr.data-test-id]="testId"
19
- (change)="fieldOnChange($event)"
29
+ (change)="fieldOnChange()"
20
30
  (blur)="fieldOnBlur($event)"
31
+ [readonly]="bReadonly$"
21
32
  />
22
33
  <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
23
34
  </mat-form-field>