@pega/react-sdk-overrides 24.2.10 → 25.1.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/Banner/Banner.css +1 -1
- package/lib/designSystemExtension/Banner/Banner.tsx +10 -7
- package/lib/designSystemExtension/CaseSummaryFields/CaseSummaryFields.css +0 -1
- package/lib/designSystemExtension/CaseSummaryFields/CaseSummaryFields.tsx +53 -37
- package/lib/designSystemExtension/DetailsFields/DetailsFields.tsx +11 -13
- package/lib/designSystemExtension/FieldGroup/FieldGroup.tsx +8 -9
- package/lib/designSystemExtension/FieldGroupList/FieldGroupList.tsx +9 -9
- package/lib/designSystemExtension/FieldValueList/FieldValueList.tsx +8 -9
- package/lib/designSystemExtension/Operator/Operator.tsx +21 -19
- package/lib/designSystemExtension/Pulse/Pulse.tsx +1 -1
- package/lib/designSystemExtension/RichTextEditor/RichTextEditor.tsx +32 -4
- package/lib/designSystemExtension/WssQuickCreate/WssQuickCreate.css +7 -14
- package/lib/designSystemExtension/WssQuickCreate/WssQuickCreate.tsx +13 -2
- package/lib/field/AutoComplete/AutoComplete.tsx +1 -1
- package/lib/field/CancelAlert/CancelAlert.css +4 -4
- package/lib/field/CancelAlert/CancelAlert.tsx +7 -10
- package/lib/field/Checkbox/Checkbox.tsx +97 -4
- package/lib/field/Currency/Currency.tsx +10 -7
- package/lib/field/Currency/currency-utils.ts +1 -2
- package/lib/field/Date/Date.tsx +8 -8
- package/lib/field/DateTime/DateTime.tsx +16 -13
- package/lib/field/Decimal/Decimal.tsx +10 -7
- package/lib/field/Dropdown/Dropdown.tsx +30 -25
- package/lib/field/Email/Email.tsx +11 -13
- package/lib/field/Group/Group.tsx +10 -8
- package/lib/field/Integer/Integer.tsx +5 -7
- package/lib/field/Location/Location.css +4 -0
- package/lib/field/Location/Location.tsx +258 -0
- package/lib/field/Location/config-ext.json +8 -0
- package/lib/field/Location/index.tsx +1 -0
- package/lib/field/Multiselect/utils.ts +1 -1
- package/lib/field/ObjectReference/ObjectReference.tsx +235 -0
- package/lib/field/ObjectReference/index.tsx +1 -0
- package/lib/field/ObjectReference/utils.ts +111 -0
- package/lib/field/Percentage/Percentage.tsx +9 -9
- package/lib/field/Phone/Phone.tsx +7 -5
- package/lib/field/RadioButtons/RadioButtons.tsx +47 -5
- package/lib/field/RichText/RichText.css +79 -0
- package/lib/field/RichText/RichText.tsx +3 -1
- package/lib/field/ScalarList/ScalarList.tsx +2 -4
- package/lib/field/SelectableCard/SelectableCard.tsx +175 -0
- package/lib/field/SelectableCard/index.tsx +1 -0
- package/lib/field/SelectableCard/utils.tsx +223 -0
- package/lib/field/SemanticLink/SemanticLink.tsx +160 -28
- package/lib/field/SemanticLink/utils.ts +1 -1
- package/lib/field/TextArea/TextArea.tsx +5 -7
- package/lib/field/TextContent/TextContent.tsx +1 -2
- package/lib/field/TextInput/TextInput.tsx +5 -7
- package/lib/field/Time/Time.tsx +4 -8
- package/lib/field/URL/URL.tsx +5 -7
- package/lib/field/UserReference/UserReference.tsx +3 -6
- package/lib/helpers/attachmentShared.ts +6 -0
- package/lib/helpers/common-utils.ts +24 -2
- package/lib/helpers/data_page.ts +0 -1
- package/lib/helpers/field-group-utils.ts +1 -1
- package/lib/helpers/formatters/Currency.ts +20 -20
- package/lib/helpers/formatters/CurrencyMap.ts +0 -2
- package/lib/helpers/formatters/common.ts +2 -1
- package/lib/helpers/formatters/index.ts +2 -4
- package/lib/helpers/object-utils.ts +10 -0
- package/lib/helpers/simpleTableHelpers.ts +118 -6
- package/lib/helpers/utils.ts +8 -1
- package/lib/helpers/versionHelpers.ts +0 -1
- package/lib/infra/ActionButtons/ActionButtons.tsx +28 -21
- package/lib/infra/Assignment/Assignment.tsx +39 -36
- package/lib/infra/AssignmentCard/AssignmentCard.tsx +2 -2
- package/lib/infra/Containers/FlowContainer/FlowContainer.tsx +21 -113
- package/lib/infra/Containers/FlowContainer/helpers.ts +1 -5
- package/lib/infra/Containers/ModalViewContainer/ListViewActionButtons/ListViewActionButtons.tsx +4 -3
- package/lib/infra/Containers/ModalViewContainer/ModalViewContainer.tsx +7 -6
- package/lib/infra/Containers/SimpleView/helper.ts +1 -1
- package/lib/infra/Containers/ViewContainer/ViewContainer.tsx +4 -5
- package/lib/infra/Containers/container-helpers.ts +52 -0
- package/lib/infra/DashboardFilter/DashboardFilter.tsx +5 -9
- package/lib/infra/DashboardFilter/filterUtils.tsx +3 -6
- package/lib/infra/DeferLoad/DeferLoad.tsx +7 -9
- package/lib/infra/ErrorBoundary/ErrorBoundary.tsx +1 -3
- package/lib/infra/MultiStep/MultiStep.css +48 -70
- package/lib/infra/MultiStep/MultiStep.tsx +27 -58
- package/lib/infra/NavBar/NavBar.css +1 -1
- package/lib/infra/NavBar/NavBar.tsx +43 -32
- package/lib/infra/Reference/Reference.tsx +3 -4
- package/lib/infra/Region/Region.tsx +1 -1
- package/lib/infra/RootContainer/RootContainer.tsx +3 -4
- package/lib/infra/Stages/Stages.tsx +3 -4
- package/lib/infra/View/View.tsx +4 -3
- package/lib/template/AdvancedSearch/AdvancedSearch.tsx +86 -0
- package/lib/template/AdvancedSearch/SearchGroup/persistUtils.ts +52 -0
- package/lib/template/AdvancedSearch/SearchGroups/SearchGroups.tsx +244 -0
- package/lib/template/AdvancedSearch/SearchGroups/hooks.ts +37 -0
- package/lib/template/AdvancedSearch/SearchGroups/index.tsx +1 -0
- package/lib/template/AdvancedSearch/SearchGroups/utils.ts +29 -0
- package/lib/template/AdvancedSearch/TemplateContext.ts +11 -0
- package/lib/template/AdvancedSearch/config-ext.json +9 -0
- package/lib/template/AdvancedSearch/index.tsx +1 -0
- package/lib/template/AppShell/AppShell.css +1 -1
- package/lib/template/AppShell/AppShell.tsx +22 -23
- package/lib/template/BannerPage/BannerPage.tsx +2 -2
- package/lib/template/CaseSummary/CaseSummary.tsx +28 -41
- package/lib/template/CaseView/CaseView.tsx +32 -38
- package/lib/template/CaseViewActionsMenu/CaseViewActionsMenu.tsx +1 -1
- package/lib/template/Confirmation/Confirmation.tsx +3 -4
- package/lib/template/DataReference/DataReference.tsx +312 -106
- package/lib/template/DataReference/DataReferenceAdvancedSearchContext.ts +10 -0
- package/lib/template/DataReference/SearchForm.tsx +149 -0
- package/lib/template/DataReference/utils.ts +90 -0
- package/lib/template/DefaultForm/DefaultForm.tsx +3 -3
- package/lib/template/DefaultForm/utils/index.ts +1 -3
- package/lib/template/DefaultPage/DefaultPage.tsx +108 -0
- package/lib/template/DefaultPage/index.tsx +1 -0
- package/lib/template/Details/Details/Details.tsx +11 -11
- package/lib/template/Details/DetailsSubTabs/DetailsSubTabs.tsx +2 -2
- package/lib/template/Details/DetailsThreeColumn/DetailsThreeColumn.tsx +11 -11
- package/lib/template/Details/DetailsTwoColumn/DetailsTwoColumn.tsx +11 -11
- package/lib/template/Details/DynamicTabs/DynamicTabs.tsx +1 -2
- package/lib/template/FieldGroupTemplate/FieldGroupTemplate.tsx +2 -5
- package/lib/template/InlineDashboard/InlineDashboard.tsx +14 -16
- package/lib/template/InlineDashboardPage/InlineDashboardPage.tsx +2 -2
- package/lib/template/ListPage/ListPage.tsx +1 -1
- package/lib/template/ListView/ListView.tsx +285 -204
- package/lib/template/ListView/hooks.ts +1 -5
- package/lib/template/ListView/utils.ts +38 -6
- package/lib/template/MultiReferenceReadOnly/MultiReferenceReadOnly.tsx +1 -1
- package/lib/template/NarrowWide/NarrowWide/NarrowWide.tsx +5 -5
- package/lib/template/NarrowWide/NarrowWideDetails/NarrowWideDetails.tsx +11 -11
- package/lib/template/NarrowWide/NarrowWideForm/NarrowWideForm.tsx +2 -2
- package/lib/template/NarrowWide/NarrowWidePage/NarrowWidePage.tsx +2 -2
- package/lib/template/OneColumn/OneColumn/OneColumn.tsx +7 -7
- package/lib/template/OneColumn/OneColumnPage/OneColumnPage.tsx +1 -1
- package/lib/template/OneColumn/OneColumnTab/OneColumnTab.tsx +2 -2
- package/lib/template/PromotedFilters/PromotedFilters.tsx +1 -3
- package/lib/template/SelfServiceCaseView/SelfServiceCaseView.tsx +145 -0
- package/lib/template/SelfServiceCaseView/index.tsx +1 -0
- package/lib/template/SimpleTable/SimpleTable/SimpleTable.tsx +2 -5
- package/lib/template/SimpleTable/SimpleTableManual/SimpleTableManual.tsx +99 -84
- package/lib/template/SimpleTable/SimpleTableSelect/SimpleTableSelect.tsx +3 -5
- package/lib/template/SingleReferenceReadOnly/SingleReferenceReadOnly.tsx +10 -2
- package/lib/template/SubTabs/SubTabs.tsx +2 -2
- package/lib/template/SubTabs/tabUtils.ts +118 -1
- package/lib/template/TwoColumn/TwoColumn/TwoColumn.tsx +9 -10
- package/lib/template/TwoColumn/TwoColumnPage/TwoColumnPage.tsx +1 -1
- package/lib/template/TwoColumn/TwoColumnTab/TwoColumnTab.tsx +9 -10
- package/lib/template/WideNarrow/WideNarrow/WideNarrow.tsx +5 -5
- package/lib/template/WideNarrow/WideNarrowDetails/WideNarrowDetails.tsx +11 -11
- package/lib/template/WideNarrow/WideNarrowForm/WideNarrowForm.tsx +2 -2
- package/lib/template/WideNarrow/WideNarrowPage/WideNarrowPage.tsx +2 -2
- package/lib/template/WssNavBar/WssNavBar.css +1 -1
- package/lib/template/WssNavBar/WssNavBar.tsx +6 -6
- package/lib/template/utils.tsx +58 -0
- package/lib/widget/AppAnnouncement/AppAnnouncement.tsx +1 -1
- package/lib/widget/Attachment/Attachment.css +7 -8
- package/lib/widget/Attachment/Attachment.tsx +304 -231
- package/lib/widget/Attachment/Attachment.types.ts +96 -0
- package/lib/widget/Attachment/AttachmentUtils.ts +316 -0
- package/lib/widget/CaseHistory/CaseHistory.tsx +5 -5
- package/lib/widget/FileUtility/ActionButtonsForFileUtil/ActionButtonsForFileUtil.css +0 -14
- package/lib/widget/FileUtility/ActionButtonsForFileUtil/ActionButtonsForFileUtil.tsx +3 -3
- package/lib/widget/FileUtility/FileUtility/FileUtility.css +7 -6
- package/lib/widget/FileUtility/FileUtility/FileUtility.tsx +30 -23
- package/lib/widget/Followers/Followers.tsx +2 -4
- package/lib/widget/QuickCreate/QuickCreate.tsx +1 -3
- package/lib/widget/SummaryItem/SummaryItem.css +9 -11
- package/lib/widget/SummaryItem/SummaryItem.tsx +3 -3
- package/lib/widget/SummaryList/SummaryList.tsx +1 -1
- package/lib/widget/ToDo/ToDo.css +1 -13
- package/lib/widget/ToDo/ToDo.tsx +38 -37
- package/package.json +1 -1
- package/lib/helpers/attachmentHelpers.ts +0 -76
- package/lib/infra/Containers/helpers.ts +0 -6
|
@@ -1,175 +1,192 @@
|
|
|
1
|
-
|
|
2
|
-
/* eslint-disable react/no-array-index-key */
|
|
3
|
-
/* eslint-disable no-nested-ternary */
|
|
4
|
-
import { useState, useEffect, useCallback } from 'react';
|
|
1
|
+
import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
|
5
2
|
import { CircularProgress, IconButton, Menu, MenuItem, Button } from '@mui/material';
|
|
6
3
|
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|
7
|
-
import download from 'downloadjs';
|
|
8
4
|
|
|
9
|
-
import { buildFilePropsFromResponse, getIconFromFileType, validateMaxSize } from '@pega/react-sdk-components/lib/components/helpers/attachmentHelpers';
|
|
10
5
|
import { Utils } from '@pega/react-sdk-components/lib/components/helpers/utils';
|
|
11
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
clearFieldErrorMessages,
|
|
8
|
+
deleteAttachments,
|
|
9
|
+
getIconFromFileType,
|
|
10
|
+
getMappedValue,
|
|
11
|
+
insertAttachments,
|
|
12
|
+
useDeepMemo,
|
|
13
|
+
useFileDownload,
|
|
14
|
+
validateFileExtension
|
|
15
|
+
} from './AttachmentUtils';
|
|
16
|
+
import { validateMaxSize } from '@pega/react-sdk-components/lib/components/helpers/attachmentShared';
|
|
17
|
+
import type { PageInstructionOptions } from './Attachment.types';
|
|
18
|
+
import type { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps';
|
|
12
19
|
|
|
13
20
|
import './Attachment.css';
|
|
14
21
|
|
|
15
22
|
interface AttachmentProps extends Omit<PConnFieldProps, 'value'> {
|
|
16
23
|
// If any, enter additional props that only exist on this component
|
|
17
24
|
value: any;
|
|
18
|
-
allowMultiple: string;
|
|
25
|
+
allowMultiple: boolean | string;
|
|
19
26
|
extensions: string;
|
|
27
|
+
editMode: string;
|
|
28
|
+
isTableFormatter: boolean;
|
|
20
29
|
}
|
|
21
30
|
|
|
22
|
-
const getAttachmentKey = (name = '') => (name ? `attachmentsList.${name}` : 'attachmentsList');
|
|
23
|
-
|
|
24
|
-
const getCurrentAttachmentsList = (key, context) => {
|
|
25
|
-
return PCore.getStoreValue(`.${key}`, 'context_data', context) || [];
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const updateAttachmentState = (pConn, key, attachments) => {
|
|
29
|
-
PCore.getStateUtils().updateState(pConn.getContextName(), key, attachments, {
|
|
30
|
-
pageReference: 'context_data',
|
|
31
|
-
isArrayDeepMerge: false
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
|
|
35
31
|
export default function Attachment(props: AttachmentProps) {
|
|
36
|
-
const { value, getPConnect, label, validatemessage,
|
|
32
|
+
const { value, getPConnect, label, validatemessage, extensions, displayMode, helperText, editMode, isTableFormatter } = props;
|
|
37
33
|
/* this is a temporary fix because required is supposed to be passed as a boolean and NOT as a string */
|
|
38
|
-
let { required, disabled } = props;
|
|
39
|
-
[required, disabled] = [required, disabled].map(
|
|
34
|
+
let { required, disabled, allowMultiple } = props;
|
|
35
|
+
[required, disabled, allowMultiple] = [required, disabled, allowMultiple].map(
|
|
36
|
+
prop => prop === true || (typeof prop === 'string' && prop === 'true')
|
|
37
|
+
);
|
|
40
38
|
const pConn = getPConnect();
|
|
41
|
-
const
|
|
39
|
+
const localizationService = pConn.getLocalizationService();
|
|
40
|
+
|
|
41
|
+
const actionSequencer = useMemo(() => PCore.getActionsSequencer(), []);
|
|
42
|
+
const rawValue = pConn.getComponentConfig().value;
|
|
43
|
+
const isAttachmentAnnotationPresent = typeof rawValue === 'object' ? false : rawValue?.includes('@ATTACHMENT');
|
|
44
|
+
const { attachments, isOldAttachment } = isAttachmentAnnotationPresent ? value : PCore.getAttachmentUtils().prepareAttachmentData(value);
|
|
45
|
+
|
|
46
|
+
let valueRef = (pConn.getStateProps() as any).value;
|
|
47
|
+
valueRef = valueRef.indexOf('.') === 0 ? valueRef.substring(1) : valueRef;
|
|
48
|
+
|
|
49
|
+
pConn.setReferenceList(`.${valueRef}`);
|
|
50
|
+
|
|
51
|
+
const isMultiAttachmentInInlineEditTable = isTableFormatter && allowMultiple && editMode === 'tableRows';
|
|
52
|
+
|
|
53
|
+
const [files, setFiles] = useState<any[]>(attachments);
|
|
54
|
+
const overrideLocalState = useRef(false);
|
|
55
|
+
const attachmentCount = useRef(attachments.length);
|
|
56
|
+
const filesWithError = useRef<any[]>([]);
|
|
57
|
+
const multiAttachmentsInInlineEdit = useRef([]);
|
|
58
|
+
const thumbnailURLs = useRef<any[]>([]);
|
|
59
|
+
const contextName = pConn.getContextName();
|
|
60
|
+
const onFileDownload = useFileDownload(contextName);
|
|
61
|
+
|
|
42
62
|
const localizedVal = PCore.getLocaleUtils().getLocaleValue;
|
|
43
63
|
const localeCategory = 'CosmosFields';
|
|
44
64
|
const uploadMultipleFilesLabel = localizedVal('file_upload_text_multiple', localeCategory);
|
|
45
65
|
const uploadSingleFileLabel = localizedVal('file_upload_text_one', localeCategory);
|
|
46
|
-
let categoryName = '';
|
|
47
|
-
if (value && value.pyCategoryName) {
|
|
48
|
-
categoryName = value.pyCategoryName;
|
|
49
|
-
}
|
|
50
66
|
const deleteIcon = Utils.getImageSrc('trash', Utils.getSDKStaticConentUrl());
|
|
51
67
|
const srcImg = Utils.getImageSrc('document-doc', Utils.getSDKStaticConentUrl());
|
|
52
|
-
|
|
53
|
-
valueRef = valueRef.indexOf('.') === 0 ? valueRef.substring(1) : valueRef;
|
|
68
|
+
|
|
54
69
|
const [anchorEl, setAnchorEl] = useState(null);
|
|
55
70
|
const open = Boolean(anchorEl);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
);
|
|
59
|
-
const [filesWithError, setFilesWithError] = useState<any[]>([]);
|
|
71
|
+
|
|
72
|
+
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
60
73
|
const [toggleUploadBegin, setToggleUploadBegin] = useState(false);
|
|
61
74
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
isArrayDeepMerge: false
|
|
66
|
-
});
|
|
67
|
-
};
|
|
75
|
+
const deleteFile = useCallback(
|
|
76
|
+
(file, fileIndex) => {
|
|
77
|
+
setAnchorEl(null);
|
|
68
78
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
79
|
+
// reset the file input so that it will allow re-uploading the same file after deletion
|
|
80
|
+
if (fileInputRef.current) {
|
|
81
|
+
fileInputRef.current.value = ''; // Reset the input
|
|
82
|
+
}
|
|
73
83
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const extension = fileObj.pyAttachName.split('.').pop();
|
|
81
|
-
fileDownload(content.data, fileObj.pyFileName, extension);
|
|
82
|
-
})
|
|
83
|
-
.catch(() => {});
|
|
84
|
-
};
|
|
84
|
+
if (filesWithError.current.length > 0) {
|
|
85
|
+
filesWithError.current = filesWithError.current.filter(fileWithError => fileWithError.props.id !== file.props.id);
|
|
86
|
+
if (filesWithError.current.length === 0) {
|
|
87
|
+
clearFieldErrorMessages(pConn);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
85
90
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// If file to be deleted is the one added in previous stage i.e. for which a file instance is created in server
|
|
93
|
-
// no need to filter currentAttachmentList as we will get another entry of file in redux with delete & label
|
|
94
|
-
// eslint-disable-next-line no-unsafe-optional-chaining
|
|
95
|
-
if (value && value?.pxResults && +value?.pyCount > 0 && file.responseProps && file?.responseProps?.pzInsKey !== 'temp') {
|
|
96
|
-
const updatedAttachments = files.map(f => {
|
|
97
|
-
if (f.responseProps && f.responseProps.pzInsKey === file.responseProps.pzInsKey) {
|
|
98
|
-
return { ...f, delete: true, label: valueRef };
|
|
99
|
-
}
|
|
100
|
-
return f;
|
|
91
|
+
if (file.inProgress) {
|
|
92
|
+
// @ts-ignore - Expected 1 arguments, but got 2.ts(2554)
|
|
93
|
+
PCore.getAttachmentUtils().cancelRequest(file.props.id, contextName);
|
|
94
|
+
actionSequencer.deRegisterBlockingAction(contextName).catch(() => {});
|
|
95
|
+
setFiles(localFiles => {
|
|
96
|
+
return localFiles.filter(localFile => localFile.props.id !== file.props.id);
|
|
101
97
|
});
|
|
98
|
+
} else {
|
|
99
|
+
deleteAttachments([file], pConn, multiAttachmentsInInlineEdit.current, {
|
|
100
|
+
allowMultiple,
|
|
101
|
+
isOldAttachment,
|
|
102
|
+
isMultiAttachmentInInlineEditTable,
|
|
103
|
+
attachmentCount: attachmentCount.current,
|
|
104
|
+
deleteIndex: fileIndex
|
|
105
|
+
} as any);
|
|
106
|
+
// Filter out without deleted file and reset the file indexes
|
|
107
|
+
setFiles(localFiles => {
|
|
108
|
+
let tempLocalFiles = [...localFiles];
|
|
109
|
+
tempLocalFiles = tempLocalFiles.filter(localFile => localFile.props.id !== file.props.id);
|
|
110
|
+
tempLocalFiles.forEach(localFile => {
|
|
111
|
+
if (!localFile.props.error && !file.props.error) {
|
|
112
|
+
const updatedDeleteIndex =
|
|
113
|
+
localFile.responseProps.deleteIndex > fileIndex ? localFile.responseProps.deleteIndex - 1 : localFile.responseProps.deleteIndex;
|
|
102
114
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
);
|
|
110
|
-
attachmentsList = [...filesPostDelete, ...newlyAddedFiles];
|
|
111
|
-
return attachmentsList;
|
|
112
|
-
});
|
|
113
|
-
} // if the file being deleted is the added in this stage i.e. whose data is not yet created in server
|
|
114
|
-
else {
|
|
115
|
-
// filter newly added files in this stage, later the updated current stage files will be added to redux once files state is updated in below setFiles()
|
|
116
|
-
currentAttachmentList = currentAttachmentList.filter(f => f.label !== valueRef);
|
|
117
|
-
setFiles(current => {
|
|
118
|
-
attachmentsList = current.filter(f => f.ID !== file.ID);
|
|
119
|
-
return attachmentsList;
|
|
115
|
+
localFile.props.onDelete = () => deleteFile(localFile, updatedDeleteIndex);
|
|
116
|
+
|
|
117
|
+
localFile.responseProps.deleteIndex = updatedDeleteIndex;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
return tempLocalFiles;
|
|
120
121
|
});
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
// @ts-ignore - 3rd parameter "responseEncoding" should be optional
|
|
124
|
-
PCore.getAttachmentUtils().cancelRequest(file.ID, pConn.getContextName());
|
|
122
|
+
if (!file.props.error) {
|
|
123
|
+
attachmentCount.current -= 1;
|
|
125
124
|
}
|
|
126
125
|
}
|
|
127
126
|
|
|
128
127
|
setToggleUploadBegin(false);
|
|
129
|
-
setFilesWithError(prevFilesWithError => {
|
|
130
|
-
return prevFilesWithError.filter(f => f.ID !== file.ID);
|
|
131
|
-
});
|
|
132
128
|
},
|
|
133
|
-
[pConn
|
|
129
|
+
[pConn]
|
|
134
130
|
);
|
|
135
131
|
|
|
136
|
-
const onUploadProgress = () => {
|
|
132
|
+
const onUploadProgress = (id, ev) => {
|
|
133
|
+
const progress = Math.floor((ev.loaded / ev.total) * 100);
|
|
134
|
+
setFiles(localFiles => [
|
|
135
|
+
...localFiles.map(localFile => {
|
|
136
|
+
if (localFile.props?.id === id) {
|
|
137
|
+
localFile.inProgress = true;
|
|
138
|
+
localFile.props.progress = progress;
|
|
139
|
+
}
|
|
140
|
+
return localFile;
|
|
141
|
+
})
|
|
142
|
+
]);
|
|
143
|
+
};
|
|
137
144
|
|
|
138
|
-
const
|
|
145
|
+
const populateErrorAndUpdateRedux = file => {
|
|
146
|
+
const fieldName = (pConn.getStateProps() as any).value;
|
|
147
|
+
// set errors to property to block submit even on errors in file upload
|
|
148
|
+
PCore.getMessageManager().addMessages({
|
|
149
|
+
messages: [
|
|
150
|
+
{
|
|
151
|
+
type: 'error',
|
|
152
|
+
message: localizationService.getLocalizedText('Error with one or more files')
|
|
153
|
+
}
|
|
154
|
+
],
|
|
155
|
+
property: fieldName,
|
|
156
|
+
pageReference: pConn.getPageReference(),
|
|
157
|
+
context: contextName
|
|
158
|
+
});
|
|
159
|
+
insertAttachments([file], pConn, multiAttachmentsInInlineEdit.current, {
|
|
160
|
+
allowMultiple,
|
|
161
|
+
isOldAttachment,
|
|
162
|
+
isMultiAttachmentInInlineEditTable,
|
|
163
|
+
attachmentCount: attachmentCount.current
|
|
164
|
+
} as any);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const errorHandler = (isFetchCanceled, file) => {
|
|
139
168
|
return error => {
|
|
140
169
|
if (!isFetchCanceled(error)) {
|
|
141
|
-
let uploadFailMsg =
|
|
170
|
+
let uploadFailMsg = localizationService.getLocalizedText('Something went wrong');
|
|
142
171
|
if (error.response && error.response.data && error.response.data.errorDetails) {
|
|
143
|
-
uploadFailMsg =
|
|
172
|
+
uploadFailMsg = localizationService.getLocalizedText(error.response.data.errorDetails[0].localizedValue);
|
|
144
173
|
}
|
|
174
|
+
|
|
145
175
|
setFiles(current => {
|
|
146
|
-
return current.map(
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
// @ts-ignore
|
|
159
|
-
messages: [
|
|
160
|
-
{
|
|
161
|
-
type: 'error',
|
|
162
|
-
// @ts-ignore - Type '{ type: string; message: string; }' is not assignable to type 'MessagesConfigObject'.
|
|
163
|
-
message: pConn.getLocalizedValue('Error with one or more files', '', '')
|
|
164
|
-
}
|
|
165
|
-
],
|
|
166
|
-
property: fieldName,
|
|
167
|
-
pageReference: pConn.getPageReference(),
|
|
168
|
-
context
|
|
169
|
-
});
|
|
170
|
-
delete f.props.progress;
|
|
176
|
+
return current.map((localFile, index) => {
|
|
177
|
+
if (localFile.props.id === file.props.id) {
|
|
178
|
+
localFile.props.meta = uploadFailMsg;
|
|
179
|
+
localFile.props.error = true;
|
|
180
|
+
localFile.props.onDelete = () => deleteFile(localFile, index);
|
|
181
|
+
localFile.props.icon = getIconFromFileType(localFile.type);
|
|
182
|
+
localFile.props.name = localizationService.getLocalizedText('Unable to upload file');
|
|
183
|
+
localFile.inProgress = false;
|
|
184
|
+
delete localFile.props.progress;
|
|
185
|
+
filesWithError.current.push(localFile);
|
|
186
|
+
|
|
187
|
+
populateErrorAndUpdateRedux(localFile);
|
|
171
188
|
}
|
|
172
|
-
return
|
|
189
|
+
return localFile;
|
|
173
190
|
});
|
|
174
191
|
});
|
|
175
192
|
}
|
|
@@ -177,81 +194,62 @@ export default function Attachment(props: AttachmentProps) {
|
|
|
177
194
|
};
|
|
178
195
|
};
|
|
179
196
|
|
|
180
|
-
const validateFileExtension = (fileObj, allowedExtensions) => {
|
|
181
|
-
if (!allowedExtensions) {
|
|
182
|
-
return true;
|
|
183
|
-
}
|
|
184
|
-
const allowedExtensionList = allowedExtensions
|
|
185
|
-
.toLowerCase()
|
|
186
|
-
.split(',')
|
|
187
|
-
.map(item => item.replaceAll('.', '').trim());
|
|
188
|
-
const extension = fileObj.name.split('.').pop().toLowerCase();
|
|
189
|
-
return allowedExtensionList.includes(extension);
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
const clearFieldErrorMessages = () => {
|
|
193
|
-
const fieldName = (pConn.getStateProps() as any).value;
|
|
194
|
-
const context = pConn.getContextName();
|
|
195
|
-
// @ts-ignore
|
|
196
|
-
PCore.getMessageManager().clearMessages({
|
|
197
|
-
type: PCore.getConstants().MESSAGES.MESSAGES_TYPE_ERROR,
|
|
198
|
-
property: fieldName,
|
|
199
|
-
pageReference: pConn.getPageReference(),
|
|
200
|
-
context
|
|
201
|
-
});
|
|
202
|
-
};
|
|
203
|
-
|
|
204
197
|
const onFileAdded = event => {
|
|
205
198
|
let addedFiles = Array.from(event.target.files);
|
|
206
|
-
addedFiles = allowMultiple
|
|
199
|
+
addedFiles = allowMultiple ? addedFiles : [addedFiles[0]];
|
|
207
200
|
const maxAttachmentSize = PCore.getEnvironmentInfo().getMaxAttachmentSize() || '5';
|
|
208
201
|
const tempFilesToBeUploaded = [
|
|
209
202
|
...addedFiles.map((f: any, index) => {
|
|
210
203
|
f.ID = `${new Date().getTime()}I${index}`;
|
|
211
|
-
f.inProgress = true;
|
|
212
204
|
f.props = {
|
|
213
205
|
type: f.type,
|
|
214
206
|
name: f.name,
|
|
207
|
+
id: f.ID,
|
|
208
|
+
format: f.name.split('.').pop(),
|
|
215
209
|
icon: getIconFromFileType(f.type),
|
|
216
|
-
onDelete: () => deleteFile(f)
|
|
210
|
+
onDelete: () => deleteFile(f, index),
|
|
211
|
+
thumbnail: window.URL.createObjectURL(f)
|
|
217
212
|
};
|
|
218
213
|
if (!validateMaxSize(f, maxAttachmentSize)) {
|
|
219
214
|
f.props.error = true;
|
|
220
|
-
f.
|
|
221
|
-
f.props.meta = pConn.getLocalizedValue(`File is too big. Max allowed size is ${maxAttachmentSize}MB.`, '', '');
|
|
215
|
+
f.props.meta = localizationService.getLocalizedText(`File is too big. Max allowed size is ${maxAttachmentSize}MB.`);
|
|
222
216
|
} else if (!validateFileExtension(f, extensions)) {
|
|
223
217
|
f.props.error = true;
|
|
224
|
-
f.
|
|
225
|
-
f.props.meta = `${pConn.getLocalizedValue('File has invalid extension. Allowed extensions are:', '', '')} ${extensions.replaceAll(
|
|
218
|
+
f.props.meta = `${localizationService.getLocalizedText('File has invalid extension. Allowed extensions are:')} ${extensions.replaceAll(
|
|
226
219
|
'.',
|
|
227
220
|
''
|
|
228
221
|
)}`;
|
|
229
222
|
}
|
|
230
223
|
if (f.props.error) {
|
|
231
224
|
const fieldName = (pConn.getStateProps() as any).value;
|
|
232
|
-
const context = pConn.getContextName();
|
|
233
225
|
PCore.getMessageManager().addMessages({
|
|
234
|
-
// @ts-ignore
|
|
235
226
|
messages: [
|
|
236
227
|
{
|
|
237
228
|
type: 'error',
|
|
238
|
-
|
|
239
|
-
message: pConn.getLocalizedValue('Error with one or more files', '', '')
|
|
229
|
+
message: localizationService.getLocalizedText('Error with one or more files')
|
|
240
230
|
}
|
|
241
231
|
],
|
|
242
232
|
property: fieldName,
|
|
243
233
|
pageReference: pConn.getPageReference(),
|
|
244
|
-
context
|
|
234
|
+
context: contextName
|
|
245
235
|
});
|
|
246
236
|
}
|
|
247
237
|
return f;
|
|
248
238
|
})
|
|
249
239
|
];
|
|
240
|
+
|
|
250
241
|
const tempFilesWithError = tempFilesToBeUploaded.filter(f => f.props.error);
|
|
251
242
|
if (tempFilesWithError.length > 0) {
|
|
252
|
-
|
|
243
|
+
filesWithError.current = [...filesWithError.current, ...tempFilesWithError];
|
|
244
|
+
|
|
245
|
+
insertAttachments(tempFilesWithError, pConn, multiAttachmentsInInlineEdit.current, {
|
|
246
|
+
allowMultiple,
|
|
247
|
+
isOldAttachment,
|
|
248
|
+
isMultiAttachmentInInlineEditTable,
|
|
249
|
+
attachmentCount: attachmentCount.current
|
|
250
|
+
} as PageInstructionOptions);
|
|
253
251
|
}
|
|
254
|
-
setFiles(current => (allowMultiple
|
|
252
|
+
setFiles(current => (!allowMultiple ? [...tempFilesToBeUploaded] : [...current, ...tempFilesToBeUploaded]));
|
|
255
253
|
setToggleUploadBegin(true);
|
|
256
254
|
};
|
|
257
255
|
|
|
@@ -260,106 +258,178 @@ export default function Attachment(props: AttachmentProps) {
|
|
|
260
258
|
.filter(e => {
|
|
261
259
|
const isFileUploaded = e.props && e.props.progress === 100;
|
|
262
260
|
const fileHasError = e.props && e.props.error;
|
|
263
|
-
const
|
|
264
|
-
|
|
261
|
+
const isFileUploadedInLastStep = e.responseProps && e.responseProps.ID !== 'temp';
|
|
262
|
+
const isFileUploadInProgress = e.inProgress;
|
|
263
|
+
return !isFileUploadInProgress && !isFileUploaded && !fileHasError && !isFileUploadedInLastStep;
|
|
265
264
|
})
|
|
266
|
-
.map(
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
onUploadProgress();
|
|
265
|
+
.map(file =>
|
|
266
|
+
PCore.getAttachmentUtils().uploadAttachment(
|
|
267
|
+
file,
|
|
268
|
+
ev => {
|
|
269
|
+
onUploadProgress(file.props.id, ev);
|
|
271
270
|
},
|
|
272
271
|
isFetchCanceled => {
|
|
273
|
-
return errorHandler(isFetchCanceled,
|
|
272
|
+
return errorHandler(isFetchCanceled, file);
|
|
274
273
|
},
|
|
275
|
-
|
|
274
|
+
contextName
|
|
276
275
|
)
|
|
277
276
|
);
|
|
277
|
+
|
|
278
|
+
// allow new files to be added when other files upload is still in progress
|
|
279
|
+
setToggleUploadBegin(false);
|
|
278
280
|
Promise.allSettled(filesToBeUploaded)
|
|
279
281
|
.then((fileResponses: any) => {
|
|
280
282
|
fileResponses = fileResponses.filter(fr => fr.status !== 'rejected'); // in case of deleting an in progress file, promise gets cancelled but still enters then block
|
|
281
283
|
if (fileResponses.length > 0) {
|
|
282
|
-
setFiles(
|
|
283
|
-
const tempFilesUploaded = [...
|
|
284
|
-
tempFilesUploaded.forEach(
|
|
285
|
-
|
|
284
|
+
setFiles(localFiles => {
|
|
285
|
+
const tempFilesUploaded = [...localFiles];
|
|
286
|
+
tempFilesUploaded.forEach(localFile => {
|
|
287
|
+
// if attach field has multiple files & in bw any error files are present
|
|
288
|
+
// Example : files = [properFile1, errFile, errFile, properFile2]
|
|
289
|
+
// indexes for delete & preview should be for files [properFile1, properFile2] which is [1,2]
|
|
290
|
+
const index = fileResponses.findIndex(fileResponse => fileResponse.value.clientFileID === localFile.props.id);
|
|
286
291
|
if (index >= 0) {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
292
|
+
fileResponses[index].value.thumbnail = localFile.props.thumbnail;
|
|
293
|
+
localFile.inProgress = false;
|
|
294
|
+
localFile.ID = fileResponses[index].value.ID;
|
|
295
|
+
localFile.props.meta = localizationService.getLocalizedText('Uploaded successfully');
|
|
296
|
+
localFile.props.progress = 100;
|
|
297
|
+
localFile.handle = fileResponses[index].value.ID;
|
|
298
|
+
localFile.label = valueRef;
|
|
299
|
+
localFile.responseProps = {
|
|
300
|
+
pzInsKey: 'temp'
|
|
296
301
|
};
|
|
297
302
|
}
|
|
298
303
|
});
|
|
299
304
|
return tempFilesUploaded;
|
|
300
305
|
});
|
|
301
306
|
|
|
302
|
-
|
|
303
|
-
|
|
307
|
+
insertAttachments(fileResponses, pConn, multiAttachmentsInInlineEdit.current, {
|
|
308
|
+
allowMultiple,
|
|
309
|
+
isOldAttachment,
|
|
310
|
+
isMultiAttachmentInInlineEditTable,
|
|
311
|
+
attachmentCount: attachmentCount.current,
|
|
312
|
+
insert: true
|
|
313
|
+
} as any);
|
|
314
|
+
attachmentCount.current += fileResponses.length;
|
|
315
|
+
|
|
316
|
+
if (filesWithError.current.length === 0) {
|
|
317
|
+
clearFieldErrorMessages(pConn);
|
|
304
318
|
}
|
|
305
319
|
}
|
|
306
|
-
|
|
320
|
+
actionSequencer.deRegisterBlockingAction(contextName).catch(() => {});
|
|
307
321
|
})
|
|
308
322
|
.catch(error => {
|
|
309
|
-
// eslint-disable-next-line no-console
|
|
310
323
|
console.log(error);
|
|
311
324
|
setToggleUploadBegin(false);
|
|
312
325
|
});
|
|
313
|
-
}, [files
|
|
326
|
+
}, [files]);
|
|
314
327
|
|
|
315
328
|
useEffect(() => {
|
|
316
329
|
if (toggleUploadBegin && files.length > 0) {
|
|
317
|
-
|
|
330
|
+
actionSequencer.registerBlockingAction(contextName).then(() => {
|
|
331
|
+
uploadFiles();
|
|
332
|
+
});
|
|
318
333
|
}
|
|
319
334
|
}, [toggleUploadBegin]);
|
|
320
335
|
|
|
321
336
|
useEffect(() => {
|
|
322
|
-
if (
|
|
323
|
-
|
|
324
|
-
// block duplicate files to redux store when added 1 after another to prevent multiple duplicates being added to the case on submit
|
|
325
|
-
const tempFiles = files.filter(f => currentAttachmentList.findIndex(fr => fr.ID === f.ID) === -1 && !f.inProgress && f.responseProps);
|
|
326
|
-
|
|
327
|
-
const updatedAttList = [...currentAttachmentList, ...tempFiles];
|
|
328
|
-
updateAttachmentState(pConn, getAttachmentKey(valueRef), updatedAttList);
|
|
337
|
+
if (filesWithError.current.length === 0) {
|
|
338
|
+
clearFieldErrorMessages(pConn);
|
|
329
339
|
}
|
|
330
|
-
}, [
|
|
340
|
+
}, [filesWithError]);
|
|
341
|
+
|
|
342
|
+
const memoizedAttachments = useDeepMemo(() => {
|
|
343
|
+
return attachments;
|
|
344
|
+
}, [attachments]);
|
|
345
|
+
|
|
346
|
+
// Prepares new structure as per Cosmos component
|
|
347
|
+
const transformAttachments = () => {
|
|
348
|
+
const transformedFiles = [...attachments];
|
|
349
|
+
let deleteIndex = -1;
|
|
350
|
+
transformedFiles.forEach(attachment => {
|
|
351
|
+
attachment.props.id = attachment.responseProps.ID;
|
|
352
|
+
attachment.props.format = attachment.props.name.split('.').pop();
|
|
353
|
+
if (attachment.props.error) {
|
|
354
|
+
attachment.responseProps.deleteIndex = deleteIndex;
|
|
355
|
+
} else {
|
|
356
|
+
deleteIndex += 1;
|
|
357
|
+
attachment.responseProps.deleteIndex = deleteIndex;
|
|
358
|
+
}
|
|
359
|
+
if (attachment.props.thumbnail) {
|
|
360
|
+
thumbnailURLs.current.push(attachment.props.thumbnail);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
return transformedFiles;
|
|
365
|
+
};
|
|
331
366
|
|
|
332
367
|
useEffect(() => {
|
|
333
|
-
|
|
334
|
-
|
|
368
|
+
const caseID = PCore.getStoreValue(`.${getMappedValue('pyID')}`, PCore.getResolvedConstantValue('caseInfo.content'), contextName);
|
|
369
|
+
if (displayMode !== 'DISPLAY_ONLY') {
|
|
370
|
+
PCore.getPubSubUtils().subscribe(
|
|
371
|
+
PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION,
|
|
372
|
+
() => {
|
|
373
|
+
overrideLocalState.current = true;
|
|
374
|
+
},
|
|
375
|
+
caseID
|
|
376
|
+
);
|
|
335
377
|
}
|
|
336
|
-
}, [filesWithError]);
|
|
337
378
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
...current.map(f => {
|
|
344
|
-
return f.responseProps.pzInsKey && !f.responseProps.pzInsKey.includes('temp')
|
|
345
|
-
? {
|
|
346
|
-
...f,
|
|
347
|
-
props: {
|
|
348
|
-
...f.props,
|
|
349
|
-
onDelete: () => deleteFile(f)
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
: { ...f };
|
|
353
|
-
}),
|
|
354
|
-
...tempUploadedFiles
|
|
355
|
-
];
|
|
356
|
-
});
|
|
357
|
-
PCore.getPubSubUtils().subscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, resetAttachmentStoredState, caseID);
|
|
379
|
+
// When component mounts, only set local files state from redux.
|
|
380
|
+
const serverFiles = transformAttachments();
|
|
381
|
+
setFiles(serverFiles);
|
|
382
|
+
filesWithError.current = serverFiles.filter(file => file.props.error);
|
|
383
|
+
|
|
358
384
|
return () => {
|
|
359
|
-
|
|
385
|
+
if (displayMode !== 'DISPLAY_ONLY') {
|
|
386
|
+
PCore.getPubSubUtils().unsubscribe(PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.ASSIGNMENT_SUBMISSION, caseID);
|
|
387
|
+
}
|
|
360
388
|
};
|
|
361
389
|
}, []);
|
|
362
390
|
|
|
391
|
+
useEffect(() => {
|
|
392
|
+
if (overrideLocalState.current) {
|
|
393
|
+
const serverFiles = transformAttachments();
|
|
394
|
+
overrideLocalState.current = false;
|
|
395
|
+
attachmentCount.current = attachments.length;
|
|
396
|
+
filesWithError.current = [];
|
|
397
|
+
setFiles(serverFiles);
|
|
398
|
+
} else {
|
|
399
|
+
// 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
|
|
400
|
+
const errorFiles = attachments.filter(attachment => attachment.props.error);
|
|
401
|
+
if (errorFiles.length === 0 && filesWithError.current.length > 0) {
|
|
402
|
+
// Check if local file state contains error files and push those to redux
|
|
403
|
+
const uniqueKey = getMappedValue('pzInsKey');
|
|
404
|
+
const transformedErrorFiles = filesWithError.current.map(errorFile => {
|
|
405
|
+
const filename = errorFile.props.name;
|
|
406
|
+
return {
|
|
407
|
+
[uniqueKey]: errorFile.props.id,
|
|
408
|
+
FileName: filename,
|
|
409
|
+
Category: '',
|
|
410
|
+
FileExtension: filename.split('.').pop() ?? filename,
|
|
411
|
+
error: errorFile.props.error || null
|
|
412
|
+
};
|
|
413
|
+
});
|
|
414
|
+
let key = '';
|
|
415
|
+
let updatedAttachments: any = [];
|
|
416
|
+
if (allowMultiple || isOldAttachment) {
|
|
417
|
+
key = isOldAttachment ? `${valueRef}.pxResults` : valueRef;
|
|
418
|
+
const existingAttachments = PCore.getStoreValue(`.${key}`, pConn.getPageReference(), pConn.getContextName()) || [];
|
|
419
|
+
updatedAttachments = [...existingAttachments, ...transformedErrorFiles];
|
|
420
|
+
} else {
|
|
421
|
+
key = valueRef;
|
|
422
|
+
updatedAttachments = transformedErrorFiles[0];
|
|
423
|
+
}
|
|
424
|
+
PCore.getStateUtils().updateState(pConn.getContextName(), key, updatedAttachments, {
|
|
425
|
+
pageReference: pConn.getPageReference(),
|
|
426
|
+
isArrayDeepMerge: false,
|
|
427
|
+
removePropertyFromChangedList: true
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}, [memoizedAttachments]);
|
|
432
|
+
|
|
363
433
|
const handleClick = event => {
|
|
364
434
|
setAnchorEl(event.currentTarget);
|
|
365
435
|
};
|
|
@@ -380,13 +450,13 @@ export default function Attachment(props: AttachmentProps) {
|
|
|
380
450
|
id={valueRef}
|
|
381
451
|
name='upload-photo'
|
|
382
452
|
type='file'
|
|
383
|
-
multiple={allowMultiple
|
|
453
|
+
multiple={allowMultiple}
|
|
384
454
|
required={required}
|
|
385
455
|
disabled={disabled}
|
|
386
456
|
onChange={onFileAdded}
|
|
387
457
|
/>
|
|
388
458
|
<Button style={{ textTransform: 'none' }} variant='outlined' color='primary' component='span'>
|
|
389
|
-
{allowMultiple
|
|
459
|
+
{allowMultiple
|
|
390
460
|
? uploadMultipleFilesLabel === 'file_upload_text_multiple'
|
|
391
461
|
? 'Choose files'
|
|
392
462
|
: uploadMultipleFilesLabel
|
|
@@ -420,7 +490,7 @@ export default function Attachment(props: AttachmentProps) {
|
|
|
420
490
|
</div>
|
|
421
491
|
<div className='psdk-utility-action'>
|
|
422
492
|
{item.ID && (
|
|
423
|
-
<button type='button' className='psdk-utility-button' aria-label='Delete Attachment' onClick={() => deleteFile(item)}>
|
|
493
|
+
<button type='button' className='psdk-utility-button' aria-label='Delete Attachment' onClick={() => deleteFile(item, index)}>
|
|
424
494
|
<img className='psdk-utility-card-action-svg-icon' src={deleteIcon} />
|
|
425
495
|
</button>
|
|
426
496
|
)}
|
|
@@ -440,11 +510,14 @@ export default function Attachment(props: AttachmentProps) {
|
|
|
440
510
|
<MenuItem
|
|
441
511
|
style={{ fontSize: '14px' }}
|
|
442
512
|
key='download'
|
|
443
|
-
onClick={() =>
|
|
513
|
+
onClick={() => {
|
|
514
|
+
setAnchorEl(null);
|
|
515
|
+
onFileDownload(item.responseProps ? item.responseProps : {});
|
|
516
|
+
}}
|
|
444
517
|
>
|
|
445
518
|
Download
|
|
446
519
|
</MenuItem>
|
|
447
|
-
<MenuItem style={{ fontSize: '14px' }} key='delete' onClick={() => deleteFile(item)}>
|
|
520
|
+
<MenuItem style={{ fontSize: '14px' }} key='delete' onClick={() => deleteFile(item, index)}>
|
|
448
521
|
Delete
|
|
449
522
|
</MenuItem>
|
|
450
523
|
</Menu>
|
|
@@ -460,8 +533,8 @@ export default function Attachment(props: AttachmentProps) {
|
|
|
460
533
|
return (
|
|
461
534
|
<div className='file-upload-container'>
|
|
462
535
|
<span className={`label ${required ? 'file-label' : ''}`}>{label}</span>
|
|
463
|
-
{((files.length === 0 && allowMultiple
|
|
464
|
-
{validatemessage !== '' ? <span className='file-error'>{validatemessage}</span> : ''}
|
|
536
|
+
{((files.length === 0 && !allowMultiple) || allowMultiple) && <section>{content}</section>}
|
|
537
|
+
{validatemessage !== '' ? <span className='file-error'>{validatemessage}</span> : <span style={{ fontSize: '14px' }}>{helperText}</span>}
|
|
465
538
|
{files && files.length > 0 && <section>{fileDisplay}</section>}
|
|
466
539
|
</div>
|
|
467
540
|
);
|