@topconsultnpm/sdkui-react 6.21.0-dev2.37 → 6.21.0-dev2.39
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/choosers/TMUserChooser.d.ts +4 -0
- package/lib/components/choosers/TMUserChooser.js +7 -5
- package/lib/components/features/documents/TMCopyToFolderForm.d.ts +8 -0
- package/lib/components/features/documents/TMCopyToFolderForm.js +56 -16
- package/lib/components/features/documents/TMDownloadRelationViewerSection.d.ts +8 -0
- package/lib/components/features/documents/TMDownloadRelationViewerSection.js +126 -108
- package/lib/components/features/documents/TMMergeToPdfForm.d.ts +8 -0
- package/lib/components/features/documents/TMMergeToPdfForm.js +146 -34
- package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +3 -2
- package/lib/components/features/documents/copyAndMergeDcmtsShared.js +3 -2
- package/lib/hooks/useDcmtOperations.d.ts +2 -1
- package/lib/hooks/useDcmtOperations.js +2 -0
- package/lib/hooks/useDocumentOperations.js +5 -5
- package/package.json +2 -2
|
@@ -16,6 +16,8 @@ interface ITMUserChooserProps extends ITMChooserProps {
|
|
|
16
16
|
initialShowChooser?: boolean;
|
|
17
17
|
/** Allow showing all users with toggle button */
|
|
18
18
|
allowShowAllUsers?: boolean;
|
|
19
|
+
/** If true, uses UserListCacheService.GetAllAdminAsync() instead of GetAllAsync() */
|
|
20
|
+
adminMode?: boolean;
|
|
19
21
|
/** Funzione per aggiornare lo stato di apertura della modale */
|
|
20
22
|
updateIsModalOpen?: (isOpen: boolean) => void;
|
|
21
23
|
}
|
|
@@ -30,6 +32,8 @@ interface ITMUserChooserFormProps extends ITMChooserFormProps<UserDescriptor> {
|
|
|
30
32
|
hideShowId?: boolean;
|
|
31
33
|
/** Allow showing all users with toggle button */
|
|
32
34
|
allowShowAllUsers?: boolean;
|
|
35
|
+
/** If true, uses UserListCacheService.GetAllAdminAsync() instead of GetAllAsync() */
|
|
36
|
+
adminMode?: boolean;
|
|
33
37
|
}
|
|
34
38
|
export declare const TMUserChooserForm: React.FunctionComponent<ITMUserChooserFormProps>;
|
|
35
39
|
export declare const TMUserIcon: ({ ud }: {
|
|
@@ -8,7 +8,7 @@ import TMSummary from '../editors/TMSummary';
|
|
|
8
8
|
import TMChooserForm from '../forms/TMChooserForm';
|
|
9
9
|
import TMButton from '../base/TMButton';
|
|
10
10
|
import TMDataUserIdItemViewer from '../viewers/TMDataUserIdItemViewer';
|
|
11
|
-
const TMUserChooser = ({ labelColor, titleForm, filter, readOnly = false, icon, width, dataSource, backgroundColor, openChooserBySingleClick, buttons = [], disabled = false, showBorder = true, hideRefresh = false, hideShowId = false, elementStyle, allowMultipleSelection, values, isModifiedWhen, label, placeHolder, validationItems = [], onValueChanged, showClearButton, initialShowChooser = false, allowShowAllUsers = false, updateIsModalOpen }) => {
|
|
11
|
+
const TMUserChooser = ({ labelColor, titleForm, filter, readOnly = false, icon, width, dataSource, backgroundColor, openChooserBySingleClick, buttons = [], disabled = false, showBorder = true, hideRefresh = false, hideShowId = false, elementStyle, allowMultipleSelection, values, isModifiedWhen, label, placeHolder, validationItems = [], onValueChanged, showClearButton, initialShowChooser = false, allowShowAllUsers = false, adminMode = false, updateIsModalOpen }) => {
|
|
12
12
|
const [showChooser, setShowChooser] = useState(initialShowChooser);
|
|
13
13
|
useEffect(() => {
|
|
14
14
|
setShowChooser(initialShowChooser);
|
|
@@ -24,14 +24,14 @@ const TMUserChooser = ({ labelColor, titleForm, filter, readOnly = false, icon,
|
|
|
24
24
|
updateIsModalOpen?.(true);
|
|
25
25
|
}
|
|
26
26
|
}, elementStyle: elementStyle, isModifiedWhen: isModifiedWhen, openEditorOnSummaryClick: openChooserBySingleClick, label: label, template: renderTemplate(), onClearClick: showClearButton ? () => { onValueChanged?.([]); } : undefined, validationItems: validationItems }), showChooser &&
|
|
27
|
-
_jsx(TMUserChooserForm, { title: titleForm, allowMultipleSelection: allowMultipleSelection, hasShowOnlySelectedItems: true, dataSource: dataSource, filter: filter, selectedIDs: values, hideRefresh: hideRefresh, hideShowId: hideShowId, allowShowAllUsers: allowShowAllUsers, onClose: () => {
|
|
27
|
+
_jsx(TMUserChooserForm, { title: titleForm, allowMultipleSelection: allowMultipleSelection, hasShowOnlySelectedItems: true, dataSource: dataSource, filter: filter, selectedIDs: values, hideRefresh: hideRefresh, hideShowId: hideShowId, allowShowAllUsers: allowShowAllUsers, adminMode: adminMode, onClose: () => {
|
|
28
28
|
setShowChooser(false);
|
|
29
29
|
summaryInputRef.current?.focus();
|
|
30
30
|
updateIsModalOpen?.(false);
|
|
31
31
|
}, onChoose: (IDs) => { onValueChanged?.(IDs); } })] }));
|
|
32
32
|
};
|
|
33
33
|
export default TMUserChooser;
|
|
34
|
-
export const TMUserChooserForm = ({ allowMultipleSelection, columns, hideRefresh = false, hideShowId = false, startWithShowOnlySelectedItems = true, filter, title, hasShowOnlySelectedItems, width, height, selectedIDs, dataSource, onClose, onChoose, allowShowAllUsers = false }) => {
|
|
34
|
+
export const TMUserChooserForm = ({ allowMultipleSelection, columns, hideRefresh = false, hideShowId = false, startWithShowOnlySelectedItems = true, filter, title, hasShowOnlySelectedItems, width, height, selectedIDs, dataSource, onClose, onChoose, allowShowAllUsers = false, adminMode = false }) => {
|
|
35
35
|
const [currentDataSource, setCurrentDataSource] = useState(dataSource);
|
|
36
36
|
const [showingAllUsers, setShowingAllUsers] = useState(false);
|
|
37
37
|
const dataColumns = useMemo(() => {
|
|
@@ -45,8 +45,10 @@ export const TMUserChooserForm = ({ allowMultipleSelection, columns, hideRefresh
|
|
|
45
45
|
const getItems = async (refreshCache) => {
|
|
46
46
|
TMSpinner.show({ description: `${SDKUI_Localizator.Loading} - ${SDK_Localizator.Users} ...` });
|
|
47
47
|
if (refreshCache)
|
|
48
|
-
UserListCacheService.RemoveAll();
|
|
49
|
-
let allUsers =
|
|
48
|
+
adminMode ? UserListCacheService.RemoveAllAdmin() : UserListCacheService.RemoveAll();
|
|
49
|
+
let allUsers = adminMode
|
|
50
|
+
? await UserListCacheService.GetAllAdminAsync()
|
|
51
|
+
: await UserListCacheService.GetAllAsync();
|
|
50
52
|
let users = filter ? allUsers?.filter(filter) : allUsers;
|
|
51
53
|
TMSpinner.hide();
|
|
52
54
|
return users;
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { DcmtInfo } from '../../../ts';
|
|
3
|
+
import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
|
|
3
4
|
import { TMCopyToFolderMode } from '../../../hooks/useDocumentOperations';
|
|
4
5
|
interface ITMCopyToFolderFormProps {
|
|
5
6
|
mode: TMCopyToFolderMode;
|
|
6
7
|
selectedDcmtInfos: Array<DcmtInfo>;
|
|
7
8
|
onClose: () => void;
|
|
8
9
|
showTMRelationViewer: boolean;
|
|
10
|
+
allTasks?: Array<TaskDescriptor>;
|
|
11
|
+
getAllTasks?: () => Promise<void>;
|
|
12
|
+
deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
|
|
13
|
+
addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
|
|
14
|
+
editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
|
|
15
|
+
handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
|
|
16
|
+
handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
|
|
9
17
|
}
|
|
10
18
|
/**
|
|
11
19
|
* Form per la copia/zip dei documenti in una cartella locale.
|
|
@@ -19,13 +19,13 @@ import TMCheckBox from '../../editors/TMCheckBox';
|
|
|
19
19
|
import ShowAlert from '../../base/TMAlert';
|
|
20
20
|
import { TMColors } from '../../../utils/theme';
|
|
21
21
|
import TMDownloadRelationViewerSection from './TMDownloadRelationViewerSection';
|
|
22
|
-
import { buildInitialDownloadSettings, fileExists, generateTargetFileName, generateUniqueFileName, getDcmtInfosToDownload, getFloatingLabelStyle, isDirectoryPickerSupported, SPLITTER_MIN,
|
|
22
|
+
import { buildInitialDownloadSettings, fileExists, generateTargetFileName, generateUniqueFileName, getDcmtInfosToDownload, getFloatingLabelStyle, isDirectoryPickerSupported, SPLITTER_MIN, SPLITTER_START_60_40, } from './copyAndMergeDcmtsShared';
|
|
23
23
|
/**
|
|
24
24
|
* Form per la copia/zip dei documenti in una cartella locale.
|
|
25
25
|
* Logica condivisa con TMMergeToPdfForm è esternalizzata in copyAndMergeDcmtsShared
|
|
26
26
|
* e TMDownloadRelationViewerSection.
|
|
27
27
|
*/
|
|
28
|
-
const TMCopyToFolderForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationViewer }) => {
|
|
28
|
+
const TMCopyToFolderForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationViewer, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
|
|
29
29
|
const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, } = useDcmtOperations();
|
|
30
30
|
const deviceType = useDeviceType();
|
|
31
31
|
// ---- Stato dei settings ----
|
|
@@ -46,8 +46,8 @@ const TMCopyToFolderForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationVi
|
|
|
46
46
|
const getTitle = () => {
|
|
47
47
|
const count = ` (${selectedDcmtInfos.length})`;
|
|
48
48
|
const modeLabelMap = {
|
|
49
|
-
onlySelected: '
|
|
50
|
-
customized: '
|
|
49
|
+
onlySelected: 'I documenti selezionati',
|
|
50
|
+
customized: 'I documenti selezionati e i correlati',
|
|
51
51
|
};
|
|
52
52
|
const modeLabel = modeLabelMap[mode] || modeLabelMap.onlySelected;
|
|
53
53
|
return `Copia in una cartella - ${modeLabel}${count}`;
|
|
@@ -195,10 +195,31 @@ const TMCopyToFolderForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationVi
|
|
|
195
195
|
const zipFileName = settings.zipFileName.trim().toLowerCase().endsWith('.zip')
|
|
196
196
|
? settings.zipFileName.trim()
|
|
197
197
|
: settings.zipFileName.trim() + '.zip';
|
|
198
|
-
|
|
198
|
+
// Crea il blob ZIP
|
|
199
|
+
const zipBlob = await ZipManager.createZip(zipEntries, {
|
|
199
200
|
compressionLevel: 6,
|
|
200
201
|
password: settings.zipPassword.trim() || undefined,
|
|
201
202
|
});
|
|
203
|
+
// Se c'è un handle della cartella: salva direttamente nella cartella selezionata
|
|
204
|
+
if (folderHandleRef.current) {
|
|
205
|
+
try {
|
|
206
|
+
// Per lo ZIP usa sempre rename automatico (come fa il browser)
|
|
207
|
+
const finalZipFileName = await generateUniqueFileName(folderHandleRef.current, zipFileName);
|
|
208
|
+
const fileHandle = await folderHandleRef.current.getFileHandle(finalZipFileName, { create: true });
|
|
209
|
+
const writable = await fileHandle.createWritable();
|
|
210
|
+
await writable.write(zipBlob);
|
|
211
|
+
await writable.close();
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
console.error('Errore nel salvataggio ZIP nella cartella, fallback al download standard:', err);
|
|
215
|
+
// Fallback: download standard del browser
|
|
216
|
+
ZipManager.downloadBlob(zipBlob, zipFileName);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
// Se non c'è un handle della cartella: download zip standard del browser
|
|
221
|
+
ZipManager.downloadBlob(zipBlob, zipFileName);
|
|
222
|
+
}
|
|
202
223
|
}
|
|
203
224
|
}
|
|
204
225
|
else {
|
|
@@ -239,18 +260,37 @@ const TMCopyToFolderForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationVi
|
|
|
239
260
|
position: 'relative',
|
|
240
261
|
border: `1px solid ${TMColors.border_normal}`,
|
|
241
262
|
borderRadius: '8px',
|
|
242
|
-
padding: '
|
|
263
|
+
padding: '10px 6px 6px 6px',
|
|
243
264
|
height: showTMRelationViewer ? '100%' : undefined,
|
|
244
265
|
flex: showTMRelationViewer ? undefined : 1,
|
|
245
266
|
minHeight: 0,
|
|
246
|
-
marginTop:
|
|
267
|
+
marginTop: '8px',
|
|
247
268
|
display: 'flex',
|
|
248
269
|
flexDirection: 'column',
|
|
249
270
|
boxSizing: 'border-box'
|
|
250
|
-
}, children: [_jsx("span", { style:
|
|
271
|
+
}, children: [_jsx("span", { style: {
|
|
272
|
+
...getFloatingLabelStyle(),
|
|
273
|
+
fontWeight: 600
|
|
274
|
+
}, children: "Parametri di configurazione" }), _jsxs("div", { style: {
|
|
275
|
+
position: 'absolute',
|
|
276
|
+
top: '-8px',
|
|
277
|
+
right: '12px',
|
|
278
|
+
display: 'flex',
|
|
279
|
+
alignItems: 'center',
|
|
280
|
+
gap: '4px',
|
|
281
|
+
backgroundColor: 'white',
|
|
282
|
+
padding: '0 4px',
|
|
283
|
+
zIndex: 1
|
|
284
|
+
}, children: [_jsx(TMButton, { btnStyle: "toolbar", icon: _jsx(IconSave, {}), caption: "Salva Layout", color: "success", disabled: isLayoutSameAsSaved(), onClick: saveLayout }), hasSavedLayout && (_jsx(TMButton, { btnStyle: "toolbar", icon: _jsx(IconDelete, {}), caption: "Rimuovi Layout", color: "error", onClick: removeLayout }))] }), _jsxs("div", { style: {
|
|
285
|
+
display: 'flex',
|
|
286
|
+
flexDirection: 'column',
|
|
287
|
+
flex: 1,
|
|
288
|
+
overflowY: 'auto',
|
|
289
|
+
minHeight: 0,
|
|
290
|
+
}, children: [_jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center' }, children: _jsx(TMRadioButton, { dataSource: [
|
|
251
291
|
{ value: 'copy', display: 'Copia in una cartella' },
|
|
252
292
|
{ value: 'zip', display: 'Comprimi in un file zip' }
|
|
253
|
-
], value: settings.exportMode, direction: "row", onValueChanged: (value) => updateSettings('exportMode', value) }) }),
|
|
293
|
+
], value: settings.exportMode, direction: "row", onValueChanged: (value) => updateSettings('exportMode', value) }) }), isDirectoryPickerSupported() ? (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '4px' }, children: [_jsx(TMTextBox, { label: "Percorso", value: settings.destinationFolder, validationItems: folderValidationItems, onValueChanged: handleFolderValueChange, readOnly: true, placeHolder: "Download", onClick: handleSelectFolder, buttons: [
|
|
254
294
|
{
|
|
255
295
|
icon: _jsx(IconFolderOpen, {}),
|
|
256
296
|
text: 'Seleziona cartella',
|
|
@@ -273,11 +313,11 @@ const TMCopyToFolderForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationVi
|
|
|
273
313
|
border: `1px solid ${TMColors.border_normal}`,
|
|
274
314
|
borderRadius: '5px',
|
|
275
315
|
backgroundColor: '#fafafa',
|
|
276
|
-
}, children: [_jsx(IconFolderOpen, {}), _jsx("span", { style: { fontSize: '0.9rem', color: '#333' }, children: "Download" })] }), _jsx("span", { style: { fontSize: '0.8rem', color: '#888', fontStyle: 'italic' }, children: "Il browser in uso non supporta la selezione della cartella. I file verranno scaricati nella cartella Download." })] }))
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
316
|
+
}, children: [_jsx(IconFolderOpen, {}), _jsx("span", { style: { fontSize: '0.9rem', color: '#333' }, children: "Download" })] }), _jsx("span", { style: { fontSize: '0.8rem', color: '#888', fontStyle: 'italic' }, children: "Il browser in uso non supporta la selezione della cartella. I file verranno scaricati nella cartella Download." })] })), settings.exportMode === 'zip' && (_jsxs("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: '12px' }, children: [_jsx(TMTextBox, { label: "Nome file zip", value: settings.zipFileName, validationItems: zipValidationItems, autoComplete: "one-time-code", onValueChanged: (e) => updateSettings('zipFileName', e.target.value) }), _jsx(TMTextBox, { label: "Proteggi con password (opzionale)", value: settings.zipPassword, type: "password", autoComplete: "one-time-code", onValueChanged: (e) => updateSettings('zipPassword', e.target.value) })] })), settings.exportMode === 'copy' && isDirectoryPickerSupported() && (_jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '4px', marginTop: '8px' }, children: isUsingDefaultDownloads ? (_jsx("span", { style: { fontSize: '0.8rem', color: '#888', fontStyle: 'italic' }, children: "Nella cartella Download il browser rinomina automaticamente i file duplicati." })) : (_jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '12px', flexWrap: 'wrap' }, children: [_jsx("label", { style: { fontSize: '0.9rem', color: '#525252', fontWeight: 500 }, children: "Se il file esiste" }), _jsx(TMRadioButton, { dataSource: [
|
|
317
|
+
{ value: 'overwrite', display: 'Copia e sostituisci' },
|
|
318
|
+
{ value: 'skip', display: 'Non copiare' },
|
|
319
|
+
{ value: 'rename', display: 'Copia, ma rinomina' },
|
|
320
|
+
], value: settings.fileExistsMode, direction: "row", onValueChanged: (value) => updateSettings('fileExistsMode', value) })] })) })), _jsxs("div", { style: { display: 'flex', alignItems: 'flex-end', gap: '12px', flexWrap: 'wrap' }, children: [_jsx("div", { style: { flex: '0 0 auto', minWidth: '160px' }, children: _jsx(TMDropDown, { label: "Per il nome file usa", value: settings.fileNamingMode, dataSource: [
|
|
281
321
|
{ value: 'onlyDid', display: 'Solo DID' },
|
|
282
322
|
{ value: 'documentTypeAndDid', display: 'Nome tipo documento e DID' },
|
|
283
323
|
{ value: 'documentTypeAndCustomMetadata', display: 'Nome tipo documento e metadati personalizzati' },
|
|
@@ -300,7 +340,7 @@ const TMCopyToFolderForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationVi
|
|
|
300
340
|
}, onBlur: (e) => {
|
|
301
341
|
e.target.style.backgroundImage = 'none';
|
|
302
342
|
e.target.style.borderBottom = `1px solid ${TMColors.border_normal}`;
|
|
303
|
-
} })] }), _jsx(TMCheckBox, { label: "Rimuovi la firma se presente", value: settings.removeSignature, onValueChanged: (value) => updateSettings('removeSignature', value) })] }), _jsxs("div", { style: { display: '
|
|
304
|
-
return (_jsx(TMModal, { width: calcResponsiveSizes(deviceType, showTMRelationViewer ? '
|
|
343
|
+
} })] }), _jsx(TMCheckBox, { label: "Rimuovi la firma se presente", value: settings.removeSignature, onValueChanged: (value) => updateSettings('removeSignature', value) })] }), _jsxs("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: '12px' }, children: [_jsx(TMInvoiceRetrieveFormats, { width: '100%', label: SDKUI_Localizator.ElectronicInvoice + ' - ' + SDKUI_Localizator.DisplayFormat, onValueChanged: (newValue) => updateSettings('invoiceFormat', newValue), value: settings.invoiceFormat, valueOrig: settings.invoiceFormat }), _jsx(TMOrderRetrieveFormats, { width: '100%', label: SDKUI_Localizator.ElectronicOrder + ' - ' + SDKUI_Localizator.DisplayFormat, value: settings.orderFormat, valueOrig: settings.orderFormat, onValueChanged: (newValue) => updateSettings('orderFormat', newValue) })] })] })] }));
|
|
344
|
+
return (_jsx(TMModal, { width: calcResponsiveSizes(deviceType, showTMRelationViewer ? '95%' : '780px', showTMRelationViewer ? '95%' : '780px', '95%'), height: calcResponsiveSizes(deviceType, showTMRelationViewer ? '95%' : '450px', showTMRelationViewer ? '95%' : '450px', '95%'), 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', padding: '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: SPLITTER_MIN, start: SPLITTER_START_60_40, 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: _jsx(TMButton, { caption: "Esegui", icon: _jsx(IconPlay, {}), color: 'success', showTooltip: false, disabled: !isFormValid() || (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0), onClick: run }) })] }) }) }));
|
|
305
345
|
};
|
|
306
346
|
export default TMCopyToFolderForm;
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
|
|
2
3
|
import { DcmtInfo } from '../../../ts';
|
|
3
4
|
import { IRelatedDcmt } from './TMMasterDetailDcmts';
|
|
4
5
|
interface ITMDownloadRelationViewerSectionProps {
|
|
5
6
|
selectedDcmtInfos: Array<DcmtInfo>;
|
|
6
7
|
/** Notifica al parent la lista dei documenti correlati selezionati (deduplicati) */
|
|
7
8
|
onSelectionChanged: (items: Array<IRelatedDcmt>) => void;
|
|
9
|
+
allTasks?: Array<TaskDescriptor>;
|
|
10
|
+
getAllTasks?: () => Promise<void>;
|
|
11
|
+
deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
|
|
12
|
+
addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
|
|
13
|
+
editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
|
|
14
|
+
handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
|
|
15
|
+
handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
|
|
8
16
|
}
|
|
9
17
|
/**
|
|
10
18
|
* Sezione condivisa tra TMCopyToFolderForm e TMMergeToPdfForm
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useRef, useState } from 'react';
|
|
3
3
|
import TreeView from 'devextreme-react/tree-view';
|
|
4
|
+
import { LayoutModes } from '@topconsultnpm/sdk-ts';
|
|
4
5
|
import { SDKUI_Localizator } from '../../../helper';
|
|
5
6
|
import { TMColors } from '../../../utils/theme';
|
|
6
7
|
import { TMSplitterLayout } from '../../base/TMLayout';
|
|
7
8
|
import TMRelationViewer from './TMRelationViewer';
|
|
8
|
-
import
|
|
9
|
+
import TMDcmtForm from './TMDcmtForm';
|
|
10
|
+
import { dedupeByTidDid, getDcmtKey, getFloatingLabelStyle, SPLITTER_MIN, SPLITTER_START_75_25, } from './copyAndMergeDcmtsShared';
|
|
9
11
|
/**
|
|
10
12
|
* Sezione condivisa tra TMCopyToFolderForm e TMMergeToPdfForm
|
|
11
13
|
* che mostra l'elenco dei documenti correlati e il tree di selezione
|
|
12
14
|
* per tipo documento / "solo metadati".
|
|
13
15
|
*/
|
|
14
|
-
const TMDownloadRelationViewerSection = ({ selectedDcmtInfos, onSelectionChanged, }) => {
|
|
16
|
+
const TMDownloadRelationViewerSection = ({ selectedDcmtInfos, onSelectionChanged, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
|
|
15
17
|
const [focusedItem, setFocusedItem] = useState(null);
|
|
16
18
|
const [selectedItems, setSelectedItems] = useState([]);
|
|
17
19
|
const [allItems, setAllItems] = useState([]);
|
|
18
20
|
const didInitSelectionRef = useRef(false);
|
|
21
|
+
// State for TMDcmtForm modal
|
|
22
|
+
const [isOpenDcmtForm, setIsOpenDcmtForm] = useState(false);
|
|
23
|
+
const [dcmtFormTID, setDcmtFormTID] = useState(undefined);
|
|
24
|
+
const [dcmtFormDID, setDcmtFormDID] = useState(undefined);
|
|
25
|
+
const [dcmtFormTitle, setDcmtFormTitle] = useState('');
|
|
19
26
|
const updateSelection = useCallback((items) => {
|
|
20
27
|
const deduped = dedupeByTidDid(items);
|
|
21
28
|
setSelectedItems(deduped);
|
|
@@ -34,122 +41,133 @@ const TMDownloadRelationViewerSection = ({ selectedDcmtInfos, onSelectionChanged
|
|
|
34
41
|
updateSelection(items.filter(i => i.isDcmt));
|
|
35
42
|
}
|
|
36
43
|
}, [updateSelection]);
|
|
37
|
-
|
|
44
|
+
const handleDocumentDoubleClick = useCallback((tid, did, name) => {
|
|
45
|
+
setDcmtFormTID(tid);
|
|
46
|
+
setDcmtFormDID(did);
|
|
47
|
+
setDcmtFormTitle(name ?? '');
|
|
48
|
+
setIsOpenDcmtForm(true);
|
|
49
|
+
}, []);
|
|
50
|
+
return (_jsxs("div", { style: {
|
|
38
51
|
position: 'relative',
|
|
39
52
|
height: '100%',
|
|
40
53
|
minHeight: 0,
|
|
41
54
|
display: 'flex',
|
|
42
55
|
flexDirection: 'column',
|
|
43
56
|
boxSizing: 'border-box'
|
|
44
|
-
}, children: _jsx("div", { style: { flex: 1, minHeight: 0, overflow: 'visible', paddingTop: '10px' }, children: _jsxs(TMSplitterLayout, { direction: 'horizontal', showSeparator: true, separatorSize: 8, separatorColor: 'transparent', separatorActiveColor: 'transparent', overflow: 'visible', min: SPLITTER_MIN, start:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
const sortedDtdNames = Array.from(dtdGroups.keys()).sort((a, b) => a.localeCompare(b));
|
|
92
|
-
const selectedKeysSet = new Set(selectedDcmtsList.map(getDcmtKey));
|
|
93
|
-
const dtdGroupInfos = sortedDtdNames.map((name) => {
|
|
94
|
-
const items = dtdGroups.get(name) ?? [];
|
|
95
|
-
const selectedCount = items.filter(it => selectedKeysSet.has(getDcmtKey(it))).length;
|
|
96
|
-
return {
|
|
97
|
-
name,
|
|
98
|
-
items,
|
|
99
|
-
total: items.length,
|
|
100
|
-
allSelected: items.length > 0 && selectedCount === items.length,
|
|
101
|
-
};
|
|
102
|
-
});
|
|
103
|
-
const treeItems = [
|
|
104
|
-
{
|
|
105
|
-
id: 'all',
|
|
106
|
-
text: `Seleziona tutti (${totalDcmts})`,
|
|
107
|
-
expanded: true,
|
|
108
|
-
selected: allSelected,
|
|
109
|
-
items: [
|
|
110
|
-
...dtdGroupInfos.map((g) => ({
|
|
111
|
-
id: `dtd::${g.name}`,
|
|
112
|
-
text: `${g.name} (${g.total})`,
|
|
113
|
-
selected: g.allSelected,
|
|
114
|
-
})),
|
|
115
|
-
{
|
|
116
|
-
id: 'metadataOnly',
|
|
117
|
-
text: `Documenti di soli metadati (${totalMetadataOnly})`,
|
|
118
|
-
selected: allMetadataOnlySelected,
|
|
119
|
-
},
|
|
120
|
-
]
|
|
121
|
-
}
|
|
122
|
-
];
|
|
123
|
-
const handleItemSelectionChanged = (e) => {
|
|
124
|
-
const itemData = e.itemData;
|
|
125
|
-
if (!itemData)
|
|
126
|
-
return;
|
|
127
|
-
if (itemData.id === 'all') {
|
|
128
|
-
updateSelection(itemData.selected ? dcmtItems : []);
|
|
57
|
+
}, children: [_jsx("div", { style: { flex: 1, minHeight: 0, overflow: 'visible', paddingTop: '10px' }, children: _jsxs(TMSplitterLayout, { direction: 'horizontal', showSeparator: true, separatorSize: 8, separatorColor: 'transparent', separatorActiveColor: 'transparent', overflow: 'visible', min: SPLITTER_MIN, start: SPLITTER_START_75_25, children: [_jsxs("div", { style: {
|
|
58
|
+
position: 'relative',
|
|
59
|
+
height: '100%',
|
|
60
|
+
minHeight: 0,
|
|
61
|
+
overflow: 'visible',
|
|
62
|
+
border: `1px solid ${TMColors.border_normal}`,
|
|
63
|
+
borderRadius: '8px',
|
|
64
|
+
padding: '4px 2px 2px 2px',
|
|
65
|
+
backgroundColor: '#fff',
|
|
66
|
+
boxSizing: 'border-box',
|
|
67
|
+
display: 'flex',
|
|
68
|
+
flexDirection: 'column'
|
|
69
|
+
}, children: [_jsxs("span", { style: getFloatingLabelStyle(), title: `Documenti correlati (${SDKUI_Localizator.Selected}: ${selectedItems.filter(item => item.isDcmt).length})`, children: ["Documenti correlati (", SDKUI_Localizator.Selected, ": ", selectedItems.filter(item => item.isDcmt).length, ")"] }), _jsx("div", { style: { flex: 1, minHeight: 0, overflowX: 'auto', overflowY: 'auto' }, children: _jsx("div", { style: { minWidth: 'max-content', height: '100%' }, children: _jsx(TMRelationViewer, { inputDcmts: selectedDcmtInfos, isForMaster: false, defaultExpandAll: true, showMetadataNames: true, allowMultipleSelection: true, showExpandAllButton: true, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged, onAllItemsChanged: handleAllItemsChanged, onDocumentDoubleClick: handleDocumentDoubleClick }) }) })] }), _jsxs("div", { style: {
|
|
70
|
+
position: 'relative',
|
|
71
|
+
height: '100%',
|
|
72
|
+
minHeight: 0,
|
|
73
|
+
overflow: 'visible',
|
|
74
|
+
border: `1px solid ${TMColors.border_normal}`,
|
|
75
|
+
borderRadius: '8px',
|
|
76
|
+
padding: '4px 2px 2px 2px',
|
|
77
|
+
backgroundColor: '#fff',
|
|
78
|
+
boxSizing: 'border-box',
|
|
79
|
+
display: 'flex',
|
|
80
|
+
flexDirection: 'column'
|
|
81
|
+
}, children: [_jsx("span", { style: getFloatingLabelStyle(), title: "Tipo documento o vista", children: "Tipo documento o vista" }), _jsx("div", { style: { flex: 1, minHeight: 0, overflow: 'auto', padding: '8px', display: 'flex', flexDirection: 'column', gap: '6px' }, children: (() => {
|
|
82
|
+
const dcmtItems = dedupeByTidDid(allItems.filter(item => item.isDcmt));
|
|
83
|
+
const metadataOnlyItems = dcmtItems.filter(item => item.fileExt === null || item.fileExt === undefined);
|
|
84
|
+
const totalDcmts = dcmtItems.length;
|
|
85
|
+
const totalMetadataOnly = metadataOnlyItems.length;
|
|
86
|
+
const selectedDcmtsList = selectedItems.filter(item => item.isDcmt);
|
|
87
|
+
const selectedDcmts = selectedDcmtsList.length;
|
|
88
|
+
const allSelected = totalDcmts > 0 && selectedDcmts === totalDcmts;
|
|
89
|
+
const selectedMetadataOnlyCount = selectedDcmtsList.filter(item => item.fileExt === null || item.fileExt === undefined).length;
|
|
90
|
+
const allMetadataOnlySelected = totalMetadataOnly > 0 && selectedMetadataOnlyCount === totalMetadataOnly;
|
|
91
|
+
// Raggruppa per nome del DcmtTypeDescriptor (campo dtd.name)
|
|
92
|
+
const getDtdName = (item) => item.dtd?.name ?? undefined;
|
|
93
|
+
const dtdGroups = new Map();
|
|
94
|
+
for (const item of dcmtItems) {
|
|
95
|
+
const name = getDtdName(item);
|
|
96
|
+
if (!name)
|
|
97
|
+
continue;
|
|
98
|
+
const arr = dtdGroups.get(name);
|
|
99
|
+
if (arr)
|
|
100
|
+
arr.push(item);
|
|
101
|
+
else
|
|
102
|
+
dtdGroups.set(name, [item]);
|
|
129
103
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
104
|
+
const sortedDtdNames = Array.from(dtdGroups.keys()).sort((a, b) => a.localeCompare(b));
|
|
105
|
+
const selectedKeysSet = new Set(selectedDcmtsList.map(getDcmtKey));
|
|
106
|
+
const dtdGroupInfos = sortedDtdNames.map((name) => {
|
|
107
|
+
const items = dtdGroups.get(name) ?? [];
|
|
108
|
+
const selectedCount = items.filter(it => selectedKeysSet.has(getDcmtKey(it))).length;
|
|
109
|
+
return {
|
|
110
|
+
name,
|
|
111
|
+
items,
|
|
112
|
+
total: items.length,
|
|
113
|
+
allSelected: items.length > 0 && selectedCount === items.length,
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
const treeItems = [
|
|
117
|
+
{
|
|
118
|
+
id: 'all',
|
|
119
|
+
text: `Seleziona tutti (${totalDcmts})`,
|
|
120
|
+
expanded: true,
|
|
121
|
+
selected: allSelected,
|
|
122
|
+
items: [
|
|
123
|
+
...dtdGroupInfos.map((g) => ({
|
|
124
|
+
id: `dtd::${g.name}`,
|
|
125
|
+
text: `${g.name} (${g.total})`,
|
|
126
|
+
selected: g.allSelected,
|
|
127
|
+
})),
|
|
128
|
+
{
|
|
129
|
+
id: 'metadataOnly',
|
|
130
|
+
text: `Documenti di soli metadati (${totalMetadataOnly})`,
|
|
131
|
+
selected: allMetadataOnlySelected,
|
|
132
|
+
},
|
|
133
|
+
]
|
|
133
134
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
];
|
|
136
|
+
const handleItemSelectionChanged = (e) => {
|
|
137
|
+
const itemData = e.itemData;
|
|
138
|
+
if (!itemData)
|
|
139
|
+
return;
|
|
140
|
+
if (itemData.id === 'all') {
|
|
141
|
+
updateSelection(itemData.selected ? dcmtItems : []);
|
|
137
142
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
143
|
+
else if (itemData.id === 'metadataOnly') {
|
|
144
|
+
if (itemData.selected) {
|
|
145
|
+
updateSelection([...selectedItems, ...metadataOnlyItems]);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
const metadataKeys = new Set(metadataOnlyItems.map(getDcmtKey));
|
|
149
|
+
updateSelection(selectedItems.filter(item => !metadataKeys.has(getDcmtKey(item))));
|
|
150
|
+
}
|
|
144
151
|
}
|
|
145
|
-
else {
|
|
146
|
-
const
|
|
147
|
-
|
|
152
|
+
else if (typeof itemData.id === 'string' && itemData.id.startsWith('dtd::')) {
|
|
153
|
+
const dtdName = itemData.id.substring('dtd::'.length);
|
|
154
|
+
const groupItems = dtdGroups.get(dtdName) ?? [];
|
|
155
|
+
if (itemData.selected) {
|
|
156
|
+
updateSelection([...selectedItems, ...groupItems]);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
const groupKeys = new Set(groupItems.map(getDcmtKey));
|
|
160
|
+
updateSelection(selectedItems.filter(item => !groupKeys.has(getDcmtKey(item))));
|
|
161
|
+
}
|
|
148
162
|
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
163
|
+
};
|
|
164
|
+
const dtdSignature = dtdGroupInfos.map(g => `${g.name}:${g.total}:${g.allSelected ? 1 : 0}`).join('|');
|
|
165
|
+
return (_jsx("div", { style: { minWidth: '280px', width: 'max-content', flexShrink: 0 }, children: _jsx(TreeView, { items: treeItems, showCheckBoxesMode: 'normal', selectionMode: 'multiple', selectNodesRecursive: false, selectByClick: true, onItemSelectionChanged: handleItemSelectionChanged }, `tv-${allSelected}-${allMetadataOnlySelected}-${totalDcmts}-${totalMetadataOnly}-${dtdSignature}`) }));
|
|
166
|
+
})() })] })] }, "TMDocumentDownload-relation-horizontal") }), isOpenDcmtForm && dcmtFormTID !== undefined && dcmtFormDID !== undefined && (_jsx(TMDcmtForm, { isModal: true, titleModal: dcmtFormTitle, TID: dcmtFormTID, DID: dcmtFormDID, layoutMode: LayoutModes.Update, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, onClose: () => {
|
|
167
|
+
setIsOpenDcmtForm(false);
|
|
168
|
+
setDcmtFormTID(undefined);
|
|
169
|
+
setDcmtFormDID(undefined);
|
|
170
|
+
setDcmtFormTitle('');
|
|
171
|
+
} }))] }));
|
|
154
172
|
};
|
|
155
173
|
export default TMDownloadRelationViewerSection;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { DcmtInfo } from '../../../ts';
|
|
3
3
|
import { MergePdfManagerType } from '../../../helper';
|
|
4
|
+
import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
|
|
4
5
|
import { TMCopyToFolderMode } from '../../../hooks/useDocumentOperations';
|
|
5
6
|
interface ITMMergeToPdfFormProps {
|
|
6
7
|
mode: TMCopyToFolderMode;
|
|
@@ -8,6 +9,13 @@ interface ITMMergeToPdfFormProps {
|
|
|
8
9
|
onClose: () => void;
|
|
9
10
|
showTMRelationViewer: boolean;
|
|
10
11
|
mergePdfManager?: MergePdfManagerType;
|
|
12
|
+
allTasks?: Array<TaskDescriptor>;
|
|
13
|
+
getAllTasks?: () => Promise<void>;
|
|
14
|
+
deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
|
|
15
|
+
addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
|
|
16
|
+
editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
|
|
17
|
+
handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
|
|
18
|
+
handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
|
|
11
19
|
}
|
|
12
20
|
/**
|
|
13
21
|
* Form per l'unione di più documenti PDF in un singolo file.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
3
|
import { DownloadTypes } from '../../../ts';
|
|
4
|
-
import { calcResponsiveSizes, IconPlay, SDKUI_Globals, SDKUI_Localizator, } from '../../../helper';
|
|
5
|
-
import { DcmtOpers, GeneralRetrieveFormats, ResultTypes, RetrieveFileOptions, ValidationItem, } from '@topconsultnpm/sdk-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
6
|
import TMModal from '../../base/TMModal';
|
|
7
7
|
import { useDeviceType } from '../../base/TMDeviceProvider';
|
|
8
8
|
import TMTextBox from '../../editors/TMTextBox';
|
|
@@ -13,22 +13,56 @@ import { TMLayoutWaitingContainer } from '../../base/TMWaitPanel';
|
|
|
13
13
|
import { TMSplitterLayout } from '../../base/TMLayout';
|
|
14
14
|
import { TMColors } from '../../../utils/theme';
|
|
15
15
|
import TMDownloadRelationViewerSection from './TMDownloadRelationViewerSection';
|
|
16
|
-
import { getDcmtInfosToDownload, getFloatingLabelStyle, isPdfExt, MIN_PDF_FOR_MERGE, SPLITTER_MIN,
|
|
16
|
+
import { getDcmtInfosToDownload, getFloatingLabelStyle, isDirectoryPickerSupported, isPdfExt, MIN_PDF_FOR_MERGE, SPLITTER_MIN, SPLITTER_START_70_30, } from './copyAndMergeDcmtsShared';
|
|
17
|
+
import ShowAlert from '../../base/TMAlert';
|
|
17
18
|
/**
|
|
18
19
|
* Form per l'unione di più documenti PDF in un singolo file.
|
|
19
20
|
* Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared
|
|
20
21
|
* con TMCopyToFolderForm.
|
|
21
22
|
*/
|
|
22
|
-
const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationViewer, mergePdfManager }) => {
|
|
23
|
+
const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationViewer, mergePdfManager, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
|
|
23
24
|
const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, } = useDcmtOperations();
|
|
24
25
|
const deviceType = useDeviceType();
|
|
25
|
-
const [pdfFileName, setPdfFileName] = useState('');
|
|
26
|
+
const [pdfFileName, setPdfFileName] = useState('merged.pdf');
|
|
27
|
+
const [destinationFolder, setDestinationFolder] = useState('Download');
|
|
26
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
|
+
};
|
|
27
61
|
const getTitle = () => {
|
|
28
62
|
const count = ` (${selectedDcmtInfos.length})`;
|
|
29
63
|
const modeLabelMap = {
|
|
30
|
-
onlySelected: '
|
|
31
|
-
customized: 'Documenti
|
|
64
|
+
onlySelected: 'Documenti selezionati',
|
|
65
|
+
customized: 'Documenti selezionati e i correlati',
|
|
32
66
|
};
|
|
33
67
|
const modeLabel = modeLabelMap[mode] || modeLabelMap.onlySelected;
|
|
34
68
|
return `Unisci in un file PDF - ${modeLabel}${count}`;
|
|
@@ -38,25 +72,51 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
38
72
|
if (!pdfFileName.trim()) {
|
|
39
73
|
pdfValidationItems.push(new ValidationItem(ResultTypes.ERROR, 'Nome file PDF', SDKUI_Localizator.RequiredField));
|
|
40
74
|
}
|
|
41
|
-
// ----
|
|
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;
|
|
42
101
|
const nonPdfSelectedItems = (() => {
|
|
43
102
|
if (showTMRelationViewer) {
|
|
44
103
|
return selectedItemsRelationViewer
|
|
45
|
-
.filter(i => i.isDcmt && !isPdfExt(i.fileExt))
|
|
104
|
+
.filter(i => i.isDcmt && !isPdfExt(i.fileExt) && !isConvertibleToPdfExt(i.fileExt))
|
|
46
105
|
.map(i => ({ key: `${i.tid}_${i.did}`, ext: i.fileExt ?? undefined }));
|
|
47
106
|
}
|
|
48
107
|
return selectedDcmtInfos
|
|
49
|
-
.filter(d => !isPdfExt(d.FILEEXT))
|
|
108
|
+
.filter(d => !isPdfExt(d.FILEEXT) && !isConvertibleToPdfExt(d.FILEEXT))
|
|
50
109
|
.map(d => ({ key: `${d.TID}_${d.DID}`, ext: d.FILEEXT }));
|
|
51
110
|
})();
|
|
52
111
|
const hasNonPdfSelected = nonPdfSelectedItems.length > 0;
|
|
53
|
-
|
|
112
|
+
// Conteggio file unibili: PDF nativi + file convertibili
|
|
113
|
+
const mergeableSelectedCount = (() => {
|
|
54
114
|
if (showTMRelationViewer) {
|
|
55
|
-
return selectedItemsRelationViewer.filter(i => i.isDcmt && isPdfExt(i.fileExt)).length;
|
|
115
|
+
return selectedItemsRelationViewer.filter(i => i.isDcmt && (isPdfExt(i.fileExt) || isConvertibleToPdfExt(i.fileExt))).length;
|
|
56
116
|
}
|
|
57
|
-
return selectedDcmtInfos.filter(d => isPdfExt(d.FILEEXT)).length;
|
|
117
|
+
return selectedDcmtInfos.filter(d => isPdfExt(d.FILEEXT) || isConvertibleToPdfExt(d.FILEEXT)).length;
|
|
58
118
|
})();
|
|
59
|
-
const hasEnoughPdfForMerge =
|
|
119
|
+
const hasEnoughPdfForMerge = mergeableSelectedCount >= MIN_PDF_FOR_MERGE;
|
|
60
120
|
const isFormValid = () => pdfValidationItems.length === 0;
|
|
61
121
|
// ---- Recupero dei file PDF da unire (condiviso tra Esegui e Anteprima) ----
|
|
62
122
|
const collectPdfFilesToMerge = async () => {
|
|
@@ -69,28 +129,29 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
69
129
|
const pdfDcmtInfosToDownload = dcmtInfosToDownload.filter(d => !nonPdfKeys.has(`${d.TID}_${d.DID}`));
|
|
70
130
|
if (pdfDcmtInfosToDownload.length === 0) {
|
|
71
131
|
TMMessageBoxManager.show({
|
|
72
|
-
message: 'Tra i documenti selezionati non è presente alcun file PDF: l\'unione non può essere eseguita.',
|
|
132
|
+
message: 'Tra i documenti selezionati non è presente alcun file PDF o convertibile in PDF: l\'unione non può essere eseguita.',
|
|
73
133
|
buttons: [ButtonNames.OK]
|
|
74
134
|
});
|
|
75
135
|
return null;
|
|
76
136
|
}
|
|
77
137
|
if (pdfDcmtInfosToDownload.length < MIN_PDF_FOR_MERGE) {
|
|
78
138
|
TMMessageBoxManager.show({
|
|
79
|
-
message: `Tra i documenti selezionati è presente un solo file PDF: per l'unione ne servono almeno ${MIN_PDF_FOR_MERGE}.`,
|
|
139
|
+
message: `Tra i documenti selezionati è presente un solo file PDF o convertibile: per l'unione ne servono almeno ${MIN_PDF_FOR_MERGE}.`,
|
|
80
140
|
buttons: [ButtonNames.OK]
|
|
81
141
|
});
|
|
82
142
|
return null;
|
|
83
143
|
}
|
|
84
144
|
const pdfFiles = [];
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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;
|
|
90
151
|
const collectFileForMerge = async (file, _dcmtInfo) => {
|
|
91
152
|
pdfFiles.push(file);
|
|
92
153
|
};
|
|
93
|
-
await downloadDcmtsAsync(pdfDcmtInfosToDownload, DownloadTypes.Dcmt, 'download', collectFileForMerge, undefined, true,
|
|
154
|
+
await downloadDcmtsAsync(pdfDcmtInfosToDownload, DownloadTypes.Dcmt, 'download', collectFileForMerge, undefined, true, rfo, false);
|
|
94
155
|
if (pdfFiles.length === 0) {
|
|
95
156
|
TMMessageBoxManager.show({ message: 'Nessun file disponibile per l\'unione.', buttons: [ButtonNames.OK] });
|
|
96
157
|
return null;
|
|
@@ -110,15 +171,26 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
110
171
|
const pdfFiles = await collectPdfFilesToMerge();
|
|
111
172
|
if (!pdfFiles)
|
|
112
173
|
return;
|
|
113
|
-
const finalName = pdfFileName.trim().toLowerCase().endsWith('.pdf')
|
|
114
|
-
? pdfFileName.trim()
|
|
115
|
-
: pdfFileName.trim() + '.pdf';
|
|
174
|
+
const finalName = pdfFileName.trim().toLowerCase().endsWith('.pdf') ? pdfFileName.trim() : pdfFileName.trim() + '.pdf';
|
|
116
175
|
try {
|
|
117
|
-
|
|
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
|
+
}
|
|
118
190
|
}
|
|
119
191
|
catch (err) {
|
|
120
|
-
console.error('Errore durante l\'unione dei PDF:', err);
|
|
121
|
-
TMMessageBoxManager.show({ message: 'Errore durante l\'unione dei PDF.', buttons: [ButtonNames.OK] });
|
|
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] });
|
|
122
194
|
return;
|
|
123
195
|
}
|
|
124
196
|
onClose();
|
|
@@ -136,7 +208,47 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
136
208
|
display: 'flex',
|
|
137
209
|
flexDirection: 'column',
|
|
138
210
|
boxSizing: 'border-box'
|
|
139
|
-
}, children: [_jsx("span", { style: getFloatingLabelStyle(), title: "Parametri di configurazione (Unisci in PDF)", children: "Parametri di configurazione" }), _jsxs("div", { style: {
|
|
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: {
|
|
140
252
|
display: 'flex',
|
|
141
253
|
flexDirection: 'column',
|
|
142
254
|
gap: '6px',
|
|
@@ -146,9 +258,9 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
146
258
|
backgroundColor: '#fdf5e2',
|
|
147
259
|
color: '#7a5d00',
|
|
148
260
|
fontSize: '0.85rem'
|
|
149
|
-
}, children: [_jsx("strong", { children: "Attenzione" }), _jsxs("ul", { style: { margin: 0, paddingLeft: '18px', display: 'flex', flexDirection: 'column', gap: '4px' }, children: [!hasEnoughPdfForMerge && (_jsx("li", { children:
|
|
150
|
-
? `Nessun PDF tra i selezionati: ne servono almeno ${MIN_PDF_FOR_MERGE}.`
|
|
151
|
-
: `Solo 1 PDF tra i selezionati: ne servono almeno ${MIN_PDF_FOR_MERGE}.` })), hasNonPdfSelected && (_jsx("li", { children: (() => {
|
|
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: (() => {
|
|
152
264
|
const extSet = Array.from(new Set(nonPdfSelectedItems.map(i => (i.ext ?? '').toString().trim().toLowerCase().replace(/^\./, '')).filter(e => e.length > 0)));
|
|
153
265
|
const extLabel = extSet.length > 0
|
|
154
266
|
? ` (${extSet.map(e => '.' + e).join(', ')})`
|
|
@@ -157,7 +269,7 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
157
269
|
? `Un documento non è in formato PDF${extLabel} e sarà escluso dall'unione.`
|
|
158
270
|
: `${nonPdfSelectedItems.length} documenti non sono in formato PDF${extLabel} e saranno esclusi dall'unione.`;
|
|
159
271
|
})() }))] })] }))] })] }));
|
|
160
|
-
return (_jsx(TMModal, { width: calcResponsiveSizes(deviceType, showTMRelationViewer ? '90%' : '
|
|
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()
|
|
161
273
|
|| (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0)
|
|
162
274
|
|| !hasEnoughPdfForMerge, onClick: run }) })] }) }) }));
|
|
163
275
|
};
|
|
@@ -3,8 +3,9 @@ import { DcmtInfo } from '../../../ts';
|
|
|
3
3
|
import { DocumentDownloadSettings, FileNamingMode } from '../../../helper';
|
|
4
4
|
import { IRelatedDcmt } from './TMMasterDetailDcmts';
|
|
5
5
|
export declare const SPLITTER_MIN: string[];
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const
|
|
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[];
|
|
8
9
|
/** Numero minimo di file PDF necessari per poterli unire in un unico documento. */
|
|
9
10
|
export declare const MIN_PDF_FOR_MERGE = 2;
|
|
10
11
|
/** Stile per le etichette "floating" posizionate sopra i bordi dei container */
|
|
@@ -5,8 +5,9 @@ import { TMColors } from '../../../utils/theme';
|
|
|
5
5
|
// Costanti condivise tra TMCopyToFolderForm e TMMergeToPdfForm
|
|
6
6
|
// ============================================================
|
|
7
7
|
export const SPLITTER_MIN = ['50', '50'];
|
|
8
|
-
export const
|
|
9
|
-
export const
|
|
8
|
+
export const SPLITTER_START_60_40 = ['60%', '40%'];
|
|
9
|
+
export const SPLITTER_START_70_30 = ['70%', '30%'];
|
|
10
|
+
export const SPLITTER_START_75_25 = ['75%', '25%'];
|
|
10
11
|
/** Numero minimo di file PDF necessari per poterli unire in un unico documento. */
|
|
11
12
|
export const MIN_PDF_FOR_MERGE = 2;
|
|
12
13
|
// ============================================================
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { RetrieveFileOptions, DcmtOpers, FileDescriptor, GeneralRetrieveFormats, InvoiceRetrieveFormats, OrderRetrieveFormats } from '@topconsultnpm/sdk-ts';
|
|
1
|
+
import { RetrieveFileOptions, DcmtOpers, FileDescriptor, GeneralRetrieveFormats, InvoiceRetrieveFormats, OrderRetrieveFormats, FileFormats } from '@topconsultnpm/sdk-ts';
|
|
2
2
|
import { DcmtInfo, DcmtOperationTypes, DownloadModes, DownloadTypes } from '../ts';
|
|
3
3
|
export interface RetrieveFormatOptions {
|
|
4
4
|
retrieveReason?: DcmtOpers;
|
|
5
|
+
cvtFormat?: FileFormats;
|
|
5
6
|
generalRetrieveFormat?: GeneralRetrieveFormats;
|
|
6
7
|
invoiceRetrieveFormat?: InvoiceRetrieveFormats;
|
|
7
8
|
orderRetrieveFormat?: OrderRetrieveFormats;
|
|
@@ -73,6 +73,8 @@ export const useDcmtOperations = () => {
|
|
|
73
73
|
abortController = new AbortController();
|
|
74
74
|
const rfo = new RetrieveFileOptions();
|
|
75
75
|
rfo.retrieveReason = retrieveOptions?.retrieveReason ?? DcmtOpers.ShowFile;
|
|
76
|
+
if (retrieveOptions?.cvtFormat !== undefined)
|
|
77
|
+
rfo.cvtFormat = retrieveOptions.cvtFormat;
|
|
76
78
|
if (retrieveOptions?.generalRetrieveFormat !== undefined)
|
|
77
79
|
rfo.generalRetrieveFormat = retrieveOptions.generalRetrieveFormat;
|
|
78
80
|
rfo.invoiceRetrieveFormat = retrieveOptions?.invoiceRetrieveFormat ?? SDKUI_Globals.userSettings.searchSettings.invoiceRetrieveFormat;
|
|
@@ -710,7 +710,7 @@ export const useDocumentOperations = (props) => {
|
|
|
710
710
|
{
|
|
711
711
|
id: 'merge-pdf-only-selected',
|
|
712
712
|
icon: _jsx("i", { className: "dx-icon-pdffile", style: { fontSize: '18px' } }),
|
|
713
|
-
name: '
|
|
713
|
+
name: 'I documenti selezionati',
|
|
714
714
|
onClick: () => {
|
|
715
715
|
setShowTMRelationViewerInCopyToFolderForm(false);
|
|
716
716
|
setOpenCopyToFolderForm({ open: true, operationType: 'mergeToPdf', mode: 'onlySelected' });
|
|
@@ -719,7 +719,7 @@ export const useDocumentOperations = (props) => {
|
|
|
719
719
|
{
|
|
720
720
|
id: 'merge-pdf-customized',
|
|
721
721
|
icon: _jsx("i", { className: "dx-icon-pdffile", style: { fontSize: '18px' } }),
|
|
722
|
-
name: '
|
|
722
|
+
name: 'I documenti selezionati e i correlati',
|
|
723
723
|
onClick: () => {
|
|
724
724
|
setShowTMRelationViewerInCopyToFolderForm(true);
|
|
725
725
|
setOpenCopyToFolderForm({ open: true, operationType: 'mergeToPdf', mode: 'customized' });
|
|
@@ -739,7 +739,7 @@ export const useDocumentOperations = (props) => {
|
|
|
739
739
|
{
|
|
740
740
|
id: 'copy-to-folder-only-selected',
|
|
741
741
|
icon: _jsx(IconCopy, {}),
|
|
742
|
-
name: '
|
|
742
|
+
name: 'I documenti selezionati',
|
|
743
743
|
onClick: () => {
|
|
744
744
|
setShowTMRelationViewerInCopyToFolderForm(false);
|
|
745
745
|
setOpenCopyToFolderForm({ open: true, operationType: 'copyToFolder', mode: 'onlySelected' });
|
|
@@ -748,7 +748,7 @@ export const useDocumentOperations = (props) => {
|
|
|
748
748
|
{
|
|
749
749
|
id: 'copy-to-folder-customized',
|
|
750
750
|
icon: _jsx(IconCopy, {}),
|
|
751
|
-
name: '
|
|
751
|
+
name: 'I documenti selezionati e i correlati',
|
|
752
752
|
onClick: () => {
|
|
753
753
|
setShowTMRelationViewerInCopyToFolderForm(true);
|
|
754
754
|
setOpenCopyToFolderForm({ open: true, operationType: 'copyToFolder', mode: 'customized', });
|
|
@@ -1263,7 +1263,7 @@ export const useDocumentOperations = (props) => {
|
|
|
1263
1263
|
updateBatchUpdateForm(false);
|
|
1264
1264
|
setIsModifiedBatchUpdate(false);
|
|
1265
1265
|
await onRefreshDataRowsAsync?.();
|
|
1266
|
-
}, onStatusChanged: (isModified) => { setIsModifiedBatchUpdate(isModified); } }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, selectedItems: approvalVID ? selectedDcmtInfos.map(item => ({ ...item, TID: approvalVID })) : selectedDcmtInfos, isReject: 0, onClose: () => updateShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, selectedItems: approvalVID ? selectedDcmtInfos.map(item => ({ ...item, TID: approvalVID })) : selectedDcmtInfos, isReject: 1, onClose: () => updateShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, selectedItems: approvalVID ? selectedDcmtInfos.map(item => ({ ...item, TID: approvalVID })) : selectedDcmtInfos, onClose: () => updateShowReAssignPopup(false) }), showMoreInfoPopup && _jsx(WorkFlowMoreInfoPopUp, { fromDTD: dtd, TID: contextConfig.approvalTID, DID: focusedItem?.DID, deviceType: deviceType, onCompleted: handleWFOperationCompleted, onClose: () => updateShowMoreInfoPopup(false), allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, triggerBlogRefresh: onRefreshBlogDatagrid }), openCopyToFolderForm.open && openCopyToFolderForm.operationType === 'mergeToPdf' && _jsx(TMMergeToPdfForm, { mode: openCopyToFolderForm.mode, selectedDcmtInfos: selectedDcmtInfos, onClose: () => setOpenCopyToFolderForm({ open: false, operationType: 'copyToFolder', mode: 'onlySelected' }), showTMRelationViewer: showTMRelationViewerInCopyToFolderForm, mergePdfManager: mergePdfManager }), openCopyToFolderForm.open && openCopyToFolderForm.operationType === 'copyToFolder' && _jsx(TMCopyToFolderForm, { mode: openCopyToFolderForm.mode, selectedDcmtInfos: selectedDcmtInfos, onClose: () => setOpenCopyToFolderForm({ open: false, operationType: 'copyToFolder', mode: 'onlySelected' }), showTMRelationViewer: showTMRelationViewerInCopyToFolderForm }), _jsx(ConfirmFormatDialog, {}), _jsx(ConfirmAttachmentsDialog, {}), _jsx(FileSourceDialog, {}), taskFormDialogComponent, s4TViewerDialogComponent, currentCustomButton && _jsx(TMCustomButton, { button: currentCustomButton, formData: currentMetadataValues, selectedItems: selectedItemsFull, onClose: () => setCurrentCustomButton(undefined) })] }));
|
|
1266
|
+
}, onStatusChanged: (isModified) => { setIsModifiedBatchUpdate(isModified); } }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, selectedItems: approvalVID ? selectedDcmtInfos.map(item => ({ ...item, TID: approvalVID })) : selectedDcmtInfos, isReject: 0, onClose: () => updateShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, selectedItems: approvalVID ? selectedDcmtInfos.map(item => ({ ...item, TID: approvalVID })) : selectedDcmtInfos, isReject: 1, onClose: () => updateShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, selectedItems: approvalVID ? selectedDcmtInfos.map(item => ({ ...item, TID: approvalVID })) : selectedDcmtInfos, onClose: () => updateShowReAssignPopup(false) }), showMoreInfoPopup && _jsx(WorkFlowMoreInfoPopUp, { fromDTD: dtd, TID: contextConfig.approvalTID, DID: focusedItem?.DID, deviceType: deviceType, onCompleted: handleWFOperationCompleted, onClose: () => updateShowMoreInfoPopup(false), allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, triggerBlogRefresh: onRefreshBlogDatagrid }), openCopyToFolderForm.open && openCopyToFolderForm.operationType === 'mergeToPdf' && _jsx(TMMergeToPdfForm, { mode: openCopyToFolderForm.mode, selectedDcmtInfos: selectedDcmtInfos, onClose: () => setOpenCopyToFolderForm({ open: false, operationType: 'copyToFolder', mode: 'onlySelected' }), showTMRelationViewer: showTMRelationViewerInCopyToFolderForm, mergePdfManager: mergePdfManager, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), openCopyToFolderForm.open && openCopyToFolderForm.operationType === 'copyToFolder' && _jsx(TMCopyToFolderForm, { mode: openCopyToFolderForm.mode, selectedDcmtInfos: selectedDcmtInfos, onClose: () => setOpenCopyToFolderForm({ open: false, operationType: 'copyToFolder', mode: 'onlySelected' }), showTMRelationViewer: showTMRelationViewerInCopyToFolderForm, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), _jsx(ConfirmFormatDialog, {}), _jsx(ConfirmAttachmentsDialog, {}), _jsx(FileSourceDialog, {}), taskFormDialogComponent, s4TViewerDialogComponent, currentCustomButton && _jsx(TMCustomButton, { button: currentCustomButton, formData: currentMetadataValues, selectedItems: selectedItemsFull, onClose: () => setCurrentCustomButton(undefined) })] }));
|
|
1267
1267
|
return {
|
|
1268
1268
|
operationItems: operationItems(),
|
|
1269
1269
|
renderFloatingBar,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topconsultnpm/sdkui-react",
|
|
3
|
-
"version": "6.21.0-dev2.
|
|
3
|
+
"version": "6.21.0-dev2.39",
|
|
4
4
|
"description": "",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"lib"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@topconsultnpm/sdk-ts": "6.21.0-dev2.
|
|
43
|
+
"@topconsultnpm/sdk-ts": "6.21.0-dev2.7",
|
|
44
44
|
"@zip.js/zip.js": "2.8.26",
|
|
45
45
|
"buffer": "^6.0.3",
|
|
46
46
|
"devextreme": "^25.2.6",
|