@topconsultnpm/sdkui-react 6.21.0-dev2.4 → 6.21.0-dev2.40
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/base/TMAccordionNew.js +1 -0
- package/lib/components/base/TMAreaManager.js +19 -3
- package/lib/components/base/TMDataGrid.js +2 -2
- package/lib/components/base/TMPanel.d.ts +7 -4
- package/lib/components/base/TMPanel.js +58 -26
- package/lib/components/choosers/TMDistinctValues.js +35 -21
- package/lib/components/choosers/TMUserChooser.d.ts +4 -0
- package/lib/components/choosers/TMUserChooser.js +7 -5
- package/lib/components/editors/TMDateBox.js +4 -2
- package/lib/components/editors/TMFormulaEditor.d.ts +2 -0
- package/lib/components/editors/TMFormulaEditor.js +75 -21
- package/lib/components/editors/TMMetadataValues.js +2 -1
- package/lib/components/editors/TMRadioButton.js +2 -1
- package/lib/components/editors/TMTextArea.d.ts +2 -0
- package/lib/components/editors/TMTextArea.js +6 -3
- package/lib/components/editors/TMTextBox.d.ts +2 -0
- package/lib/components/editors/TMTextBox.js +3 -3
- package/lib/components/features/archive/TMArchive.js +1 -1
- package/lib/components/features/documents/TMCopyToFolderForm.d.ts +24 -0
- package/lib/components/features/documents/TMCopyToFolderForm.js +346 -0
- package/lib/components/features/documents/TMDcmtForm.d.ts +1 -0
- package/lib/components/features/documents/TMDcmtForm.js +107 -29
- package/lib/components/features/documents/TMDcmtFormActionButtons.js +17 -2
- package/lib/components/features/documents/TMDcmtPreview.d.ts +1 -0
- package/lib/components/features/documents/TMDcmtPreview.js +2 -2
- package/lib/components/features/documents/TMDcmtTasks.d.ts +1 -0
- package/lib/components/features/documents/TMDcmtTasks.js +2 -2
- package/lib/components/features/documents/TMDownloadRelationViewerSection.d.ts +23 -0
- package/lib/components/features/documents/TMDownloadRelationViewerSection.js +173 -0
- package/lib/components/features/documents/TMFileUploader.js +1 -1
- package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +4 -0
- package/lib/components/features/documents/TMMasterDetailDcmts.js +6 -5
- package/lib/components/features/documents/TMMergeToPdfForm.d.ts +26 -0
- package/lib/components/features/documents/TMMergeToPdfForm.js +276 -0
- package/lib/components/features/documents/TMRelationViewer.d.ts +13 -0
- package/lib/components/features/documents/TMRelationViewer.js +75 -6
- package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +54 -0
- package/lib/components/features/documents/copyAndMergeDcmtsShared.js +263 -0
- package/lib/components/features/search/SignatureParamsManager.d.ts +70 -0
- package/lib/components/features/search/SignatureParamsManager.js +145 -0
- package/lib/components/features/search/TMSavedQuerySelector.d.ts +2 -2
- package/lib/components/features/search/TMSavedQuerySelector.js +3 -2
- package/lib/components/features/search/TMSearch.d.ts +6 -1
- package/lib/components/features/search/TMSearch.js +16 -10
- package/lib/components/features/search/TMSearchQueryPanel.js +1 -1
- package/lib/components/features/search/TMSearchResult.d.ts +4 -0
- package/lib/components/features/search/TMSearchResult.js +86 -21
- package/lib/components/features/search/TMViewHistoryDcmt.js +1 -2
- package/lib/components/features/workflow/diagram/queryDescriptorParser.js +3 -6
- package/lib/components/forms/Login/TMLoginForm.d.ts +9 -0
- package/lib/components/forms/Login/TMLoginForm.js +44 -0
- package/lib/components/grids/TMBlogAttachments.d.ts +1 -0
- package/lib/components/grids/TMBlogAttachments.js +38 -12
- package/lib/components/grids/TMBlogsPost.js +7 -1
- package/lib/components/grids/TMBlogsPostUtils.js +11 -17
- package/lib/components/index.d.ts +1 -0
- package/lib/components/index.js +1 -0
- package/lib/components/pages/TMPage.js +3 -1
- package/lib/components/query/TMQueryEditor.js +1 -1
- package/lib/components/viewers/TMTidViewer.js +1 -1
- package/lib/helper/GlobalStyles.js +6 -0
- package/lib/helper/SDKUI_Globals.d.ts +15 -0
- package/lib/helper/SDKUI_Globals.js +15 -1
- package/lib/helper/SDKUI_Localizator.d.ts +52 -0
- package/lib/helper/SDKUI_Localizator.js +522 -0
- package/lib/helper/TMPdfViewer.js +25 -24
- package/lib/helper/TMUtils.d.ts +19 -0
- package/lib/helper/ZipManager.d.ts +56 -0
- package/lib/helper/ZipManager.js +104 -0
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/hooks/useDataUserIdItem.js +6 -4
- package/lib/hooks/useDcmtOperations.d.ts +9 -2
- package/lib/hooks/useDcmtOperations.js +31 -20
- package/lib/hooks/useDocumentOperations.d.ts +5 -0
- package/lib/hooks/useDocumentOperations.js +90 -20
- package/lib/hooks/useForm.js +5 -2
- package/lib/hooks/useResizeObserver.d.ts +1 -1
- package/lib/hooks/useResizeObserver.js +16 -15
- package/package.json +3 -2
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
|
+
import { DownloadTypes } from '../../../ts';
|
|
4
|
+
import { calcResponsiveSizes, IconFolderOpen, IconPlay, IconUndo, SDKUI_Globals, SDKUI_Localizator, } from '../../../helper';
|
|
5
|
+
import { DcmtOpers, FileFormats, GeneralRetrieveFormats, ResultTypes, RetrieveFileOptions, ValidationItem, } from '@topconsultnpm/sdk-ts';
|
|
6
|
+
import TMModal from '../../base/TMModal';
|
|
7
|
+
import { useDeviceType } from '../../base/TMDeviceProvider';
|
|
8
|
+
import TMTextBox from '../../editors/TMTextBox';
|
|
9
|
+
import TMButton from '../../base/TMButton';
|
|
10
|
+
import { ButtonNames, TMMessageBoxManager } from '../../base/TMPopUp';
|
|
11
|
+
import { useDcmtOperations } from '../../../hooks/useDcmtOperations';
|
|
12
|
+
import { TMLayoutWaitingContainer } from '../../base/TMWaitPanel';
|
|
13
|
+
import { TMSplitterLayout } from '../../base/TMLayout';
|
|
14
|
+
import { TMColors } from '../../../utils/theme';
|
|
15
|
+
import TMDownloadRelationViewerSection from './TMDownloadRelationViewerSection';
|
|
16
|
+
import { getDcmtInfosToDownload, getFloatingLabelStyle, isDirectoryPickerSupported, isPdfExt, MIN_PDF_FOR_MERGE, SPLITTER_MIN, SPLITTER_START_70_30, } from './copyAndMergeDcmtsShared';
|
|
17
|
+
import ShowAlert from '../../base/TMAlert';
|
|
18
|
+
/**
|
|
19
|
+
* Form per l'unione di più documenti PDF in un singolo file.
|
|
20
|
+
* Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared
|
|
21
|
+
* con TMCopyToFolderForm.
|
|
22
|
+
*/
|
|
23
|
+
const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationViewer, mergePdfManager, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
|
|
24
|
+
const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, } = useDcmtOperations();
|
|
25
|
+
const deviceType = useDeviceType();
|
|
26
|
+
const [pdfFileName, setPdfFileName] = useState('merged.pdf');
|
|
27
|
+
const [destinationFolder, setDestinationFolder] = useState('Download');
|
|
28
|
+
const [selectedItemsRelationViewer, setSelectedItemsRelationViewer] = useState([]);
|
|
29
|
+
// ---- Ref per la selezione cartella (File System Access API) ----
|
|
30
|
+
const folderHandleRef = useRef(null);
|
|
31
|
+
const skipSelectFolderRef = useRef(false);
|
|
32
|
+
const isPickerActiveRef = useRef(false);
|
|
33
|
+
const isUsingDefaultDownloads = destinationFolder === 'Download' && !folderHandleRef.current;
|
|
34
|
+
// ---- Handler dei campi cartella ----
|
|
35
|
+
const handleFolderValueChange = (e) => {
|
|
36
|
+
setDestinationFolder(e.target.value);
|
|
37
|
+
folderHandleRef.current = null;
|
|
38
|
+
};
|
|
39
|
+
const handleSelectFolder = async () => {
|
|
40
|
+
if (skipSelectFolderRef.current) {
|
|
41
|
+
skipSelectFolderRef.current = false;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (isPickerActiveRef.current)
|
|
45
|
+
return;
|
|
46
|
+
try {
|
|
47
|
+
isPickerActiveRef.current = true;
|
|
48
|
+
const dirHandle = await window.showDirectoryPicker({ mode: 'readwrite' });
|
|
49
|
+
folderHandleRef.current = dirHandle;
|
|
50
|
+
setDestinationFolder(dirHandle.name);
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
if (err.name !== 'AbortError') {
|
|
54
|
+
console.error('Errore nella selezione della cartella:', err);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
isPickerActiveRef.current = false;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const getTitle = () => {
|
|
62
|
+
const count = ` (${selectedDcmtInfos.length})`;
|
|
63
|
+
const modeLabelMap = {
|
|
64
|
+
onlySelected: 'Documenti selezionati',
|
|
65
|
+
customized: 'Documenti selezionati e i correlati',
|
|
66
|
+
};
|
|
67
|
+
const modeLabel = modeLabelMap[mode] || modeLabelMap.onlySelected;
|
|
68
|
+
return `Unisci in un file PDF - ${modeLabel}${count}`;
|
|
69
|
+
};
|
|
70
|
+
// ---- Validazione ----
|
|
71
|
+
const pdfValidationItems = [];
|
|
72
|
+
if (!pdfFileName.trim()) {
|
|
73
|
+
pdfValidationItems.push(new ValidationItem(ResultTypes.ERROR, 'Nome file PDF', SDKUI_Localizator.RequiredField));
|
|
74
|
+
}
|
|
75
|
+
// ---- Helper per file convertibili in PDF ----
|
|
76
|
+
const isConvertibleToPdfExt = (ext) => {
|
|
77
|
+
if (!ext)
|
|
78
|
+
return false;
|
|
79
|
+
const normalized = ext.toString().trim().toLowerCase().replace(/^\./, '');
|
|
80
|
+
return [
|
|
81
|
+
'doc', 'docx', 'dot', 'dotx', 'docm', 'dotm', 'odt', 'rtf', 'txt',
|
|
82
|
+
'csv', 'xls', 'xlsx',
|
|
83
|
+
'ppt', 'pptx', 'ppsx',
|
|
84
|
+
'htm', 'html', 'xml',
|
|
85
|
+
'bmp', 'jpg', 'jpeg', 'tif', 'tiff',
|
|
86
|
+
'eml', 'msg'
|
|
87
|
+
].includes(normalized);
|
|
88
|
+
};
|
|
89
|
+
// ---- Statistiche selezione PDF / convertibili / non-PDF ----
|
|
90
|
+
const convertibleSelectedItems = (() => {
|
|
91
|
+
if (showTMRelationViewer) {
|
|
92
|
+
return selectedItemsRelationViewer
|
|
93
|
+
.filter(i => i.isDcmt && isConvertibleToPdfExt(i.fileExt))
|
|
94
|
+
.map(i => ({ key: `${i.tid}_${i.did}`, ext: i.fileExt ?? undefined }));
|
|
95
|
+
}
|
|
96
|
+
return selectedDcmtInfos
|
|
97
|
+
.filter(d => isConvertibleToPdfExt(d.FILEEXT))
|
|
98
|
+
.map(d => ({ key: `${d.TID}_${d.DID}`, ext: d.FILEEXT }));
|
|
99
|
+
})();
|
|
100
|
+
const hasConvertibleSelected = convertibleSelectedItems.length > 0;
|
|
101
|
+
const nonPdfSelectedItems = (() => {
|
|
102
|
+
if (showTMRelationViewer) {
|
|
103
|
+
return selectedItemsRelationViewer
|
|
104
|
+
.filter(i => i.isDcmt && !isPdfExt(i.fileExt) && !isConvertibleToPdfExt(i.fileExt))
|
|
105
|
+
.map(i => ({ key: `${i.tid}_${i.did}`, ext: i.fileExt ?? undefined }));
|
|
106
|
+
}
|
|
107
|
+
return selectedDcmtInfos
|
|
108
|
+
.filter(d => !isPdfExt(d.FILEEXT) && !isConvertibleToPdfExt(d.FILEEXT))
|
|
109
|
+
.map(d => ({ key: `${d.TID}_${d.DID}`, ext: d.FILEEXT }));
|
|
110
|
+
})();
|
|
111
|
+
const hasNonPdfSelected = nonPdfSelectedItems.length > 0;
|
|
112
|
+
// Conteggio file unibili: PDF nativi + file convertibili
|
|
113
|
+
const mergeableSelectedCount = (() => {
|
|
114
|
+
if (showTMRelationViewer) {
|
|
115
|
+
return selectedItemsRelationViewer.filter(i => i.isDcmt && (isPdfExt(i.fileExt) || isConvertibleToPdfExt(i.fileExt))).length;
|
|
116
|
+
}
|
|
117
|
+
return selectedDcmtInfos.filter(d => isPdfExt(d.FILEEXT) || isConvertibleToPdfExt(d.FILEEXT)).length;
|
|
118
|
+
})();
|
|
119
|
+
const hasEnoughPdfForMerge = mergeableSelectedCount >= MIN_PDF_FOR_MERGE;
|
|
120
|
+
const isFormValid = () => pdfValidationItems.length === 0;
|
|
121
|
+
// ---- Recupero dei file PDF da unire (condiviso tra Esegui e Anteprima) ----
|
|
122
|
+
const collectPdfFilesToMerge = async () => {
|
|
123
|
+
const dcmtInfosToDownload = getDcmtInfosToDownload(selectedDcmtInfos, selectedItemsRelationViewer, showTMRelationViewer);
|
|
124
|
+
if (dcmtInfosToDownload.length === 0) {
|
|
125
|
+
TMMessageBoxManager.show({ message: 'Nessun documento selezionato.', buttons: [ButtonNames.OK] });
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
const nonPdfKeys = new Set(nonPdfSelectedItems.map(i => i.key));
|
|
129
|
+
const pdfDcmtInfosToDownload = dcmtInfosToDownload.filter(d => !nonPdfKeys.has(`${d.TID}_${d.DID}`));
|
|
130
|
+
if (pdfDcmtInfosToDownload.length === 0) {
|
|
131
|
+
TMMessageBoxManager.show({
|
|
132
|
+
message: 'Tra i documenti selezionati non è presente alcun file PDF o convertibile in PDF: l\'unione non può essere eseguita.',
|
|
133
|
+
buttons: [ButtonNames.OK]
|
|
134
|
+
});
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
if (pdfDcmtInfosToDownload.length < MIN_PDF_FOR_MERGE) {
|
|
138
|
+
TMMessageBoxManager.show({
|
|
139
|
+
message: `Tra i documenti selezionati è presente un solo file PDF o convertibile: per l'unione ne servono almeno ${MIN_PDF_FOR_MERGE}.`,
|
|
140
|
+
buttons: [ButtonNames.OK]
|
|
141
|
+
});
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
const pdfFiles = [];
|
|
145
|
+
const rfo = new RetrieveFileOptions();
|
|
146
|
+
rfo.retrieveReason = DcmtOpers.None;
|
|
147
|
+
rfo.generalRetrieveFormat = GeneralRetrieveFormats.Original;
|
|
148
|
+
rfo.cvtFormat = FileFormats.PDF;
|
|
149
|
+
rfo.invoiceRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.invoiceRetrieveFormat;
|
|
150
|
+
rfo.orderRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.orderRetrieveFormat;
|
|
151
|
+
const collectFileForMerge = async (file, _dcmtInfo) => {
|
|
152
|
+
pdfFiles.push(file);
|
|
153
|
+
};
|
|
154
|
+
await downloadDcmtsAsync(pdfDcmtInfosToDownload, DownloadTypes.Dcmt, 'download', collectFileForMerge, undefined, true, rfo, false);
|
|
155
|
+
if (pdfFiles.length === 0) {
|
|
156
|
+
TMMessageBoxManager.show({ message: 'Nessun file disponibile per l\'unione.', buttons: [ButtonNames.OK] });
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
return pdfFiles;
|
|
160
|
+
};
|
|
161
|
+
// ---- Esecuzione: scarica i PDF e li unisce ----
|
|
162
|
+
const run = async () => {
|
|
163
|
+
if (pdfValidationItems.length > 0) {
|
|
164
|
+
TMMessageBoxManager.show({ message: 'Per favore, correggi gli errori prima di procedere.', buttons: [ButtonNames.OK] });
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (!mergePdfManager) {
|
|
168
|
+
TMMessageBoxManager.show({ message: 'La funzionalità di unione PDF non è disponibile.', buttons: [ButtonNames.OK] });
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const pdfFiles = await collectPdfFilesToMerge();
|
|
172
|
+
if (!pdfFiles)
|
|
173
|
+
return;
|
|
174
|
+
const finalName = pdfFileName.trim().toLowerCase().endsWith('.pdf') ? pdfFileName.trim() : pdfFileName.trim() + '.pdf';
|
|
175
|
+
try {
|
|
176
|
+
// Se c'è una cartella selezionata (non Download di default), salva direttamente nella cartella
|
|
177
|
+
if (folderHandleRef.current) {
|
|
178
|
+
const mergedFile = await mergePdfManager.mergeToFile(pdfFiles, finalName);
|
|
179
|
+
const fileHandle = await folderHandleRef.current.getFileHandle(finalName, { create: true });
|
|
180
|
+
const writable = await fileHandle.createWritable();
|
|
181
|
+
await writable.write(mergedFile);
|
|
182
|
+
await writable.close();
|
|
183
|
+
ShowAlert({ message: `Il file PDF unito è stato salvato nella cartella "${folderHandleRef.current.name}".`, mode: 'success', duration: 3000, title: 'Successo' });
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
// Altrimenti usa il download standard del browser
|
|
187
|
+
await mergePdfManager.mergeAndDownload(pdfFiles, finalName);
|
|
188
|
+
ShowAlert({ message: 'Il file PDF unito è stato scaricato.', mode: 'success', duration: 3000, title: 'Successo' });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
console.error('Errore durante l\'unione dei file PDF o convertibili:', err);
|
|
193
|
+
TMMessageBoxManager.show({ message: 'Errore durante l\'unione dei file PDF o convertibili.', buttons: [ButtonNames.OK] });
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
onClose();
|
|
197
|
+
};
|
|
198
|
+
// ---- Render della sezione configurazione (solo PDF file name + warning) ----
|
|
199
|
+
const configSection = (_jsxs("div", { style: {
|
|
200
|
+
position: 'relative',
|
|
201
|
+
border: `1px solid ${TMColors.border_normal}`,
|
|
202
|
+
borderRadius: '8px',
|
|
203
|
+
padding: '8px',
|
|
204
|
+
height: showTMRelationViewer ? '100%' : undefined,
|
|
205
|
+
flex: showTMRelationViewer ? undefined : 1,
|
|
206
|
+
minHeight: 0,
|
|
207
|
+
marginTop: showTMRelationViewer ? '10px' : undefined,
|
|
208
|
+
display: 'flex',
|
|
209
|
+
flexDirection: 'column',
|
|
210
|
+
boxSizing: 'border-box'
|
|
211
|
+
}, children: [_jsx("span", { style: getFloatingLabelStyle(), title: "Parametri di configurazione (Unisci in PDF)", children: "Parametri di configurazione" }), _jsxs("div", { style: {
|
|
212
|
+
display: 'flex',
|
|
213
|
+
flexDirection: 'column',
|
|
214
|
+
gap: '12px',
|
|
215
|
+
flex: 1,
|
|
216
|
+
overflowY: 'auto',
|
|
217
|
+
minHeight: 0,
|
|
218
|
+
}, children: [_jsxs("div", { style: { display: 'grid', gridTemplateColumns: isDirectoryPickerSupported() ? '1fr 1fr' : '1fr', gap: '12px' }, children: [isDirectoryPickerSupported() && (_jsx(TMTextBox, { label: "Percorso", value: destinationFolder, onValueChanged: handleFolderValueChange, readOnly: true, placeHolder: "Download", onClick: handleSelectFolder, buttons: [
|
|
219
|
+
{
|
|
220
|
+
icon: _jsx(IconFolderOpen, {}),
|
|
221
|
+
text: 'Seleziona cartella',
|
|
222
|
+
onClick: handleSelectFolder
|
|
223
|
+
},
|
|
224
|
+
...(!isUsingDefaultDownloads ? [{
|
|
225
|
+
icon: _jsx(IconUndo, {}),
|
|
226
|
+
text: 'Ripristina Download',
|
|
227
|
+
onClick: () => {
|
|
228
|
+
skipSelectFolderRef.current = true;
|
|
229
|
+
setDestinationFolder('Download');
|
|
230
|
+
folderHandleRef.current = null;
|
|
231
|
+
}
|
|
232
|
+
}] : [])
|
|
233
|
+
] })), _jsx(TMTextBox, { label: "Nome file PDF", value: pdfFileName, validationItems: pdfValidationItems, autoComplete: "one-time-code", onValueChanged: (e) => setPdfFileName(e.target.value) })] }), hasConvertibleSelected && (_jsxs("div", { style: {
|
|
234
|
+
display: 'flex',
|
|
235
|
+
flexDirection: 'column',
|
|
236
|
+
gap: '6px',
|
|
237
|
+
padding: '8px 12px',
|
|
238
|
+
border: '1px solid #6db3f0',
|
|
239
|
+
borderRadius: '5px',
|
|
240
|
+
backgroundColor: '#e2f0fd',
|
|
241
|
+
color: '#00527a',
|
|
242
|
+
fontSize: '0.85rem'
|
|
243
|
+
}, children: [_jsx("strong", { children: "Nota" }), _jsx("ul", { style: { margin: 0, paddingLeft: '18px', display: 'flex', flexDirection: 'column', gap: '4px' }, children: _jsx("li", { children: (() => {
|
|
244
|
+
const extSet = Array.from(new Set(convertibleSelectedItems.map(i => (i.ext ?? '').toString().trim().toLowerCase().replace(/^\./, '')).filter(e => e.length > 0)));
|
|
245
|
+
const extLabel = extSet.length > 0
|
|
246
|
+
? ` (${extSet.map(e => '.' + e).join(', ')})`
|
|
247
|
+
: '';
|
|
248
|
+
return convertibleSelectedItems.length === 1
|
|
249
|
+
? `Un documento${extLabel} verrà convertito in PDF durante l'unione.`
|
|
250
|
+
: `${convertibleSelectedItems.length} documenti${extLabel} verranno convertiti in PDF durante l'unione.`;
|
|
251
|
+
})() }) })] })), (!hasEnoughPdfForMerge || hasNonPdfSelected || !isDirectoryPickerSupported()) && (_jsxs("div", { style: {
|
|
252
|
+
display: 'flex',
|
|
253
|
+
flexDirection: 'column',
|
|
254
|
+
gap: '6px',
|
|
255
|
+
padding: '8px 12px',
|
|
256
|
+
border: '1px solid #f0c36d',
|
|
257
|
+
borderRadius: '5px',
|
|
258
|
+
backgroundColor: '#fdf5e2',
|
|
259
|
+
color: '#7a5d00',
|
|
260
|
+
fontSize: '0.85rem'
|
|
261
|
+
}, children: [_jsx("strong", { children: "Attenzione" }), _jsxs("ul", { style: { margin: 0, paddingLeft: '18px', display: 'flex', flexDirection: 'column', gap: '4px' }, children: [!isDirectoryPickerSupported() && (_jsx("li", { children: "Il browser in uso non supporta la selezione della cartella. I file verranno scaricati nella cartella Download." })), !hasEnoughPdfForMerge && (_jsx("li", { children: mergeableSelectedCount === 0
|
|
262
|
+
? `Nessun file PDF o convertibile tra i selezionati: ne servono almeno ${MIN_PDF_FOR_MERGE}.`
|
|
263
|
+
: `Solo 1 file PDF o convertibile tra i selezionati: ne servono almeno ${MIN_PDF_FOR_MERGE}.` })), hasNonPdfSelected && (_jsx("li", { children: (() => {
|
|
264
|
+
const extSet = Array.from(new Set(nonPdfSelectedItems.map(i => (i.ext ?? '').toString().trim().toLowerCase().replace(/^\./, '')).filter(e => e.length > 0)));
|
|
265
|
+
const extLabel = extSet.length > 0
|
|
266
|
+
? ` (${extSet.map(e => '.' + e).join(', ')})`
|
|
267
|
+
: '';
|
|
268
|
+
return nonPdfSelectedItems.length === 1
|
|
269
|
+
? `Un documento non è in formato PDF${extLabel} e sarà escluso dall'unione.`
|
|
270
|
+
: `${nonPdfSelectedItems.length} documenti non sono in formato PDF${extLabel} e saranno esclusi dall'unione.`;
|
|
271
|
+
})() }))] })] }))] })] }));
|
|
272
|
+
return (_jsx(TMModal, { width: calcResponsiveSizes(deviceType, showTMRelationViewer ? '90%' : '500px', showTMRelationViewer ? '90%' : '500px', '95%'), height: calcResponsiveSizes(deviceType, showTMRelationViewer ? '90%' : '500px', showTMRelationViewer ? '90%' : '500px', showTMRelationViewer ? '95%' : '500px'), title: getTitle(), onClose: onClose, showCloseButton: true, children: _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, 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: SPLITTER_MIN, start: SPLITTER_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', gap: '12px', flexShrink: 0 }, children: _jsx(TMButton, { caption: mergeableSelectedCount === 0 ? 'Unisci in PDF' : `Unisci ${mergeableSelectedCount} file in PDF`, icon: _jsx(IconPlay, {}), color: 'success', showTooltip: false, disabled: !isFormValid()
|
|
273
|
+
|| (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0)
|
|
274
|
+
|| !hasEnoughPdfForMerge, onClick: run }) })] }) }) }));
|
|
275
|
+
};
|
|
276
|
+
export default TMMergeToPdfForm;
|
|
@@ -50,6 +50,8 @@ export interface TMRelationViewerProps {
|
|
|
50
50
|
onFocusedItemChanged?: (item: RelationTreeItem | null) => void;
|
|
51
51
|
/** Callback when selected items change */
|
|
52
52
|
onSelectedItemsChanged?: (items: RelationTreeItem[]) => void;
|
|
53
|
+
/** Callback fired when the internal tree data changes, providing a flattened list of all items currently rendered */
|
|
54
|
+
onAllItemsChanged?: (items: RelationTreeItem[]) => void;
|
|
53
55
|
/** Callback when a document is double-clicked */
|
|
54
56
|
onDocumentDoubleClick?: (tid: number, did: number, name?: string) => void;
|
|
55
57
|
/** Custom item renderer (full control). Return undefined to use default renderer. */
|
|
@@ -109,6 +111,17 @@ export interface TMRelationViewerProps {
|
|
|
109
111
|
* (used in master-detail context)
|
|
110
112
|
*/
|
|
111
113
|
focusedItemFormData?: MetadataValueDescriptorEx[];
|
|
114
|
+
/**
|
|
115
|
+
* If true, shows a toolbar button to expand/collapse all tree nodes.
|
|
116
|
+
* Default: false
|
|
117
|
+
*/
|
|
118
|
+
showExpandAllButton?: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* If true, all tree nodes are expanded by default on initial load.
|
|
121
|
+
* If false (default), uses the standard initial expansion behavior
|
|
122
|
+
* (root container + first document + first correlation folder).
|
|
123
|
+
*/
|
|
124
|
+
defaultExpandAll?: boolean;
|
|
112
125
|
}
|
|
113
126
|
/**
|
|
114
127
|
* Check if document type has detail relations
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import { DcmtTypeListCacheService, SDK_Globals, DataColumnTypes, MetadataFormats, SystemMIDs, MetadataDataDomains, RelationCacheService, RelationTypes, UserListCacheService } from "@topconsultnpm/sdk-ts";
|
|
4
|
-
import { genUniqueId, IconFolder, IconBackhandIndexPointingRight, IconCircleInfo, getDcmtCicoStatus } from '../../../helper';
|
|
4
|
+
import { genUniqueId, IconFolder, IconBackhandIndexPointingRight, IconCircleInfo, getDcmtCicoStatus, IconChevronDown, IconChevronRight } from '../../../helper';
|
|
5
5
|
import { TMColors } from '../../../utils/theme';
|
|
6
|
-
import { StyledDivHorizontal, StyledBadge } from '../../base/Styled';
|
|
6
|
+
import { StyledDivHorizontal, StyledBadge, StyledToolbarForm } from '../../base/Styled';
|
|
7
7
|
import TMTreeView from '../../base/TMTreeView';
|
|
8
8
|
import { TMWaitPanel } from '../../base/TMWaitPanel';
|
|
9
9
|
import TMDataListItemViewer from '../../viewers/TMDataListItemViewer';
|
|
@@ -136,12 +136,14 @@ export const searchResultToDataSource = async (searchResult, hideSysMetadata) =>
|
|
|
136
136
|
}
|
|
137
137
|
return output;
|
|
138
138
|
};
|
|
139
|
-
const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndicator = true, allowShowZeroDcmts = true, initialShowZeroDcmts = false, allowedTIDs, allowMultipleSelection = false, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onDocumentDoubleClick, customItemRender, customDocumentStyle, customMainContainerContent, customDocumentContent, showMetadataNames = false, maxDepthLevel = 2, invertMasterNavigation = true, additionalStaticItems, showMainDocument = true, labelMainContainer, onNoRelationsFound, onItemContextMenu, focusedItemFormData = [] }) => {
|
|
139
|
+
const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndicator = true, allowShowZeroDcmts = true, initialShowZeroDcmts = false, allowedTIDs, allowMultipleSelection = false, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onAllItemsChanged, onDocumentDoubleClick, customItemRender, customDocumentStyle, customMainContainerContent, customDocumentContent, showMetadataNames = false, maxDepthLevel = 2, invertMasterNavigation = true, additionalStaticItems, showMainDocument = true, labelMainContainer, onNoRelationsFound, onItemContextMenu, focusedItemFormData = [], showExpandAllButton = false, defaultExpandAll = false }) => {
|
|
140
140
|
// State
|
|
141
141
|
const [dcmtTypes, setDcmtTypes] = useState([]);
|
|
142
142
|
const [treeData, setTreeData] = useState([]);
|
|
143
143
|
const [showZeroDcmts, setShowZeroDcmts] = useState(initialShowZeroDcmts);
|
|
144
144
|
const [staticItemsState, setStaticItemsState] = useState([]);
|
|
145
|
+
const [allExpanded, setAllExpanded] = useState(defaultExpandAll);
|
|
146
|
+
const initialExpandAllAppliedRef = React.useRef(false);
|
|
145
147
|
const [showWaitPanel, setShowWaitPanel] = useState(false);
|
|
146
148
|
const [waitPanelTextPrimary, setWaitPanelTextPrimary] = useState('');
|
|
147
149
|
const [waitPanelValuePrimary, setWaitPanelValuePrimary] = useState(0);
|
|
@@ -271,7 +273,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
271
273
|
console.error('❌ Error loading detail documents:', error);
|
|
272
274
|
}
|
|
273
275
|
return items;
|
|
274
|
-
}, [allowedTIDs
|
|
276
|
+
}, [allowedTIDs]);
|
|
275
277
|
/**
|
|
276
278
|
* Recursively retrieve master documents
|
|
277
279
|
*/
|
|
@@ -734,6 +736,24 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
734
736
|
// and may contain custom properties that would be lost by the spread operator
|
|
735
737
|
return [...treeData, ...itemsToMerge];
|
|
736
738
|
}, [treeData, additionalStaticItems, staticItemsState]);
|
|
739
|
+
/**
|
|
740
|
+
* Notify parent with a flattened list of all items whenever the merged tree data changes.
|
|
741
|
+
*/
|
|
742
|
+
useEffect(() => {
|
|
743
|
+
if (!onAllItemsChanged)
|
|
744
|
+
return;
|
|
745
|
+
const flatten = (items) => {
|
|
746
|
+
const out = [];
|
|
747
|
+
for (const it of items) {
|
|
748
|
+
out.push(it);
|
|
749
|
+
if (it.items && Array.isArray(it.items)) {
|
|
750
|
+
out.push(...flatten(it.items));
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
return out;
|
|
754
|
+
};
|
|
755
|
+
onAllItemsChanged(flatten(mergedTreeData));
|
|
756
|
+
}, [mergedTreeData, onAllItemsChanged]);
|
|
737
757
|
/**
|
|
738
758
|
* Load data when inputs change
|
|
739
759
|
*/
|
|
@@ -1118,7 +1138,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
1118
1138
|
}
|
|
1119
1139
|
}
|
|
1120
1140
|
return (_jsxs("div", { onDoubleClick: handleDoubleClick, style: documentStyle, children: [item.did && item.tid && showCurrentDcmtIndicator && inputDcmts?.some(d => d.DID === item.did && d.TID === item.tid) ? _jsx(IconBackhandIndexPointingRight, { fontSize: 22, overflow: 'visible' }) : _jsx(_Fragment, {}), item.values && (_jsx(TMDcmtIcon, { tid: item.values?.TID?.value, did: item.values?.DID?.value, fileExtension: item.values?.FILEEXT?.value, fileCount: item.values?.FILECOUNT?.value, isLexProt: item.values?.IsLexProt?.value, isMail: item.values?.ISMAIL?.value, isShared: item.values?.ISSHARED?.value, isSigned: item.values?.ISSIGNED?.value, downloadMode: 'openInNewWindow' })), checkoutStatusIcon, metadataContent] }));
|
|
1121
|
-
}, [onDocumentDoubleClick, showCurrentDcmtIndicator, inputDcmts, customMainContainerContent, customDocumentStyle, customDocumentContent, showMetadataNames, showMainDocument,
|
|
1141
|
+
}, [onDocumentDoubleClick, showCurrentDcmtIndicator, inputDcmts, customMainContainerContent, customDocumentStyle, customDocumentContent, showMetadataNames, showMainDocument, allUsers]);
|
|
1122
1142
|
/**
|
|
1123
1143
|
* Wrapper renderer that handles custom rendering if provided
|
|
1124
1144
|
*/
|
|
@@ -1148,6 +1168,42 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
1148
1168
|
const handleSelectedItemsChanged = useCallback((items) => {
|
|
1149
1169
|
onSelectedItemsChanged?.(items);
|
|
1150
1170
|
}, [onSelectedItemsChanged]);
|
|
1171
|
+
/**
|
|
1172
|
+
* Recursively set the `expanded` property on every node that has children loaded.
|
|
1173
|
+
* Nodes without `items` are left untouched (will be loaded lazily on user click).
|
|
1174
|
+
*/
|
|
1175
|
+
const setExpandedRecursively = useCallback((nodes, expanded) => {
|
|
1176
|
+
if (!nodes || !Array.isArray(nodes))
|
|
1177
|
+
return [];
|
|
1178
|
+
return nodes.map(node => {
|
|
1179
|
+
const hasChildren = Array.isArray(node.items) && node.items.length > 0;
|
|
1180
|
+
const newItems = hasChildren ? setExpandedRecursively(node.items, expanded) : node.items;
|
|
1181
|
+
// Only toggle expansion if the node is expandable (container/doc with children or marked expandible)
|
|
1182
|
+
const canExpand = hasChildren || node.isExpandible;
|
|
1183
|
+
return { ...node, expanded: canExpand ? expanded : node.expanded, items: newItems };
|
|
1184
|
+
});
|
|
1185
|
+
}, []);
|
|
1186
|
+
const handleToggleExpandAll = useCallback(() => {
|
|
1187
|
+
const next = !allExpanded;
|
|
1188
|
+
setAllExpanded(next);
|
|
1189
|
+
setTreeData(prev => setExpandedRecursively(prev, next));
|
|
1190
|
+
setStaticItemsState(prev => setExpandedRecursively(prev, next));
|
|
1191
|
+
userInteractedWithStaticItemsRef.current = true;
|
|
1192
|
+
}, [allExpanded, setExpandedRecursively]);
|
|
1193
|
+
/**
|
|
1194
|
+
* Apply defaultExpandAll once on initial tree load.
|
|
1195
|
+
*/
|
|
1196
|
+
useEffect(() => {
|
|
1197
|
+
if (!defaultExpandAll)
|
|
1198
|
+
return;
|
|
1199
|
+
if (initialExpandAllAppliedRef.current)
|
|
1200
|
+
return;
|
|
1201
|
+
if (!treeData || treeData.length === 0)
|
|
1202
|
+
return;
|
|
1203
|
+
initialExpandAllAppliedRef.current = true;
|
|
1204
|
+
setTreeData(prev => setExpandedRecursively(prev, true));
|
|
1205
|
+
setStaticItemsState(prev => setExpandedRecursively(prev, true));
|
|
1206
|
+
}, [defaultExpandAll, treeData, setExpandedRecursively]);
|
|
1151
1207
|
/**
|
|
1152
1208
|
* Handle data changed - separate static items from dynamic tree data
|
|
1153
1209
|
*/
|
|
@@ -1169,7 +1225,20 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
1169
1225
|
return null;
|
|
1170
1226
|
return _jsx("div", { style: { padding: '20px', textAlign: 'center', color: '#666' }, children: "Nessuna relazione disponibile." });
|
|
1171
1227
|
}
|
|
1172
|
-
return (_jsxs(
|
|
1228
|
+
return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', height: '100%', minHeight: 0, width: '100%' }, children: [showExpandAllButton && (_jsx(StyledToolbarForm, { style: { flexShrink: 0 }, children: _jsxs("button", { type: "button", onClick: handleToggleExpandAll, title: allExpanded ? 'Comprimi tutto' : 'Espandi tutto', style: {
|
|
1229
|
+
display: 'inline-flex',
|
|
1230
|
+
alignItems: 'center',
|
|
1231
|
+
gap: '4px',
|
|
1232
|
+
padding: '4px 8px',
|
|
1233
|
+
fontSize: '0.8rem',
|
|
1234
|
+
color: TMColors.primary,
|
|
1235
|
+
background: 'transparent',
|
|
1236
|
+
border: `1px solid ${TMColors.border_normal}`,
|
|
1237
|
+
borderRadius: '4px',
|
|
1238
|
+
cursor: 'pointer',
|
|
1239
|
+
lineHeight: 1,
|
|
1240
|
+
whiteSpace: 'nowrap'
|
|
1241
|
+
}, children: [allExpanded ? _jsx(IconChevronRight, { fontSize: 14 }) : _jsx(IconChevronDown, { fontSize: 14 }), _jsx("span", { children: allExpanded ? 'Comprimi tutto' : 'Espandi tutto' })] }) })), _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 }) }), 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) => {
|
|
1173
1242
|
setTimeout(() => {
|
|
1174
1243
|
abortController?.abort();
|
|
1175
1244
|
}, 100);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DcmtInfo } from '../../../ts';
|
|
3
|
+
import { DocumentDownloadSettings, FileNamingMode } from '../../../helper';
|
|
4
|
+
import { IRelatedDcmt } from './TMMasterDetailDcmts';
|
|
5
|
+
export declare const SPLITTER_MIN: string[];
|
|
6
|
+
export declare const SPLITTER_START_60_40: string[];
|
|
7
|
+
export declare const SPLITTER_START_70_30: string[];
|
|
8
|
+
export declare const SPLITTER_START_75_25: string[];
|
|
9
|
+
/** Numero minimo di file PDF necessari per poterli unire in un unico documento. */
|
|
10
|
+
export declare const MIN_PDF_FOR_MERGE = 2;
|
|
11
|
+
/** Stile per le etichette "floating" posizionate sopra i bordi dei container */
|
|
12
|
+
export declare const getFloatingLabelStyle: () => React.CSSProperties;
|
|
13
|
+
/** Chiave univoca per un IRelatedDcmt basata sulla coppia tid+did */
|
|
14
|
+
export declare const getDcmtKey: (item: IRelatedDcmt) => string;
|
|
15
|
+
/** Deduplica gli IRelatedDcmt in base alla coppia tid+did (mantiene la prima occorrenza) */
|
|
16
|
+
export declare const dedupeByTidDid: (items: ReadonlyArray<IRelatedDcmt>) => Array<IRelatedDcmt>;
|
|
17
|
+
/** Verifica se showDirectoryPicker è supportato (Chrome, Edge) */
|
|
18
|
+
export declare const isDirectoryPickerSupported: () => boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Verifica se un'estensione (con o senza punto iniziale, case-insensitive) è "pdf".
|
|
21
|
+
*/
|
|
22
|
+
export declare const isPdfExt: (ext: string | null | undefined) => boolean;
|
|
23
|
+
/** Sanitizza il nome file per Windows (rimuove caratteri illegali e limita la lunghezza) */
|
|
24
|
+
export declare const sanitizeFileName: (fileName: string, fallbackName: string, maxLength?: number) => string;
|
|
25
|
+
/** Verifica se un file esiste nella cartella (FileSystemDirectoryHandle) */
|
|
26
|
+
export declare const fileExists: (dirHandle: FileSystemDirectoryHandle, fileName: string) => Promise<boolean>;
|
|
27
|
+
/** Genera un nome file univoco aggiungendo un suffisso numerico se già esistente */
|
|
28
|
+
export declare const generateUniqueFileName: (dirHandle: FileSystemDirectoryHandle, originalName: string) => Promise<string>;
|
|
29
|
+
/** Recupera il nome leggibile del tipo documento (cache) */
|
|
30
|
+
export declare const getTypeName: (tid: number | undefined) => Promise<string>;
|
|
31
|
+
/** Formatta un valore convertendo le date in formato dd-MM-yyyy [HH-mm-ss] */
|
|
32
|
+
export declare const formatMetadataValue: (value: string) => string;
|
|
33
|
+
/** Recupera i metadati filtrati (primi 5 con mid > 100 e valore presente), concatenati con separatorChar */
|
|
34
|
+
export declare const getFilteredMetadata: (tid: number, did: number, separatorChar: string) => Promise<string | null>;
|
|
35
|
+
/** Opzioni di naming necessarie per generare il nome del file di destinazione */
|
|
36
|
+
export interface IFileNamingOptions {
|
|
37
|
+
fileNamingMode: FileNamingMode;
|
|
38
|
+
separatorChar: string;
|
|
39
|
+
}
|
|
40
|
+
/** Genera il nome file di destinazione in base alle impostazioni di naming */
|
|
41
|
+
export declare const generateTargetFileName: (file: File, dcmtInfo: DcmtInfo, options: IFileNamingOptions) => Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Restituisce i documenti da scaricare:
|
|
44
|
+
* - se è visibile il TMRelationViewer, usa gli isDcmt selezionati al suo interno
|
|
45
|
+
* - altrimenti restituisce i selectedDcmtInfos passati come prop
|
|
46
|
+
*/
|
|
47
|
+
export declare const getDcmtInfosToDownload: (selectedDcmtInfos: Array<DcmtInfo>, selectedItemsRelationViewer: Array<IRelatedDcmt>, showTMRelationViewer: boolean) => Array<DcmtInfo>;
|
|
48
|
+
/**
|
|
49
|
+
* Costruisce lo stato iniziale di DocumentDownloadSettings combinando:
|
|
50
|
+
* - i valori salvati in userSettings (se presenti)
|
|
51
|
+
* - i default della classe
|
|
52
|
+
* Nota: destinationFolder e zipPassword vengono sempre resettati per sicurezza.
|
|
53
|
+
*/
|
|
54
|
+
export declare const buildInitialDownloadSettings: (saved: DocumentDownloadSettings | undefined, defaultInvoiceFormat: DocumentDownloadSettings["invoiceFormat"], defaultOrderFormat: DocumentDownloadSettings["orderFormat"]) => DocumentDownloadSettings;
|