@pega/angular-sdk-overrides 0.25.1 → 0.25.3
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/alert/alert.component.scss +3 -3
- package/lib/designSystemExtension/banner/banner.component.scss +12 -2
- package/lib/designSystemExtension/material-case-summary/material-case-summary.component.html +6 -3
- package/lib/designSystemExtension/material-case-summary/material-case-summary.component.scss +5 -34
- package/lib/designSystemExtension/material-details/material-details.component.scss +0 -5
- package/lib/designSystemExtension/material-details-fields/material-details-fields.component.html +2 -2
- package/lib/designSystemExtension/material-details-fields/material-details-fields.component.scss +4 -3
- package/lib/designSystemExtension/material-summary-item/material-summary-item.component.scss +2 -17
- package/lib/designSystemExtension/material-utility/material-utility.component.scss +1 -2
- package/lib/designSystemExtension/material-vertical-tabs/material-vertical-tabs.component.scss +1 -1
- package/lib/designSystemExtension/operator/operator.component.html +1 -1
- package/lib/designSystemExtension/operator/operator.component.scss +3 -10
- package/lib/designSystemExtension/operator/operator.component.ts +0 -1
- package/lib/designSystemExtension/pulse/pulse.component.scss +2 -2
- package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.scss +0 -1
- package/lib/designSystemExtension/wss-quick-create/wss-quick-create.component.scss +16 -8
- package/lib/field/auto-complete/auto-complete.component.html +0 -1
- package/lib/field/auto-complete/auto-complete.component.ts +35 -172
- package/lib/field/cancel-alert/cancel-alert.component.html +8 -12
- package/lib/field/cancel-alert/cancel-alert.component.scss +2 -3
- package/lib/field/cancel-alert/cancel-alert.component.ts +24 -36
- package/lib/field/check-box/check-box.component.html +0 -1
- package/lib/field/check-box/check-box.component.scss +0 -1
- package/lib/field/check-box/check-box.component.ts +19 -149
- package/lib/field/currency/currency.component.ts +36 -168
- package/lib/field/date/date.component.html +1 -1
- package/lib/field/date/date.component.ts +30 -150
- package/lib/field/date-time/date-time.component.ts +31 -149
- package/lib/field/decimal/decimal.component.ts +38 -163
- package/lib/field/dropdown/dropdown.component.ts +29 -151
- package/lib/field/email/email.component.ts +16 -155
- package/lib/field/field.base.ts +149 -0
- package/lib/field/group/group.component.ts +7 -4
- package/lib/field/integer/integer.component.ts +18 -157
- package/lib/field/location/location.component.ts +1 -1
- package/lib/field/multiselect/multiselect.component.ts +46 -148
- package/lib/field/multiselect/utils.ts +55 -47
- package/lib/field/object-reference/object-reference.component.html +17 -0
- package/lib/field/object-reference/object-reference.component.scss +0 -0
- package/lib/field/object-reference/object-reference.component.spec.ts +22 -0
- package/lib/field/object-reference/object-reference.component.ts +237 -0
- package/lib/field/percentage/percentage.component.ts +37 -154
- package/lib/field/phone/phone.component.ts +28 -142
- package/lib/field/radio-buttons/radio-buttons.component.scss +4 -2
- package/lib/field/radio-buttons/radio-buttons.component.ts +35 -161
- package/lib/field/rich-text/rich-text.component.ts +19 -90
- package/lib/field/scalar-list/scalar-list.component.ts +17 -72
- package/lib/field/selectable-card/selectable-card.component.html +54 -24
- package/lib/field/selectable-card/selectable-card.component.scss +11 -0
- package/lib/field/selectable-card/selectable-card.component.ts +16 -52
- package/lib/field/semantic-link/semantic-link.component.html +4 -8
- package/lib/field/semantic-link/semantic-link.component.scss +0 -13
- package/lib/field/semantic-link/semantic-link.component.ts +165 -5
- package/lib/field/text/text.component.scss +0 -1
- package/lib/field/text-area/text-area.component.ts +18 -152
- package/lib/field/text-input/text-input.component.ts +16 -155
- package/lib/field/time/time.component.ts +17 -151
- package/lib/field/url/url.component.ts +16 -154
- package/lib/field/user-reference/user-reference.component.scss +0 -1
- package/lib/field/user-reference/user-reference.component.ts +2 -3
- package/lib/infra/Containers/flow-container/flow-container.component.ts +5 -7
- package/lib/infra/Containers/modal-view-container/modal-view-container.component.ts +5 -10
- package/lib/infra/Containers/view-container/helper.ts +35 -2
- package/lib/infra/Containers/view-container/view-container.component.ts +1 -1
- package/lib/infra/action-buttons/action-buttons.component.html +13 -8
- package/lib/infra/action-buttons/action-buttons.component.scss +23 -0
- package/lib/infra/action-buttons/action-buttons.component.ts +1 -2
- package/lib/infra/assignment/assignment.component.ts +8 -6
- package/lib/infra/assignment-card/assignment-card.component.html +1 -2
- package/lib/infra/assignment-card/assignment-card.component.scss +0 -4
- package/lib/infra/assignment-card/assignment-card.component.ts +21 -4
- package/lib/infra/defer-load/defer-load.component.html +6 -2
- package/lib/infra/defer-load/defer-load.component.ts +16 -10
- package/lib/infra/multi-step/multi-step.component.scss +1 -21
- package/lib/infra/navbar/navbar.component.html +25 -28
- package/lib/infra/navbar/navbar.component.scss +16 -4
- package/lib/infra/navbar/navbar.component.ts +8 -3
- package/lib/infra/root-container/root-container.component.scss +0 -1
- package/lib/infra/root-container/root-container.component.ts +1 -2
- package/lib/infra/stages/stages.component.html +2 -2
- package/lib/infra/stages/stages.component.scss +7 -35
- package/lib/infra/stages/stages.component.ts +4 -2
- package/lib/infra/view/view.component.html +1 -1
- package/lib/infra/view/view.component.ts +0 -2
- package/lib/template/advanced-search/advanced-search.component.html +12 -0
- package/lib/template/advanced-search/advanced-search.component.scss +0 -0
- package/lib/template/advanced-search/advanced-search.component.spec.ts +0 -0
- package/lib/template/advanced-search/advanced-search.component.ts +112 -0
- package/lib/template/advanced-search/advanced-search.service.ts +27 -0
- package/lib/template/advanced-search/search-group/persist-utils.ts +56 -0
- package/lib/template/advanced-search/search-groups/search-groups.component.html +32 -0
- package/lib/template/advanced-search/search-groups/search-groups.component.scss +0 -0
- package/lib/template/advanced-search/search-groups/search-groups.component.spec.ts +0 -0
- package/lib/template/advanced-search/search-groups/search-groups.component.ts +294 -0
- package/lib/template/advanced-search/search-groups/utils.ts +29 -0
- package/lib/template/app-shell/app-shell.component.html +4 -1
- package/lib/template/app-shell/app-shell.component.scss +0 -3
- package/lib/template/app-shell/app-shell.component.ts +46 -7
- package/lib/template/case-summary/case-summary.component.scss +0 -2
- package/lib/template/case-view/case-view.component.html +3 -3
- package/lib/template/case-view/case-view.component.scss +18 -10
- package/lib/template/case-view/case-view.component.ts +1 -1
- package/lib/template/data-reference/data-reference-advanced-search.service.ts +16 -0
- package/lib/template/data-reference/data-reference.component.html +11 -8
- package/lib/template/data-reference/data-reference.component.ts +346 -112
- package/lib/template/data-reference/search-form/search-form.component.html +39 -0
- package/lib/template/data-reference/search-form/search-form.component.scss +11 -0
- package/lib/template/data-reference/search-form/search-form.component.spec.ts +0 -0
- package/lib/template/data-reference/search-form/search-form.component.ts +167 -0
- package/lib/template/data-reference/search-form/tabsData.ts +160 -0
- package/lib/template/data-reference/utils.ts +92 -0
- package/lib/template/default-form/default-form.component.ts +10 -2
- package/lib/template/default-page/default-page.component.html +34 -0
- package/lib/template/default-page/default-page.component.scss +31 -0
- package/lib/template/default-page/default-page.component.spec.ts +24 -0
- package/lib/template/default-page/default-page.component.ts +64 -0
- package/lib/template/field-group-list/field-group-list.component.scss +0 -1
- package/lib/template/inline-dashboard-page/inline-dashboard-page.component.ts +1 -1
- package/lib/template/list-view/list-view.component.html +9 -4
- package/lib/template/list-view/list-view.component.scss +21 -21
- package/lib/template/list-view/list-view.component.ts +154 -84
- package/lib/template/list-view/utils.ts +25 -2
- package/lib/template/object-page/object-page.component.html +1 -0
- package/lib/template/object-page/object-page.component.scss +0 -0
- package/lib/template/object-page/object-page.component.spec.ts +22 -0
- package/lib/template/object-page/object-page.component.ts +14 -0
- package/lib/template/one-column-tab/one-column-tab.component.scss +1 -1
- package/lib/template/repeating-structures/repeating-structures.component.ts +0 -1
- package/lib/template/self-service-case-view/self-service-case-view.component.html +80 -0
- package/lib/template/self-service-case-view/self-service-case-view.component.scss +124 -0
- package/lib/template/self-service-case-view/self-service-case-view.component.spec.ts +24 -0
- package/lib/template/self-service-case-view/self-service-case-view.component.ts +216 -0
- package/lib/template/simple-table/simple-table.component.ts +0 -1
- package/lib/template/simple-table-manual/helpers.ts +2 -2
- package/lib/template/simple-table-manual/simple-table-manual.component.html +4 -4
- package/lib/template/simple-table-manual/simple-table-manual.component.scss +4 -14
- package/lib/template/simple-table-manual/simple-table-manual.component.ts +8 -4
- package/lib/template/single-reference-readonly/single-reference-readonly.component.html +4 -1
- package/lib/template/single-reference-readonly/single-reference-readonly.component.scss +21 -0
- package/lib/template/single-reference-readonly/single-reference-readonly.component.ts +104 -3
- package/lib/template/utils.ts +42 -0
- package/lib/template/wss-nav-bar/wss-nav-bar.component.html +5 -4
- package/lib/template/wss-nav-bar/wss-nav-bar.component.scss +2 -8
- package/lib/template/wss-nav-bar/wss-nav-bar.component.ts +1 -8
- package/lib/widget/app-announcement/app-announcement.component.html +1 -2
- package/lib/widget/app-announcement/app-announcement.component.scss +2 -2
- package/lib/widget/attachment/Attachment.types.ts +92 -0
- package/lib/widget/attachment/AttachmentUtils.ts +287 -0
- package/lib/widget/attachment/attachment.component.html +3 -3
- package/lib/widget/attachment/attachment.component.scss +2 -5
- package/lib/widget/attachment/attachment.component.ts +255 -254
- package/lib/widget/feed-container/feed-container.component.scss +3 -9
- package/lib/widget/feed-container/feed-container.component.ts +2 -2
- package/lib/widget/file-utility/file-utility.component.html +3 -3
- package/lib/widget/file-utility/file-utility.component.scss +5 -16
- package/lib/widget/list-utility/list-utility.component.scss +3 -5
- package/lib/widget/todo/todo.component.html +8 -5
- package/lib/widget/todo/todo.component.scss +10 -11
- package/lib/widget/todo/todo.component.ts +6 -2
- package/package.json +1 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Component, Input, OnInit, forwardRef, OnDestroy } from '@angular/core';
|
|
3
|
+
import { FormGroup } from '@angular/forms';
|
|
4
|
+
import { ComponentMetadataConfig } from '@pega/pcore-pconnect-typedefs/interpreter/types';
|
|
5
|
+
import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
|
|
6
|
+
import { ComponentMapperComponent } from '@pega/angular-sdk-components';
|
|
7
|
+
import { generateColumns, getDataRelationshipContextFromKey } from '@pega/angular-sdk-components';
|
|
8
|
+
import { PConnFieldProps } from '@pega/angular-sdk-components';
|
|
9
|
+
|
|
10
|
+
interface ObjectReferenceProps extends PConnFieldProps {
|
|
11
|
+
showPromotedFilters: boolean;
|
|
12
|
+
inline: boolean;
|
|
13
|
+
parameters: object;
|
|
14
|
+
mode: string;
|
|
15
|
+
targetObjectType: any;
|
|
16
|
+
allowAndPersistChangesInReviewMode: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@Component({
|
|
20
|
+
selector: 'app-object-reference',
|
|
21
|
+
imports: [CommonModule, forwardRef(() => ComponentMapperComponent)],
|
|
22
|
+
templateUrl: './object-reference.component.html',
|
|
23
|
+
styleUrl: './object-reference.component.scss'
|
|
24
|
+
})
|
|
25
|
+
export class ObjectReferenceComponent implements OnInit, OnDestroy {
|
|
26
|
+
@Input() pConn$: typeof PConnect;
|
|
27
|
+
@Input() formGroup$: FormGroup;
|
|
28
|
+
|
|
29
|
+
angularPConnectData: AngularPConnectData = {};
|
|
30
|
+
configProps: ObjectReferenceProps;
|
|
31
|
+
value: { [key: string]: any };
|
|
32
|
+
readOnly: boolean;
|
|
33
|
+
isForm: boolean;
|
|
34
|
+
type: string;
|
|
35
|
+
isDisplayModeEnabled: boolean;
|
|
36
|
+
canBeChangedInReviewMode: boolean;
|
|
37
|
+
newComponentName: string;
|
|
38
|
+
newPconn: typeof PConnect;
|
|
39
|
+
rawViewMetadata: ComponentMetadataConfig | undefined;
|
|
40
|
+
|
|
41
|
+
constructor(private angularPConnect: AngularPConnectService) {}
|
|
42
|
+
|
|
43
|
+
ngOnInit() {
|
|
44
|
+
this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
|
|
45
|
+
this.checkAndUpdate();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
onStateChange() {
|
|
49
|
+
this.checkAndUpdate();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
ngOnDestroy() {
|
|
53
|
+
if (this.angularPConnectData.unsubscribeFn) {
|
|
54
|
+
this.angularPConnectData.unsubscribeFn();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
checkAndUpdate() {
|
|
59
|
+
const shouldUpdate = this.angularPConnect.shouldComponentUpdate(this);
|
|
60
|
+
if (shouldUpdate) {
|
|
61
|
+
this.updateSelf();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
updateSelf() {
|
|
66
|
+
this.configProps = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as ObjectReferenceProps;
|
|
67
|
+
const {
|
|
68
|
+
displayMode,
|
|
69
|
+
allowAndPersistChangesInReviewMode: editableInReview = false,
|
|
70
|
+
targetObjectType,
|
|
71
|
+
mode,
|
|
72
|
+
parameters,
|
|
73
|
+
hideLabel,
|
|
74
|
+
inline,
|
|
75
|
+
showPromotedFilters
|
|
76
|
+
} = this.configProps;
|
|
77
|
+
|
|
78
|
+
const referenceType: string = targetObjectType === 'case' ? 'Case' : 'Data';
|
|
79
|
+
this.rawViewMetadata = this.pConn$.getRawMetadata();
|
|
80
|
+
const refFieldMetadata = this.pConn$.getFieldMetadata(this.rawViewMetadata?.config?.value?.split('.', 2)[1] ?? '');
|
|
81
|
+
const propsToUse = { ...this.pConn$.getInheritedProps(), ...this.configProps };
|
|
82
|
+
|
|
83
|
+
this.isDisplayModeEnabled = displayMode === 'DISPLAY_ONLY';
|
|
84
|
+
this.type = this.getComponentType();
|
|
85
|
+
this.canBeChangedInReviewMode = editableInReview && ['Autocomplete', 'Dropdown'].includes(this.type);
|
|
86
|
+
|
|
87
|
+
if (this.type === 'SemanticLink' && !this.canBeChangedInReviewMode) {
|
|
88
|
+
const config: any = {
|
|
89
|
+
...this.rawViewMetadata?.config,
|
|
90
|
+
primaryField: (this.rawViewMetadata?.config as any).displayField,
|
|
91
|
+
caseClass: (this.rawViewMetadata?.config as any).targetObjectClass,
|
|
92
|
+
text: (this.rawViewMetadata?.config as any).displayField,
|
|
93
|
+
caseID: (this.rawViewMetadata?.config as any).value,
|
|
94
|
+
contextPage: `@P .${(this.rawViewMetadata?.config as any).displayField ? getDataRelationshipContextFromKey((this.rawViewMetadata?.config as any).displayField) : null}`,
|
|
95
|
+
resourceParams: { workID: (this.rawViewMetadata?.config as any).value },
|
|
96
|
+
resourcePayload: { caseClassName: (this.rawViewMetadata?.config as any).targetObjectClass }
|
|
97
|
+
};
|
|
98
|
+
this.createSemanticLinkPConnect(config, displayMode ?? '', referenceType, hideLabel);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (this.type !== 'SemanticLink' && !this.isDisplayModeEnabled) {
|
|
103
|
+
const config: any = { ...this.rawViewMetadata?.config };
|
|
104
|
+
generateColumns(config, this.pConn$, referenceType);
|
|
105
|
+
config.deferDatasource = true;
|
|
106
|
+
config.listType = 'datapage';
|
|
107
|
+
if (['Dropdown', 'AutoComplete'].includes(this.type) && !config.placeholder) {
|
|
108
|
+
config.placeholder = '@L Select...';
|
|
109
|
+
}
|
|
110
|
+
config.showPromotedFilters = showPromotedFilters;
|
|
111
|
+
if (!this.canBeChangedInReviewMode) {
|
|
112
|
+
config.displayMode = displayMode;
|
|
113
|
+
}
|
|
114
|
+
config.parameters = parameters;
|
|
115
|
+
|
|
116
|
+
this.createOtherComponentPConnect(config, propsToUse, mode, refFieldMetadata, referenceType, hideLabel, inline);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
onRecordChange(value) {
|
|
121
|
+
const caseKey = this.pConn$.getCaseInfo().getKey() ?? '';
|
|
122
|
+
const refreshOptions = { autoDetectRefresh: true, propertyName: '' };
|
|
123
|
+
refreshOptions.propertyName = this.rawViewMetadata?.config?.value ?? '';
|
|
124
|
+
|
|
125
|
+
if (!this.canBeChangedInReviewMode || !this.pConn$.getValue('__currentPageTabViewName')) {
|
|
126
|
+
const pgRef = this.pConn$.getPageReference().replace('caseInfo.content', '') ?? '';
|
|
127
|
+
const viewName = this.rawViewMetadata?.name;
|
|
128
|
+
if (viewName && viewName.length > 0) {
|
|
129
|
+
getPConnect().getActionsApi().refreshCaseView(caseKey, viewName, pgRef, refreshOptions);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const propValue = value;
|
|
134
|
+
const propName =
|
|
135
|
+
this.rawViewMetadata?.type === 'SimpleTableSelect' && this.configProps.mode === 'multi'
|
|
136
|
+
? PCore.getAnnotationUtils().getPropertyName(this.rawViewMetadata?.config?.selectionList ?? '')
|
|
137
|
+
: PCore.getAnnotationUtils().getPropertyName(this.rawViewMetadata?.config?.value ?? '');
|
|
138
|
+
|
|
139
|
+
if (propValue && this.canBeChangedInReviewMode && this.isDisplayModeEnabled) {
|
|
140
|
+
PCore.getCaseUtils()
|
|
141
|
+
.getCaseEditLock(caseKey, '')
|
|
142
|
+
.then(caseResponse => {
|
|
143
|
+
const pageTokens = this.pConn$.getPageReference().replace('caseInfo.content', '').split('.');
|
|
144
|
+
let curr = {};
|
|
145
|
+
const commitData = curr;
|
|
146
|
+
|
|
147
|
+
pageTokens?.forEach(el => {
|
|
148
|
+
if (el !== '') {
|
|
149
|
+
curr[el] = {};
|
|
150
|
+
curr = curr[el];
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// expecting format like {Customer: {pyID:"C-100"}}
|
|
155
|
+
const propArr = propName.split('.');
|
|
156
|
+
propArr.forEach((element, idx) => {
|
|
157
|
+
if (idx + 1 === propArr.length) {
|
|
158
|
+
curr[element] = propValue;
|
|
159
|
+
} else {
|
|
160
|
+
curr[element] = {};
|
|
161
|
+
curr = curr[element];
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
PCore.getCaseUtils()
|
|
166
|
+
.updateCaseEditFieldsData(caseKey, { [caseKey]: commitData }, caseResponse.headers.etag, this.pConn$?.getContextName() ?? '')
|
|
167
|
+
.then(response => {
|
|
168
|
+
PCore.getContainerUtils().updateParentLastUpdateTime(this.pConn$.getContextName() ?? '', response.data.data.caseInfo.lastUpdateTime);
|
|
169
|
+
PCore.getContainerUtils().updateRelatedContextEtag(this.pConn$.getContextName() ?? '', response.headers.etag);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private getComponentType(): string {
|
|
176
|
+
// componentType is not defined in ComponentMetadataConfig type so using any
|
|
177
|
+
return (this.rawViewMetadata?.config as any)?.componentType;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private createSemanticLinkPConnect(config: any, displayMode: string, referenceType: string, hideLabel: boolean) {
|
|
181
|
+
const semanticLinkConfig = {
|
|
182
|
+
...config,
|
|
183
|
+
displayMode,
|
|
184
|
+
referenceType,
|
|
185
|
+
hideLabel,
|
|
186
|
+
dataRelationshipContext: config.displayField ? getDataRelationshipContextFromKey(config.displayField) : null
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const component = this.pConn$.createComponent({ type: 'SemanticLink', config: semanticLinkConfig }, '', 0, {});
|
|
190
|
+
this.newPconn = component?.getPConnect();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
private createOtherComponentPConnect(
|
|
194
|
+
config: any,
|
|
195
|
+
propsToUse: any,
|
|
196
|
+
mode: string,
|
|
197
|
+
refFieldMetadata: any,
|
|
198
|
+
referenceType: string,
|
|
199
|
+
hideLabel: boolean,
|
|
200
|
+
inline: boolean
|
|
201
|
+
) {
|
|
202
|
+
const fieldMetaData = {
|
|
203
|
+
datasourceMetadata: {
|
|
204
|
+
datasource: {
|
|
205
|
+
parameters: config.parameters ?? {},
|
|
206
|
+
propertyForDisplayText: config.datasource?.fields?.text?.substring(3) ?? config.datasource?.fields?.text,
|
|
207
|
+
propertyForValue: config.datasource?.fields?.value?.substring(3) ?? config.datasource?.fields?.value,
|
|
208
|
+
name: config.referenceList ?? ''
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const componentConfig = {
|
|
214
|
+
...config,
|
|
215
|
+
descriptors: mode === 'single' ? refFieldMetadata?.descriptors : null,
|
|
216
|
+
datasourceMetadata: fieldMetaData.datasourceMetadata,
|
|
217
|
+
required: propsToUse.required,
|
|
218
|
+
visibility: propsToUse.visibility,
|
|
219
|
+
disabled: propsToUse.disabled,
|
|
220
|
+
label: propsToUse.label,
|
|
221
|
+
readOnly: false,
|
|
222
|
+
...(mode === 'single' && { referenceType }),
|
|
223
|
+
contextClass: config.targetObjectClass,
|
|
224
|
+
primaryField: config.displayField,
|
|
225
|
+
dataRelationshipContext: config.displayField ? getDataRelationshipContextFromKey(config.displayField) : null,
|
|
226
|
+
hideLabel,
|
|
227
|
+
inline
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
const component = this.pConn$.createComponent({ type: this.type, config: componentConfig }, '', 0, {});
|
|
231
|
+
this.newComponentName = component?.getPConnect().getComponentName();
|
|
232
|
+
this.newPconn = component?.getPConnect();
|
|
233
|
+
if (this.rawViewMetadata?.config) {
|
|
234
|
+
this.rawViewMetadata.config = { ...config };
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { Component,
|
|
1
|
+
import { Component, forwardRef } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { FormControl,
|
|
3
|
+
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
|
4
4
|
import { MatInputModule } from '@angular/material/input';
|
|
5
5
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
6
|
-
import { interval } from 'rxjs';
|
|
7
6
|
import { NgxCurrencyDirective, NgxCurrencyInputMode } from 'ngx-currency';
|
|
8
|
-
|
|
9
|
-
import {
|
|
7
|
+
|
|
8
|
+
import { FieldBase } from '@pega/angular-sdk-components';
|
|
10
9
|
import { ComponentMapperComponent } from '@pega/angular-sdk-components';
|
|
11
10
|
import { handleEvent } from '@pega/angular-sdk-components';
|
|
12
11
|
import { getCurrencyCharacters } from '@pega/angular-sdk-components';
|
|
13
|
-
import { PConnFieldProps } from '@pega/angular-sdk-components';
|
|
14
12
|
import { format } from '@pega/angular-sdk-components';
|
|
13
|
+
import { PConnFieldProps } from '@pega/angular-sdk-components';
|
|
15
14
|
|
|
16
|
-
interface PercentageProps extends PConnFieldProps {
|
|
15
|
+
interface PercentageProps extends Omit<PConnFieldProps, 'value'> {
|
|
16
|
+
value?: number;
|
|
17
17
|
showGroupSeparators?: string;
|
|
18
18
|
decimalPrecision?: number;
|
|
19
19
|
currencyISOCode?: string;
|
|
@@ -26,155 +26,54 @@ interface PercentageProps extends PConnFieldProps {
|
|
|
26
26
|
styleUrls: ['./percentage.component.scss'],
|
|
27
27
|
imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, NgxCurrencyDirective, forwardRef(() => ComponentMapperComponent)]
|
|
28
28
|
})
|
|
29
|
-
export class PercentageComponent
|
|
30
|
-
@Input() pConn$: typeof PConnect;
|
|
31
|
-
@Input() formGroup$: FormGroup;
|
|
32
|
-
|
|
33
|
-
// Used with AngularPConnect
|
|
34
|
-
angularPConnectData: AngularPConnectData = {};
|
|
29
|
+
export class PercentageComponent extends FieldBase {
|
|
35
30
|
configProps$: PercentageProps;
|
|
31
|
+
override fieldControl = new FormControl<number | null>(null, null);
|
|
36
32
|
|
|
37
|
-
label$ = '';
|
|
38
|
-
value$: number;
|
|
39
|
-
bRequired$ = false;
|
|
40
|
-
bReadonly$ = false;
|
|
41
|
-
bDisabled$ = false;
|
|
42
|
-
bVisible$ = true;
|
|
43
|
-
displayMode$?: string = '';
|
|
44
|
-
controlName$: string;
|
|
45
|
-
bHasForm$ = true;
|
|
46
|
-
componentReference = '';
|
|
47
|
-
testId: string;
|
|
48
|
-
helperText: string;
|
|
49
|
-
placeholder: string;
|
|
50
33
|
decimalSeparator: string;
|
|
51
34
|
thousandSeparator: string;
|
|
52
|
-
inputMode: any;
|
|
35
|
+
inputMode: any = NgxCurrencyInputMode.Natural;
|
|
53
36
|
decimalPrecision: number | undefined;
|
|
54
|
-
fieldControl = new FormControl<number | null>(null, null);
|
|
55
|
-
actionsApi: Object;
|
|
56
|
-
propName: string;
|
|
57
37
|
formattedValue: string;
|
|
58
38
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
ngOnInit(): void {
|
|
66
|
-
// First thing in initialization is registering and subscribing to the AngularPConnect service
|
|
67
|
-
this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
|
|
68
|
-
this.controlName$ = this.angularPConnect.getComponentID(this);
|
|
39
|
+
/**
|
|
40
|
+
* Updates the component when there are changes in the state.
|
|
41
|
+
*/
|
|
42
|
+
override updateSelf(): void {
|
|
43
|
+
// Resolve configuration properties
|
|
44
|
+
this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as PercentageProps;
|
|
69
45
|
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
// this.updateSelf();
|
|
73
|
-
this.checkAndUpdate();
|
|
46
|
+
// Update component common properties
|
|
47
|
+
this.updateComponentCommonProperties(this.configProps$);
|
|
74
48
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
this.
|
|
79
|
-
this.
|
|
80
|
-
} else {
|
|
81
|
-
this.bReadonly$ = true;
|
|
82
|
-
this.bHasForm$ = false;
|
|
49
|
+
// Set component specific properties
|
|
50
|
+
const { value } = this.configProps$;
|
|
51
|
+
if (value) {
|
|
52
|
+
this.value$ = value;
|
|
53
|
+
this.fieldControl.setValue(value);
|
|
83
54
|
}
|
|
84
|
-
}
|
|
85
55
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
this.formGroup$.removeControl(this.controlName$);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (this.angularPConnectData.unsubscribeFn) {
|
|
92
|
-
this.angularPConnectData.unsubscribeFn();
|
|
93
|
-
}
|
|
56
|
+
// update percentage properties
|
|
57
|
+
this.updatePercentageProperties(this.configProps$);
|
|
94
58
|
}
|
|
95
59
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
// ONLY call updateSelf when the component should update
|
|
107
|
-
if (bUpdateSelf) {
|
|
108
|
-
this.updateSelf();
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// updateSelf
|
|
113
|
-
updateSelf(): void {
|
|
114
|
-
// moved this from ngOnInit() and call this from there instead...
|
|
115
|
-
this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as PercentageProps;
|
|
116
|
-
this.testId = this.configProps$.testId;
|
|
117
|
-
this.label$ = this.configProps$.label;
|
|
118
|
-
this.displayMode$ = this.configProps$.displayMode;
|
|
119
|
-
this.inputMode = NgxCurrencyInputMode.Natural;
|
|
120
|
-
const nValue: any = this.configProps$.value;
|
|
121
|
-
if (nValue) {
|
|
122
|
-
this.value$ = nValue;
|
|
123
|
-
this.fieldControl.setValue(nValue);
|
|
124
|
-
}
|
|
125
|
-
this.helperText = this.configProps$.helperText;
|
|
126
|
-
this.placeholder = this.configProps$.placeholder || '';
|
|
127
|
-
const showGroupSeparators = this.configProps$.showGroupSeparators;
|
|
60
|
+
/**
|
|
61
|
+
* Updates the percentage properties
|
|
62
|
+
*
|
|
63
|
+
* @param {Object} configProps - Configuration properties.
|
|
64
|
+
* @param {boolean} configProps.showGroupSeparators - Whether to show group separators.
|
|
65
|
+
* @param {number} configProps.decimalPrecision - The number of decimal places to display.
|
|
66
|
+
*/
|
|
67
|
+
updatePercentageProperties(configProps): void {
|
|
68
|
+
const { showGroupSeparators, decimalPrecision } = configProps;
|
|
128
69
|
|
|
129
70
|
const theSymbols = getCurrencyCharacters('');
|
|
130
71
|
this.decimalSeparator = theSymbols.theDecimalIndicator;
|
|
131
72
|
this.thousandSeparator = showGroupSeparators ? theSymbols.theDigitGroupSeparator : '';
|
|
73
|
+
this.decimalPrecision = decimalPrecision ?? 2;
|
|
132
74
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if (this.displayMode$ === 'DISPLAY_ONLY' || this.displayMode$ === 'STACKED_LARGE_VAL') {
|
|
137
|
-
this.formattedValue = nValue ? format(nValue, 'percentage') : '';
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
|
|
141
|
-
setTimeout(() => {
|
|
142
|
-
if (this.configProps$.required != null) {
|
|
143
|
-
this.bRequired$ = this.utils.getBooleanValue(this.configProps$.required);
|
|
144
|
-
}
|
|
145
|
-
this.cdRef.detectChanges();
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
if (this.configProps$.visibility != null) {
|
|
149
|
-
this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// disabled
|
|
153
|
-
if (this.configProps$.disabled != undefined) {
|
|
154
|
-
this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (this.bDisabled$) {
|
|
158
|
-
this.fieldControl.disable();
|
|
159
|
-
} else {
|
|
160
|
-
this.fieldControl.enable();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (this.configProps$.readOnly != null) {
|
|
164
|
-
this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
this.decimalPrecision = this.configProps$?.decimalPrecision ?? 2;
|
|
168
|
-
|
|
169
|
-
this.componentReference = this.pConn$.getStateProps().value;
|
|
170
|
-
|
|
171
|
-
// trigger display of error message with field control
|
|
172
|
-
if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
|
|
173
|
-
const timer = interval(100).subscribe(() => {
|
|
174
|
-
this.fieldControl.setErrors({ message: true });
|
|
175
|
-
this.fieldControl.markAsTouched();
|
|
176
|
-
timer.unsubscribe();
|
|
177
|
-
});
|
|
75
|
+
if (['DISPLAY_ONLY', 'STACKED_LARGE_VAL'].includes(this.displayMode$)) {
|
|
76
|
+
this.formattedValue = this.value$ ? format(this.value$, 'percentage') : '';
|
|
178
77
|
}
|
|
179
78
|
}
|
|
180
79
|
|
|
@@ -210,20 +109,4 @@ export class PercentageComponent implements OnInit, OnDestroy {
|
|
|
210
109
|
handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
|
|
211
110
|
}
|
|
212
111
|
}
|
|
213
|
-
|
|
214
|
-
getErrorMessage() {
|
|
215
|
-
// field control gets error message from here
|
|
216
|
-
let errMessage = '';
|
|
217
|
-
// look for validation messages for json, pre-defined or just an error pushed from workitem (400)
|
|
218
|
-
if (this.fieldControl.hasError('message')) {
|
|
219
|
-
errMessage = this.angularPConnectData.validateMessage ?? '';
|
|
220
|
-
return errMessage;
|
|
221
|
-
}
|
|
222
|
-
if (this.fieldControl.hasError('required')) {
|
|
223
|
-
errMessage = 'You must enter a value';
|
|
224
|
-
} else if (this.fieldControl.errors) {
|
|
225
|
-
errMessage = this.fieldControl.errors.toString();
|
|
226
|
-
}
|
|
227
|
-
return errMessage;
|
|
228
|
-
}
|
|
229
112
|
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { Component,
|
|
1
|
+
import { Component, forwardRef } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
|
-
import {
|
|
3
|
+
import { ReactiveFormsModule } from '@angular/forms';
|
|
4
4
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
5
|
-
import { interval } from 'rxjs';
|
|
6
5
|
import { MatTelInput } from 'mat-tel-input';
|
|
7
6
|
import { parsePhoneNumberFromString } from 'libphonenumber-js';
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
import { handleEvent } from '@pega/angular-sdk-components';
|
|
7
|
+
|
|
8
|
+
import { FieldBase } from '@pega/angular-sdk-components';
|
|
11
9
|
import { ComponentMapperComponent } from '@pega/angular-sdk-components';
|
|
10
|
+
import { handleEvent } from '@pega/angular-sdk-components';
|
|
12
11
|
import { PConnFieldProps } from '@pega/angular-sdk-components';
|
|
13
12
|
|
|
14
13
|
interface PhoneProps extends PConnFieldProps {
|
|
@@ -21,141 +20,28 @@ interface PhoneProps extends PConnFieldProps {
|
|
|
21
20
|
styleUrls: ['./phone.component.scss'],
|
|
22
21
|
imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatTelInput, forwardRef(() => ComponentMapperComponent)]
|
|
23
22
|
})
|
|
24
|
-
export class PhoneComponent
|
|
25
|
-
@Input() pConn$: typeof PConnect;
|
|
26
|
-
@Input() formGroup$: FormGroup;
|
|
27
|
-
|
|
28
|
-
// Used with AngularPConnect
|
|
29
|
-
angularPConnectData: AngularPConnectData = {};
|
|
23
|
+
export class PhoneComponent extends FieldBase {
|
|
30
24
|
configProps$: PhoneProps;
|
|
31
25
|
|
|
32
|
-
label$ = '';
|
|
33
|
-
value$: string;
|
|
34
|
-
bRequired$ = false;
|
|
35
|
-
bReadonly$ = false;
|
|
36
|
-
bDisabled$ = false;
|
|
37
|
-
bVisible$ = true;
|
|
38
|
-
displayMode$?: string = '';
|
|
39
|
-
controlName$: string;
|
|
40
|
-
bHasForm$ = true;
|
|
41
|
-
testId: string;
|
|
42
|
-
helperText: string;
|
|
43
|
-
placeholder: string;
|
|
44
|
-
|
|
45
|
-
fieldControl = new FormControl('', null);
|
|
46
|
-
|
|
47
|
-
actionsApi: Object;
|
|
48
|
-
propName: string;
|
|
49
26
|
preferredCountries: string[] = ['us'];
|
|
50
27
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
ngOnInit(): void {
|
|
58
|
-
// First thing in initialization is registering and subscribing to the AngularPConnect service
|
|
59
|
-
this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
|
|
60
|
-
this.controlName$ = this.angularPConnect.getComponentID(this);
|
|
61
|
-
|
|
62
|
-
// Then, continue on with other initialization
|
|
63
|
-
|
|
64
|
-
// call updateSelf when initializing
|
|
65
|
-
// this.updateSelf();
|
|
66
|
-
this.checkAndUpdate();
|
|
67
|
-
|
|
68
|
-
if (this.formGroup$) {
|
|
69
|
-
// add control to formGroup
|
|
70
|
-
this.formGroup$.addControl(this.controlName$, this.fieldControl);
|
|
71
|
-
this.fieldControl.setValue(this.value$);
|
|
72
|
-
this.bHasForm$ = true;
|
|
73
|
-
} else {
|
|
74
|
-
this.bReadonly$ = true;
|
|
75
|
-
this.bHasForm$ = false;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
ngOnDestroy(): void {
|
|
80
|
-
if (this.formGroup$) {
|
|
81
|
-
this.formGroup$.removeControl(this.controlName$);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (this.angularPConnectData.unsubscribeFn) {
|
|
85
|
-
this.angularPConnectData.unsubscribeFn();
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Callback passed when subscribing to store change
|
|
90
|
-
onStateChange() {
|
|
91
|
-
this.checkAndUpdate();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
checkAndUpdate() {
|
|
95
|
-
// Should always check the bridge to see if the component should
|
|
96
|
-
// update itself (re-render)
|
|
97
|
-
const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
|
|
98
|
-
|
|
99
|
-
// ONLY call updateSelf when the component should update
|
|
100
|
-
if (bUpdateSelf) {
|
|
101
|
-
this.updateSelf();
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// updateSelf
|
|
106
|
-
updateSelf(): void {
|
|
107
|
-
// moved this from ngOnInit() and call this from there instead...
|
|
28
|
+
/**
|
|
29
|
+
* Updates the component when there are changes in the state.
|
|
30
|
+
*/
|
|
31
|
+
override updateSelf(): void {
|
|
32
|
+
// Resolve config properties
|
|
108
33
|
this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as PhoneProps;
|
|
109
34
|
|
|
110
|
-
|
|
111
|
-
this.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
35
|
+
// Update component common properties
|
|
36
|
+
this.updateComponentCommonProperties(this.configProps$);
|
|
37
|
+
|
|
38
|
+
// Extract and normalize the value property
|
|
39
|
+
const { value } = this.configProps$;
|
|
40
|
+
if (value) {
|
|
41
|
+
this.value$ = value;
|
|
115
42
|
this.fieldControl.setValue(this.value$);
|
|
116
43
|
this.updatePreferredCountries();
|
|
117
44
|
}
|
|
118
|
-
this.helperText = this.configProps$.helperText;
|
|
119
|
-
this.placeholder = this.configProps$.placeholder || '';
|
|
120
|
-
this.actionsApi = this.pConn$.getActionsApi();
|
|
121
|
-
this.propName = this.pConn$.getStateProps().value;
|
|
122
|
-
|
|
123
|
-
// timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
|
|
124
|
-
setTimeout(() => {
|
|
125
|
-
if (this.configProps$.required != null) {
|
|
126
|
-
this.bRequired$ = this.utils.getBooleanValue(this.configProps$.required);
|
|
127
|
-
}
|
|
128
|
-
this.cdRef.detectChanges();
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
if (this.configProps$.visibility != null) {
|
|
132
|
-
this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// disabled
|
|
136
|
-
if (this.configProps$.disabled != undefined) {
|
|
137
|
-
this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (this.bDisabled$) {
|
|
141
|
-
this.fieldControl.disable();
|
|
142
|
-
} else {
|
|
143
|
-
this.fieldControl.enable();
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (this.configProps$.readOnly != null) {
|
|
147
|
-
this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// trigger display of error message with field control
|
|
151
|
-
if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
|
|
152
|
-
const timer = interval(100).subscribe(() => {
|
|
153
|
-
this.fieldControl.setErrors({ message: true });
|
|
154
|
-
this.fieldControl.markAsTouched();
|
|
155
|
-
|
|
156
|
-
timer.unsubscribe();
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
45
|
}
|
|
160
46
|
|
|
161
47
|
fieldOnBlur() {
|
|
@@ -167,7 +53,7 @@ export class PhoneComponent implements OnInit, OnDestroy {
|
|
|
167
53
|
const newVal = this.formGroup$.controls[this.controlName$].value;
|
|
168
54
|
const isValueChanged = newVal?.toString() !== oldVal.toString();
|
|
169
55
|
|
|
170
|
-
if (isValueChanged
|
|
56
|
+
if (isValueChanged) {
|
|
171
57
|
const value = this.formGroup$.controls[this.controlName$].value;
|
|
172
58
|
handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
|
|
173
59
|
}
|
|
@@ -183,20 +69,20 @@ export class PhoneComponent implements OnInit, OnDestroy {
|
|
|
183
69
|
}
|
|
184
70
|
}
|
|
185
71
|
|
|
186
|
-
getErrorMessage() {
|
|
187
|
-
let errMessage = '';
|
|
188
|
-
|
|
72
|
+
override getErrorMessage() {
|
|
189
73
|
// look for validation messages for json, pre-defined or just an error pushed from workitem (400)
|
|
190
74
|
if (this.fieldControl.hasError('message')) {
|
|
191
|
-
|
|
192
|
-
return errMessage;
|
|
75
|
+
return this.angularPConnectData.validateMessage ?? '';
|
|
193
76
|
}
|
|
77
|
+
|
|
194
78
|
if (this.fieldControl.hasError('required')) {
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
|
|
79
|
+
return 'You must enter a value';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (this.fieldControl.errors) {
|
|
83
|
+
return 'Invalid Phone';
|
|
198
84
|
}
|
|
199
85
|
|
|
200
|
-
return
|
|
86
|
+
return '';
|
|
201
87
|
}
|
|
202
88
|
}
|