@topconsultnpm/sdkui-react 6.21.0-t2 → 6.21.0-t3
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/NewComponents/ContextMenu/TMContextMenu.js +22 -1
- package/lib/components/NewComponents/ContextMenu/styles.d.ts +4 -4
- package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +6 -6
- package/lib/components/base/Styled.d.ts +1 -1
- package/lib/components/base/TMAreaManager.js +11 -0
- package/lib/components/base/TMCounterBar.d.ts +2 -2
- package/lib/components/base/TMCounterContainer.d.ts +2 -1
- package/lib/components/base/TMCustomButton.d.ts +1 -1
- package/lib/components/base/TMDataGrid.js +12 -2
- package/lib/components/base/TMDataGridExportForm.d.ts +2 -1
- package/lib/components/base/TMDataGridExportForm.js +19 -8
- package/lib/components/base/TMFileManager.d.ts +2 -1
- package/lib/components/base/TMFileManagerDataGridView.d.ts +2 -1
- package/lib/components/base/TMFileManagerDataGridView.js +4 -4
- package/lib/components/base/TMFileManagerThumbnailItems.d.ts +1 -1
- package/lib/components/base/TMFileManagerThumbnailItems.js +3 -3
- package/lib/components/base/TMFileManagerThumbnailsView.d.ts +1 -1
- package/lib/components/base/TMFileManagerUtils.d.ts +7 -0
- package/lib/components/base/TMFileManagerUtils.js +14 -1
- package/lib/components/base/TMLayout.d.ts +4 -4
- package/lib/components/base/TMList.d.ts +2 -1
- package/lib/components/base/TMListView.d.ts +1 -1
- package/lib/components/base/TMModal.js +2 -2
- package/lib/components/base/TMPopUp.d.ts +1 -0
- package/lib/components/base/TMPopUp.js +59 -2
- package/lib/components/base/TMSpinner.d.ts +5 -2
- package/lib/components/base/TMSpinner.js +33 -6
- package/lib/components/base/TMTab.d.ts +4 -3
- package/lib/components/base/TMTooltip.d.ts +1 -1
- package/lib/components/base/TMTreeView.d.ts +1 -1
- package/lib/components/base/TMTreeView.js +12 -15
- package/lib/components/base/TMUserAvatar.d.ts +2 -1
- package/lib/components/base/TMVilViewer.d.ts +2 -1
- package/lib/components/base/TMWaitPanel.d.ts +5 -2
- package/lib/components/base/TMWaitPanel.js +8 -6
- package/lib/components/choosers/TMDynDataListItemChooser.d.ts +1 -1
- package/lib/components/choosers/TMDynDataListItemChooser.js +6 -1
- package/lib/components/choosers/TMGroupChooser.js +1 -1
- package/lib/components/choosers/TMInvoiceRetrieveFormats.d.ts +2 -1
- package/lib/components/choosers/TMOrderRetrieveFormats.d.ts +2 -1
- package/lib/components/choosers/TMRelationChooser.d.ts +3 -3
- package/lib/components/choosers/TMUserChooser.d.ts +2 -2
- package/lib/components/editors/TMEditorStyled.d.ts +6 -6
- package/lib/components/editors/TMFormulaEditor.d.ts +2 -1
- package/lib/components/editors/TMFormulaEditor.js +98 -49
- package/lib/components/editors/TMHtmlContentDisplay.d.ts +2 -1
- package/lib/components/editors/TMHtmlEditor.d.ts +2 -1
- package/lib/components/editors/TMMetadataEditor.js +6 -2
- package/lib/components/editors/TMMetadataValues.js +23 -6
- package/lib/components/editors/TMTreeDropDown.d.ts +1 -1
- package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +1 -1
- package/lib/components/features/blog/TMBlogCommentForm.d.ts +2 -1
- package/lib/components/features/blog/TMBlogCommentForm.js +5 -2
- package/lib/components/features/documents/TMCopyToFolderForm.js +46 -24
- package/lib/components/features/documents/TMDcmtForm.js +19 -9
- package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +1 -1
- package/lib/components/features/documents/TMDcmtIcon.d.ts +2 -1
- package/lib/components/features/documents/TMDcmtIcon.js +1 -1
- package/lib/components/features/documents/TMDcmtPreview.d.ts +1 -1
- package/lib/components/features/documents/TMDcmtTasks.d.ts +2 -1
- package/lib/components/features/documents/TMDragDropOverlay.d.ts +1 -1
- package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +0 -2
- package/lib/components/features/documents/TMMasterDetailDcmts.js +4 -5
- package/lib/components/features/documents/TMMergeToPdfForm.d.ts +0 -2
- package/lib/components/features/documents/TMMergeToPdfForm.js +26 -10
- package/lib/components/features/documents/TMRelationViewer.js +8 -3
- package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +0 -13
- package/lib/components/features/documents/copyAndMergeDcmtsShared.js +1 -39
- package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +2 -1
- package/lib/components/features/search/TMMetadataOutputForm.d.ts +18 -0
- package/lib/components/features/search/TMMetadataOutputForm.js +225 -0
- package/lib/components/features/search/TMMetadataSorterForm.d.ts +18 -0
- package/lib/components/features/search/TMMetadataSorterForm.js +243 -0
- package/lib/components/features/search/TMSavedQuerySelector.d.ts +2 -2
- package/lib/components/features/search/TMSearch.d.ts +0 -2
- package/lib/components/features/search/TMSearch.js +2 -2
- package/lib/components/features/search/TMSearchQueryEditor.js +14 -8
- package/lib/components/features/search/TMSearchQueryPanel.js +249 -58
- package/lib/components/features/search/TMSearchResult.d.ts +1 -2
- package/lib/components/features/search/TMSearchResult.js +40 -20
- package/lib/components/features/search/TMSearchResultFloatingActionButton.d.ts +1 -1
- package/lib/components/features/search/TMSignatureInfoContent.d.ts +2 -1
- package/lib/components/features/search/TMViewHistoryDcmt.d.ts +2 -1
- package/lib/components/features/search/TMViewHistoryDcmt.js +1 -1
- package/lib/components/features/search/metadataFormHelper.d.ts +16 -0
- package/lib/components/features/search/metadataFormHelper.js +77 -0
- package/lib/components/features/tasks/TMTaskForm.d.ts +1 -1
- package/lib/components/features/tasks/TMTaskFormUtils.d.ts +10 -10
- package/lib/components/features/tasks/TMTasksAgenda.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksCalendar.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksHeader.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksPanelContent.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksUtilsView.d.ts +5 -5
- package/lib/components/features/tasks/TMTasksView.d.ts +1 -1
- package/lib/components/features/wg/TMWGsCopyMoveForm.d.ts +3 -2
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +8 -7
- package/lib/components/forms/Login/Chooser.d.ts +2 -2
- package/lib/components/forms/Login/TMLoginForm.js +15 -3
- package/lib/components/forms/TMChooserForm.d.ts +2 -1
- package/lib/components/forms/TMSaveForm.d.ts +4 -4
- package/lib/components/grids/TMBlogAttachments.d.ts +2 -1
- package/lib/components/grids/TMBlogAttachments.js +2 -2
- package/lib/components/grids/TMBlogHeader.d.ts +1 -1
- package/lib/components/grids/TMBlogsPost.d.ts +1 -1
- package/lib/components/grids/TMBlogsPost.js +5 -3
- package/lib/components/grids/TMBlogsPostUtils.d.ts +10 -9
- package/lib/components/grids/TMBlogsPostUtils.js +3 -1
- package/lib/components/grids/TMValidationItemsList.d.ts +2 -1
- package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +2 -1
- package/lib/components/layout/panelManager/TMPanelManagerContext.d.ts +2 -2
- package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +1 -1
- package/lib/components/layout/panelManager/TMPanelManagerWithPersistenceProvider.d.ts +2 -2
- package/lib/components/layout/panelManager/TMPanelWrapper.d.ts +2 -2
- package/lib/components/pages/TMPage.d.ts +1 -1
- package/lib/components/settings/SettingsAppearance.d.ts +2 -1
- package/lib/components/sidebar/TMAboutApp.d.ts +2 -1
- package/lib/components/sidebar/TMHeader.d.ts +3 -3
- package/lib/components/viewers/TMDataListItemViewer.d.ts +3 -2
- package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +3 -2
- package/lib/components/viewers/TMMidViewer.d.ts +2 -2
- package/lib/components/viewers/TMTidViewer.d.ts +2 -2
- package/lib/components/wizard/TMWizard.d.ts +1 -0
- package/lib/components/wizard/TMWizard.js +5 -3
- package/lib/helper/Enum_Localizator.js +1 -0
- package/lib/helper/MergePdfManager.d.ts +45 -0
- package/lib/helper/MergePdfManager.js +148 -0
- package/lib/helper/SDKUI_Globals.js +2 -1
- package/lib/helper/SDKUI_Localizator.d.ts +6 -0
- package/lib/helper/SDKUI_Localizator.js +60 -0
- package/lib/helper/TMCommandsContextMenu.d.ts +1 -1
- package/lib/helper/TMIcons.d.ts +278 -278
- package/lib/helper/TMPdfViewer.d.ts +2 -1
- package/lib/helper/TMToppyMessage.d.ts +2 -2
- package/lib/helper/TMUtils.d.ts +24 -20
- package/lib/helper/TMUtils.js +55 -0
- package/lib/helper/checkinCheckoutManager.d.ts +4 -3
- package/lib/helper/checkinCheckoutManager.js +29 -11
- package/lib/helper/helpers.d.ts +3 -2
- package/lib/helper/helpers.js +1 -0
- package/lib/hooks/useCheckInOutOperations.d.ts +4 -3
- package/lib/hooks/useDataUserIdItem.js +1 -1
- package/lib/hooks/useDcmtOperations.d.ts +18 -1
- package/lib/hooks/useDcmtOperations.js +235 -24
- package/lib/hooks/useDocumentOperations.d.ts +0 -2
- package/lib/hooks/useDocumentOperations.js +27 -10
- package/lib/hooks/useInputDialog.d.ts +2 -1
- package/lib/hooks/useRelatedDocuments.js +4 -4
- package/lib/services/platform_services.d.ts +7 -6
- package/lib/ts/types.d.ts +2 -1
- package/lib/ts/types.js +1 -0
- package/package.json +14 -7
|
@@ -246,7 +246,7 @@ const TMBlogCommentForm = (props) => {
|
|
|
246
246
|
alignItems: 'center',
|
|
247
247
|
padding: '0 8px',
|
|
248
248
|
}, children: currentDraftAttachments.length > 0 ? (currentDraftAttachments.map(draft => {
|
|
249
|
-
const tooltipContent = (_jsxs("div", { style: { textAlign: 'left' }, children: [_jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Name, ":"] }), " ", draft.name ?? '-'] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Author, ":"] }), " ", draft.updaterName ?? '-'] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Version, ":"] }), " ", draft.version] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Size, ":"] }), " ", formatBytes(draft.size ?? 0)] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.CreationTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(draft.creationTime)] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.LastUpdateTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(draft.lastUpdateTime)] })] }));
|
|
249
|
+
const tooltipContent = (_jsxs("div", { style: { textAlign: 'left' }, children: [_jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Name, ":"] }), " ", draft.name ?? '-'] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Author, ":"] }), " ", draft.updaterName ?? '-'] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Extension, ":"] }), " ", draft.ext ?? '-'] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Version, ":"] }), " ", draft.version] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Size, ":"] }), " ", formatBytes(draft.size ?? 0)] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.CreationTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(draft.creationTime)] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.LastUpdateTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(draft.lastUpdateTime)] })] }));
|
|
250
250
|
return _jsxs("div", { style: {
|
|
251
251
|
display: 'inline-flex',
|
|
252
252
|
alignItems: 'center',
|
|
@@ -264,7 +264,7 @@ const TMBlogCommentForm = (props) => {
|
|
|
264
264
|
}, onMouseLeave: (e) => {
|
|
265
265
|
e.currentTarget.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
|
|
266
266
|
e.currentTarget.style.backgroundColor = '#fff';
|
|
267
|
-
}, children: [draft.ext ? (
|
|
267
|
+
}, children: [draft.ext ? (_jsxs("span", { style: { marginRight: '10px', display: 'flex', alignItems: 'center', position: 'relative', width: draft.isSigned ? '30px' : undefined }, children: [getFileIcon(draft.ext, undefined, tooltipContent), draft.isSigned == 1 && _jsx("div", { style: { position: 'absolute', bottom: '-4px', right: '-7px' }, children: _jsx(TMTooltip, { content: "Documento firmato", children: _jsx(IconSignature, { fontSize: 28 }) }) })] })) : (_jsx(IconAttachment, { style: { marginRight: '5px' } })), _jsx("span", { style: { marginRight: '8px', display: 'flex', alignItems: 'center' }, children: draft.name }), draft.version && (_jsx("span", { style: {
|
|
268
268
|
display: 'inline-flex',
|
|
269
269
|
width: '20px',
|
|
270
270
|
height: '20px',
|
|
@@ -349,3 +349,6 @@ const TMAttachmentsView = (props) => {
|
|
|
349
349
|
}, []);
|
|
350
350
|
return _jsx(TMChooserForm, { title: SDKUI_Localizator.Attachments, allowMultipleSelection: true, allowApplyWithZeroSelection: true, startWithShowOnlySelectedItems: true, hasShowOnlySelectedItems: false, width: calcResponsiveSizes(deviceType, '700px', '700px', '95%'), height: "500px", manageUseLocalizedName: false, columns: dataColumns, showDefaultColumns: false, selectedIDs: selectedIDs, dataSource: dataSource, hasShowId: true, hideRefresh: false, onClose: onClose, onChoose: onChoose });
|
|
351
351
|
};
|
|
352
|
+
function IconSignature(props) {
|
|
353
|
+
return (_jsx("svg", { height: "1em", viewBox: "0 0 450 450", width: "1em", fill: "currentColor", ...props, children: _jsx("g", { children: _jsx("g", { children: _jsxs("g", { clipRule: "evenodd", fill: "rgb(0,0,0)", fillRule: "evenodd", children: [_jsx("path", { d: "m366.6 67.8 1.1-4c.4-1.5.6-3 .6-4.5 0-8.1-5.5-15.2-13.3-17.3-9.5-2.5-19.3 3.2-21.8 12.8l-20.4 77.9 34.6 9z" }), _jsx("path", { d: "m234.9 198.9h148.6v35.7h-148.6z", transform: "matrix(.253 -.968 .968 .253 21.311 461.088)" }), _jsx("path", { d: "m292.8 316 8.4 2.2 4.5-17.3-34.6-9.1-4.5 17.4 8.3 2.2z" }), _jsx("path", { d: "m275.3 319.7-12.7 14.7 5.4 40.3 24.4-32.5-3.9-19.1zm6.5 23.3c-.8 2.9-3.7 4.6-6.6 3.9s-4.6-3.7-3.9-6.6 3.7-4.6 6.6-3.9 4.6 3.7 3.9 6.6z" }), _jsx("path", { d: "m395.6 71.5-20.3-5.5-2 7.7 16.5 4.4-24.8 95c-.6 2.1.7 4.3 2.8 4.8.3.1.7.1 1 .1 1.8 0 3.4-1.2 3.8-3l25.8-98.8c.6-2-.7-4.2-2.8-4.7z" }), _jsx("path", { d: "" }), _jsx("path", { d: "m243.4 379.8c-1.8-1.2-4.3-.8-5.5 1.1-9.6 14.1-29.9 19.6-45.3 12.2-.5-.2-.9-.5-1.4-.7-3.5-1.8-7.9-4-12.8-2.7-2.7.7-4.7 2.3-6.5 3.6-1.5 1.2-2.8 2.2-3.9 2.2-2 .1-4-3-5-5.9-.2-.5-.4-1-.5-1.5-1.4-4.1-3.1-9.1-7.8-11.8-5.8-3.3-12.9-.9-17.4 3-2.4 2-4.2 4.4-6 6.7-1.2 1.5-2.3 2.9-3.4 4.1-7.5 7.9-20.3 10-30.2 5.6 7.6-6.9 13-15.5 15.4-24.9s1-21.1-7.8-25.8c-4.5-2.4-9.9-2.4-15.2.2-4.4 2.2-8.4 5.9-10.9 10.3-3.9 7-5.1 15.4-3.3 23.8 1.4 6.3 4.3 12 8.4 16.5-8.4 4.9-18.2 7.3-27.8 6.1-2.2-.3-4.2 1.2-4.5 3.4s1.2 4.2 3.4 4.5c2.1.3 4.1.4 6.2.4 10 0 20.1-3.1 29.1-9 6.1 3.7 13.5 5.4 21.1 4.7 8.5-.8 16.3-4.4 21.8-10.2 1.5-1.5 2.7-3.1 3.9-4.7 1.6-2.1 3.1-4 4.9-5.6 2.4-2 6-3.4 8.3-2.1 2.1 1.2 3.1 4.2 4.2 7.5.2.5.4 1.1.6 1.6 2.5 7 7.1 11.1 12.4 11.1h.6c3.6-.2 6.2-2.2 8.3-3.9 1.3-1 2.5-2 3.6-2.2 2-.5 4.5.8 7.2 2.1.5.3 1 .5 1.5.7 5.7 2.7 11.9 4 18.2 4 14.4 0 29-6.9 37.1-18.9 1.3-1.8.9-4.3-1-5.5zm-152.6 11.3c-8.1-8-10.4-21.8-4.8-31.7 2.5-4.5 7.5-8.2 12-8.2 1.2 0 2.3.3 3.4.8 5 2.7 5.5 10.6 3.9 16.8-2.2 8.7-7.5 16.5-14.5 22.3z" })] }) }) }) }));
|
|
354
|
+
}
|
|
@@ -32,6 +32,11 @@ const TMCopyToFolderForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationVi
|
|
|
32
32
|
// ---- Stato dei settings ----
|
|
33
33
|
const [settings, setSettings] = useState(() => buildInitialDownloadSettings(SDKUI_Globals.userSettings.documentDownloadSettings, SDKUI_Globals.userSettings.searchSettings.invoiceRetrieveFormat, SDKUI_Globals.userSettings.searchSettings.orderRetrieveFormat));
|
|
34
34
|
const [selectedItemsRelationViewer, setSelectedItemsRelationViewer] = useState([]);
|
|
35
|
+
// ---- Stato per la creazione ZIP (spinner separato) ----
|
|
36
|
+
const [isCreatingZip, setIsCreatingZip] = useState(false);
|
|
37
|
+
const [zipProgressText, setZipProgressText] = useState('');
|
|
38
|
+
const [zipProgressValue, setZipProgressValue] = useState(0);
|
|
39
|
+
const [zipProgressMax, setZipProgressMax] = useState(0);
|
|
35
40
|
const [hasSavedLayout, setHasSavedLayout] = useState(() => {
|
|
36
41
|
const saved = SDKUI_Globals.userSettings.documentDownloadSettings;
|
|
37
42
|
const defaults = new DocumentDownloadSettings();
|
|
@@ -171,7 +176,7 @@ const TMCopyToFolderForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationVi
|
|
|
171
176
|
retrieveOptions.invoiceRetrieveFormat = settings.invoiceFormat ?? SDKUI_Globals.userSettings.searchSettings.invoiceRetrieveFormat;
|
|
172
177
|
retrieveOptions.orderRetrieveFormat = settings.orderFormat ?? SDKUI_Globals.userSettings.searchSettings.orderRetrieveFormat;
|
|
173
178
|
if (settings.exportMode === 'copy') {
|
|
174
|
-
await downloadDcmtsAsync(dcmtInfosToDownload, DownloadTypes.Dcmt, 'download', writeFileToFolder,
|
|
179
|
+
await downloadDcmtsAsync({ inputDcmts: dcmtInfosToDownload, downloadType: DownloadTypes.Dcmt, downloadMode: 'download', onFileDownloaded: writeFileToFolder, skipConfirmation: true, retrieveOptions, useCache: false });
|
|
175
180
|
}
|
|
176
181
|
else if (settings.exportMode === 'zip') {
|
|
177
182
|
const zipEntries = [];
|
|
@@ -194,38 +199,55 @@ const TMCopyToFolderForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationVi
|
|
|
194
199
|
});
|
|
195
200
|
zipEntries.push({ filename: getUniqueZipFileName(targetFileName), data: file });
|
|
196
201
|
};
|
|
197
|
-
await downloadDcmtsAsync(dcmtInfosToDownload, DownloadTypes.Dcmt, 'download', collectFileForZip,
|
|
202
|
+
await downloadDcmtsAsync({ inputDcmts: dcmtInfosToDownload, downloadType: DownloadTypes.Dcmt, downloadMode: 'download', onFileDownloaded: collectFileForZip, skipConfirmation: true, retrieveOptions, useCache: false });
|
|
198
203
|
if (zipEntries.length > 0) {
|
|
199
204
|
const zipFileName = settings.zipFileName.trim().toLowerCase().endsWith('.zip')
|
|
200
205
|
? settings.zipFileName.trim()
|
|
201
206
|
: settings.zipFileName.trim() + '.zip';
|
|
202
207
|
// Crea il blob ZIP
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
208
|
+
setIsCreatingZip(true);
|
|
209
|
+
setZipProgressMax(zipEntries.length);
|
|
210
|
+
setZipProgressValue(0);
|
|
211
|
+
setZipProgressText(SDKUI_Localizator.CompressToZipFile);
|
|
212
|
+
try {
|
|
213
|
+
const zipBlob = await ZipManager.createZip(zipEntries, {
|
|
214
|
+
compressionLevel: 6,
|
|
215
|
+
password: settings.zipPassword.trim() || undefined,
|
|
216
|
+
onProgress: (current, total, filename) => {
|
|
217
|
+
setZipProgressValue(current);
|
|
218
|
+
setZipProgressText(`${SDKUI_Localizator.CompressToZipFile}: ${filename}`);
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
// Se c'è un handle della cartella: salva direttamente nella cartella selezionata
|
|
222
|
+
if (folderHandleRef.current) {
|
|
223
|
+
try {
|
|
224
|
+
// Per lo ZIP usa sempre rename automatico (come fa il browser)
|
|
225
|
+
const finalZipFileName = await generateUniqueFileName(folderHandleRef.current, zipFileName);
|
|
226
|
+
const fileHandle = await folderHandleRef.current.getFileHandle(finalZipFileName, { create: true });
|
|
227
|
+
const writable = await fileHandle.createWritable();
|
|
228
|
+
await writable.write(zipBlob);
|
|
229
|
+
await writable.close();
|
|
230
|
+
ShowAlert({ message: SDKUI_Localizator.ZipCreatedSavedInFolder.replaceParams(finalZipFileName, folderHandleRef.current.name), mode: 'success', duration: 5000, title: SDKUI_Localizator.CompressToZipFile });
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
console.error('Error saving ZIP to folder, fallback to standard download:', err);
|
|
234
|
+
// Fallback: download standard del browser
|
|
235
|
+
ZipManager.downloadBlob(zipBlob, zipFileName);
|
|
236
|
+
ShowAlert({ message: SDKUI_Localizator.ZipCreatedSavedInFolder.replaceParams(zipFileName, "Download"), mode: 'success', duration: 5000, title: SDKUI_Localizator.CompressToZipFile });
|
|
237
|
+
}
|
|
217
238
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
// Fallback: download standard del browser
|
|
239
|
+
else {
|
|
240
|
+
// Se non c'è un handle della cartella: download zip standard del browser
|
|
221
241
|
ZipManager.downloadBlob(zipBlob, zipFileName);
|
|
222
242
|
ShowAlert({ message: SDKUI_Localizator.ZipCreatedSavedInFolder.replaceParams(zipFileName, "Download"), mode: 'success', duration: 5000, title: SDKUI_Localizator.CompressToZipFile });
|
|
223
243
|
}
|
|
224
244
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
245
|
+
catch (err) {
|
|
246
|
+
console.error('Error creating ZIP:', err);
|
|
247
|
+
ShowAlert({ message: SDKUI_Localizator.Error, mode: 'error', duration: 5000, title: SDKUI_Localizator.CompressToZipFile });
|
|
248
|
+
}
|
|
249
|
+
finally {
|
|
250
|
+
setIsCreatingZip(false);
|
|
229
251
|
}
|
|
230
252
|
}
|
|
231
253
|
}
|
|
@@ -355,7 +377,7 @@ const TMCopyToFolderForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationVi
|
|
|
355
377
|
{ value: 'skip', display: SDKUI_Localizator.DoNotCopy },
|
|
356
378
|
{ value: 'rename', display: SDKUI_Localizator.CopyButRename },
|
|
357
379
|
], value: isUsingDefaultDownloads ? 'rename' : settings.fileExistsMode, direction: "row", disabled: isUsingDefaultDownloads, onValueChanged: (value) => updateSettings('fileExistsMode', value), fontSize: '0.9rem' }) }), isUsingDefaultDownloads && (_jsx("span", { style: { fontSize: '0.8rem', color: '#888', fontStyle: 'italic', marginTop: '4px', display: 'block' }, children: SDKUI_Localizator.BrowserAutoRenamesDuplicateFilesInDownloadsFolder }))] }) }), fileNamingRow, formatSelectorsRow] })), settings.exportMode === 'zip' && (_jsxs("div", { style: { display: 'flex', flexWrap: 'wrap', columnGap: '10px' }, children: [_jsxs("div", { style: { display: 'flex', flexWrap: 'wrap', columnGap: '10px', width: '100%' }, children: [folderSelector, _jsx("div", { style: { flex: '1 1 280px', minWidth: '280px' }, children: _jsx(TMTextBox, { label: SDKUI_Localizator.ZipFileName, value: settings.zipFileName, validationItems: zipValidationItems, autoComplete: "one-time-code", onValueChanged: (e) => updateSettings('zipFileName', e.target.value) }) }), _jsx("div", { style: { flex: '1 1 280px', minWidth: '280px' }, children: _jsx(TMTextBox, { label: SDKUI_Localizator.ProtectWithPasswordOptional, value: settings.zipPassword, type: "password", autoComplete: "one-time-code", onValueChanged: (e) => updateSettings('zipPassword', e.target.value) }) })] }), fileNamingRow, formatSelectorsRow] }))] })] }));
|
|
358
|
-
return (_jsx(
|
|
380
|
+
return (_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel || isCreatingZip, showWaitPanelPrimary: isCreatingZip ? true : showPrimary, showWaitPanelSecondary: isCreatingZip ? false : showSecondary, waitPanelTitle: isCreatingZip ? SDKUI_Localizator.CompressToZipFile : waitPanelTitle, waitPanelTextPrimary: isCreatingZip ? zipProgressText : waitPanelTextPrimary, waitPanelValuePrimary: isCreatingZip ? zipProgressValue : waitPanelValuePrimary, waitPanelMaxValuePrimary: isCreatingZip ? zipProgressMax : waitPanelMaxValuePrimary, waitPanelTextSecondary: isCreatingZip ? '' : waitPanelTextSecondary, waitPanelValueSecondary: isCreatingZip ? 0 : waitPanelValueSecondary, waitPanelMaxValueSecondary: isCreatingZip ? 0 : waitPanelMaxValueSecondary, isCancelable: !isCreatingZip, abortController: abortController, usePortal: true, children: _jsx(TMModal, { width: calcResponsiveSizes(deviceType, showTMRelationViewer ? '95%' : '950px', '95%', '95%'), height: showTMRelationViewer ? '95%' : 'auto', title: getTitle(), onClose: onClose, showCloseButton: true, children: _jsxs("div", { onContextMenu: (e) => e.preventDefault(), style: { display: 'flex', flexDirection: 'column', padding: '4px 4px 16px 4px', width: '100%', height: '100%', boxSizing: 'border-box', overflow: 'hidden' }, children: [showTMRelationViewer ? (_jsx("div", { style: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }, children: _jsxs(TMSplitterLayout, { direction: 'vertical', showSeparator: true, separatorSize: 8, separatorColor: 'transparent', separatorActiveColor: 'transparent', overflow: 'hidden', min: ["50", "50"], start: ['65%', '35%'], children: [_jsx(TMDownloadRelationViewerSection, { selectedDcmtInfos: selectedDcmtInfos, onSelectionChanged: setSelectedItemsRelationViewer, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), configSection] }, "TMCopyToFolder-relation-config") })) : (configSection), _jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', flexShrink: 0, marginTop: '12px' }, children: _jsxs("button", { disabled: !isFormValid() || (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0), onClick: run, style: {
|
|
359
381
|
display: 'flex',
|
|
360
382
|
alignItems: 'center',
|
|
361
383
|
justifyContent: 'center',
|
|
@@ -922,9 +922,14 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
|
|
|
922
922
|
setWaitPanelValueSecondaryLocal(pd.ProgressBarValue);
|
|
923
923
|
setWaitPanelTextSecondaryLocal(`${SDKUI_Localizator.Archiving}... ${Globalization.getNumberDisplayValue(pd.ProgressBarValue, true)} / ${Globalization.getNumberDisplayValue(maxFileSize, true)}`);
|
|
924
924
|
if (pd.ProgressBarValue === pd.ProgressBarMaximum) {
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
925
|
+
// Cambia subito il titolo alla fase 2 quando l'upload termina
|
|
926
|
+
// e mostra la progress bar primaria con valore iniziale 20%
|
|
927
|
+
setWaitPanelTitleLocal(SDKUI_Localizator.ArchivingCompletionInProgress);
|
|
928
|
+
setShowSecondaryLocal(false);
|
|
929
|
+
setShowPrimaryLocal(true);
|
|
930
|
+
setWaitPanelMaxValuePrimaryLocal(3);
|
|
931
|
+
setWaitPanelValuePrimaryLocal(0.6); // 20% di 3
|
|
932
|
+
setWaitPanelTextPrimaryLocal(SDKUI_Localizator.ArchivingCompletionInProgress);
|
|
928
933
|
firstBlock = true;
|
|
929
934
|
}
|
|
930
935
|
});
|
|
@@ -933,11 +938,22 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
|
|
|
933
938
|
const savedFormData = structuredClone(formDataRef.current);
|
|
934
939
|
setFormDataOrig(savedFormData);
|
|
935
940
|
formDataOrigRef.current = savedFormData;
|
|
941
|
+
// Fase 2: Completamento archiviazione (la progress bar primaria è già visibile dal callback)
|
|
942
|
+
// Imposta il titolo anche qui per sicurezza, nel caso il callback non venga eseguito
|
|
943
|
+
setWaitPanelTitleLocal(SDKUI_Localizator.ArchivingCompletionInProgress);
|
|
944
|
+
// Step 1/3: Aggiornamento griglia di ricerca
|
|
945
|
+
setWaitPanelValuePrimaryLocal(1);
|
|
936
946
|
await onRefreshSearchAsyncDatagrid?.();
|
|
947
|
+
// Step 2/3: Callback di salvataggio
|
|
948
|
+
setWaitPanelValuePrimaryLocal(2);
|
|
937
949
|
await onSavedAsyncCallback?.(ae.TID, newDID);
|
|
950
|
+
// Step 3/3: Aggiornamento lista metadati
|
|
951
|
+
setWaitPanelValuePrimaryLocal(3);
|
|
938
952
|
// Usa fromDTDRef.current invece di fromDTD per evitare stale closure,
|
|
939
953
|
// garantendo di avere il descrittore del tipo documento corrente.
|
|
940
954
|
await setMetadataList(fromDTDRef.current?.metadata ?? [], undefined, true, newDID);
|
|
955
|
+
// Breve pausa per mostrare il completamento al 100%
|
|
956
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
941
957
|
handleReset();
|
|
942
958
|
let newMruTIDS = updateMruTids(SDKUI_Globals.userSettings.archivingSettings.mruTIDs, TID);
|
|
943
959
|
SDKUI_Globals.userSettings.archivingSettings.mruTIDs = newMruTIDS;
|
|
@@ -951,12 +967,6 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
|
|
|
951
967
|
TMExceptionBoxManager.show({ exception: err });
|
|
952
968
|
}
|
|
953
969
|
finally {
|
|
954
|
-
setWaitPanelTextPrimaryLocal('');
|
|
955
|
-
setWaitPanelMaxValuePrimaryLocal(0);
|
|
956
|
-
setWaitPanelValuePrimaryLocal(0);
|
|
957
|
-
setWaitPanelTextSecondaryLocal('');
|
|
958
|
-
setWaitPanelMaxValueSecondaryLocal(0);
|
|
959
|
-
setWaitPanelValueSecondaryLocal(0);
|
|
960
970
|
setShowWaitPanelLocal(false);
|
|
961
971
|
setUseWaitPanelLocalState(false);
|
|
962
972
|
}
|
|
@@ -30,5 +30,5 @@ interface TMDcmtFormActionButtonsProps {
|
|
|
30
30
|
setShowMoreInfoTaskPopup: React.Dispatch<React.SetStateAction<boolean>>;
|
|
31
31
|
setShowMoreInfoTaskTask: React.Dispatch<React.SetStateAction<TaskDescriptor | undefined>>;
|
|
32
32
|
}
|
|
33
|
-
declare const TMDcmtFormActionButtons: (props: TMDcmtFormActionButtonsProps) =>
|
|
33
|
+
declare const TMDcmtFormActionButtons: (props: TMDcmtFormActionButtonsProps) => React.JSX.Element;
|
|
34
34
|
export default TMDcmtFormActionButtons;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import { DcmtInfo, DownloadModes, DownloadTypes } from '../../../ts';
|
|
2
3
|
import { FileDescriptor } from '@topconsultnpm/sdk-ts';
|
|
3
4
|
interface ITMDcmtIconProps {
|
|
@@ -14,5 +15,5 @@ interface ITMDcmtIconProps {
|
|
|
14
15
|
openInOffice?: (selectedDcmtsOrFocused: Array<DcmtInfo>) => Promise<void>;
|
|
15
16
|
onDownloadDcmtsAsync?: (inputDcmts: DcmtInfo[] | undefined, downloadType: DownloadTypes, downloadMode: DownloadModes, onFileDownloaded?: (dcmtFile: File | undefined) => void, confirmAttachments?: (list: FileDescriptor[]) => Promise<string[] | undefined>) => Promise<void>;
|
|
16
17
|
}
|
|
17
|
-
declare const TMDcmtIcon: ({ fileExtension, fileCount, isLexProt, isSigned, isMail, isShared, tid, did, downloadMode, tooltipContent, openInOffice, onDownloadDcmtsAsync }: ITMDcmtIconProps) =>
|
|
18
|
+
declare const TMDcmtIcon: ({ fileExtension, fileCount, isLexProt, isSigned, isMail, isShared, tid, did, downloadMode, tooltipContent, openInOffice, onDownloadDcmtsAsync }: ITMDcmtIconProps) => React.JSX.Element;
|
|
18
19
|
export default TMDcmtIcon;
|
|
@@ -41,7 +41,7 @@ const TMDcmtIcon = ({ fileExtension, fileCount, isLexProt, isSigned, isMail, isS
|
|
|
41
41
|
await onDownloadDcmtsAsync?.(dcmt, DownloadTypes.Dcmt, effectiveDownloadMode);
|
|
42
42
|
}
|
|
43
43
|
else {
|
|
44
|
-
await downloadDcmtsAsync(dcmt, DownloadTypes.Dcmt, effectiveDownloadMode);
|
|
44
|
+
await downloadDcmtsAsync({ inputDcmts: dcmt, downloadType: DownloadTypes.Dcmt, downloadMode: effectiveDownloadMode });
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
}, [tid, did, fileExtension, downloadMode, openInOffice, onDownloadDcmtsAsync, downloadDcmtsAsync]);
|
|
@@ -25,7 +25,7 @@ export declare const TMNothingToShow: ({ text, secondText, fileExt, icon }: {
|
|
|
25
25
|
secondText?: any;
|
|
26
26
|
fileExt?: string;
|
|
27
27
|
icon?: any;
|
|
28
|
-
}) =>
|
|
28
|
+
}) => React.JSX.Element;
|
|
29
29
|
export declare const StyledHeaderIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$color"> & {
|
|
30
30
|
$color: string;
|
|
31
31
|
}, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$color"> & {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React from "react";
|
|
1
2
|
import { FormModes, TaskContext } from "../../../ts";
|
|
2
3
|
import { HomeBlogPost, TaskDescriptor } from "@topconsultnpm/sdk-ts";
|
|
3
4
|
interface TMDcmtTasksProps {
|
|
@@ -12,5 +13,5 @@ interface TMDcmtTasksProps {
|
|
|
12
13
|
handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
|
|
13
14
|
onBack?: () => void;
|
|
14
15
|
}
|
|
15
|
-
declare const TMDcmtTasks: (props: TMDcmtTasksProps) =>
|
|
16
|
+
declare const TMDcmtTasks: (props: TMDcmtTasksProps) => React.JSX.Element;
|
|
16
17
|
export default TMDcmtTasks;
|
|
@@ -2,5 +2,5 @@ interface TMDragDropOverlayProps {
|
|
|
2
2
|
handleFile: (file: File) => void;
|
|
3
3
|
refocusAfterFileInput: () => void;
|
|
4
4
|
}
|
|
5
|
-
declare const TMDragDropOverlay: (props: TMDragDropOverlayProps) => import("react
|
|
5
|
+
declare const TMDragDropOverlay: (props: TMDragDropOverlayProps) => import("react").JSX.Element;
|
|
6
6
|
export default TMDragDropOverlay;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { HomeBlogPost, SearchResultDescriptor, TaskDescriptor } from '@topconsultnpm/sdk-ts';
|
|
3
3
|
import { RelationTreeItem } from './TMRelationViewer';
|
|
4
|
-
import { MergePdfManagerType } from '../../../helper';
|
|
5
4
|
import { DcmtInfo, TaskContext, MetadataValueDescriptorEx } from '../../../ts';
|
|
6
5
|
import { DeviceContextProps } from '../../base/TMDeviceProvider';
|
|
7
6
|
export type IRelatedDcmt = RelationTreeItem;
|
|
@@ -29,7 +28,6 @@ interface ITMMasterDetailDcmtsProps extends DeviceContextProps {
|
|
|
29
28
|
openS4TViewer?: boolean;
|
|
30
29
|
onOpenS4TViewerRequest?: (dcmtInfo: Array<DcmtInfo>, refreshDocumentPreview?: (() => Promise<void>)) => void;
|
|
31
30
|
onOpenPdfEditorRequest?: ((dcmtInfo: Array<DcmtInfo>, refreshDocumentPreview?: () => Promise<void>) => void);
|
|
32
|
-
mergePdfManager?: MergePdfManagerType;
|
|
33
31
|
datagridUtility?: {
|
|
34
32
|
onRefreshSearchAsyncDatagrid?: () => Promise<void>;
|
|
35
33
|
onRefreshDataRowsAsync?: (() => Promise<void>);
|
|
@@ -16,7 +16,7 @@ import TMDcmtForm from './TMDcmtForm';
|
|
|
16
16
|
import { TMNothingToShow } from './TMDcmtPreview';
|
|
17
17
|
import { Spinner, TMButton } from '../..';
|
|
18
18
|
import { useDocumentOperations } from '../../../hooks/useDocumentOperations';
|
|
19
|
-
const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, appendMasterDcmts, onTaskCreateRequest, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, datagridUtility, dcmtUtility,
|
|
19
|
+
const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, appendMasterDcmts, onTaskCreateRequest, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, datagridUtility, dcmtUtility, }) => {
|
|
20
20
|
const floatingBarContainerRef = useRef(null);
|
|
21
21
|
const [focusedItem, setFocusedItem] = useState();
|
|
22
22
|
const [selectedItems, setSelectedItems] = useState([]);
|
|
@@ -211,7 +211,6 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
211
211
|
openTaskFormHandler,
|
|
212
212
|
onRefreshAfterAddDcmtToFavs,
|
|
213
213
|
},
|
|
214
|
-
mergePdfManager: mergePdfManager
|
|
215
214
|
});
|
|
216
215
|
// Load dtdMaster when inputDcmts changes
|
|
217
216
|
useEffect(() => {
|
|
@@ -305,7 +304,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
305
304
|
position: contextMenuPosition,
|
|
306
305
|
onClose: () => setContextMenuVisible(false)
|
|
307
306
|
} })] }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged, handleNoRelationsFound, onItemContextMenu, contextMenuVisible, contextMenuPosition, refreshKey, focusedItemFormData]);
|
|
308
|
-
const tmFormOrResult = useMemo(() => _jsx(TMFormOrResultWrapper, { refreshKey: refreshKeyFormOrResult, deviceType: deviceType, focusedItem: focusedItem, onTaskCreateRequest: onTaskCreateRequest, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, handleNavigateToReference: handleNavigateToReference, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onRefreshSearchResults: onRefreshAllPanels
|
|
307
|
+
const tmFormOrResult = useMemo(() => _jsx(TMFormOrResultWrapper, { refreshKey: refreshKeyFormOrResult, deviceType: deviceType, focusedItem: focusedItem, onTaskCreateRequest: onTaskCreateRequest, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, handleNavigateToReference: handleNavigateToReference, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onRefreshSearchResults: onRefreshAllPanels }), [focusedItem, deviceType, allTasks, handleNavigateToWGs, handleNavigateToDossiers, handleNavigateToReference, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshAfterAddDcmtToFavs, refreshKeyFormOrResult]);
|
|
309
308
|
const initialPanelDimensions = {
|
|
310
309
|
'tmTreeView': { width: '50%', height: '100%' },
|
|
311
310
|
'tmFormOrResult': { width: '50%', height: '100%' },
|
|
@@ -424,11 +423,11 @@ const TMRelationViewerWrapper = ({ refreshKey, inputDcmts, isForMaster, showCurr
|
|
|
424
423
|
}, [onItemContextMenu, handleFocusedItemChanged]);
|
|
425
424
|
return (_jsx(TMRelationViewer, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, initialShowZeroDcmts: showZeroDcmts, customItemRender: customItemRender, allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: onSelectedItemsChanged, maxDepthLevel: 1, invertMasterNavigation: false, showExpandAllButton: true, onNoRelationsFound: onNoRelationsFound, onItemContextMenu: onContextMenu, focusedItemFormData: focusedItemFormData }, refreshKey));
|
|
426
425
|
};
|
|
427
|
-
const TMFormOrResultWrapper = ({ refreshKey, deviceType, focusedItem, onTaskCreateRequest, allTasks = [],
|
|
426
|
+
const TMFormOrResultWrapper = ({ refreshKey, deviceType, focusedItem, onTaskCreateRequest, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshSearchAsyncDatagrid, onRefreshSearchResults, handleNavigateToReference }) => {
|
|
428
427
|
const { setPanelVisibilityById } = useTMPanelManagerContext();
|
|
429
428
|
return (_jsx(_Fragment, { children: focusedItem?.isDcmt ?
|
|
430
429
|
_jsx(TMDcmtForm, { groupId: 'tmFormOrResult', TID: focusedItem?.tid, DID: focusedItem.did, allowButtonsRefs: true, isClosable: deviceType !== DeviceType.MOBILE, allowNavigation: false, allowRelations: deviceType !== DeviceType.MOBILE, showDcmtFormSidebar: false, onClose: () => { setPanelVisibilityById('tmTreeView', true); }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, onReferenceClick: handleNavigateToReference, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, focusedItem?.tid, focusedItem?.did), openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, datagridUtility: {
|
|
431
430
|
onRefreshSearchAsyncDatagrid,
|
|
432
431
|
} }, refreshKey) :
|
|
433
|
-
_jsx(TMSearchResult, { groupId: 'tmFormOrResult', isClosable: deviceType !== DeviceType.MOBILE, context: SearchResultContext.METADATA_SEARCH, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, searchResults: focusedItem?.searchResult ?? [], showSearchResultSidebar: false, showDcmtFormSidebar: false, onTaskCreateRequest: onTaskCreateRequest, onClose: () => { setPanelVisibilityById('tmTreeView', true); }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, editPdfForm: editPdfForm, onOpenPdfEditorRequest: onOpenPdfEditorRequest, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, enablePinIcons: false, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, showBackButton: false, onRefreshSearchAsyncDatagrid: onRefreshSearchResults,
|
|
432
|
+
_jsx(TMSearchResult, { groupId: 'tmFormOrResult', isClosable: deviceType !== DeviceType.MOBILE, context: SearchResultContext.METADATA_SEARCH, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, searchResults: focusedItem?.searchResult ?? [], showSearchResultSidebar: false, showDcmtFormSidebar: false, autoFocusFirstRow: false, onTaskCreateRequest: onTaskCreateRequest, onClose: () => { setPanelVisibilityById('tmTreeView', true); }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, editPdfForm: editPdfForm, onOpenPdfEditorRequest: onOpenPdfEditorRequest, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, enablePinIcons: false, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, showBackButton: false, onRefreshSearchAsyncDatagrid: onRefreshSearchResults, onReferenceClick: handleNavigateToReference }, refreshKey) }));
|
|
434
433
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { DcmtInfo } from '../../../ts';
|
|
3
|
-
import { MergePdfManagerType } from '../../../helper';
|
|
4
3
|
import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
|
|
5
4
|
import { TMCopyToFolderMode } from '../../../hooks/useDocumentOperations';
|
|
6
5
|
interface ITMMergeToPdfFormProps {
|
|
@@ -8,7 +7,6 @@ interface ITMMergeToPdfFormProps {
|
|
|
8
7
|
selectedDcmtInfos: Array<DcmtInfo>;
|
|
9
8
|
onClose: () => void;
|
|
10
9
|
showTMRelationViewer: boolean;
|
|
11
|
-
mergePdfManager?: MergePdfManagerType;
|
|
12
10
|
allTasks?: Array<TaskDescriptor>;
|
|
13
11
|
getAllTasks?: () => Promise<void>;
|
|
14
12
|
deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
|
|
@@ -15,17 +15,23 @@ import TMDownloadRelationViewerSection from './TMDownloadRelationViewerSection';
|
|
|
15
15
|
import { getDcmtInfosToDownload, getFloatingLabelStyle, isDirectoryPickerSupported, isPdfExt, MIN_PDF_FOR_MERGE, } from './copyAndMergeDcmtsShared';
|
|
16
16
|
import ShowAlert from '../../base/TMAlert';
|
|
17
17
|
import TMTooltip from '../../base/TMTooltip';
|
|
18
|
+
import MergePdfManager from '../../../helper/MergePdfManager';
|
|
18
19
|
/**
|
|
19
20
|
* Form per l'unione di più documenti PDF in un singolo file.
|
|
20
21
|
* Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared
|
|
21
22
|
* con TMCopyToFolderForm.
|
|
22
23
|
*/
|
|
23
|
-
const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationViewer,
|
|
24
|
+
const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationViewer, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
|
|
24
25
|
const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, } = useDcmtOperations();
|
|
25
26
|
const deviceType = useDeviceType();
|
|
26
|
-
const [pdfFileName, setPdfFileName] = useState(
|
|
27
|
+
const [pdfFileName, setPdfFileName] = useState(`${SDKUI_Localizator.Result.toLowerCase()}.pdf`);
|
|
27
28
|
const [destinationFolder, setDestinationFolder] = useState('Download');
|
|
28
29
|
const [selectedItemsRelationViewer, setSelectedItemsRelationViewer] = useState([]);
|
|
30
|
+
// ---- Stato per il merge PDF (progress bar) ----
|
|
31
|
+
const [isMergingPdf, setIsMergingPdf] = useState(false);
|
|
32
|
+
const [mergeProgressText, setMergeProgressText] = useState('');
|
|
33
|
+
const [mergeProgressValue, setMergeProgressValue] = useState(0);
|
|
34
|
+
const [mergeProgressMax, setMergeProgressMax] = useState(0);
|
|
29
35
|
// ---- Ref per la selezione cartella (File System Access API) ----
|
|
30
36
|
const folderHandleRef = useRef(null);
|
|
31
37
|
const skipSelectFolderRef = useRef(false);
|
|
@@ -137,7 +143,7 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
137
143
|
const collectFileForMerge = async (file, _dcmtInfo) => {
|
|
138
144
|
pdfFiles.push(file);
|
|
139
145
|
};
|
|
140
|
-
await downloadDcmtsAsync(pdfDcmtInfosToDownload, DownloadTypes.Dcmt, 'download', collectFileForMerge,
|
|
146
|
+
await downloadDcmtsAsync({ inputDcmts: pdfDcmtInfosToDownload, downloadType: DownloadTypes.Dcmt, downloadMode: 'download', onFileDownloaded: collectFileForMerge, skipConfirmation: true, retrieveOptions: rfo, useCache: false });
|
|
141
147
|
if (pdfFiles.length === 0) {
|
|
142
148
|
TMMessageBoxManager.show({ message: SDKUI_Localizator.NoFilesAvailableForMerge, buttons: [ButtonNames.OK] });
|
|
143
149
|
return null;
|
|
@@ -150,18 +156,25 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
150
156
|
TMMessageBoxManager.show({ message: SDKUI_Localizator.PleaseCorrectErrorsBeforeProceeding, buttons: [ButtonNames.OK] });
|
|
151
157
|
return;
|
|
152
158
|
}
|
|
153
|
-
if (!mergePdfManager) {
|
|
154
|
-
TMMessageBoxManager.show({ message: SDKUI_Localizator.PdfMergeFeatureNotAvailable, buttons: [ButtonNames.OK] });
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
159
|
const pdfFiles = await collectPdfFilesToMerge();
|
|
158
160
|
if (!pdfFiles)
|
|
159
161
|
return;
|
|
160
162
|
const finalName = pdfFileName.trim().toLowerCase().endsWith('.pdf') ? pdfFileName.trim() : pdfFileName.trim() + '.pdf';
|
|
163
|
+
// Inizializza progress bar per il merge
|
|
164
|
+
setIsMergingPdf(true);
|
|
165
|
+
setMergeProgressMax(pdfFiles.length);
|
|
166
|
+
setMergeProgressValue(0);
|
|
167
|
+
setMergeProgressText(SDKUI_Localizator.MergeToPdf);
|
|
161
168
|
try {
|
|
169
|
+
const mergeOptions = {
|
|
170
|
+
onProgress: (current, total, file) => {
|
|
171
|
+
setMergeProgressValue(current);
|
|
172
|
+
setMergeProgressText(`${SDKUI_Localizator.MergeToPdf}: ${file.name}`);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
162
175
|
// Se c'è una cartella selezionata (non Download di default), salva direttamente nella cartella
|
|
163
176
|
if (folderHandleRef.current) {
|
|
164
|
-
const mergedFile = await
|
|
177
|
+
const mergedFile = await MergePdfManager.mergeToFile(pdfFiles, finalName, mergeOptions);
|
|
165
178
|
const fileHandle = await folderHandleRef.current.getFileHandle(finalName, { create: true });
|
|
166
179
|
const writable = await fileHandle.createWritable();
|
|
167
180
|
await writable.write(mergedFile);
|
|
@@ -170,7 +183,7 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
170
183
|
}
|
|
171
184
|
else {
|
|
172
185
|
// Altrimenti usa il download standard del browser
|
|
173
|
-
await
|
|
186
|
+
await MergePdfManager.mergeAndDownload(pdfFiles, finalName, mergeOptions);
|
|
174
187
|
ShowAlert({ message: SDKUI_Localizator.PdfMergedSavedInFolder.replaceParams('Download'), mode: 'success', duration: 5000, title: SDKUI_Localizator.MergeToPdf });
|
|
175
188
|
}
|
|
176
189
|
}
|
|
@@ -179,6 +192,9 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
179
192
|
TMMessageBoxManager.show({ message: SDKUI_Localizator.PdfMergeError, buttons: [ButtonNames.OK] });
|
|
180
193
|
return;
|
|
181
194
|
}
|
|
195
|
+
finally {
|
|
196
|
+
setIsMergingPdf(false);
|
|
197
|
+
}
|
|
182
198
|
onClose();
|
|
183
199
|
};
|
|
184
200
|
// ---- Render della sezione configurazione (solo PDF file name + warning) ----
|
|
@@ -265,7 +281,7 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
265
281
|
? SDKUI_Localizator.FileNotPdfWillBeExcluded.replaceParams(extLabel)
|
|
266
282
|
: SDKUI_Localizator.FilesNotPdfWillBeExcluded.replaceParams(nonPdfSelectedItems.length.toString(), extLabel);
|
|
267
283
|
})() }))] })] }))] })] }));
|
|
268
|
-
return (_jsx(
|
|
284
|
+
return (_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel || isMergingPdf, showWaitPanelPrimary: isMergingPdf ? true : showPrimary, showWaitPanelSecondary: isMergingPdf ? false : showSecondary, waitPanelTitle: isMergingPdf ? SDKUI_Localizator.MergeToPdf : waitPanelTitle, waitPanelTextPrimary: isMergingPdf ? mergeProgressText : waitPanelTextPrimary, waitPanelValuePrimary: isMergingPdf ? mergeProgressValue : waitPanelValuePrimary, waitPanelMaxValuePrimary: isMergingPdf ? mergeProgressMax : waitPanelMaxValuePrimary, waitPanelTextSecondary: isMergingPdf ? '' : waitPanelTextSecondary, waitPanelValueSecondary: isMergingPdf ? 0 : waitPanelValueSecondary, waitPanelMaxValueSecondary: isMergingPdf ? 0 : waitPanelMaxValueSecondary, isCancelable: !isMergingPdf, abortController: abortController, usePortal: true, children: _jsx(TMModal, { width: calcResponsiveSizes(deviceType, showTMRelationViewer ? '90%' : '500px', showTMRelationViewer ? '90%' : '500px', '95%'), height: showTMRelationViewer ? '95%' : 'auto', title: getTitle(), onClose: onClose, showCloseButton: true, children: _jsxs("div", { onContextMenu: (e) => e.preventDefault(), style: { display: 'flex', flexDirection: 'column', gap: '16px', padding: '16px', width: '100%', height: '100%', boxSizing: 'border-box', overflow: 'hidden' }, children: [showTMRelationViewer ? (_jsx("div", { style: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }, children: _jsxs(TMSplitterLayout, { direction: 'vertical', showSeparator: true, separatorSize: 8, separatorColor: 'transparent', separatorActiveColor: 'transparent', overflow: 'hidden', min: ["50", "50"], start: ["70%", "30%"], children: [_jsx(TMDownloadRelationViewerSection, { selectedDcmtInfos: selectedDcmtInfos, onSelectionChanged: setSelectedItemsRelationViewer, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), configSection] }, "TMMergeToPdf-relation-config") })) : (configSection), _jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', flexShrink: 0, marginTop: '12px' }, children: _jsxs("button", { disabled: !isFormValid() || (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0) || !hasEnoughPdfForMerge, onClick: run, style: {
|
|
269
285
|
display: 'flex',
|
|
270
286
|
alignItems: 'center',
|
|
271
287
|
justifyContent: 'center',
|
|
@@ -1236,9 +1236,14 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
1236
1236
|
border: `1px solid ${TMColors.border_normal}`,
|
|
1237
1237
|
borderRadius: '4px',
|
|
1238
1238
|
cursor: 'pointer',
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
}, children: [allExpanded ? _jsx(IconChevronRight, { fontSize: 14 }) : _jsx(IconChevronDown, { fontSize: 14 }), _jsx("span", { children: allExpanded ? SDKUI_Localizator.CollapseAll : SDKUI_Localizator.ExpandAll })] }) })), _jsx("div", { style: { flex: 1, minHeight: 0, overflow: 'auto' }, children: _jsx(TMTreeView, { dataSource: mergedTreeData, itemRender: finalItemRender, calculateItemsForNode: calculateItemsForNode, onDataChanged: handleDataChanged, focusedItem: focusedItem, onFocusedItemChanged: handleFocusedItemChanged, allowMultipleSelection: allowMultipleSelection, selectedItems: selectedItems, itemsPerPage: 100, onSelectionChanged: handleSelectedItemsChanged, onItemContextMenu: onItemContextMenu
|
|
1239
|
+
whiteSpace: 'nowrap',
|
|
1240
|
+
outline: 'none'
|
|
1241
|
+
}, children: [_jsx("span", { style: { display: 'flex', alignItems: 'center' }, children: allExpanded ? _jsx(IconChevronRight, { fontSize: 14 }) : _jsx(IconChevronDown, { fontSize: 14 }) }), _jsx("span", { children: allExpanded ? SDKUI_Localizator.CollapseAll : SDKUI_Localizator.ExpandAll })] }) })), _jsx("div", { style: { flex: 1, minHeight: 0, overflow: 'auto' }, children: _jsx(TMTreeView, { dataSource: mergedTreeData, itemRender: finalItemRender, calculateItemsForNode: calculateItemsForNode, onDataChanged: handleDataChanged, focusedItem: focusedItem, onFocusedItemChanged: handleFocusedItemChanged, allowMultipleSelection: allowMultipleSelection, selectedItems: selectedItems, itemsPerPage: 100, onSelectionChanged: handleSelectedItemsChanged, onItemContextMenu: onItemContextMenu, shouldDelayFocusOnEvent: (node, e) => {
|
|
1242
|
+
// Ritarda il focus quando si clicca sull'icona del documento
|
|
1243
|
+
// per permettere al doppio click di funzionare
|
|
1244
|
+
const target = e.target;
|
|
1245
|
+
return !!target.closest('.tm-dcmt-icon');
|
|
1246
|
+
} }) }), showExpansionWaitPanel && (_jsx(TMWaitPanel, { title: isForMaster ? 'Caricamento documenti master' : 'Caricamento documenti dettaglio', showPrimary: true, textPrimary: expansionWaitPanelText, valuePrimary: expansionWaitPanelValue, maxValuePrimary: expansionWaitPanelMaxValue, isCancelable: true, abortController: expansionAbortController, onAbortClick: (abortController) => {
|
|
1242
1247
|
setTimeout(() => {
|
|
1243
1248
|
abortController?.abort();
|
|
1244
1249
|
}, 100);
|
|
@@ -19,19 +19,6 @@ export declare const isDirectoryPickerSupported: () => boolean;
|
|
|
19
19
|
* il file viene restituito senza firma.
|
|
20
20
|
*/
|
|
21
21
|
export declare const isPdfExt: (ext: string | null | undefined) => boolean;
|
|
22
|
-
/**
|
|
23
|
-
* Estrae l'estensione completa da un nome file, gestendo estensioni composite
|
|
24
|
-
* a più livelli come .PDF.P7M, .XML.P7M.TS, etc.
|
|
25
|
-
*
|
|
26
|
-
* Esempi:
|
|
27
|
-
* - "documento.pdf" -> ".pdf"
|
|
28
|
-
* - "DCMT_123.PDF.P7M" -> ".PDF.P7M"
|
|
29
|
-
* - "fattura.xml.p7m" -> ".xml.p7m"
|
|
30
|
-
* - "example.XML.P7M.TS" -> ".XML.P7M.TS"
|
|
31
|
-
* - "file.tar.gz" -> ".gz" (tar.gz non è gestito come firma)
|
|
32
|
-
* - "file" -> ""
|
|
33
|
-
*/
|
|
34
|
-
export declare const getFullFileExtension: (fileName: string, depth?: number) => string;
|
|
35
22
|
/**
|
|
36
23
|
* Estrae il nome base del file (senza estensione completa).
|
|
37
24
|
* Gestisce estensioni composite come .PDF.P7M
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DcmtTypeListCacheService, LayoutModes, SDK_Globals } from '@topconsultnpm/sdk-ts';
|
|
2
|
-
import { searchResultToMetadataValues, DocumentDownloadSettings } from '../../../helper';
|
|
2
|
+
import { searchResultToMetadataValues, DocumentDownloadSettings, getFullFileExtension } from '../../../helper';
|
|
3
3
|
import { TMColors } from '../../../utils/theme';
|
|
4
4
|
/** Numero minimo di file PDF necessari per poterli unire in un unico documento. */
|
|
5
5
|
export const MIN_PDF_FOR_MERGE = 2;
|
|
@@ -61,44 +61,6 @@ export const isPdfExt = (ext) => {
|
|
|
61
61
|
const normalized = ext.trim().toLowerCase().replace(/^\./, '');
|
|
62
62
|
return normalized === 'pdf' || normalized === 'pdf.p7m' || normalized === 'pdf.tsd' || normalized === 'pdf.m7m';
|
|
63
63
|
};
|
|
64
|
-
/**
|
|
65
|
-
* Estensioni di firma/marca temporale note che possono avvolgere altre estensioni.
|
|
66
|
-
* Es: file.pdf.p7m, file.xml.p7m, file.docx.p7m, file.xml.p7m.ts
|
|
67
|
-
*/
|
|
68
|
-
const SIGNATURE_EXTENSIONS = new Set(['p7m', 'p7s', 'm7m', 'tsd', 'tsr', 'ts']);
|
|
69
|
-
/** Profondità massima di ricorsione per la ricerca di estensioni composite */
|
|
70
|
-
const MAX_EXTENSION_DEPTH = 5;
|
|
71
|
-
/**
|
|
72
|
-
* Estrae l'estensione completa da un nome file, gestendo estensioni composite
|
|
73
|
-
* a più livelli come .PDF.P7M, .XML.P7M.TS, etc.
|
|
74
|
-
*
|
|
75
|
-
* Esempi:
|
|
76
|
-
* - "documento.pdf" -> ".pdf"
|
|
77
|
-
* - "DCMT_123.PDF.P7M" -> ".PDF.P7M"
|
|
78
|
-
* - "fattura.xml.p7m" -> ".xml.p7m"
|
|
79
|
-
* - "example.XML.P7M.TS" -> ".XML.P7M.TS"
|
|
80
|
-
* - "file.tar.gz" -> ".gz" (tar.gz non è gestito come firma)
|
|
81
|
-
* - "file" -> ""
|
|
82
|
-
*/
|
|
83
|
-
export const getFullFileExtension = (fileName, depth = 0) => {
|
|
84
|
-
if (!fileName || depth > MAX_EXTENSION_DEPTH)
|
|
85
|
-
return '';
|
|
86
|
-
const lastDotIndex = fileName.lastIndexOf('.');
|
|
87
|
-
if (lastDotIndex <= 0)
|
|
88
|
-
return '';
|
|
89
|
-
const lastExtension = fileName.substring(lastDotIndex + 1).toLowerCase();
|
|
90
|
-
// Se l'ultima estensione è una firma/marca, cerca ricorsivamente le estensioni precedenti
|
|
91
|
-
if (SIGNATURE_EXTENSIONS.has(lastExtension)) {
|
|
92
|
-
const nameWithoutLastExt = fileName.substring(0, lastDotIndex);
|
|
93
|
-
const innerExtension = getFullFileExtension(nameWithoutLastExt, depth + 1);
|
|
94
|
-
if (innerExtension) {
|
|
95
|
-
// Concatena l'estensione interna con quella corrente
|
|
96
|
-
return innerExtension + fileName.substring(lastDotIndex);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
// Estensione singola (o estensione base dopo le firme)
|
|
100
|
-
return fileName.substring(lastDotIndex);
|
|
101
|
-
};
|
|
102
64
|
/**
|
|
103
65
|
* Estrae il nome base del file (senza estensione completa).
|
|
104
66
|
* Gestisce estensioni composite come .PDF.P7M
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
1
2
|
import { DcmtInfo } from "../../../ts";
|
|
2
3
|
interface TMDcmtCheckoutInfoFormProps {
|
|
3
4
|
dtdName: string;
|
|
4
5
|
selectedDcmtOrFocused: DcmtInfo;
|
|
5
6
|
onClose: () => void;
|
|
6
7
|
}
|
|
7
|
-
declare const TMDcmtCheckoutInfoForm: (props: TMDcmtCheckoutInfoFormProps) =>
|
|
8
|
+
declare const TMDcmtCheckoutInfoForm: (props: TMDcmtCheckoutInfoFormProps) => React.JSX.Element;
|
|
8
9
|
export default TMDcmtCheckoutInfoForm;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { MetadataDescriptor, QueryDescriptor, SelectItem } from "@topconsultnpm/sdk-ts";
|
|
3
|
+
interface TMMetadataOutputFormProps {
|
|
4
|
+
/** QueryDescriptor da cui estrarre i metadati disponibili */
|
|
5
|
+
qd?: QueryDescriptor;
|
|
6
|
+
/** Lista di SelectItem attualmente selezionati */
|
|
7
|
+
selectedSelectItems?: SelectItem[];
|
|
8
|
+
/** Consente di visualizzare i metadati di sistema (es. MID < 150) */
|
|
9
|
+
allowSysMetadata?: boolean;
|
|
10
|
+
/** Funzione predicato per filtrare i metadati (es. solo quelli con permesso canView) */
|
|
11
|
+
filterMetadata?: (value: MetadataDescriptor, index: number, array: MetadataDescriptor[]) => unknown;
|
|
12
|
+
/** Callback chiamata alla chiusura del form */
|
|
13
|
+
onClose: () => void;
|
|
14
|
+
/** Callback chiamata quando l'utente conferma la selezione dei SelectItem */
|
|
15
|
+
onChoose?: (selectItems: SelectItem[] | undefined) => void;
|
|
16
|
+
}
|
|
17
|
+
declare const TMMetadataOutputForm: (props: TMMetadataOutputFormProps) => React.JSX.Element;
|
|
18
|
+
export default TMMetadataOutputForm;
|