@pega/angular-sdk-overrides 0.23.5 → 0.24.1
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.
- package/lib/designSystemExtension/material-case-summary/material-case-summary.component.html +5 -2
- package/lib/designSystemExtension/material-case-summary/material-case-summary.component.ts +3 -1
- package/lib/designSystemExtension/operator/operator.component.ts +6 -4
- package/lib/field/auto-complete/auto-complete.component.ts +1 -1
- package/lib/field/check-box/check-box.component.html +16 -15
- package/lib/field/check-box/check-box.component.scss +14 -1
- package/lib/field/check-box/check-box.component.ts +127 -44
- package/lib/field/group/group.component.html +1 -1
- package/lib/field/group/group.component.ts +4 -0
- package/lib/field/multiselect/multiselect.component.html +34 -0
- package/lib/field/multiselect/multiselect.component.scss +7 -0
- package/lib/field/multiselect/multiselect.component.spec.ts +21 -0
- package/lib/field/multiselect/multiselect.component.ts +363 -0
- package/lib/field/multiselect/utils.ts +209 -0
- package/lib/field/rich-text/rich-text.component.html +1 -1
- package/lib/field/time/time.component.html +1 -0
- package/lib/field/time/time.component.ts +2 -0
- package/lib/field/url/url.component.html +1 -0
- package/lib/field/url/url.component.ts +2 -0
- package/lib/infra/Containers/view-container/view-container.component.ts +7 -6
- package/lib/infra/multi-step/multi-step.component.scss +1 -0
- package/lib/infra/navbar/navbar.component.html +3 -3
- package/lib/infra/navbar/navbar.component.ts +4 -2
- package/lib/template/case-summary/case-summary.component.ts +37 -3
- package/lib/template/field-value-list/field-value-list.component.html +7 -2
- package/lib/template/field-value-list/field-value-list.component.ts +1 -0
- package/lib/template/list-view/list-view.component.html +4 -4
- package/lib/template/list-view/list-view.component.ts +21 -24
- package/lib/template/list-view/utils.ts +4 -2
- package/lib/template/simple-table-manual/helpers.ts +1 -1
- package/lib/template/simple-table-manual/simple-table-manual.component.html +1 -1
- package/lib/template/simple-table-manual/simple-table-manual.component.ts +44 -7
- package/lib/template/wss-nav-bar/wss-nav-bar.component.html +1 -1
- package/lib/template/wss-nav-bar/wss-nav-bar.component.ts +2 -1
- package/lib/widget/attachment/attachment.component.html +9 -1
- package/lib/widget/attachment/attachment.component.ts +4 -1
- package/package.json +1 -1
|
@@ -0,0 +1,363 @@
|
|
|
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, MatAutocompleteSelectedEvent, MatAutocompleteTrigger } 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
|
+
|
|
17
|
+
@Component({
|
|
18
|
+
selector: 'app-multiselect',
|
|
19
|
+
templateUrl: './multiselect.component.html',
|
|
20
|
+
styleUrls: ['./multiselect.component.scss'],
|
|
21
|
+
standalone: true,
|
|
22
|
+
imports: [
|
|
23
|
+
CommonModule,
|
|
24
|
+
ReactiveFormsModule,
|
|
25
|
+
MatFormFieldModule,
|
|
26
|
+
MatInputModule,
|
|
27
|
+
MatAutocompleteModule,
|
|
28
|
+
MatOptionModule,
|
|
29
|
+
MatCheckboxModule,
|
|
30
|
+
MatIconModule,
|
|
31
|
+
MatChipsModule,
|
|
32
|
+
forwardRef(() => ComponentMapperComponent)
|
|
33
|
+
]
|
|
34
|
+
})
|
|
35
|
+
export class MultiselectComponent implements OnInit, OnDestroy {
|
|
36
|
+
@Input() pConn$: typeof PConnect;
|
|
37
|
+
@Input() formGroup$: FormGroup;
|
|
38
|
+
|
|
39
|
+
// Used with AngularPConnect
|
|
40
|
+
angularPConnectData: AngularPConnectData = {};
|
|
41
|
+
|
|
42
|
+
label$ = '';
|
|
43
|
+
value$ = '';
|
|
44
|
+
bRequired$ = false;
|
|
45
|
+
bDisabled$ = false;
|
|
46
|
+
bVisible$ = true;
|
|
47
|
+
controlName$: string;
|
|
48
|
+
bHasForm$ = true;
|
|
49
|
+
listType: string;
|
|
50
|
+
placeholder: string;
|
|
51
|
+
fieldControl = new FormControl('', null);
|
|
52
|
+
parameters: {};
|
|
53
|
+
hideLabel: boolean;
|
|
54
|
+
configProps$: any;
|
|
55
|
+
|
|
56
|
+
referenceList: any;
|
|
57
|
+
selectionKey: string;
|
|
58
|
+
primaryField: string;
|
|
59
|
+
initialCaseClass: any;
|
|
60
|
+
showSecondaryInSearchOnly = false;
|
|
61
|
+
isGroupData = false;
|
|
62
|
+
referenceType;
|
|
63
|
+
secondaryFields;
|
|
64
|
+
groupDataSource = [];
|
|
65
|
+
matchPosition = 'contains';
|
|
66
|
+
maxResultsDisplay;
|
|
67
|
+
groupColumnsConfig = [{}];
|
|
68
|
+
selectionList;
|
|
69
|
+
listActions: any;
|
|
70
|
+
selectedItems: any[] = [];
|
|
71
|
+
itemsTreeBaseData = [];
|
|
72
|
+
displayFieldMeta: any;
|
|
73
|
+
dataApiObj: any;
|
|
74
|
+
itemsTree: any[] = [];
|
|
75
|
+
trigger: any;
|
|
76
|
+
|
|
77
|
+
constructor(
|
|
78
|
+
private angularPConnect: AngularPConnectService,
|
|
79
|
+
private utils: Utils
|
|
80
|
+
) {}
|
|
81
|
+
|
|
82
|
+
ngOnInit(): void {
|
|
83
|
+
// First thing in initialization is registering and subscribing to the AngularPConnect service
|
|
84
|
+
this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
|
|
85
|
+
this.controlName$ = this.angularPConnect.getComponentID(this);
|
|
86
|
+
|
|
87
|
+
// Then, continue on with other initialization
|
|
88
|
+
this.checkAndUpdate();
|
|
89
|
+
|
|
90
|
+
if (this.formGroup$) {
|
|
91
|
+
// add control to formGroup
|
|
92
|
+
this.formGroup$.addControl(this.controlName$, this.fieldControl);
|
|
93
|
+
this.fieldControl.setValue(this.value$);
|
|
94
|
+
this.bHasForm$ = true;
|
|
95
|
+
} else {
|
|
96
|
+
this.bHasForm$ = false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
ngOnDestroy(): void {
|
|
101
|
+
if (this.formGroup$) {
|
|
102
|
+
this.formGroup$.removeControl(this.controlName$);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (this.angularPConnectData.unsubscribeFn) {
|
|
106
|
+
this.angularPConnectData.unsubscribeFn();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Callback passed when subscribing to store change
|
|
111
|
+
onStateChange() {
|
|
112
|
+
this.checkAndUpdate();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
checkAndUpdate() {
|
|
116
|
+
// Should always check the bridge to see if the component should
|
|
117
|
+
// update itself (re-render)
|
|
118
|
+
const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
|
|
119
|
+
|
|
120
|
+
// ONLY call updateSelf when the component should update
|
|
121
|
+
if (bUpdateSelf) {
|
|
122
|
+
this.updateSelf();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// updateSelf
|
|
127
|
+
updateSelf() {
|
|
128
|
+
this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps());
|
|
129
|
+
|
|
130
|
+
let { datasource = [], columns = [{}] } = this.configProps$;
|
|
131
|
+
this.setPropertyValuesFromProps();
|
|
132
|
+
|
|
133
|
+
if (this.referenceList.length > 0) {
|
|
134
|
+
datasource = this.referenceList;
|
|
135
|
+
columns = [
|
|
136
|
+
{
|
|
137
|
+
value: this.primaryField,
|
|
138
|
+
display: 'true',
|
|
139
|
+
useForSearch: true,
|
|
140
|
+
primary: 'true'
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
value: this.selectionKey,
|
|
144
|
+
setProperty: this.selectionKey,
|
|
145
|
+
key: 'true'
|
|
146
|
+
}
|
|
147
|
+
];
|
|
148
|
+
let secondaryColumns: any = [];
|
|
149
|
+
if (this.secondaryFields) {
|
|
150
|
+
secondaryColumns = this.secondaryFields.map(secondaryField => ({
|
|
151
|
+
value: secondaryField,
|
|
152
|
+
display: 'true',
|
|
153
|
+
secondary: 'true',
|
|
154
|
+
useForSearch: 'true'
|
|
155
|
+
}));
|
|
156
|
+
} else {
|
|
157
|
+
secondaryColumns = [
|
|
158
|
+
{
|
|
159
|
+
value: this.selectionKey,
|
|
160
|
+
display: 'true',
|
|
161
|
+
secondary: 'true',
|
|
162
|
+
useForSearch: 'true'
|
|
163
|
+
}
|
|
164
|
+
];
|
|
165
|
+
}
|
|
166
|
+
if (this.referenceType === 'Case') {
|
|
167
|
+
columns = [...columns, ...secondaryColumns];
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
this.value$ = this.value$ ? this.value$ : '';
|
|
172
|
+
const contextName = this.pConn$.getContextName();
|
|
173
|
+
|
|
174
|
+
const dataConfig = {
|
|
175
|
+
dataSource: datasource,
|
|
176
|
+
groupDataSource: this.groupDataSource,
|
|
177
|
+
isGroupData: this.isGroupData,
|
|
178
|
+
showSecondaryInSearchOnly: this.showSecondaryInSearchOnly,
|
|
179
|
+
parameters: this.parameters,
|
|
180
|
+
matchPosition: this.matchPosition,
|
|
181
|
+
listType: this.listType,
|
|
182
|
+
maxResultsDisplay: this.maxResultsDisplay || '100',
|
|
183
|
+
columns: preProcessColumns(columns),
|
|
184
|
+
groupColumnsConfig: preProcessColumns(this.groupColumnsConfig)
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const groupsDisplayFieldMeta = this.listType !== 'associated' ? getDisplayFieldsMetaData(dataConfig.groupColumnsConfig) : null;
|
|
188
|
+
|
|
189
|
+
this.itemsTreeBaseData = getGroupDataForItemsTree(this.groupDataSource, groupsDisplayFieldMeta, this.showSecondaryInSearchOnly) || [];
|
|
190
|
+
|
|
191
|
+
this.itemsTree = this.isGroupData ? getGroupDataForItemsTree(this.groupDataSource, groupsDisplayFieldMeta, this.showSecondaryInSearchOnly) : [];
|
|
192
|
+
|
|
193
|
+
this.displayFieldMeta = this.listType !== 'associated' ? getDisplayFieldsMetaData(dataConfig.columns) : null;
|
|
194
|
+
|
|
195
|
+
this.listActions = this.pConn$.getListActions();
|
|
196
|
+
this.pConn$.setReferenceList(this.selectionList);
|
|
197
|
+
|
|
198
|
+
if (this.configProps$.visibility != null) {
|
|
199
|
+
this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// disabled
|
|
203
|
+
if (this.configProps$.disabled != undefined) {
|
|
204
|
+
this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (this.bDisabled$) {
|
|
208
|
+
this.fieldControl.disable();
|
|
209
|
+
} else {
|
|
210
|
+
this.fieldControl.enable();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (this.listType !== 'associated') {
|
|
214
|
+
PCore.getDataApi()
|
|
215
|
+
?.init(dataConfig, contextName)
|
|
216
|
+
.then(async dataObj => {
|
|
217
|
+
this.dataApiObj = dataObj;
|
|
218
|
+
if (!this.isGroupData) {
|
|
219
|
+
this.getCaseListBasedOnParams(this.value$ ?? '', '', [...this.selectedItems], [...this.itemsTree]);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
setPropertyValuesFromProps() {
|
|
226
|
+
this.label$ = this.configProps$.label;
|
|
227
|
+
this.placeholder = this.configProps$.placeholder || '';
|
|
228
|
+
this.listType = this.configProps$.listType ? this.configProps$.listType : '';
|
|
229
|
+
this.hideLabel = this.configProps$.hideLabel;
|
|
230
|
+
this.parameters = this.configProps$?.parameters ? this.configProps$?.parameters : {};
|
|
231
|
+
this.referenceList = this.configProps$?.referenceList;
|
|
232
|
+
this.selectionKey = this.configProps$?.selectionKey;
|
|
233
|
+
this.primaryField = this.configProps$?.primaryField;
|
|
234
|
+
this.initialCaseClass = this.configProps$?.initialCaseClass;
|
|
235
|
+
this.showSecondaryInSearchOnly = this.configProps$?.showSecondaryInSearchOnly ? this.configProps$?.showSecondaryInSearchOnly : false;
|
|
236
|
+
this.isGroupData = this.configProps$?.isGroupData ? this.configProps$.isGroupData : false;
|
|
237
|
+
this.referenceType = this.configProps$?.referenceType;
|
|
238
|
+
this.secondaryFields = this.configProps$?.secondaryFields;
|
|
239
|
+
this.groupDataSource = this.configProps$?.groupDataSource ? this.configProps$?.groupDataSource : [];
|
|
240
|
+
this.matchPosition = this.configProps$?.matchPosition ? this.configProps$?.matchPosition : 'contains';
|
|
241
|
+
this.maxResultsDisplay = this.configProps$?.maxResultsDisplay;
|
|
242
|
+
this.groupColumnsConfig = this.configProps$?.groupColumnsConfig ? this.configProps$?.groupColumnsConfig : [{}];
|
|
243
|
+
this.selectionList = this.configProps$?.selectionList;
|
|
244
|
+
this.value$ = this.configProps$?.value;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// main search function trigger
|
|
248
|
+
getCaseListBasedOnParams(searchText, group, selectedRows, currentItemsTree, isTriggeredFromSearch = false) {
|
|
249
|
+
if (this.referenceList && this.referenceList.length > 0) {
|
|
250
|
+
this.listActions.getSelectedRows(true).then(result => {
|
|
251
|
+
selectedRows =
|
|
252
|
+
result.length > 0
|
|
253
|
+
? result.map(item => {
|
|
254
|
+
return {
|
|
255
|
+
id: item[this.selectionKey.startsWith('.') ? this.selectionKey.substring(1) : this.selectionKey],
|
|
256
|
+
primary: item[this.primaryField.startsWith('.') ? this.primaryField.substring(1) : this.primaryField]
|
|
257
|
+
};
|
|
258
|
+
})
|
|
259
|
+
: [];
|
|
260
|
+
this.selectedItems = selectedRows;
|
|
261
|
+
|
|
262
|
+
const initalItemsTree = isTriggeredFromSearch || !currentItemsTree ? [...this.itemsTreeBaseData] : [...currentItemsTree];
|
|
263
|
+
|
|
264
|
+
doSearch(
|
|
265
|
+
searchText,
|
|
266
|
+
group,
|
|
267
|
+
this.initialCaseClass,
|
|
268
|
+
this.displayFieldMeta,
|
|
269
|
+
this.dataApiObj,
|
|
270
|
+
initalItemsTree,
|
|
271
|
+
this.isGroupData,
|
|
272
|
+
this.showSecondaryInSearchOnly,
|
|
273
|
+
selectedRows || []
|
|
274
|
+
).then(res => {
|
|
275
|
+
this.itemsTree = res || [];
|
|
276
|
+
if (this.trigger) {
|
|
277
|
+
this.trigger.openPanel();
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
fieldOnChange(event: Event) {
|
|
285
|
+
this.value$ = (event.target as HTMLInputElement).value;
|
|
286
|
+
this.getCaseListBasedOnParams(this.value$, '', [...this.selectedItems], [...this.itemsTree], true);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
optionChanged(event: MatAutocompleteSelectedEvent) {
|
|
290
|
+
this.angularPConnectData.actions?.onChange(this, event);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
optionClicked = (event: Event, data: any, trigger?: MatAutocompleteTrigger): void => {
|
|
294
|
+
event.stopPropagation();
|
|
295
|
+
this.toggleSelection(data, trigger);
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
toggleSelection = (data: any, trigger?: MatAutocompleteTrigger): void => {
|
|
299
|
+
data.selected = !data.selected;
|
|
300
|
+
this.trigger = trigger;
|
|
301
|
+
this.itemsTree.map((ele: any) => {
|
|
302
|
+
if (ele.id === data.id) {
|
|
303
|
+
ele.selected = data.selected;
|
|
304
|
+
}
|
|
305
|
+
return ele;
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
if (data.selected === true) {
|
|
309
|
+
this.selectedItems.push(data);
|
|
310
|
+
} else {
|
|
311
|
+
const index = this.selectedItems.findIndex(value => value.id === data.id);
|
|
312
|
+
this.selectedItems.splice(index, 1);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
this.value$ = '';
|
|
316
|
+
// if this is a referenceList case
|
|
317
|
+
if (this.referenceList) this.setSelectedItemsForReferenceList(data);
|
|
318
|
+
|
|
319
|
+
this.getCaseListBasedOnParams(this.value$, '', [...this.selectedItems], [...this.itemsTree], true);
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
removeChip = (data: any): void => {
|
|
323
|
+
if (data) {
|
|
324
|
+
data = this.itemsTree.filter((ele: any) => {
|
|
325
|
+
return ele.id === data.id;
|
|
326
|
+
});
|
|
327
|
+
this.toggleSelection(data[0]);
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
setSelectedItemsForReferenceList(data: any) {
|
|
332
|
+
// Clear error messages if any
|
|
333
|
+
const propName = (this.pConn$.getStateProps() as any).selectionList;
|
|
334
|
+
this.pConn$.clearErrorMessages({
|
|
335
|
+
property: propName,
|
|
336
|
+
category: '',
|
|
337
|
+
context: ''
|
|
338
|
+
});
|
|
339
|
+
const { selected } = data;
|
|
340
|
+
if (selected) {
|
|
341
|
+
insertInstruction(this.pConn$, this.selectionList, this.selectionKey, this.primaryField, data);
|
|
342
|
+
} else {
|
|
343
|
+
deleteInstruction(this.pConn$, this.selectionList, this.selectionKey, data);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
getErrorMessage() {
|
|
348
|
+
let errMessage = '';
|
|
349
|
+
|
|
350
|
+
// look for validation messages for json, pre-defined or just an error pushed from workitem (400)
|
|
351
|
+
if (this.fieldControl.hasError('message')) {
|
|
352
|
+
errMessage = this.angularPConnectData.validateMessage ?? '';
|
|
353
|
+
return errMessage;
|
|
354
|
+
}
|
|
355
|
+
if (this.fieldControl.hasError('required')) {
|
|
356
|
+
errMessage = 'You must enter a value';
|
|
357
|
+
} else if (this.fieldControl.errors) {
|
|
358
|
+
errMessage = this.fieldControl.errors.toString();
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return errMessage;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
@@ -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,5 +1,5 @@
|
|
|
1
1
|
<div *ngIf="displayMode$; else noDisplayMode">
|
|
2
|
-
<component-mapper *ngIf="bVisible$ !== false" name="FieldValueList" [props]="{ label$, value$, displayMode
|
|
2
|
+
<component-mapper *ngIf="bVisible$ !== false" name="FieldValueList" [props]="{ label$, value$, displayMode$, isHtml$: true }"></component-mapper>
|
|
3
3
|
</div>
|
|
4
4
|
<ng-template #noDisplayMode>
|
|
5
5
|
<div *ngIf="!bReadonly$; else noEdit">
|
|
@@ -36,6 +36,7 @@ export class TimeComponent implements OnInit, OnDestroy {
|
|
|
36
36
|
bVisible$ = true;
|
|
37
37
|
displayMode$?: string = '';
|
|
38
38
|
controlName$: string;
|
|
39
|
+
testId = '';
|
|
39
40
|
bHasForm$ = true;
|
|
40
41
|
componentReference = '';
|
|
41
42
|
helperText: string;
|
|
@@ -100,6 +101,7 @@ export class TimeComponent implements OnInit, OnDestroy {
|
|
|
100
101
|
// moved this from ngOnInit() and call this from there instead...
|
|
101
102
|
this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as TimeProps;
|
|
102
103
|
|
|
104
|
+
this.testId = this.configProps$.testId;
|
|
103
105
|
this.label$ = this.configProps$.label;
|
|
104
106
|
this.displayMode$ = this.configProps$.displayMode;
|
|
105
107
|
|
|
@@ -36,6 +36,7 @@ export class UrlComponent implements OnInit, OnDestroy {
|
|
|
36
36
|
bVisible$ = true;
|
|
37
37
|
displayMode$?: string = '';
|
|
38
38
|
controlName$: string;
|
|
39
|
+
testId = '';
|
|
39
40
|
bHasForm$ = true;
|
|
40
41
|
componentReference = '';
|
|
41
42
|
helperText: string;
|
|
@@ -106,6 +107,7 @@ export class UrlComponent implements OnInit, OnDestroy {
|
|
|
106
107
|
this.value$ = this.configProps$.value;
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
this.testId = this.configProps$.testId;
|
|
109
111
|
this.label$ = this.configProps$.label;
|
|
110
112
|
this.displayMode$ = this.configProps$.displayMode;
|
|
111
113
|
this.helperText = this.configProps$.helperText;
|
|
@@ -118,17 +118,18 @@ export class ViewContainerComponent implements OnInit, OnDestroy {
|
|
|
118
118
|
/* NOTE: setContainerLimit use is temporary. It is a non-public, unsupported API. */
|
|
119
119
|
PCore.getContainerUtils().setContainerLimit(`${APP.APP}/${name}`, limit);
|
|
120
120
|
}
|
|
121
|
-
}
|
|
122
121
|
|
|
123
|
-
|
|
124
|
-
// @ts-ignore - Property 'getMetadata' is private and only accessible within class
|
|
125
|
-
if (this.pConn$.getMetadata().children) {
|
|
122
|
+
if (!PCore.checkIfSemanticURL()) {
|
|
126
123
|
containerMgr.addContainerItem(this.dispatchObject);
|
|
127
124
|
}
|
|
128
|
-
|
|
129
|
-
sessionStorage.setItem('hasViewContainer', 'true');
|
|
130
125
|
}
|
|
131
126
|
|
|
127
|
+
// if (sessionStorage.getItem('hasViewContainer') == 'false') {
|
|
128
|
+
// // @ts-ignore - Property 'getMetadata' is private and only accessible within class
|
|
129
|
+
|
|
130
|
+
// sessionStorage.setItem('hasViewContainer', 'true');
|
|
131
|
+
// }
|
|
132
|
+
|
|
132
133
|
// cannot call checkAndUpdate becasue first time through, will call updateSelf and that is incorrect (causes issues).
|
|
133
134
|
// however, need angularPConnect to be initialized with currentProps for future updates, so calling shouldComponentUpdate directly
|
|
134
135
|
// without checking to update here in init, will initialize and this is correct
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*ngFor="let caseType of caseTypes$"
|
|
23
23
|
(click)="navPanelCreateCaseType(caseType.pyClassName, caseType.pyFlowType)"
|
|
24
24
|
>
|
|
25
|
-
<span class="psdk-nav-button-span">{{ caseType.pyLabel }}</span>
|
|
25
|
+
<span class="psdk-nav-button-span">{{ localeUtils.getLocaleValue(caseType.pyLabel, '', localeReference) }}</span>
|
|
26
26
|
</mat-list-item>
|
|
27
27
|
</mat-list>
|
|
28
28
|
</mat-list>
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
<mat-list-item (click)="navPanelButtonClick(page)">
|
|
33
33
|
<div class="flex-box">
|
|
34
34
|
<img class="psdk-nav-svg-icon" src="{{ page.iconName }}" />
|
|
35
|
-
<span class="psdk-nav-button-span">{{
|
|
35
|
+
<span class="psdk-nav-button-span">{{ localeUtils.getLocaleValue(page.pyLabel, '', localeReference) }}</span>
|
|
36
36
|
</div>
|
|
37
37
|
</mat-list-item>
|
|
38
38
|
</mat-list>
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
</mat-list-item>
|
|
49
49
|
<mat-menu #menu="matMenu">
|
|
50
50
|
<button mat-menu-item>Profile</button>
|
|
51
|
-
<button mat-menu-item (click)="navPanelLogoutClick()">{{ localizedVal('
|
|
51
|
+
<button mat-menu-item (click)="navPanelLogoutClick()">{{ localizedVal('Log off', localeCategory) }}</button>
|
|
52
52
|
</mat-menu>
|
|
53
53
|
</mat-list>
|
|
54
54
|
</div>
|