@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.
- package/lib/designSystemExtension/alert-banner/alert-banner.component.ts +1 -1
- package/lib/designSystemExtension/case-create-stage/case-create-stage.component.ts +1 -1
- package/lib/designSystemExtension/material-case-summary/material-case-summary.component.html +7 -4
- package/lib/designSystemExtension/material-case-summary/material-case-summary.component.scss +2 -1
- package/lib/designSystemExtension/material-case-summary/material-case-summary.component.ts +3 -1
- package/lib/designSystemExtension/material-details-fields/material-details-fields.component.html +1 -1
- package/lib/designSystemExtension/material-details-fields/material-details-fields.component.ts +4 -1
- package/lib/designSystemExtension/material-vertical-tabs/material-vertical-tabs.component.html +1 -1
- package/lib/designSystemExtension/operator/operator.component.ts +11 -6
- package/lib/designSystemExtension/pulse/pulse.component.ts +7 -7
- package/lib/field/auto-complete/auto-complete.component.ts +17 -14
- package/lib/field/cancel-alert/cancel-alert.component.ts +0 -2
- 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 +128 -45
- package/lib/field/currency/currency.component.html +16 -7
- package/lib/field/currency/currency.component.ts +55 -20
- package/lib/field/date/date.component.html +1 -6
- package/lib/field/date/date.component.ts +22 -39
- package/lib/field/date-time/date-time.component.html +6 -7
- package/lib/field/date-time/date-time.component.ts +28 -45
- package/lib/field/decimal/decimal.component.html +14 -4
- package/lib/field/decimal/decimal.component.ts +47 -7
- package/lib/field/dropdown/dropdown.component.ts +132 -21
- package/lib/field/email/email.component.ts +14 -4
- package/lib/field/group/group.component.html +1 -1
- package/lib/field/group/group.component.ts +6 -2
- package/lib/field/integer/integer.component.html +1 -1
- package/lib/field/integer/integer.component.ts +13 -5
- package/lib/field/multiselect/multiselect.component.html +33 -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 +369 -0
- package/lib/field/multiselect/utils.ts +209 -0
- package/lib/field/percentage/percentage.component.html +17 -6
- package/lib/field/percentage/percentage.component.ts +51 -12
- package/lib/field/phone/phone.component.html +1 -1
- package/lib/field/phone/phone.component.ts +11 -14
- package/lib/field/radio-buttons/radio-buttons.component.ts +9 -12
- package/lib/field/rich-text/config-ext.json +10 -0
- package/lib/field/rich-text/rich-text.component.html +1 -1
- package/lib/field/rich-text/rich-text.component.ts +8 -6
- package/lib/field/scalar-list/scalar-list.component.ts +4 -4
- package/lib/field/text/text.component.ts +2 -0
- package/lib/field/text-area/text-area.component.html +2 -1
- package/lib/field/text-area/text-area.component.ts +13 -8
- package/lib/field/text-input/text-input.component.html +1 -1
- package/lib/field/text-input/text-input.component.ts +13 -5
- package/lib/field/time/time.component.html +3 -2
- package/lib/field/time/time.component.ts +23 -7
- package/lib/field/url/url.component.html +2 -1
- package/lib/field/url/url.component.ts +15 -5
- package/lib/field/user-reference/user-reference.component.html +42 -45
- package/lib/field/user-reference/user-reference.component.ts +73 -27
- package/lib/infra/Containers/base-components/flow-container-base.component.ts +22 -0
- package/lib/infra/Containers/base-components/helper.ts +89 -0
- package/lib/infra/Containers/flow-container/flow-container.component.html +9 -4
- package/lib/infra/Containers/flow-container/flow-container.component.ts +38 -33
- package/lib/infra/Containers/modal-view-container/modal-view-container.component.ts +41 -9
- package/lib/infra/Containers/preview-view-container/preview-view-container.component.ts +1 -1
- package/lib/infra/Containers/view-container/helper.ts +22 -0
- package/lib/infra/Containers/view-container/view-container.component.ts +5 -18
- package/lib/infra/assignment/assignment.component.ts +37 -39
- package/lib/infra/dashboard-filter/dashboard-filter.component.ts +0 -1
- package/lib/infra/defer-load/defer-load.component.ts +9 -12
- package/lib/infra/multi-step/multi-step.component.html +1 -1
- package/lib/infra/multi-step/multi-step.component.scss +1 -0
- package/lib/infra/navbar/navbar.component.html +4 -4
- package/lib/infra/navbar/navbar.component.ts +9 -6
- package/lib/infra/root-container/root-container.component.ts +3 -3
- package/lib/infra/stages/stages.component.scss +2 -2
- package/lib/infra/view/view.component.html +7 -20
- package/lib/infra/view/view.component.ts +21 -3
- package/lib/template/app-shell/app-shell.component.ts +20 -2
- package/lib/template/banner-page/config-ext.json +9 -0
- package/lib/template/base/details-template-base.ts +67 -0
- package/lib/template/base/form-template-base.ts +10 -0
- package/lib/template/case-summary/case-summary.component.ts +38 -4
- package/lib/template/case-view/case-view.component.html +7 -7
- package/lib/template/case-view/case-view.component.scss +2 -0
- package/lib/template/case-view/case-view.component.ts +8 -19
- package/lib/template/confirmation/confirmation.component.ts +1 -1
- package/lib/template/data-reference/data-reference.component.ts +37 -43
- package/lib/template/default-form/default-form.component.html +0 -4
- package/lib/template/default-form/default-form.component.ts +7 -23
- package/lib/template/details/details.component.ts +7 -41
- package/lib/template/details-narrow-wide/details-narrow-wide.component.ts +6 -39
- package/lib/template/details-one-column/details-one-column.component.ts +7 -42
- package/lib/template/details-sub-tabs/details-sub-tabs.component.html +1 -2
- package/lib/template/details-sub-tabs/details-sub-tabs.component.ts +5 -37
- package/lib/template/details-three-column/details-three-column.component.ts +7 -43
- package/lib/template/details-two-column/details-two-column.component.ts +8 -44
- package/lib/template/details-wide-narrow/details-wide-narrow.component.ts +7 -42
- package/lib/template/dynamic-tabs/dynamic-tabs.component.html +3 -0
- package/lib/template/dynamic-tabs/dynamic-tabs.component.ts +8 -4
- package/lib/template/field-group-template/field-group-template.component.ts +4 -14
- package/lib/template/field-value-list/field-value-list.component.html +8 -3
- package/lib/template/field-value-list/field-value-list.component.scss +2 -1
- package/lib/template/field-value-list/field-value-list.component.ts +1 -0
- package/lib/template/inline-dashboard-page/config-ext.json +9 -0
- package/lib/template/inline-dashboard-page/inline-dashboard-page.component.ts +2 -2
- package/lib/template/list-view/list-view.component.html +9 -6
- package/lib/template/list-view/list-view.component.scss +11 -0
- package/lib/template/list-view/list-view.component.ts +60 -32
- package/lib/template/list-view/listViewHelpers.ts +1 -2
- package/lib/template/narrow-wide-form/narrow-wide-form.component.ts +1 -1
- package/lib/template/one-column/one-column.component.ts +4 -3
- package/lib/template/one-column-tab/one-column-tab.component.ts +1 -1
- package/lib/template/page/page.component.ts +1 -1
- package/lib/template/promoted-filters/promoted-filters.component.ts +1 -1
- package/lib/template/repeating-structures/repeating-structures.component.ts +2 -3
- package/lib/template/simple-table/simple-table.component.ts +0 -2
- package/lib/template/simple-table-manual/helpers.ts +2 -2
- package/lib/template/simple-table-manual/simple-table-manual.component.html +1 -1
- package/lib/template/simple-table-manual/simple-table-manual.component.scss +1 -0
- package/lib/template/simple-table-manual/simple-table-manual.component.ts +60 -28
- package/lib/template/simple-table-select/simple-table-select.component.ts +5 -7
- package/lib/template/three-column/three-column.component.ts +4 -3
- package/lib/template/two-column/two-column.component.ts +4 -3
- package/lib/template/two-column-tab/two-column-tab.component.ts +1 -1
- package/lib/template/wide-narrow-form/wide-narrow-form.component.ts +4 -3
- package/lib/template/wide-narrow-page/wide-narrow-page.component.ts +1 -1
- package/lib/template/wss-nav-bar/wss-nav-bar.component.html +1 -1
- package/lib/template/wss-nav-bar/wss-nav-bar.component.ts +5 -4
- package/lib/widget/attachment/attachment.component.html +50 -26
- package/lib/widget/attachment/attachment.component.scss +118 -0
- package/lib/widget/attachment/attachment.component.ts +256 -503
- package/lib/widget/case-history/case-history.component.ts +1 -2
- package/lib/widget/feed-container/feed-container.component.ts +7 -11
- package/lib/widget/file-utility/file-utility.component.html +2 -2
- package/lib/widget/file-utility/file-utility.component.ts +15 -22
- package/lib/widget/list-utility/list-utility.component.html +1 -1
- package/lib/widget/quick-create/config-ext.json +9 -0
- package/lib/widget/quick-create/quick-create.component.ts +1 -1
- package/lib/widget/todo/todo.component.html +8 -7
- package/lib/widget/todo/todo.component.ts +97 -86
- package/package.json +1 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { Component, OnInit, Input, NgZone, forwardRef, OnDestroy } from '@angular/core';
|
|
1
|
+
import { Component, OnInit, Input, NgZone, forwardRef, OnDestroy, ViewChild, ElementRef } from '@angular/core';
|
|
2
2
|
import { FormGroup } from '@angular/forms';
|
|
3
3
|
import { CommonModule } from '@angular/common';
|
|
4
4
|
import { MatButtonModule } from '@angular/material/button';
|
|
5
|
+
import { MatMenuModule } from '@angular/material/menu';
|
|
6
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
5
7
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
6
8
|
import download from 'downloadjs';
|
|
7
9
|
import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
|
|
@@ -21,7 +23,7 @@ interface AttachmentProps extends Omit<PConnFieldProps, 'value'> {
|
|
|
21
23
|
templateUrl: './attachment.component.html',
|
|
22
24
|
styleUrls: ['./attachment.component.scss'],
|
|
23
25
|
standalone: true,
|
|
24
|
-
imports: [CommonModule, MatProgressSpinnerModule, MatButtonModule, forwardRef(() => ComponentMapperComponent)]
|
|
26
|
+
imports: [CommonModule, MatProgressSpinnerModule, MatMenuModule, MatIconModule, MatButtonModule, forwardRef(() => ComponentMapperComponent)]
|
|
25
27
|
})
|
|
26
28
|
export class AttachmentComponent implements OnInit, OnDestroy {
|
|
27
29
|
@Input() pConn$: typeof PConnect;
|
|
@@ -29,6 +31,7 @@ export class AttachmentComponent implements OnInit, OnDestroy {
|
|
|
29
31
|
|
|
30
32
|
// For interaction with AngularPConnect
|
|
31
33
|
angularPConnectData: AngularPConnectData = {};
|
|
34
|
+
@ViewChild('uploader', { static: false }) fileInput: ElementRef;
|
|
32
35
|
|
|
33
36
|
label$ = '';
|
|
34
37
|
value$: any;
|
|
@@ -37,16 +40,8 @@ export class AttachmentComponent implements OnInit, OnDestroy {
|
|
|
37
40
|
bDisabled$ = false;
|
|
38
41
|
bVisible$ = true;
|
|
39
42
|
bLoading$ = false;
|
|
40
|
-
arFiles$: any[] = [];
|
|
41
|
-
arFileList$: any[] = [];
|
|
42
|
-
removeFileFromList$: any;
|
|
43
|
-
arMenuList$: any[] = [];
|
|
44
43
|
bShowSelector$ = true;
|
|
45
|
-
bShowJustDelete$ = false;
|
|
46
|
-
att_valueRef: any;
|
|
47
44
|
att_categoryName: string;
|
|
48
|
-
att_id: string;
|
|
49
|
-
myFiles: any;
|
|
50
45
|
fileTemp: any = {};
|
|
51
46
|
caseID: any;
|
|
52
47
|
allowMultiple$ = false;
|
|
@@ -55,7 +50,17 @@ export class AttachmentComponent implements OnInit, OnDestroy {
|
|
|
55
50
|
validateMessage: string | undefined = '';
|
|
56
51
|
valueRef: string;
|
|
57
52
|
imagePath$: string;
|
|
58
|
-
|
|
53
|
+
localizedVal = PCore.getLocaleUtils().getLocaleValue;
|
|
54
|
+
localeCategory = 'CosmosFields';
|
|
55
|
+
uploadMultipleFilesLabel = this.localizedVal('file_upload_text_multiple', this.localeCategory);
|
|
56
|
+
uploadSingleFileLabel = this.localizedVal('file_upload_text_one', this.localeCategory);
|
|
57
|
+
filesWithError: any = [];
|
|
58
|
+
files: any = [];
|
|
59
|
+
categoryName: string;
|
|
60
|
+
displayMode: string | undefined;
|
|
61
|
+
srcImg: any;
|
|
62
|
+
deleteIcon: string;
|
|
63
|
+
tempFilesToBeUploaded: any[];
|
|
59
64
|
constructor(
|
|
60
65
|
private angularPConnect: AngularPConnectService,
|
|
61
66
|
private utils: Utils,
|
|
@@ -65,13 +70,36 @@ export class AttachmentComponent implements OnInit, OnDestroy {
|
|
|
65
70
|
ngOnInit(): void {
|
|
66
71
|
// // First thing in initialization is registering and subscribing to the AngularPConnect service
|
|
67
72
|
this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
|
|
68
|
-
|
|
69
|
-
this.removeFileFromList$ = { onClick: this._removeFileFromList.bind(this) };
|
|
70
|
-
|
|
71
73
|
this.caseID = PCore.getStoreValue('.pyID', 'caseInfo.content', this.pConn$.getContextName());
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
this.srcImg = this.utils.getImageSrc('document-doc', this.utils.getSDKStaticContentUrl());
|
|
75
|
+
this.deleteIcon = this.utils.getImageSrc('trash', this.utils.getSDKStaticContentUrl());
|
|
74
76
|
this.checkAndUpdate();
|
|
77
|
+
this.getAttachments();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
getAttachments() {
|
|
81
|
+
let tempUploadedFiles = this.getCurrentAttachmentsList(this.getAttachmentKey(this.valueRef), this.pConn$.getContextName());
|
|
82
|
+
tempUploadedFiles = tempUploadedFiles.filter(f => f.label === this.valueRef && f.delete !== true);
|
|
83
|
+
this.files?.map(f => {
|
|
84
|
+
return f.responseProps?.pzInsKey && !f.responseProps.pzInsKey.includes('temp')
|
|
85
|
+
? {
|
|
86
|
+
...f,
|
|
87
|
+
props: {
|
|
88
|
+
...f.props,
|
|
89
|
+
onDelete: () => this.deleteFile(f)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
: { ...f };
|
|
93
|
+
});
|
|
94
|
+
this.files = [...this.files, ...tempUploadedFiles];
|
|
95
|
+
PCore.getPubSubUtils().subscribe(
|
|
96
|
+
PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION,
|
|
97
|
+
this.resetAttachmentStoredState.bind(this),
|
|
98
|
+
this.caseID
|
|
99
|
+
);
|
|
100
|
+
return () => {
|
|
101
|
+
PCore.getPubSubUtils().unsubscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, this.caseID);
|
|
102
|
+
};
|
|
75
103
|
}
|
|
76
104
|
|
|
77
105
|
checkAndUpdate() {
|
|
@@ -85,77 +113,15 @@ export class AttachmentComponent implements OnInit, OnDestroy {
|
|
|
85
113
|
}
|
|
86
114
|
}
|
|
87
115
|
|
|
88
|
-
ngOnDestroy(): void {
|
|
89
|
-
if (this.angularPConnectData.unsubscribeFn) {
|
|
90
|
-
this.angularPConnectData.unsubscribeFn();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
PCore.getPubSubUtils().unsubscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, this.caseID);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
116
|
// Callback passed when subscribing to store change
|
|
97
117
|
onStateChange() {
|
|
98
118
|
this.checkAndUpdate();
|
|
99
119
|
}
|
|
100
120
|
|
|
101
|
-
updateAttachmentsInfo() {
|
|
102
|
-
// @ts-ignore - Property 'attachmentsInfo' does not exist on type 'C11nEnv'
|
|
103
|
-
if (!this.pConn$.attachmentsInfo) {
|
|
104
|
-
// @ts-ignore - Property 'attachmentsInfo' does not exist on type 'C11nEnv'
|
|
105
|
-
this.pConn$.attachmentsInfo = {
|
|
106
|
-
type: 'File',
|
|
107
|
-
attachmentFieldName: this.att_valueRef,
|
|
108
|
-
category: this.att_categoryName
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
processFile(file, i) {
|
|
114
|
-
file.props.type = file.responseProps.pyMimeFileExtension;
|
|
115
|
-
file.props.mimeType = file.responseProps.pyMimeFileExtension;
|
|
116
|
-
file.props.ID = file.responseProps.pzInsKey;
|
|
117
|
-
|
|
118
|
-
const arMenuList = [
|
|
119
|
-
{
|
|
120
|
-
icon: 'download',
|
|
121
|
-
text: this.pConn$.getLocalizedValue('Download', '', ''),
|
|
122
|
-
onClick: () => this._downloadFileFromList(this.value$.pxResults[i])
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
icon: 'trash',
|
|
126
|
-
text: this.pConn$.getLocalizedValue('Delete', '', ''),
|
|
127
|
-
onClick: () => this._removeFileFromList(this.arFileList$[i])
|
|
128
|
-
}
|
|
129
|
-
];
|
|
130
|
-
|
|
131
|
-
const arFilesAttachmentIDs: any = [];
|
|
132
|
-
this.arFileList$.forEach(arFile => {
|
|
133
|
-
arFilesAttachmentIDs.push(arFile.id);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
if (!arFilesAttachmentIDs.includes(file.props.ID)) {
|
|
137
|
-
this.arFileList$.push(
|
|
138
|
-
this.getNewListUtilityItemProps({
|
|
139
|
-
att: file.props,
|
|
140
|
-
downloadFile: null,
|
|
141
|
-
cancelFile: null,
|
|
142
|
-
deleteFile: null,
|
|
143
|
-
removeFile: null
|
|
144
|
-
})
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
this.arFileList$[i].actions = arMenuList;
|
|
149
|
-
this.arFileList$[i].noDeleteIcon = true;
|
|
150
|
-
|
|
151
|
-
this.bShowSelector$ = false;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
121
|
updateSelf() {
|
|
155
122
|
const configProps: AttachmentProps = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as AttachmentProps;
|
|
156
|
-
const stateProps
|
|
157
|
-
|
|
158
|
-
const { value, label, extensions } = configProps;
|
|
123
|
+
const stateProps = this.pConn$.getStateProps();
|
|
124
|
+
const { value, label, extensions, displayMode } = configProps;
|
|
159
125
|
|
|
160
126
|
if (configProps.required != null) {
|
|
161
127
|
this.bRequired$ = this.utils.getBooleanValue(configProps.required);
|
|
@@ -177,114 +143,62 @@ export class AttachmentComponent implements OnInit, OnDestroy {
|
|
|
177
143
|
this.allowMultiple$ = this.utils.getBooleanValue(configProps.allowMultiple);
|
|
178
144
|
}
|
|
179
145
|
|
|
180
|
-
this.bShowJustDelete$ = true;
|
|
181
146
|
this.label$ = label;
|
|
182
147
|
this.value$ = value;
|
|
183
148
|
this.status = stateProps.status;
|
|
149
|
+
|
|
184
150
|
this.validateMessage = this.angularPConnectData.validateMessage;
|
|
185
151
|
this.extensions$ = extensions;
|
|
186
|
-
this.valueRef =
|
|
152
|
+
this.valueRef = this.pConn$.getStateProps().value;
|
|
187
153
|
this.valueRef = this.valueRef.startsWith('.') ? this.valueRef.substring(1) : this.valueRef;
|
|
188
|
-
|
|
154
|
+
this.displayMode = displayMode;
|
|
189
155
|
/* this is a temporary fix because required is supposed to be passed as a boolean and NOT as a string */
|
|
190
156
|
let { required, disabled } = configProps;
|
|
191
157
|
[required, disabled] = [required, disabled].map(prop => prop === true || (typeof prop === 'string' && prop === 'true'));
|
|
192
158
|
|
|
193
|
-
this.
|
|
159
|
+
this.categoryName = '';
|
|
194
160
|
if (value && value.pyCategoryName) {
|
|
195
|
-
this.
|
|
161
|
+
this.categoryName = value.pyCategoryName;
|
|
196
162
|
}
|
|
197
163
|
|
|
198
|
-
|
|
199
|
-
|
|
164
|
+
if (value?.pxResults && +value.pyCount > 0) {
|
|
165
|
+
this.files = value.pxResults.map(f => this.buildFilePropsFromResponse(f));
|
|
166
|
+
}
|
|
200
167
|
|
|
201
168
|
this.updateAttachments();
|
|
202
169
|
}
|
|
203
170
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
if (this.myFiles?.length && this.arFiles$.length === 0) {
|
|
214
|
-
this.arFileList$ = this.myFiles.map(att => {
|
|
215
|
-
return this.getNewListUtilityItemProps({
|
|
216
|
-
att,
|
|
217
|
-
downloadFile: null,
|
|
218
|
-
cancelFile: null,
|
|
219
|
-
deleteFile: null,
|
|
220
|
-
removeFile: null
|
|
221
|
-
});
|
|
222
|
-
});
|
|
171
|
+
buildFilePropsFromResponse(respObj) {
|
|
172
|
+
return {
|
|
173
|
+
props: {
|
|
174
|
+
meta: `${respObj.pyCategoryName}, ${respObj.pxCreateOperator}`,
|
|
175
|
+
name: respObj.pyAttachName,
|
|
176
|
+
icon: this.utils.getIconFromFileType(respObj.pyMimeFileExtension)
|
|
177
|
+
},
|
|
178
|
+
responseProps: {
|
|
179
|
+
...respObj
|
|
223
180
|
}
|
|
224
|
-
|
|
225
|
-
const myFilesAttachmentIDs: any = [];
|
|
226
|
-
this.myFiles.forEach(myFile => {
|
|
227
|
-
myFilesAttachmentIDs.push(myFile.ID);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
this.arFiles$.forEach(arFile => {
|
|
231
|
-
if (!myFilesAttachmentIDs.includes(arFile.ID)) {
|
|
232
|
-
this.myFiles = [...this.myFiles, arFile];
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
this.bShowJustDelete$ = true;
|
|
238
|
-
this.bShowSelector$ = !(this.arFileList$?.length > 0) || this.allowMultiple$;
|
|
239
|
-
|
|
240
|
-
if (this.arFileList$.length > 0) {
|
|
241
|
-
this.CheckForInvalidAttachment();
|
|
242
|
-
}
|
|
243
|
-
PCore.getPubSubUtils().subscribe(
|
|
244
|
-
PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION,
|
|
245
|
-
this.resetAttachmentStoredState.bind(this),
|
|
246
|
-
this.caseID
|
|
247
|
-
);
|
|
181
|
+
};
|
|
248
182
|
}
|
|
249
183
|
|
|
250
|
-
|
|
251
|
-
this.
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
if (file) {
|
|
259
|
-
const currentAttachmentList = this.getCurrentAttachmentsList(this.getAttachmentKey(this.att_valueRef), this.pConn$.getContextName());
|
|
260
|
-
const index = currentAttachmentList.findIndex(element => element.props.ID === file.props.ID);
|
|
261
|
-
let tempFiles: any = [];
|
|
262
|
-
if (index < 0) {
|
|
263
|
-
tempFiles = [file];
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
PCore.getStateUtils().updateState(
|
|
267
|
-
this.pConn$.getContextName(),
|
|
268
|
-
this.getAttachmentKey(this.att_valueRef),
|
|
269
|
-
[...currentAttachmentList, ...tempFiles],
|
|
270
|
-
{
|
|
271
|
-
pageReference: 'context_data',
|
|
272
|
-
isArrayDeepMerge: false
|
|
273
|
-
}
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
});
|
|
184
|
+
updateAttachments() {
|
|
185
|
+
if (this.files.length > 0 && this.displayMode !== 'DISPLAY_ONLY') {
|
|
186
|
+
const currentAttachmentList = this.getCurrentAttachmentsList(this.getAttachmentKey(this.valueRef), this.pConn$.getContextName());
|
|
187
|
+
// block duplicate files to redux store when added 1 after another to prevent multiple duplicates being added to the case on submit
|
|
188
|
+
const tempFiles = this.files.filter(f => currentAttachmentList.findIndex(fr => fr.ID === f.ID) === -1 && !f.inProgress && f.responseProps);
|
|
189
|
+
const updatedAttList = [...currentAttachmentList, ...tempFiles];
|
|
190
|
+
this.updateAttachmentState(this.pConn$, this.getAttachmentKey(this.valueRef), updatedAttList);
|
|
191
|
+
}
|
|
278
192
|
}
|
|
279
193
|
|
|
280
194
|
resetAttachmentStoredState() {
|
|
281
|
-
PCore.getStateUtils().updateState(this.pConn
|
|
195
|
+
PCore.getStateUtils().updateState(this.pConn$?.getContextName(), this.getAttachmentKey(this.valueRef), undefined, {
|
|
282
196
|
pageReference: 'context_data',
|
|
283
197
|
isArrayDeepMerge: false
|
|
284
198
|
});
|
|
285
199
|
}
|
|
286
200
|
|
|
287
|
-
|
|
201
|
+
downloadFile(fileObj: any) {
|
|
288
202
|
PCore.getAttachmentUtils()
|
|
289
203
|
// @ts-ignore - 3rd parameter "responseEncoding" should be optional
|
|
290
204
|
.downloadAttachment(fileObj.pzInsKey, this.pConn$.getContextName())
|
|
@@ -304,146 +218,196 @@ export class AttachmentComponent implements OnInit, OnDestroy {
|
|
|
304
218
|
|
|
305
219
|
getAttachmentKey = (name = '') => (name ? `attachmentsList.${name}` : 'attachmentsList');
|
|
306
220
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
this.arFileList$.forEach(file => {
|
|
310
|
-
if (file.secondary.error) {
|
|
311
|
-
isValid = false;
|
|
312
|
-
}
|
|
313
|
-
});
|
|
314
|
-
if (isValid) {
|
|
315
|
-
// @ts-ignore
|
|
316
|
-
PCore.getMessageManager().clearMessages({
|
|
317
|
-
type: PCore.getConstants().MESSAGES.MESSAGES_TYPE_ERROR,
|
|
318
|
-
property: (this.pConn$.getStateProps() as any).value,
|
|
319
|
-
pageReference: this.pConn$.getPageReference(),
|
|
320
|
-
context: this.pConn$.getContextName()
|
|
321
|
-
});
|
|
322
|
-
}
|
|
221
|
+
getCurrentAttachmentsList(key, context) {
|
|
222
|
+
return PCore.getStoreValue(`.${key}`, 'context_data', context) || [];
|
|
323
223
|
}
|
|
324
224
|
|
|
325
|
-
|
|
326
|
-
const
|
|
327
|
-
|
|
225
|
+
validateMaxSize(fileObj, maxSizeInMB): boolean {
|
|
226
|
+
const fileSize = (fileObj.size / 1048576).toFixed(2);
|
|
227
|
+
return parseFloat(fileSize) < parseFloat(maxSizeInMB);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
validateFileExtension = (fileObj, allowedExtensions) => {
|
|
231
|
+
if (!allowedExtensions) {
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
const allowedExtensionList = allowedExtensions
|
|
235
|
+
.toLowerCase()
|
|
236
|
+
.split(',')
|
|
237
|
+
.map(item => item.replaceAll('.', '').trim());
|
|
238
|
+
const extension = fileObj.name.split('.').pop().toLowerCase();
|
|
239
|
+
return allowedExtensionList.includes(extension);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
updateAttachmentState(pConn, key, attachments) {
|
|
243
|
+
PCore.getStateUtils().updateState(this.pConn$.getContextName(), key, attachments, {
|
|
244
|
+
pageReference: 'context_data',
|
|
245
|
+
isArrayDeepMerge: false
|
|
246
|
+
});
|
|
247
|
+
}
|
|
328
248
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
249
|
+
deleteFile(file) {
|
|
250
|
+
const attachmentsList: any[] = [];
|
|
251
|
+
let currentAttachmentList = this.getCurrentAttachmentsList(this.getAttachmentKey(this.valueRef), this.pConn$.getContextName());
|
|
252
|
+
|
|
253
|
+
// If file to be deleted is the one added in previous stage i.e. for which a file instance is created in server
|
|
254
|
+
// no need to filter currentAttachmentList as we will get another entry of file in redux with delete & label
|
|
255
|
+
// eslint-disable-next-line no-unsafe-optional-chaining
|
|
256
|
+
if (this.value$ && this.value$?.pxResults && +this.value$?.pyCount > 0 && file.responseProps && file?.responseProps?.pzInsKey !== 'temp') {
|
|
257
|
+
const updatedAttachments = this.files.map(f => {
|
|
258
|
+
if (f.responseProps && f.responseProps.pzInsKey === file.responseProps.pzInsKey) {
|
|
259
|
+
return { ...f, delete: true, label: this.valueRef };
|
|
335
260
|
}
|
|
336
|
-
return
|
|
261
|
+
return f;
|
|
337
262
|
});
|
|
338
263
|
|
|
339
264
|
// updating the redux store to help form-handler in passing the data to delete the file from server
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
} else {
|
|
345
|
-
currentAttachmentList = currentAttachmentList.filter(f => f.ID !== item.id);
|
|
346
|
-
PCore.getStateUtils().updateState(
|
|
347
|
-
this.pConn$.getContextName(),
|
|
348
|
-
this.getAttachmentKey(this.att_valueRef),
|
|
349
|
-
[...currentAttachmentList, ...attachmentsList],
|
|
350
|
-
{
|
|
351
|
-
pageReference: 'context_data',
|
|
352
|
-
isArrayDeepMerge: false
|
|
353
|
-
}
|
|
265
|
+
this.updateAttachmentState(this.pConn$, this.getAttachmentKey(this.valueRef), [...updatedAttachments]);
|
|
266
|
+
const newlyAddedFiles = this.files.filter(f => !!f.ID);
|
|
267
|
+
const filesPostDelete = this.files.filter(
|
|
268
|
+
f => f.responseProps?.pzInsKey !== 'temp' && f.responseProps?.pzInsKey !== file.responseProps?.pzInsKey
|
|
354
269
|
);
|
|
270
|
+
this.files = [...filesPostDelete, ...newlyAddedFiles];
|
|
271
|
+
} // if the file being deleted is the added in this stage i.e. whose data is not yet created in server
|
|
272
|
+
else {
|
|
273
|
+
// filter newly added files in this stage, later the updated current stage files will be added to redux once files state is updated
|
|
274
|
+
currentAttachmentList = currentAttachmentList.filter(f => f.ID !== file.ID);
|
|
275
|
+
this.files = this.files.filter(f => f.ID !== file.ID);
|
|
276
|
+
|
|
277
|
+
this.updateAttachmentState(this.pConn$, this.getAttachmentKey(this.valueRef), [...currentAttachmentList, ...attachmentsList]);
|
|
278
|
+
if (file.inProgress) {
|
|
279
|
+
// @ts-ignore - 3rd parameter "responseEncoding" should be optional
|
|
280
|
+
PCore.getAttachmentUtils().cancelRequest(file.ID, this.pConn$.getContextName());
|
|
281
|
+
}
|
|
355
282
|
}
|
|
356
283
|
|
|
357
|
-
|
|
358
|
-
|
|
284
|
+
this.filesWithError = this.filesWithError?.filter(f => f.ID !== file.ID);
|
|
285
|
+
if (this.filesWithError.length === 0) {
|
|
286
|
+
this.clearFieldErrorMessages();
|
|
359
287
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
this.CheckForInvalidAttachment();
|
|
288
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
289
|
+
this.fileInput && this.fileInput.nativeElement.value ? null : '';
|
|
290
|
+
}
|
|
365
291
|
|
|
366
|
-
|
|
292
|
+
onFileAdded(event) {
|
|
293
|
+
let addedFiles = Array.from(event.target.files);
|
|
294
|
+
addedFiles = this.allowMultiple$ ? addedFiles : [addedFiles[0]];
|
|
295
|
+
const maxAttachmentSize = PCore.getEnvironmentInfo().getMaxAttachmentSize() || '5';
|
|
296
|
+
this.tempFilesToBeUploaded = [
|
|
297
|
+
...addedFiles.map((f: any, index) => {
|
|
298
|
+
f.ID = `${new Date().getTime()}I${index}`;
|
|
299
|
+
f.inProgress = true;
|
|
300
|
+
f.props = {
|
|
301
|
+
type: f.type,
|
|
302
|
+
name: f.name,
|
|
303
|
+
icon: this.utils.getIconFromFileType(f.type),
|
|
304
|
+
onDelete: () => this.deleteFile(f)
|
|
305
|
+
};
|
|
306
|
+
if (!this.validateMaxSize(f, maxAttachmentSize)) {
|
|
307
|
+
f.props.error = true;
|
|
308
|
+
f.inProgress = false;
|
|
309
|
+
f.props.meta = this.pConn$.getLocalizedValue(`File is too big. Max allowed size is ${maxAttachmentSize}MB.`, '', '');
|
|
310
|
+
} else if (!this.validateFileExtension(f, this.extensions$)) {
|
|
311
|
+
f.props.error = true;
|
|
312
|
+
f.inProgress = false;
|
|
313
|
+
f.props.meta = `${this.pConn$.getLocalizedValue(
|
|
314
|
+
'File has invalid extension. Allowed extensions are:',
|
|
315
|
+
'',
|
|
316
|
+
''
|
|
317
|
+
)} ${this.extensions$.replaceAll('.', '')}`;
|
|
318
|
+
}
|
|
319
|
+
if (f.props.error) {
|
|
320
|
+
const fieldName = this.pConn$.getStateProps().value;
|
|
321
|
+
const context = this.pConn$.getContextName();
|
|
322
|
+
PCore.getMessageManager().addMessages({
|
|
323
|
+
messages: [
|
|
324
|
+
{
|
|
325
|
+
type: 'error',
|
|
326
|
+
message: this.pConn$.getLocalizedValue('Error with one or more files', '', '')
|
|
327
|
+
}
|
|
328
|
+
],
|
|
329
|
+
property: fieldName,
|
|
330
|
+
pageReference: this.pConn$.getPageReference(),
|
|
331
|
+
context
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
return f;
|
|
335
|
+
})
|
|
336
|
+
];
|
|
337
|
+
const tempFilesWithError = this.tempFilesToBeUploaded.filter(f => f.props.error);
|
|
338
|
+
if (tempFilesWithError.length > 0) {
|
|
339
|
+
this.filesWithError = tempFilesWithError;
|
|
340
|
+
}
|
|
341
|
+
if (!this.allowMultiple$) {
|
|
342
|
+
this.files = [...this.tempFilesToBeUploaded];
|
|
343
|
+
} else {
|
|
344
|
+
this.files = [...this.files, ...this.tempFilesToBeUploaded];
|
|
345
|
+
}
|
|
346
|
+
this.uploadFiles();
|
|
367
347
|
}
|
|
368
348
|
|
|
369
|
-
|
|
370
|
-
|
|
349
|
+
clearFieldErrorMessages() {
|
|
350
|
+
const fieldName = this.pConn$.getStateProps().value;
|
|
351
|
+
const context = this.pConn$.getContextName();
|
|
352
|
+
PCore.getMessageManager().clearMessages({
|
|
353
|
+
type: PCore.getConstants().MESSAGES.MESSAGES_TYPE_ERROR,
|
|
354
|
+
property: fieldName,
|
|
355
|
+
pageReference: this.pConn$.getPageReference(),
|
|
356
|
+
context
|
|
357
|
+
});
|
|
371
358
|
}
|
|
372
359
|
|
|
373
|
-
|
|
360
|
+
onUploadProgress() {}
|
|
361
|
+
|
|
362
|
+
errorHandler(isFetchCanceled, attachedFile) {
|
|
374
363
|
return error => {
|
|
375
364
|
if (!isFetchCanceled(error)) {
|
|
376
365
|
let uploadFailMsg = this.pConn$.getLocalizedValue('Something went wrong', '', '');
|
|
377
366
|
if (error.response && error.response.data && error.response.data.errorDetails) {
|
|
378
367
|
uploadFailMsg = this.pConn$.getLocalizedValue(error.response.data.errorDetails[0].localizedValue, '', '');
|
|
379
368
|
}
|
|
380
|
-
for (const myFile of this.myFiles) {
|
|
381
|
-
if (myFile.ID === file.ID) {
|
|
382
|
-
myFile.meta = uploadFailMsg;
|
|
383
|
-
myFile.error = true;
|
|
384
|
-
myFile.fileName = this.pConn$.getLocalizedValue('Unable to upload file', '', '');
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
this.bShowSelector$ = false;
|
|
388
|
-
this.arFileList$ = this.myFiles.map(att => {
|
|
389
|
-
if (att.id) {
|
|
390
|
-
return att;
|
|
391
|
-
}
|
|
392
|
-
return this.getNewListUtilityItemProps({
|
|
393
|
-
att,
|
|
394
|
-
downloadFile: null,
|
|
395
|
-
cancelFile: null,
|
|
396
|
-
deleteFile: null,
|
|
397
|
-
removeFile: null
|
|
398
|
-
});
|
|
399
|
-
});
|
|
400
369
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
370
|
+
this.files.map(f => {
|
|
371
|
+
if (f.ID === attachedFile.ID) {
|
|
372
|
+
f.props.meta = uploadFailMsg;
|
|
373
|
+
f.props.error = true;
|
|
374
|
+
f.props.onDelete = () => this.deleteFile(f);
|
|
375
|
+
f.props.icon = this.utils.getIconFromFileType(f.type);
|
|
376
|
+
f.props.name = this.pConn$.getLocalizedValue('Unable to upload file', '', '');
|
|
377
|
+
f.inProgress = false;
|
|
378
|
+
const fieldName = this.pConn$.getStateProps().value;
|
|
379
|
+
const context = this.pConn$.getContextName();
|
|
380
|
+
// set errors to property to block submit even on errors in file upload
|
|
381
|
+
PCore.getMessageManager().addMessages({
|
|
382
|
+
messages: [
|
|
383
|
+
{
|
|
384
|
+
type: 'error',
|
|
385
|
+
message: this.pConn$.getLocalizedValue('Error with one or more files', '', '')
|
|
386
|
+
}
|
|
387
|
+
],
|
|
388
|
+
property: fieldName,
|
|
389
|
+
pageReference: this.pConn$.getPageReference(),
|
|
390
|
+
context
|
|
391
|
+
});
|
|
392
|
+
delete f.props.progress;
|
|
393
|
+
}
|
|
394
|
+
return f;
|
|
412
395
|
});
|
|
413
|
-
|
|
414
|
-
this.bShowJustDelete$ = true;
|
|
415
|
-
this.bLoading$ = false;
|
|
416
396
|
}
|
|
417
397
|
throw error;
|
|
418
398
|
};
|
|
419
399
|
}
|
|
420
400
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
if (this.arFiles$.length) {
|
|
424
|
-
arrAttachmentFiles = this.arFiles$;
|
|
425
|
-
} else {
|
|
426
|
-
arrAttachmentFiles = this.arFileList$;
|
|
427
|
-
}
|
|
428
|
-
this.arFiles$ = [...arrAttachmentFiles, ...this.getFiles(event.target.files)];
|
|
429
|
-
|
|
430
|
-
// convert FileList to an array
|
|
431
|
-
this.myFiles = Array.from(this.arFiles$);
|
|
432
|
-
|
|
433
|
-
this.bLoading$ = true;
|
|
434
|
-
|
|
435
|
-
const filesToBeUploaded = this.myFiles
|
|
401
|
+
uploadFiles() {
|
|
402
|
+
const filesToBeUploaded = this.files
|
|
436
403
|
.filter(e => {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
const isFileUploaded = e && e.progress === 100;
|
|
441
|
-
const fileHasError = e && e.error;
|
|
404
|
+
const isFileUploaded = e.props && e.props.progress === 100;
|
|
405
|
+
const fileHasError = e.props && e.props.error;
|
|
442
406
|
const isFileUploadedinLastStep = e.responseProps && e.responseProps.pzInsKey;
|
|
443
407
|
return !isFileUploaded && !fileHasError && !isFileUploadedinLastStep;
|
|
444
408
|
})
|
|
445
409
|
.map(f =>
|
|
446
|
-
PCore.getAttachmentUtils().uploadAttachment(
|
|
410
|
+
window.PCore.getAttachmentUtils().uploadAttachment(
|
|
447
411
|
f,
|
|
448
412
|
() => {
|
|
449
413
|
this.onUploadProgress();
|
|
@@ -454,252 +418,41 @@ export class AttachmentComponent implements OnInit, OnDestroy {
|
|
|
454
418
|
this.pConn$.getContextName()
|
|
455
419
|
)
|
|
456
420
|
);
|
|
457
|
-
|
|
458
421
|
Promise.allSettled(filesToBeUploaded)
|
|
459
422
|
.then((fileResponses: any) => {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
if (index >= 0) {
|
|
477
|
-
reqObj = {
|
|
478
|
-
type: 'File',
|
|
479
|
-
label: this.att_valueRef,
|
|
480
|
-
category: this.att_categoryName,
|
|
481
|
-
handle: successFileResponses[index].value.ID,
|
|
482
|
-
ID: fileRes.ID,
|
|
483
|
-
name: fileRes.name
|
|
484
|
-
};
|
|
485
|
-
newAttachments = [...newAttachments, reqObj];
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
const currentAttachmentList = this.getCurrentAttachmentsList(this.getAttachmentKey(this.att_valueRef), this.pConn$.getContextName()).filter(
|
|
489
|
-
f => f.label !== this.att_valueRef
|
|
490
|
-
);
|
|
491
|
-
PCore.getStateUtils().updateState(
|
|
492
|
-
this.pConn$.getContextName(),
|
|
493
|
-
this.getAttachmentKey(this.att_valueRef),
|
|
494
|
-
[...currentAttachmentList, ...newAttachments],
|
|
495
|
-
{
|
|
496
|
-
pageReference: 'context_data',
|
|
497
|
-
isArrayDeepMerge: false
|
|
498
|
-
}
|
|
499
|
-
);
|
|
500
|
-
this.arFiles$ = tempFilesUploaded;
|
|
501
|
-
|
|
502
|
-
this.ngZone.run(() => {
|
|
503
|
-
this.bShowSelector$ = this.allowMultiple$;
|
|
504
|
-
this.arFiles$.forEach(file => {
|
|
505
|
-
if (!file.error) {
|
|
506
|
-
file.meta = this.pConn$.getLocalizedValue('File uploaded successfully', '', '');
|
|
507
|
-
}
|
|
508
|
-
});
|
|
509
|
-
this.arFileList$ = this.myFiles.map(att => {
|
|
510
|
-
if (att.id) {
|
|
511
|
-
return att;
|
|
512
|
-
}
|
|
513
|
-
return this.getNewListUtilityItemProps({
|
|
514
|
-
att,
|
|
515
|
-
downloadFile: null,
|
|
516
|
-
cancelFile: null,
|
|
517
|
-
deleteFile: null,
|
|
518
|
-
removeFile: null
|
|
423
|
+
fileResponses = fileResponses.filter(fr => fr.status !== 'rejected'); // in case of deleting an in progress file, promise gets cancelled but still enters then block
|
|
424
|
+
if (fileResponses.length > 0) {
|
|
425
|
+
this.files.forEach(f => {
|
|
426
|
+
const index = fileResponses.findIndex((fr: any) => fr.value.clientFileID === f.ID);
|
|
427
|
+
if (index >= 0) {
|
|
428
|
+
f.props.meta = this.pConn$.getLocalizedValue('Uploaded successfully', '', '');
|
|
429
|
+
f.props.progress = 100;
|
|
430
|
+
f.inProgress = false;
|
|
431
|
+
f.handle = fileResponses[index].value.ID;
|
|
432
|
+
f.label = this.valueRef;
|
|
433
|
+
f.category = this.categoryName;
|
|
434
|
+
f.responseProps = {
|
|
435
|
+
pzInsKey: 'temp',
|
|
436
|
+
pyAttachName: f.props.name
|
|
437
|
+
};
|
|
438
|
+
}
|
|
519
439
|
});
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
this.bShowJustDelete$ = true;
|
|
525
|
-
this.bLoading$ = false;
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
handleFileUploadFailure() {
|
|
531
|
-
this.bShowJustDelete$ = true;
|
|
532
|
-
this.bLoading$ = false;
|
|
533
|
-
this.bShowSelector$ = this.allowMultiple$;
|
|
534
|
-
this.myFiles.forEach(file => {
|
|
535
|
-
if (file?.secondary?.error) {
|
|
536
|
-
file.meta = 'File uploaded failed';
|
|
537
|
-
}
|
|
538
|
-
});
|
|
539
|
-
|
|
540
|
-
this.arFileList$ = this.myFiles.map(att => {
|
|
541
|
-
return this.getNewListUtilityItemProps({
|
|
542
|
-
att,
|
|
543
|
-
downloadFile: null,
|
|
544
|
-
cancelFile: null,
|
|
545
|
-
deleteFile: null,
|
|
546
|
-
removeFile: null
|
|
547
|
-
});
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
this.bShowJustDelete$ = true;
|
|
551
|
-
this.bLoading$ = false;
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
getNewListUtilityItemProps = ({ att, cancelFile, downloadFile, deleteFile, removeFile }) => {
|
|
555
|
-
let actions;
|
|
556
|
-
let isDownloadable = false;
|
|
557
|
-
|
|
558
|
-
if (att.progress && att.progress !== 100) {
|
|
559
|
-
actions = [
|
|
560
|
-
{
|
|
561
|
-
id: `Cancel-${att.ID}`,
|
|
562
|
-
text: this.pConn$.getLocalizedValue('Cancel', '', ''),
|
|
563
|
-
icon: 'times',
|
|
564
|
-
onClick: cancelFile
|
|
565
|
-
}
|
|
566
|
-
];
|
|
567
|
-
} else if (att.links) {
|
|
568
|
-
const isFile = att.type === 'FILE';
|
|
569
|
-
const ID = att.ID.replace(/\s/gi, '');
|
|
570
|
-
const actionsMap = new Map([
|
|
571
|
-
[
|
|
572
|
-
'download',
|
|
573
|
-
{
|
|
574
|
-
id: `download-${ID}`,
|
|
575
|
-
text: isFile ? this.pConn$.getLocalizedValue('Download', '', '') : this.pConn$.getLocalizedValue('Open', '', ''),
|
|
576
|
-
icon: isFile ? 'download' : 'open',
|
|
577
|
-
onClick: downloadFile
|
|
578
|
-
}
|
|
579
|
-
],
|
|
580
|
-
[
|
|
581
|
-
'delete',
|
|
582
|
-
{
|
|
583
|
-
id: `Delete-${ID}`,
|
|
584
|
-
text: this.pConn$.getLocalizedValue('Delete', '', ''),
|
|
585
|
-
icon: 'trash',
|
|
586
|
-
onClick: deleteFile
|
|
440
|
+
this.updateAttachments();
|
|
441
|
+
if (this.filesWithError?.length === 0) {
|
|
442
|
+
this.clearFieldErrorMessages();
|
|
587
443
|
}
|
|
588
|
-
]
|
|
589
|
-
]);
|
|
590
|
-
actions = [];
|
|
591
|
-
actionsMap.forEach((action, actionKey) => {
|
|
592
|
-
if (att.links[actionKey]) {
|
|
593
|
-
actions.push(action);
|
|
594
444
|
}
|
|
445
|
+
})
|
|
446
|
+
.catch(error => {
|
|
447
|
+
console.log(error);
|
|
595
448
|
});
|
|
596
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
597
|
-
isDownloadable = att.links.download;
|
|
598
|
-
} else if (att.error) {
|
|
599
|
-
actions = [
|
|
600
|
-
{
|
|
601
|
-
id: `Remove-${att.ID}`,
|
|
602
|
-
text: this.pConn$.getLocalizedValue('Remove', '', ''),
|
|
603
|
-
icon: 'trash',
|
|
604
|
-
onClick: removeFile
|
|
605
|
-
}
|
|
606
|
-
];
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
return {
|
|
610
|
-
id: att.ID,
|
|
611
|
-
visual: {
|
|
612
|
-
icon: this.utils.getIconForAttachment(att),
|
|
613
|
-
progress: att.progress == 100 ? undefined : att.progress
|
|
614
|
-
},
|
|
615
|
-
primary: {
|
|
616
|
-
type: att.type,
|
|
617
|
-
name: att.error ? att.fileName : att.name,
|
|
618
|
-
icon: 'trash',
|
|
619
|
-
click: removeFile
|
|
620
|
-
},
|
|
621
|
-
secondary: {
|
|
622
|
-
text: att.meta,
|
|
623
|
-
error: att.error
|
|
624
|
-
},
|
|
625
|
-
actions
|
|
626
|
-
};
|
|
627
|
-
};
|
|
628
|
-
|
|
629
|
-
onUploadProgress() {}
|
|
630
|
-
|
|
631
|
-
getFiles(arFiles: any[]): any[] {
|
|
632
|
-
const files = this.allowMultiple$ ? arFiles : [arFiles[0]];
|
|
633
|
-
return this.setNewFiles(files);
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
setNewFiles(arFiles) {
|
|
637
|
-
let index = 0;
|
|
638
|
-
const maxAttachmentSize = PCore.getEnvironmentInfo().getMaxAttachmentSize() || 5;
|
|
639
|
-
for (const file of arFiles) {
|
|
640
|
-
file.mimeType = file.type;
|
|
641
|
-
file.icon = this.utils.getIconFromFileType(file.type);
|
|
642
|
-
file.ID = `${new Date().getTime()}I${index}`;
|
|
643
|
-
|
|
644
|
-
if (!this.validateMaxSize(file, maxAttachmentSize)) {
|
|
645
|
-
file.error = true;
|
|
646
|
-
file.meta = this.pConn$.getLocalizedValue('File is too big. Max allowed size is 5MB.', '', '');
|
|
647
|
-
} else if (!this.validateFileExtension(file, this.extensions$)) {
|
|
648
|
-
file.error = true;
|
|
649
|
-
file.meta = `${this.pConn$.getLocalizedValue('File has invalid extension. Allowed extensions are:', '', '')} ${this.extensions$.replaceAll(
|
|
650
|
-
'.',
|
|
651
|
-
''
|
|
652
|
-
)}`;
|
|
653
|
-
}
|
|
654
|
-
if (file.error) {
|
|
655
|
-
const fieldName = (this.pConn$.getStateProps() as any).value;
|
|
656
|
-
const context = this.pConn$.getContextName();
|
|
657
|
-
PCore.getMessageManager().addMessages({
|
|
658
|
-
// @ts-ignore
|
|
659
|
-
messages: [
|
|
660
|
-
{
|
|
661
|
-
type: 'error',
|
|
662
|
-
message: this.pConn$.getLocalizedValue('Error with one or more files', '', '')
|
|
663
|
-
}
|
|
664
|
-
],
|
|
665
|
-
property: fieldName,
|
|
666
|
-
pageReference: this.pConn$.getPageReference(),
|
|
667
|
-
context
|
|
668
|
-
});
|
|
669
|
-
}
|
|
670
|
-
index++;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
return [...arFiles];
|
|
674
449
|
}
|
|
675
450
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
validateFileExtension = (fileObj, allowedExtensions) => {
|
|
682
|
-
if (!allowedExtensions) {
|
|
683
|
-
return true;
|
|
451
|
+
ngOnDestroy(): void {
|
|
452
|
+
if (this.angularPConnectData.unsubscribeFn) {
|
|
453
|
+
this.angularPConnectData.unsubscribeFn();
|
|
684
454
|
}
|
|
685
|
-
const allowedExtensionList = allowedExtensions
|
|
686
|
-
.toLowerCase()
|
|
687
|
-
.split(',')
|
|
688
|
-
.map(item => item.replaceAll('.', '').trim());
|
|
689
|
-
const extension = fileObj.name.split('.').pop().toLowerCase();
|
|
690
|
-
return allowedExtensionList.includes(extension);
|
|
691
|
-
};
|
|
692
455
|
|
|
693
|
-
|
|
694
|
-
return {
|
|
695
|
-
props: {
|
|
696
|
-
meta: `${respObj.pyCategoryName}, ${respObj.pxCreateOperator}`,
|
|
697
|
-
name: respObj.pyAttachName,
|
|
698
|
-
icon: this.utils.getIconFromFileType(respObj.pyMimeFileExtension)
|
|
699
|
-
},
|
|
700
|
-
responseProps: {
|
|
701
|
-
...respObj
|
|
702
|
-
}
|
|
703
|
-
};
|
|
456
|
+
PCore.getPubSubUtils().unsubscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, this.caseID);
|
|
704
457
|
}
|
|
705
458
|
}
|