@pega/react-sdk-components 0.25.5 → 0.25.6
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/components/designSystemExtension/CaseSummaryFields/CaseSummaryFields.js +1 -1
- package/lib/components/designSystemExtension/CaseSummaryFields/CaseSummaryFields.js.map +1 -1
- package/lib/components/field/RadioButtons/RadioButtons.js +1 -1
- package/lib/components/field/RadioButtons/RadioButtons.js.map +1 -1
- package/lib/components/field/SelectableCard/utils.d.ts +0 -1
- package/lib/components/field/SelectableCard/utils.d.ts.map +1 -1
- package/lib/components/field/SelectableCard/utils.js +0 -3
- package/lib/components/field/SelectableCard/utils.js.map +1 -1
- package/lib/components/field/SemanticLink/SemanticLink.js +1 -1
- package/lib/components/field/SemanticLink/SemanticLink.js.map +1 -1
- package/lib/components/helpers/attachmentShared.d.ts +2 -0
- package/lib/components/helpers/attachmentShared.d.ts.map +1 -0
- package/lib/components/helpers/attachmentShared.js +6 -0
- package/lib/components/helpers/attachmentShared.js.map +1 -0
- package/lib/components/helpers/formatters/Currency.d.ts +1 -0
- package/lib/components/helpers/formatters/Currency.d.ts.map +1 -1
- package/lib/components/helpers/formatters/Currency.js +8 -4
- package/lib/components/helpers/formatters/Currency.js.map +1 -1
- package/lib/components/helpers/formatters/index.d.ts +1 -0
- package/lib/components/helpers/formatters/index.d.ts.map +1 -1
- package/lib/components/helpers/object-utils.d.ts +9 -0
- package/lib/components/helpers/object-utils.d.ts.map +1 -0
- package/lib/components/helpers/object-utils.js +11 -0
- package/lib/components/helpers/object-utils.js.map +1 -0
- package/lib/components/infra/Containers/ModalViewContainer/ModalViewContainer.d.ts.map +1 -1
- package/lib/components/infra/Containers/ModalViewContainer/ModalViewContainer.js +2 -1
- package/lib/components/infra/Containers/ModalViewContainer/ModalViewContainer.js.map +1 -1
- package/lib/components/infra/MultiStep/MultiStep.css +0 -2
- package/lib/components/template/AppShell/AppShell.d.ts.map +1 -1
- package/lib/components/template/AppShell/AppShell.js +4 -0
- package/lib/components/template/AppShell/AppShell.js.map +1 -1
- package/lib/components/template/CaseSummary/CaseSummary.d.ts.map +1 -1
- package/lib/components/template/CaseSummary/CaseSummary.js +56 -2
- package/lib/components/template/CaseSummary/CaseSummary.js.map +1 -1
- package/lib/components/template/SingleReferenceReadOnly/SingleReferenceReadOnly.d.ts.map +1 -1
- package/lib/components/template/SingleReferenceReadOnly/SingleReferenceReadOnly.js +3 -2
- package/lib/components/template/SingleReferenceReadOnly/SingleReferenceReadOnly.js.map +1 -1
- package/lib/components/widget/Attachment/Attachment.d.ts +3 -1
- package/lib/components/widget/Attachment/Attachment.d.ts.map +1 -1
- package/lib/components/widget/Attachment/Attachment.js +241 -189
- package/lib/components/widget/Attachment/Attachment.js.map +1 -1
- package/lib/components/widget/Attachment/Attachment.types.d.ts +90 -0
- package/lib/components/widget/Attachment/Attachment.types.d.ts.map +1 -0
- package/lib/components/widget/Attachment/Attachment.types.js +2 -0
- package/lib/components/widget/Attachment/Attachment.types.js.map +1 -0
- package/lib/components/widget/Attachment/AttachmentUtils.d.ts +25 -0
- package/lib/components/widget/Attachment/AttachmentUtils.d.ts.map +1 -0
- package/lib/components/widget/Attachment/AttachmentUtils.js +255 -0
- package/lib/components/widget/Attachment/AttachmentUtils.js.map +1 -0
- package/lib/components/widget/FileUtility/FileUtility/FileUtility.d.ts +1 -0
- package/lib/components/widget/FileUtility/FileUtility/FileUtility.d.ts.map +1 -1
- package/lib/components/widget/FileUtility/FileUtility/FileUtility.js +21 -8
- package/lib/components/widget/FileUtility/FileUtility/FileUtility.js.map +1 -1
- package/lib/components/widget/ToDo/ToDo.js +1 -1
- package/lib/components/widget/ToDo/ToDo.js.map +1 -1
- package/lib/mediaco/ToDo/ToDo.css +81 -0
- package/lib/mediaco/ToDo/ToDo.d.ts +16 -0
- package/lib/mediaco/ToDo/ToDo.d.ts.map +1 -0
- package/lib/mediaco/ToDo/ToDo.js +187 -0
- package/lib/mediaco/ToDo/ToDo.js.map +1 -0
- package/lib/mediaco/ToDo/index.d.ts +2 -0
- package/lib/mediaco/ToDo/index.d.ts.map +1 -0
- package/lib/mediaco/ToDo/index.js +2 -0
- package/lib/mediaco/ToDo/index.js.map +1 -0
- package/package.json +1 -1
- package/lib/components/helpers/attachmentHelpers.d.ts +0 -16
- package/lib/components/helpers/attachmentHelpers.d.ts.map +0 -1
- package/lib/components/helpers/attachmentHelpers.js +0 -94
- package/lib/components/helpers/attachmentHelpers.js.map +0 -1
|
@@ -2,189 +2,173 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
|
3
3
|
import { CircularProgress, IconButton, Menu, MenuItem, Button } from '@mui/material';
|
|
4
4
|
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|
5
|
-
import { getIconFromFileType, isFileUploadedToServer, useFileDownload, validateMaxSize } from '../../helpers/attachmentHelpers';
|
|
6
5
|
import { Utils } from '../../helpers/utils';
|
|
6
|
+
import { clearFieldErrorMessages, deleteAttachments, getIconFromFileType, getMappedValue, insertAttachments, useDeepMemo, useFileDownload, validateFileExtension } from './AttachmentUtils';
|
|
7
|
+
import { validateMaxSize } from '../../helpers/attachmentShared';
|
|
7
8
|
import './Attachment.css';
|
|
8
|
-
const getAttachmentKey = (name, embeddedReference) => {
|
|
9
|
-
return `attachmentsList${embeddedReference}.${name}`;
|
|
10
|
-
};
|
|
11
|
-
const getCurrentAttachmentsList = (key, context) => {
|
|
12
|
-
return PCore.getStoreValue(`.${key}`, 'context_data', context) || [];
|
|
13
|
-
};
|
|
14
|
-
const updateAttachmentState = (pConn, key, attachments) => {
|
|
15
|
-
PCore.getStateUtils().updateState(pConn.getContextName(), key, attachments, {
|
|
16
|
-
pageReference: 'context_data',
|
|
17
|
-
isArrayDeepMerge: false
|
|
18
|
-
});
|
|
19
|
-
};
|
|
20
9
|
export default function Attachment(props) {
|
|
21
|
-
const { value, getPConnect, label, validatemessage,
|
|
10
|
+
const { value, getPConnect, label, validatemessage, extensions, displayMode, helperText, editMode, isTableFormatter } = props;
|
|
22
11
|
/* this is a temporary fix because required is supposed to be passed as a boolean and NOT as a string */
|
|
23
|
-
let { required, disabled } = props;
|
|
24
|
-
[required, disabled] = [required, disabled].map(prop => prop === true || (typeof prop === 'string' && prop === 'true'));
|
|
12
|
+
let { required, disabled, allowMultiple } = props;
|
|
13
|
+
[required, disabled, allowMultiple] = [required, disabled, allowMultiple].map(prop => prop === true || (typeof prop === 'string' && prop === 'true'));
|
|
25
14
|
const pConn = getPConnect();
|
|
15
|
+
const localizationService = pConn.getLocalizationService();
|
|
26
16
|
const actionSequencer = useMemo(() => PCore.getActionsSequencer(), []);
|
|
27
|
-
const
|
|
17
|
+
const rawValue = pConn.getComponentConfig().value;
|
|
18
|
+
const isAttachmentAnnotationPresent = typeof rawValue === 'object' ? false : rawValue?.includes('@ATTACHMENT');
|
|
19
|
+
const { attachments, isOldAttachment } = isAttachmentAnnotationPresent ? value : PCore.getAttachmentUtils().prepareAttachmentData(value);
|
|
20
|
+
let valueRef = pConn.getStateProps().value;
|
|
21
|
+
valueRef = valueRef.indexOf('.') === 0 ? valueRef.substring(1) : valueRef;
|
|
22
|
+
pConn.setReferenceList(`.${valueRef}`);
|
|
23
|
+
const isMultiAttachmentInInlineEditTable = isTableFormatter && allowMultiple && editMode === 'tableRows';
|
|
24
|
+
const [files, setFiles] = useState(attachments);
|
|
25
|
+
const overrideLocalState = useRef(false);
|
|
26
|
+
const attachmentCount = useRef(attachments.length);
|
|
27
|
+
const filesWithError = useRef([]);
|
|
28
|
+
const multiAttachmentsInInlineEdit = useRef([]);
|
|
29
|
+
const thumbnailURLs = useRef([]);
|
|
30
|
+
const contextName = pConn.getContextName();
|
|
31
|
+
const onFileDownload = useFileDownload(contextName);
|
|
28
32
|
const localizedVal = PCore.getLocaleUtils().getLocaleValue;
|
|
29
33
|
const localeCategory = 'CosmosFields';
|
|
30
34
|
const uploadMultipleFilesLabel = localizedVal('file_upload_text_multiple', localeCategory);
|
|
31
35
|
const uploadSingleFileLabel = localizedVal('file_upload_text_one', localeCategory);
|
|
32
36
|
const deleteIcon = Utils.getImageSrc('trash', Utils.getSDKStaticConentUrl());
|
|
33
37
|
const srcImg = Utils.getImageSrc('document-doc', Utils.getSDKStaticConentUrl());
|
|
34
|
-
let valueRef = pConn.getStateProps().value;
|
|
35
|
-
valueRef = valueRef.indexOf('.') === 0 ? valueRef.substring(1) : valueRef;
|
|
36
38
|
const [anchorEl, setAnchorEl] = useState(null);
|
|
37
39
|
const open = Boolean(anchorEl);
|
|
38
|
-
const rawValue = pConn.getComponentConfig().value;
|
|
39
|
-
const isAttachmentAnnotationPresent = typeof rawValue === 'object' ? false : rawValue?.includes('@ATTACHMENT');
|
|
40
|
-
const { hasUploadedFiles, attachments, categoryName } = isAttachmentAnnotationPresent
|
|
41
|
-
? value
|
|
42
|
-
: PCore.getAttachmentUtils().prepareAttachmentData(value);
|
|
43
40
|
const fileInputRef = useRef(null);
|
|
44
|
-
const [files, setFiles] = useState(attachments);
|
|
45
|
-
const [filesWithError, setFilesWithError] = useState([]);
|
|
46
41
|
const [toggleUploadBegin, setToggleUploadBegin] = useState(false);
|
|
47
|
-
const
|
|
48
|
-
const onFileDownload = useFileDownload(context);
|
|
49
|
-
let embeddedProperty = pConn
|
|
50
|
-
.getPageReference()
|
|
51
|
-
.replace(PCore.getConstants().CASE_INFO.CASE_INFO_CONTENT, '')
|
|
52
|
-
.replace(PCore.getConstants().DATA_INFO.DATA_INFO_CONTENT, '');
|
|
53
|
-
if (valueRef?.indexOf('.') > 0) {
|
|
54
|
-
embeddedProperty = valueRef.substring(0, valueRef.indexOf('.') + 1);
|
|
55
|
-
}
|
|
56
|
-
const resetAttachmentStoredState = () => {
|
|
57
|
-
PCore.getStateUtils().updateState(pConn.getContextName(), getAttachmentKey(valueRef, embeddedProperty), undefined, {
|
|
58
|
-
pageReference: 'context_data',
|
|
59
|
-
isArrayDeepMerge: false
|
|
60
|
-
});
|
|
61
|
-
};
|
|
62
|
-
const deleteFile = useCallback(file => {
|
|
42
|
+
const deleteFile = useCallback((file, fileIndex) => {
|
|
63
43
|
setAnchorEl(null);
|
|
64
44
|
// reset the file input so that it will allow re-uploading the same file after deletion
|
|
65
45
|
if (fileInputRef.current) {
|
|
66
46
|
fileInputRef.current.value = ''; // Reset the input
|
|
67
47
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
updateAttachmentState(pConn, getAttachmentKey(valueRef, embeddedProperty), [...updatedAttachments]);
|
|
81
|
-
setFiles(current => {
|
|
82
|
-
const newlyAddedFiles = current.filter(f => !!f.ID);
|
|
83
|
-
const filesPostDelete = current.filter(f => isFileUploadedToServer(f) && f.responseProps?.ID !== file.responseProps?.ID);
|
|
84
|
-
attachmentsList = [...filesPostDelete, ...newlyAddedFiles];
|
|
85
|
-
return attachmentsList;
|
|
48
|
+
if (filesWithError.current.length > 0) {
|
|
49
|
+
filesWithError.current = filesWithError.current.filter(fileWithError => fileWithError.props.id !== file.props.id);
|
|
50
|
+
if (filesWithError.current.length === 0) {
|
|
51
|
+
clearFieldErrorMessages(pConn);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (file.inProgress) {
|
|
55
|
+
// @ts-ignore - Expected 1 arguments, but got 2.ts(2554)
|
|
56
|
+
PCore.getAttachmentUtils().cancelRequest(file.props.id, contextName);
|
|
57
|
+
actionSequencer.deRegisterBlockingAction(contextName).catch(() => { });
|
|
58
|
+
setFiles(localFiles => {
|
|
59
|
+
return localFiles.filter(localFile => localFile.props.id !== file.props.id);
|
|
86
60
|
});
|
|
87
|
-
}
|
|
61
|
+
}
|
|
88
62
|
else {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
63
|
+
deleteAttachments([file], pConn, multiAttachmentsInInlineEdit.current, {
|
|
64
|
+
allowMultiple,
|
|
65
|
+
isOldAttachment,
|
|
66
|
+
isMultiAttachmentInInlineEditTable,
|
|
67
|
+
attachmentCount: attachmentCount.current,
|
|
68
|
+
deleteIndex: fileIndex
|
|
69
|
+
});
|
|
70
|
+
// Filter out without deleted file and reset the file indexes
|
|
71
|
+
setFiles(localFiles => {
|
|
72
|
+
let tempLocalFiles = [...localFiles];
|
|
73
|
+
tempLocalFiles = tempLocalFiles.filter(localFile => localFile.props.id !== file.props.id);
|
|
74
|
+
tempLocalFiles.forEach(localFile => {
|
|
75
|
+
if (!localFile.props.error && !file.props.error) {
|
|
76
|
+
const updatedDeleteIndex = localFile.responseProps.deleteIndex > fileIndex ? localFile.responseProps.deleteIndex - 1 : localFile.responseProps.deleteIndex;
|
|
77
|
+
localFile.props.onDelete = () => deleteFile(localFile, updatedDeleteIndex);
|
|
78
|
+
localFile.responseProps.deleteIndex = updatedDeleteIndex;
|
|
79
|
+
}
|
|
98
80
|
});
|
|
81
|
+
return tempLocalFiles;
|
|
82
|
+
});
|
|
83
|
+
if (!file.props.error) {
|
|
84
|
+
attachmentCount.current -= 1;
|
|
99
85
|
}
|
|
100
86
|
}
|
|
101
87
|
setToggleUploadBegin(false);
|
|
102
|
-
|
|
103
|
-
|
|
88
|
+
}, [pConn]);
|
|
89
|
+
const onUploadProgress = (id, ev) => {
|
|
90
|
+
const progress = Math.floor((ev.loaded / ev.total) * 100);
|
|
91
|
+
setFiles(localFiles => [
|
|
92
|
+
...localFiles.map(localFile => {
|
|
93
|
+
if (localFile.props?.id === id) {
|
|
94
|
+
localFile.inProgress = true;
|
|
95
|
+
localFile.props.progress = progress;
|
|
96
|
+
}
|
|
97
|
+
return localFile;
|
|
98
|
+
})
|
|
99
|
+
]);
|
|
100
|
+
};
|
|
101
|
+
const populateErrorAndUpdateRedux = file => {
|
|
102
|
+
const fieldName = pConn.getStateProps().value;
|
|
103
|
+
// set errors to property to block submit even on errors in file upload
|
|
104
|
+
PCore.getMessageManager().addMessages({
|
|
105
|
+
messages: [
|
|
106
|
+
{
|
|
107
|
+
type: 'error',
|
|
108
|
+
message: localizationService.getLocalizedText('Error with one or more files')
|
|
109
|
+
}
|
|
110
|
+
],
|
|
111
|
+
property: fieldName,
|
|
112
|
+
pageReference: pConn.getPageReference(),
|
|
113
|
+
context: contextName
|
|
114
|
+
});
|
|
115
|
+
insertAttachments([file], pConn, multiAttachmentsInInlineEdit.current, {
|
|
116
|
+
allowMultiple,
|
|
117
|
+
isOldAttachment,
|
|
118
|
+
isMultiAttachmentInInlineEditTable,
|
|
119
|
+
attachmentCount: attachmentCount.current
|
|
104
120
|
});
|
|
105
|
-
}
|
|
106
|
-
const
|
|
107
|
-
const errorHandler = (isFetchCanceled, attachedFile) => {
|
|
121
|
+
};
|
|
122
|
+
const errorHandler = (isFetchCanceled, file) => {
|
|
108
123
|
return error => {
|
|
109
124
|
if (!isFetchCanceled(error)) {
|
|
110
|
-
let uploadFailMsg =
|
|
125
|
+
let uploadFailMsg = localizationService.getLocalizedText('Something went wrong');
|
|
111
126
|
if (error.response && error.response.data && error.response.data.errorDetails) {
|
|
112
|
-
uploadFailMsg =
|
|
127
|
+
uploadFailMsg = localizationService.getLocalizedText(error.response.data.errorDetails[0].localizedValue);
|
|
113
128
|
}
|
|
114
129
|
setFiles(current => {
|
|
115
|
-
return current.map(
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
messages: [
|
|
127
|
-
{
|
|
128
|
-
type: 'error',
|
|
129
|
-
message: pConn.getLocalizedValue('Error with one or more files', '', '')
|
|
130
|
-
}
|
|
131
|
-
],
|
|
132
|
-
property: fieldName,
|
|
133
|
-
pageReference: pConn.getPageReference(),
|
|
134
|
-
context
|
|
135
|
-
});
|
|
136
|
-
delete f.props.progress;
|
|
130
|
+
return current.map((localFile, index) => {
|
|
131
|
+
if (localFile.props.id === file.props.id) {
|
|
132
|
+
localFile.props.meta = uploadFailMsg;
|
|
133
|
+
localFile.props.error = true;
|
|
134
|
+
localFile.props.onDelete = () => deleteFile(localFile, index);
|
|
135
|
+
localFile.props.icon = getIconFromFileType(localFile.type);
|
|
136
|
+
localFile.props.name = localizationService.getLocalizedText('Unable to upload file');
|
|
137
|
+
localFile.inProgress = false;
|
|
138
|
+
delete localFile.props.progress;
|
|
139
|
+
filesWithError.current.push(localFile);
|
|
140
|
+
populateErrorAndUpdateRedux(localFile);
|
|
137
141
|
}
|
|
138
|
-
return
|
|
142
|
+
return localFile;
|
|
139
143
|
});
|
|
140
144
|
});
|
|
141
145
|
}
|
|
142
146
|
throw error;
|
|
143
147
|
};
|
|
144
148
|
};
|
|
145
|
-
const validateFileExtension = (fileObj, allowedExtensions) => {
|
|
146
|
-
if (!allowedExtensions) {
|
|
147
|
-
return true;
|
|
148
|
-
}
|
|
149
|
-
const allowedExtensionList = allowedExtensions
|
|
150
|
-
.toLowerCase()
|
|
151
|
-
.split(',')
|
|
152
|
-
.map(item => item.replaceAll('.', '').trim());
|
|
153
|
-
const extension = fileObj.name.split('.').pop().toLowerCase();
|
|
154
|
-
return allowedExtensionList.includes(extension);
|
|
155
|
-
};
|
|
156
|
-
const clearFieldErrorMessages = () => {
|
|
157
|
-
const fieldName = pConn.getStateProps().value;
|
|
158
|
-
PCore.getMessageManager().clearMessages({
|
|
159
|
-
type: PCore.getConstants().MESSAGES.MESSAGES_TYPE_ERROR,
|
|
160
|
-
property: fieldName,
|
|
161
|
-
pageReference: pConn.getPageReference(),
|
|
162
|
-
context
|
|
163
|
-
});
|
|
164
|
-
};
|
|
165
149
|
const onFileAdded = event => {
|
|
166
150
|
let addedFiles = Array.from(event.target.files);
|
|
167
|
-
addedFiles = allowMultiple
|
|
151
|
+
addedFiles = allowMultiple ? addedFiles : [addedFiles[0]];
|
|
168
152
|
const maxAttachmentSize = PCore.getEnvironmentInfo().getMaxAttachmentSize() || '5';
|
|
169
153
|
const tempFilesToBeUploaded = [
|
|
170
154
|
...addedFiles.map((f, index) => {
|
|
171
155
|
f.ID = `${new Date().getTime()}I${index}`;
|
|
172
|
-
f.inProgress = true;
|
|
173
156
|
f.props = {
|
|
174
157
|
type: f.type,
|
|
175
158
|
name: f.name,
|
|
159
|
+
id: f.ID,
|
|
160
|
+
format: f.name.split('.').pop(),
|
|
176
161
|
icon: getIconFromFileType(f.type),
|
|
177
|
-
onDelete: () => deleteFile(f)
|
|
162
|
+
onDelete: () => deleteFile(f, index),
|
|
163
|
+
thumbnail: window.URL.createObjectURL(f)
|
|
178
164
|
};
|
|
179
165
|
if (!validateMaxSize(f, maxAttachmentSize)) {
|
|
180
166
|
f.props.error = true;
|
|
181
|
-
f.
|
|
182
|
-
f.props.meta = pConn.getLocalizedValue(`File is too big. Max allowed size is ${maxAttachmentSize}MB.`, '', '');
|
|
167
|
+
f.props.meta = localizationService.getLocalizedText(`File is too big. Max allowed size is ${maxAttachmentSize}MB.`);
|
|
183
168
|
}
|
|
184
169
|
else if (!validateFileExtension(f, extensions)) {
|
|
185
170
|
f.props.error = true;
|
|
186
|
-
f.
|
|
187
|
-
f.props.meta = `${pConn.getLocalizedValue('File has invalid extension. Allowed extensions are:', '', '')} ${extensions.replaceAll('.', '')}`;
|
|
171
|
+
f.props.meta = `${localizationService.getLocalizedText('File has invalid extension. Allowed extensions are:')} ${extensions.replaceAll('.', '')}`;
|
|
188
172
|
}
|
|
189
173
|
if (f.props.error) {
|
|
190
174
|
const fieldName = pConn.getStateProps().value;
|
|
@@ -192,12 +176,12 @@ export default function Attachment(props) {
|
|
|
192
176
|
messages: [
|
|
193
177
|
{
|
|
194
178
|
type: 'error',
|
|
195
|
-
message:
|
|
179
|
+
message: localizationService.getLocalizedText('Error with one or more files')
|
|
196
180
|
}
|
|
197
181
|
],
|
|
198
182
|
property: fieldName,
|
|
199
183
|
pageReference: pConn.getPageReference(),
|
|
200
|
-
context
|
|
184
|
+
context: contextName
|
|
201
185
|
});
|
|
202
186
|
}
|
|
203
187
|
return f;
|
|
@@ -205,9 +189,15 @@ export default function Attachment(props) {
|
|
|
205
189
|
];
|
|
206
190
|
const tempFilesWithError = tempFilesToBeUploaded.filter(f => f.props.error);
|
|
207
191
|
if (tempFilesWithError.length > 0) {
|
|
208
|
-
|
|
192
|
+
filesWithError.current = [...filesWithError.current, ...tempFilesWithError];
|
|
193
|
+
insertAttachments(tempFilesWithError, pConn, multiAttachmentsInInlineEdit.current, {
|
|
194
|
+
allowMultiple,
|
|
195
|
+
isOldAttachment,
|
|
196
|
+
isMultiAttachmentInInlineEditTable,
|
|
197
|
+
attachmentCount: attachmentCount.current
|
|
198
|
+
});
|
|
209
199
|
}
|
|
210
|
-
setFiles(current => (allowMultiple
|
|
200
|
+
setFiles(current => (!allowMultiple ? [...tempFilesToBeUploaded] : [...current, ...tempFilesToBeUploaded]));
|
|
211
201
|
setToggleUploadBegin(true);
|
|
212
202
|
};
|
|
213
203
|
const uploadFiles = useCallback(() => {
|
|
@@ -215,102 +205,164 @@ export default function Attachment(props) {
|
|
|
215
205
|
.filter(e => {
|
|
216
206
|
const isFileUploaded = e.props && e.props.progress === 100;
|
|
217
207
|
const fileHasError = e.props && e.props.error;
|
|
218
|
-
const
|
|
219
|
-
|
|
208
|
+
const isFileUploadedInLastStep = e.responseProps && e.responseProps.ID !== 'temp';
|
|
209
|
+
const isFileUploadInProgress = e.inProgress;
|
|
210
|
+
return !isFileUploadInProgress && !isFileUploaded && !fileHasError && !isFileUploadedInLastStep;
|
|
220
211
|
})
|
|
221
|
-
.map(
|
|
222
|
-
onUploadProgress();
|
|
212
|
+
.map(file => PCore.getAttachmentUtils().uploadAttachment(file, ev => {
|
|
213
|
+
onUploadProgress(file.props.id, ev);
|
|
223
214
|
}, isFetchCanceled => {
|
|
224
|
-
return errorHandler(isFetchCanceled,
|
|
225
|
-
},
|
|
215
|
+
return errorHandler(isFetchCanceled, file);
|
|
216
|
+
}, contextName));
|
|
217
|
+
// allow new files to be added when other files upload is still in progress
|
|
218
|
+
setToggleUploadBegin(false);
|
|
226
219
|
Promise.allSettled(filesToBeUploaded)
|
|
227
220
|
.then((fileResponses) => {
|
|
228
221
|
fileResponses = fileResponses.filter(fr => fr.status !== 'rejected'); // in case of deleting an in progress file, promise gets cancelled but still enters then block
|
|
229
222
|
if (fileResponses.length > 0) {
|
|
230
|
-
setFiles(
|
|
231
|
-
const tempFilesUploaded = [...
|
|
232
|
-
tempFilesUploaded.forEach(
|
|
233
|
-
|
|
223
|
+
setFiles(localFiles => {
|
|
224
|
+
const tempFilesUploaded = [...localFiles];
|
|
225
|
+
tempFilesUploaded.forEach(localFile => {
|
|
226
|
+
// if attach field has multiple files & in bw any error files are present
|
|
227
|
+
// Example : files = [properFile1, errFile, errFile, properFile2]
|
|
228
|
+
// indexes for delete & preview should be for files [properFile1, properFile2] which is [1,2]
|
|
229
|
+
const index = fileResponses.findIndex(fileResponse => fileResponse.value.clientFileID === localFile.props.id);
|
|
234
230
|
if (index >= 0) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
231
|
+
fileResponses[index].value.thumbnail = localFile.props.thumbnail;
|
|
232
|
+
localFile.inProgress = false;
|
|
233
|
+
localFile.ID = fileResponses[index].value.ID;
|
|
234
|
+
localFile.props.meta = localizationService.getLocalizedText('Uploaded successfully');
|
|
235
|
+
localFile.props.progress = 100;
|
|
236
|
+
localFile.handle = fileResponses[index].value.ID;
|
|
237
|
+
localFile.label = valueRef;
|
|
238
|
+
localFile.responseProps = {
|
|
239
|
+
pzInsKey: 'temp'
|
|
244
240
|
};
|
|
245
241
|
}
|
|
246
242
|
});
|
|
247
243
|
return tempFilesUploaded;
|
|
248
244
|
});
|
|
249
|
-
|
|
250
|
-
|
|
245
|
+
insertAttachments(fileResponses, pConn, multiAttachmentsInInlineEdit.current, {
|
|
246
|
+
allowMultiple,
|
|
247
|
+
isOldAttachment,
|
|
248
|
+
isMultiAttachmentInInlineEditTable,
|
|
249
|
+
attachmentCount: attachmentCount.current,
|
|
250
|
+
insert: true
|
|
251
|
+
});
|
|
252
|
+
attachmentCount.current += fileResponses.length;
|
|
253
|
+
if (filesWithError.current.length === 0) {
|
|
254
|
+
clearFieldErrorMessages(pConn);
|
|
251
255
|
}
|
|
252
256
|
}
|
|
253
|
-
|
|
257
|
+
actionSequencer.deRegisterBlockingAction(contextName).catch(() => { });
|
|
254
258
|
})
|
|
255
259
|
.catch(error => {
|
|
256
260
|
console.log(error);
|
|
257
261
|
setToggleUploadBegin(false);
|
|
258
262
|
});
|
|
259
|
-
}, [files
|
|
263
|
+
}, [files]);
|
|
260
264
|
useEffect(() => {
|
|
261
265
|
if (toggleUploadBegin && files.length > 0) {
|
|
262
|
-
|
|
266
|
+
actionSequencer.registerBlockingAction(contextName).then(() => {
|
|
267
|
+
uploadFiles();
|
|
268
|
+
});
|
|
263
269
|
}
|
|
264
270
|
}, [toggleUploadBegin]);
|
|
265
271
|
useEffect(() => {
|
|
266
|
-
if (
|
|
267
|
-
|
|
268
|
-
// block duplicate files to redux store when added 1 after another to prevent multiple duplicates being added to the case on submit
|
|
269
|
-
const tempFiles = files.filter(f => currentAttachmentList.findIndex(fr => fr.ID === f.ID) === -1 && !f.inProgress && f.responseProps);
|
|
270
|
-
const updatedAttList = [...currentAttachmentList, ...tempFiles];
|
|
271
|
-
updateAttachmentState(pConn, getAttachmentKey(valueRef, embeddedProperty), updatedAttList);
|
|
272
|
-
}
|
|
273
|
-
}, [files]);
|
|
274
|
-
useEffect(() => {
|
|
275
|
-
if (filesWithError.length === 0) {
|
|
276
|
-
clearFieldErrorMessages();
|
|
272
|
+
if (filesWithError.current.length === 0) {
|
|
273
|
+
clearFieldErrorMessages(pConn);
|
|
277
274
|
}
|
|
278
275
|
}, [filesWithError]);
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
276
|
+
const memoizedAttachments = useDeepMemo(() => {
|
|
277
|
+
return attachments;
|
|
278
|
+
}, [attachments]);
|
|
279
|
+
// Prepares new structure as per Cosmos component
|
|
280
|
+
const transformAttachments = () => {
|
|
281
|
+
const transformedFiles = [...attachments];
|
|
282
|
+
let deleteIndex = -1;
|
|
283
|
+
transformedFiles.forEach(attachment => {
|
|
284
|
+
attachment.props.id = attachment.responseProps.ID;
|
|
285
|
+
attachment.props.format = attachment.props.name.split('.').pop();
|
|
286
|
+
if (attachment.props.error) {
|
|
287
|
+
attachment.responseProps.deleteIndex = deleteIndex;
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
deleteIndex += 1;
|
|
291
|
+
attachment.responseProps.deleteIndex = deleteIndex;
|
|
292
|
+
}
|
|
293
|
+
if (attachment.props.thumbnail) {
|
|
294
|
+
thumbnailURLs.current.push(attachment.props.thumbnail);
|
|
295
|
+
}
|
|
297
296
|
});
|
|
297
|
+
return transformedFiles;
|
|
298
|
+
};
|
|
299
|
+
useEffect(() => {
|
|
300
|
+
const caseID = PCore.getStoreValue(`.${getMappedValue('pyID')}`, PCore.getResolvedConstantValue('caseInfo.content'), contextName);
|
|
298
301
|
if (displayMode !== 'DISPLAY_ONLY') {
|
|
299
|
-
PCore.getPubSubUtils().subscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION,
|
|
302
|
+
PCore.getPubSubUtils().subscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, () => {
|
|
303
|
+
overrideLocalState.current = true;
|
|
304
|
+
}, caseID);
|
|
300
305
|
}
|
|
306
|
+
// When component mounts, only set local files state from redux.
|
|
307
|
+
const serverFiles = transformAttachments();
|
|
308
|
+
setFiles(serverFiles);
|
|
309
|
+
filesWithError.current = serverFiles.filter(file => file.props.error);
|
|
301
310
|
return () => {
|
|
302
311
|
if (displayMode !== 'DISPLAY_ONLY') {
|
|
303
312
|
PCore.getPubSubUtils().unsubscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, caseID);
|
|
304
313
|
}
|
|
305
314
|
};
|
|
306
315
|
}, []);
|
|
316
|
+
useEffect(() => {
|
|
317
|
+
if (overrideLocalState.current) {
|
|
318
|
+
const serverFiles = transformAttachments();
|
|
319
|
+
overrideLocalState.current = false;
|
|
320
|
+
attachmentCount.current = attachments.length;
|
|
321
|
+
filesWithError.current = [];
|
|
322
|
+
setFiles(serverFiles);
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
// Determine whether refresh call has overridden any error files in redux, push error files back to redux from local state to perform client side validation during assignment submit
|
|
326
|
+
const errorFiles = attachments.filter(attachment => attachment.props.error);
|
|
327
|
+
if (errorFiles.length === 0 && filesWithError.current.length > 0) {
|
|
328
|
+
// Check if local file state contains error files and push those to redux
|
|
329
|
+
const uniqueKey = getMappedValue('pzInsKey');
|
|
330
|
+
const transformedErrorFiles = filesWithError.current.map(errorFile => {
|
|
331
|
+
const filename = errorFile.props.name;
|
|
332
|
+
return {
|
|
333
|
+
[uniqueKey]: errorFile.props.id,
|
|
334
|
+
FileName: filename,
|
|
335
|
+
Category: '',
|
|
336
|
+
FileExtension: filename.split('.').pop() ?? filename,
|
|
337
|
+
error: errorFile.props.error || null
|
|
338
|
+
};
|
|
339
|
+
});
|
|
340
|
+
let key = '';
|
|
341
|
+
let updatedAttachments = [];
|
|
342
|
+
if (allowMultiple || isOldAttachment) {
|
|
343
|
+
key = isOldAttachment ? `${valueRef}.pxResults` : valueRef;
|
|
344
|
+
const existingAttachments = PCore.getStoreValue(`.${key}`, pConn.getPageReference(), pConn.getContextName()) || [];
|
|
345
|
+
updatedAttachments = [...existingAttachments, ...transformedErrorFiles];
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
key = valueRef;
|
|
349
|
+
updatedAttachments = transformedErrorFiles[0];
|
|
350
|
+
}
|
|
351
|
+
PCore.getStateUtils().updateState(pConn.getContextName(), key, updatedAttachments, {
|
|
352
|
+
pageReference: pConn.getPageReference(),
|
|
353
|
+
isArrayDeepMerge: false,
|
|
354
|
+
removePropertyFromChangedList: true
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}, [memoizedAttachments]);
|
|
307
359
|
const handleClick = event => {
|
|
308
360
|
setAnchorEl(event.currentTarget);
|
|
309
361
|
};
|
|
310
362
|
const handleClose = () => {
|
|
311
363
|
setAnchorEl(null);
|
|
312
364
|
};
|
|
313
|
-
const content = (_jsx("div", { style: { marginBottom: '8px' }, children: _jsxs("div", { className: `${disabled ? 'file-disabled' : ''} ${validatemessage === '' ? 'file-div' : 'file-div-error'}`, children: [_jsx("div", { hidden: true, id: 'attachment-ID', children: valueRef }), _jsxs("label", { htmlFor: valueRef, children: [_jsx("input", { style: { display: 'none' }, id: valueRef, name: 'upload-photo', type: 'file', multiple: allowMultiple
|
|
365
|
+
const content = (_jsx("div", { style: { marginBottom: '8px' }, children: _jsxs("div", { className: `${disabled ? 'file-disabled' : ''} ${validatemessage === '' ? 'file-div' : 'file-div-error'}`, children: [_jsx("div", { hidden: true, id: 'attachment-ID', children: valueRef }), _jsxs("label", { htmlFor: valueRef, children: [_jsx("input", { style: { display: 'none' }, id: valueRef, name: 'upload-photo', type: 'file', multiple: allowMultiple, required: required, disabled: disabled, onChange: onFileAdded }), _jsx(Button, { style: { textTransform: 'none' }, variant: 'outlined', color: 'primary', component: 'span', children: allowMultiple
|
|
314
366
|
? uploadMultipleFilesLabel === 'file_upload_text_multiple'
|
|
315
367
|
? 'Choose files'
|
|
316
368
|
: uploadMultipleFilesLabel
|
|
@@ -320,11 +372,11 @@ export default function Attachment(props) {
|
|
|
320
372
|
const fileDisplay = (_jsx("div", { children: files &&
|
|
321
373
|
files.length > 0 &&
|
|
322
374
|
files.map((item, index) => {
|
|
323
|
-
return (_jsxs("div", { className: 'psdk-utility-card', children: [_jsxs("div", { className: 'psdk-utility-card-icon', children: [!item.inProgress && _jsx("img", { className: 'psdk-utility-card-svg-icon', src: srcImg }), item.inProgress && (_jsx("div", { children: _jsx(CircularProgress, {}) }))] }), _jsxs("div", { className: 'psdk-utility-card-main', children: [_jsx("div", { className: 'psdk-utility-card-main-primary-label', children: item.props.name }), item.props.meta && _jsx("div", { style: { color: item.props.error ? 'red' : undefined }, children: item.props.meta })] }), _jsxs("div", { className: 'psdk-utility-action', children: [item.ID && (_jsx("button", { type: 'button', className: 'psdk-utility-button', "aria-label": 'Delete Attachment', onClick: () => deleteFile(item), children: _jsx("img", { className: 'psdk-utility-card-action-svg-icon', src: deleteIcon }) })), !item.ID && (_jsxs("div", { children: [_jsx(IconButton, { id: 'setting-button', "aria-controls": open ? 'file-menu' : undefined, "aria-expanded": open ? 'true' : undefined, "aria-haspopup": 'true', onClick: handleClick, size: 'large', children: _jsx(MoreVertIcon, {}) }), _jsxs(Menu, { style: { marginTop: '3rem' }, id: 'file-menu', anchorEl: anchorEl, keepMounted: true, open: Boolean(anchorEl), onClose: handleClose, children: [_jsx(MenuItem, { style: { fontSize: '14px' }, onClick: () => {
|
|
375
|
+
return (_jsxs("div", { className: 'psdk-utility-card', children: [_jsxs("div", { className: 'psdk-utility-card-icon', children: [!item.inProgress && _jsx("img", { className: 'psdk-utility-card-svg-icon', src: srcImg }), item.inProgress && (_jsx("div", { children: _jsx(CircularProgress, {}) }))] }), _jsxs("div", { className: 'psdk-utility-card-main', children: [_jsx("div", { className: 'psdk-utility-card-main-primary-label', children: item.props.name }), item.props.meta && _jsx("div", { style: { color: item.props.error ? 'red' : undefined }, children: item.props.meta })] }), _jsxs("div", { className: 'psdk-utility-action', children: [item.ID && (_jsx("button", { type: 'button', className: 'psdk-utility-button', "aria-label": 'Delete Attachment', onClick: () => deleteFile(item, index), children: _jsx("img", { className: 'psdk-utility-card-action-svg-icon', src: deleteIcon }) })), !item.ID && (_jsxs("div", { children: [_jsx(IconButton, { id: 'setting-button', "aria-controls": open ? 'file-menu' : undefined, "aria-expanded": open ? 'true' : undefined, "aria-haspopup": 'true', onClick: handleClick, size: 'large', children: _jsx(MoreVertIcon, {}) }), _jsxs(Menu, { style: { marginTop: '3rem' }, id: 'file-menu', anchorEl: anchorEl, keepMounted: true, open: Boolean(anchorEl), onClose: handleClose, children: [_jsx(MenuItem, { style: { fontSize: '14px' }, onClick: () => {
|
|
324
376
|
setAnchorEl(null);
|
|
325
377
|
onFileDownload(item.responseProps ? item.responseProps : {});
|
|
326
|
-
}, children: "Download" }, 'download'), _jsx(MenuItem, { style: { fontSize: '14px' }, onClick: () => deleteFile(item), children: "Delete" }, 'delete')] })] }))] })] }, index));
|
|
378
|
+
}, children: "Download" }, 'download'), _jsx(MenuItem, { style: { fontSize: '14px' }, onClick: () => deleteFile(item, index), children: "Delete" }, 'delete')] })] }))] })] }, index));
|
|
327
379
|
}) }));
|
|
328
|
-
return (_jsxs("div", { className: 'file-upload-container', children: [_jsx("span", { className: `label ${required ? 'file-label' : ''}`, children: label }), ((files.length === 0 && allowMultiple
|
|
380
|
+
return (_jsxs("div", { className: 'file-upload-container', children: [_jsx("span", { className: `label ${required ? 'file-label' : ''}`, children: label }), ((files.length === 0 && !allowMultiple) || allowMultiple) && _jsx("section", { children: content }), validatemessage !== '' ? _jsx("span", { className: 'file-error', children: validatemessage }) : _jsx("span", { style: { fontSize: '14px' }, children: helperText }), files && files.length > 0 && _jsx("section", { children: fileDisplay })] }));
|
|
329
381
|
}
|
|
330
382
|
//# sourceMappingURL=Attachment.js.map
|