@topconsultnpm/sdkui-react 6.21.0-dev2.53 → 6.21.0-dev2.54
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/features/documents/copyAndMergeDcmtsShared.d.ts +3 -2
- package/lib/components/features/documents/copyAndMergeDcmtsShared.js +15 -12
- package/lib/components/forms/TMResultDialog.d.ts +1 -1
- package/lib/components/forms/TMResultDialog.js +4 -2
- package/lib/hooks/useDcmtOperations.d.ts +1 -1
- package/lib/hooks/useDcmtOperations.js +8 -8
- package/lib/hooks/useDocumentOperations.js +34 -23
- package/package.json +1 -1
|
@@ -18,16 +18,17 @@ export declare const isDirectoryPickerSupported: () => boolean;
|
|
|
18
18
|
export declare const isPdfExt: (ext: string | null | undefined) => boolean;
|
|
19
19
|
/**
|
|
20
20
|
* Estrae l'estensione completa da un nome file, gestendo estensioni composite
|
|
21
|
-
* come .PDF.P7M, .
|
|
21
|
+
* a più livelli come .PDF.P7M, .XML.P7M.TS, etc.
|
|
22
22
|
*
|
|
23
23
|
* Esempi:
|
|
24
24
|
* - "documento.pdf" -> ".pdf"
|
|
25
25
|
* - "DCMT_123.PDF.P7M" -> ".PDF.P7M"
|
|
26
26
|
* - "fattura.xml.p7m" -> ".xml.p7m"
|
|
27
|
+
* - "example.XML.P7M.TS" -> ".XML.P7M.TS"
|
|
27
28
|
* - "file.tar.gz" -> ".gz" (tar.gz non è gestito come firma)
|
|
28
29
|
* - "file" -> ""
|
|
29
30
|
*/
|
|
30
|
-
export declare const getFullFileExtension: (fileName: string) => string;
|
|
31
|
+
export declare const getFullFileExtension: (fileName: string, depth?: number) => string;
|
|
31
32
|
/**
|
|
32
33
|
* Estrae il nome base del file (senza estensione completa).
|
|
33
34
|
* Gestisce estensioni composite come .PDF.P7M
|
|
@@ -60,37 +60,40 @@ export const isPdfExt = (ext) => {
|
|
|
60
60
|
};
|
|
61
61
|
/**
|
|
62
62
|
* Estensioni di firma/marca temporale note che possono avvolgere altre estensioni.
|
|
63
|
-
* Es: file.pdf.p7m, file.xml.p7m, file.docx.p7m
|
|
63
|
+
* Es: file.pdf.p7m, file.xml.p7m, file.docx.p7m, file.xml.p7m.ts
|
|
64
64
|
*/
|
|
65
|
-
const SIGNATURE_EXTENSIONS = new Set(['p7m', 'p7s', 'm7m', 'tsd', 'tsr']);
|
|
65
|
+
const SIGNATURE_EXTENSIONS = new Set(['p7m', 'p7s', 'm7m', 'tsd', 'tsr', 'ts']);
|
|
66
|
+
/** Profondità massima di ricorsione per la ricerca di estensioni composite */
|
|
67
|
+
const MAX_EXTENSION_DEPTH = 5;
|
|
66
68
|
/**
|
|
67
69
|
* Estrae l'estensione completa da un nome file, gestendo estensioni composite
|
|
68
|
-
* come .PDF.P7M, .
|
|
70
|
+
* a più livelli come .PDF.P7M, .XML.P7M.TS, etc.
|
|
69
71
|
*
|
|
70
72
|
* Esempi:
|
|
71
73
|
* - "documento.pdf" -> ".pdf"
|
|
72
74
|
* - "DCMT_123.PDF.P7M" -> ".PDF.P7M"
|
|
73
75
|
* - "fattura.xml.p7m" -> ".xml.p7m"
|
|
76
|
+
* - "example.XML.P7M.TS" -> ".XML.P7M.TS"
|
|
74
77
|
* - "file.tar.gz" -> ".gz" (tar.gz non è gestito come firma)
|
|
75
78
|
* - "file" -> ""
|
|
76
79
|
*/
|
|
77
|
-
export const getFullFileExtension = (fileName) => {
|
|
78
|
-
if (!fileName)
|
|
80
|
+
export const getFullFileExtension = (fileName, depth = 0) => {
|
|
81
|
+
if (!fileName || depth > MAX_EXTENSION_DEPTH)
|
|
79
82
|
return '';
|
|
80
83
|
const lastDotIndex = fileName.lastIndexOf('.');
|
|
81
84
|
if (lastDotIndex <= 0)
|
|
82
85
|
return '';
|
|
83
86
|
const lastExtension = fileName.substring(lastDotIndex + 1).toLowerCase();
|
|
84
|
-
// Se l'ultima estensione è una firma/marca, cerca
|
|
87
|
+
// Se l'ultima estensione è una firma/marca, cerca ricorsivamente le estensioni precedenti
|
|
85
88
|
if (SIGNATURE_EXTENSIONS.has(lastExtension)) {
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
89
|
-
//
|
|
90
|
-
return fileName.substring(
|
|
89
|
+
const nameWithoutLastExt = fileName.substring(0, lastDotIndex);
|
|
90
|
+
const innerExtension = getFullFileExtension(nameWithoutLastExt, depth + 1);
|
|
91
|
+
if (innerExtension) {
|
|
92
|
+
// Concatena l'estensione interna con quella corrente
|
|
93
|
+
return innerExtension + fileName.substring(lastDotIndex);
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
|
-
// Estensione singola
|
|
96
|
+
// Estensione singola (o estensione base dopo le firme)
|
|
94
97
|
return fileName.substring(lastDotIndex);
|
|
95
98
|
};
|
|
96
99
|
/**
|
|
@@ -16,5 +16,5 @@ interface ITMResultDialogProps {
|
|
|
16
16
|
declare const TMResultDialog: React.FC<ITMResultDialogProps>;
|
|
17
17
|
export default TMResultDialog;
|
|
18
18
|
export declare class TMResultManager {
|
|
19
|
-
static show(result: ResultInfo[], title: string, id1Caption: string | undefined, id2Caption: string | undefined, customMsg?: string, customDuration?: number): void;
|
|
19
|
+
static show(result: ResultInfo[], title: string, id1Caption: string | undefined, id2Caption: string | undefined, customMsg?: string, customDuration?: number, showSuccessAlert?: boolean): void;
|
|
20
20
|
}
|
|
@@ -29,11 +29,13 @@ const TMResultDialog = ({ title, result, id1Caption, id2Caption }) => {
|
|
|
29
29
|
};
|
|
30
30
|
export default TMResultDialog;
|
|
31
31
|
export class TMResultManager {
|
|
32
|
-
static show(result, title, id1Caption, id2Caption, customMsg, customDuration) {
|
|
32
|
+
static show(result, title, id1Caption, id2Caption, customMsg, customDuration, showSuccessAlert = true) {
|
|
33
33
|
const warningsCount = result.filter(o => o.resultType == ResultTypes.WARNING).length;
|
|
34
34
|
const errorsCount = result.filter(o => o.resultType == ResultTypes.ERROR).length;
|
|
35
35
|
if (warningsCount <= 0 && errorsCount <= 0) {
|
|
36
|
-
|
|
36
|
+
if (showSuccessAlert) {
|
|
37
|
+
ShowAlert({ message: customMsg && customMsg.length > 0 ? customMsg : SDKUI_Localizator.OperationSuccess, mode: 'success', duration: customDuration && customDuration > 0 ? customDuration : 3000, title: title });
|
|
38
|
+
}
|
|
37
39
|
return;
|
|
38
40
|
}
|
|
39
41
|
let container = document.createElement('div');
|
|
@@ -19,7 +19,7 @@ export interface UseDcmtOperationsReturn {
|
|
|
19
19
|
waitPanelTextSecondary: string;
|
|
20
20
|
waitPanelValueSecondary: number;
|
|
21
21
|
waitPanelMaxValueSecondary: number;
|
|
22
|
-
downloadDcmtsAsync: (inputDcmts: DcmtInfo[] | undefined, downloadType?: DownloadTypes, downloadMode?: DownloadModes, onFileDownloaded?: (dcmtFile: File, dcmtInfo: DcmtInfo) => void | Promise<void>, confirmAttachments?: (list: FileDescriptor[]) => Promise<string[] | undefined>, skipConfirmation?: boolean, retrieveOptions?: RetrieveFormatOptions, useCache?: boolean) => Promise<void>;
|
|
22
|
+
downloadDcmtsAsync: (inputDcmts: DcmtInfo[] | undefined, downloadType?: DownloadTypes, downloadMode?: DownloadModes, onFileDownloaded?: (dcmtFile: File, dcmtInfo: DcmtInfo) => void | Promise<void>, confirmAttachments?: (list: FileDescriptor[]) => Promise<string[] | undefined>, skipConfirmation?: boolean, retrieveOptions?: RetrieveFormatOptions, useCache?: boolean, showSuccessAlert?: boolean) => Promise<void>;
|
|
23
23
|
getDcmtFileAsync: (inputDcmt: DcmtInfo | undefined, rfo: RetrieveFileOptions, operationTitle: string, keepWaitPanelPrimary: boolean, bypassCache?: boolean) => Promise<{
|
|
24
24
|
file: File | undefined;
|
|
25
25
|
isFromCache: boolean;
|
|
@@ -75,7 +75,7 @@ export const useDcmtOperations = () => {
|
|
|
75
75
|
const [waitPanelMaxValueSecondary, setWaitPanelMaxValueSecondary] = useState(0);
|
|
76
76
|
const { OpenFileDialog } = useFileDialog();
|
|
77
77
|
const [selectFileSource, FileSourceDialog] = useFileSourceDialog();
|
|
78
|
-
const _downloadDcmtsAsync = async (inputDcmts, downloadMode = "download", onFileDownloaded, skipConfirmation = false, retrieveOptions, useCache = true) => {
|
|
78
|
+
const _downloadDcmtsAsync = async (inputDcmts, downloadMode = "download", onFileDownloaded, skipConfirmation = false, retrieveOptions, useCache = true, showSuccessAlert = true) => {
|
|
79
79
|
if (inputDcmts === undefined)
|
|
80
80
|
return;
|
|
81
81
|
if (inputDcmts.length <= 0)
|
|
@@ -189,9 +189,9 @@ export const useDcmtOperations = () => {
|
|
|
189
189
|
setWaitPanelMaxValueSecondary(0);
|
|
190
190
|
setWaitPanelValueSecondary(0);
|
|
191
191
|
setShowWaitPanel(false);
|
|
192
|
-
TMResultManager.show(result, operationTitle, "TID", "DID");
|
|
192
|
+
TMResultManager.show(result, operationTitle, "TID", "DID", undefined, undefined, showSuccessAlert);
|
|
193
193
|
};
|
|
194
|
-
const _downloadAttachmentsAsync = async (inputDcmts, confirmAttachments) => {
|
|
194
|
+
const _downloadAttachmentsAsync = async (inputDcmts, confirmAttachments, showSuccessAlert = true) => {
|
|
195
195
|
if (inputDcmts === undefined)
|
|
196
196
|
return;
|
|
197
197
|
if (inputDcmts.length !== 1)
|
|
@@ -239,7 +239,7 @@ export const useDcmtOperations = () => {
|
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
|
-
TMResultManager.show(result, operationTitle, "TID", "DID");
|
|
242
|
+
TMResultManager.show(result, operationTitle, "TID", "DID", undefined, undefined, showSuccessAlert);
|
|
243
243
|
}
|
|
244
244
|
catch (ex) {
|
|
245
245
|
TMSpinner.hide();
|
|
@@ -251,11 +251,11 @@ export const useDcmtOperations = () => {
|
|
|
251
251
|
TMExceptionBoxManager.show({ exception: err });
|
|
252
252
|
}
|
|
253
253
|
};
|
|
254
|
-
const downloadDcmtsAsync = async (inputDcmts, downloadType = DownloadTypes.Attachment, downloadMode = "download", onFileDownloaded, confirmAttachments, skipConfirmation = false, retrieveOptions, useCache = true) => {
|
|
254
|
+
const downloadDcmtsAsync = async (inputDcmts, downloadType = DownloadTypes.Attachment, downloadMode = "download", onFileDownloaded, confirmAttachments, skipConfirmation = false, retrieveOptions, useCache = true, showSuccessAlert = true) => {
|
|
255
255
|
switch (downloadType) {
|
|
256
|
-
case DownloadTypes.Dcmt: return await _downloadDcmtsAsync(inputDcmts, downloadMode, onFileDownloaded, skipConfirmation, retrieveOptions, useCache);
|
|
257
|
-
case DownloadTypes.Attachment: return await _downloadAttachmentsAsync(inputDcmts, confirmAttachments);
|
|
258
|
-
default: return await _downloadDcmtsAsync(inputDcmts, undefined, undefined, skipConfirmation, retrieveOptions, useCache);
|
|
256
|
+
case DownloadTypes.Dcmt: return await _downloadDcmtsAsync(inputDcmts, downloadMode, onFileDownloaded, skipConfirmation, retrieveOptions, useCache, showSuccessAlert);
|
|
257
|
+
case DownloadTypes.Attachment: return await _downloadAttachmentsAsync(inputDcmts, confirmAttachments, showSuccessAlert);
|
|
258
|
+
default: return await _downloadDcmtsAsync(inputDcmts, undefined, undefined, skipConfirmation, retrieveOptions, useCache, showSuccessAlert);
|
|
259
259
|
}
|
|
260
260
|
};
|
|
261
261
|
const uploadDcmtsAsync = async (inputDcmts, operationTitle, operType, actionAfterOperationAsync) => {
|
|
@@ -23,7 +23,6 @@ import { useInputAttachmentsDialog, useInputCvtFormatDialog } from "./useInputDi
|
|
|
23
23
|
import { useRelatedDocuments } from "./useRelatedDocuments";
|
|
24
24
|
import { convertSearchResultDescriptorToFileItems, dcmtsFileCachePreview, getDcmtCicoStatus, getMoreInfoTasksForDocument, IconActivity, IconArchiveDetail, IconArchiveDoc, IconArchiveMaster, IconBatchUpdate, IconCheck, IconCheckFile, IconCheckIn, IconCircleInfo, IconCloseCircle, IconConvertFilePdf, IconCopy, IconCustom, IconDelete, IconDetailDcmts, IconDotsVerticalCircleOutline, IconDownload, IconEdit, IconExportTo, IconFileDots, IconHide, IconInfo, IconMenuCAArchive, IconMoveToFolder, IconPair, IconPin, IconPlatform, IconPreview, IconRelation, IconSearch, IconShare, IconSharedDcmt, IconShow, IconSignaturePencil, IconStar, IconSubstFile, IconUndo, IconUnpair, IconUserGroupOutline, isPdfEditorAvailable, SDKUI_Localizator, searchResultToMetadataValues, TMImageLibrary } from '../helper';
|
|
25
25
|
import { isXMLFileExt } from "../helper/dcmtsHelper";
|
|
26
|
-
import { isPdfExt } from "../components/features/documents/copyAndMergeDcmtsShared";
|
|
27
26
|
import TMCopyToFolderForm from "../components/features/documents/TMCopyToFolderForm";
|
|
28
27
|
import TMMergeToPdfForm from "../components/features/documents/TMMergeToPdfForm";
|
|
29
28
|
export const getSelectedDcmtsOrFocused = (selectedItems, focusedItem, fileFormat) => {
|
|
@@ -569,7 +568,10 @@ export const useDocumentOperations = (props) => {
|
|
|
569
568
|
};
|
|
570
569
|
};
|
|
571
570
|
const printMenuItem = () => {
|
|
572
|
-
|
|
571
|
+
// Take the first document (used for validation checks)
|
|
572
|
+
const firstDoc = selectedDcmtInfos?.[0];
|
|
573
|
+
// Check if the selected document is a PDF
|
|
574
|
+
const isPdf = firstDoc?.FILEEXT?.toLowerCase() === "pdf";
|
|
573
575
|
return {
|
|
574
576
|
id: 'print',
|
|
575
577
|
icon: _jsx("i", { className: "dx-icon-print", style: { fontSize: '20px' } }),
|
|
@@ -579,27 +581,36 @@ export const useDocumentOperations = (props) => {
|
|
|
579
581
|
onClick: isPdf ? async () => {
|
|
580
582
|
const handlePrint = async (file, _dcmtInfo) => {
|
|
581
583
|
const fileURL = window.URL.createObjectURL(file);
|
|
582
|
-
// Usa un iframe nascosto
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
584
|
+
// Usa un iframe nascosto con sandbox per:
|
|
585
|
+
// 1. Bloccare l'esecuzione di JavaScript nel PDF
|
|
586
|
+
// 2. Non aprire un nuovo tab
|
|
587
|
+
const printFrame = document.createElement('iframe');
|
|
588
|
+
printFrame.style.position = 'fixed';
|
|
589
|
+
printFrame.style.right = '0';
|
|
590
|
+
printFrame.style.bottom = '0';
|
|
591
|
+
printFrame.style.width = '0';
|
|
592
|
+
printFrame.style.height = '0';
|
|
593
|
+
printFrame.style.border = 'none';
|
|
594
|
+
// sandbox senza 'allow-scripts' blocca l'esecuzione di JS
|
|
595
|
+
/* printFrame.sandbox.add('allow-same-origin'); */
|
|
596
|
+
printFrame.src = fileURL;
|
|
597
|
+
document.body.appendChild(printFrame);
|
|
598
|
+
printFrame.onload = () => {
|
|
599
|
+
try {
|
|
600
|
+
printFrame.contentWindow?.focus();
|
|
601
|
+
printFrame.contentWindow?.print();
|
|
602
|
+
}
|
|
603
|
+
catch (e) {
|
|
604
|
+
console.error('Errore durante la stampa:', e);
|
|
605
|
+
}
|
|
606
|
+
// Cleanup dopo un delay per permettere la stampa
|
|
596
607
|
setTimeout(() => {
|
|
597
|
-
document.body.removeChild(
|
|
608
|
+
document.body.removeChild(printFrame);
|
|
598
609
|
window.URL.revokeObjectURL(fileURL);
|
|
599
|
-
},
|
|
610
|
+
}, 60000);
|
|
600
611
|
};
|
|
601
612
|
};
|
|
602
|
-
await downloadDcmtsAsync(selectedDcmtInfos, DownloadTypes.Dcmt, "download", handlePrint, undefined, true);
|
|
613
|
+
await downloadDcmtsAsync(selectedDcmtInfos, DownloadTypes.Dcmt, "download", handlePrint, undefined, true, undefined, true, false);
|
|
603
614
|
} : undefined,
|
|
604
615
|
};
|
|
605
616
|
};
|
|
@@ -1118,7 +1129,7 @@ export const useDocumentOperations = (props) => {
|
|
|
1118
1129
|
batchUpdateMenuItem(),
|
|
1119
1130
|
passToArchive(),
|
|
1120
1131
|
...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
|
|
1121
|
-
printMenuItem()
|
|
1132
|
+
...(!isMobile ? [printMenuItem()] : [])
|
|
1122
1133
|
]
|
|
1123
1134
|
},
|
|
1124
1135
|
signatureMenuItem(),
|
|
@@ -1162,7 +1173,7 @@ export const useDocumentOperations = (props) => {
|
|
|
1162
1173
|
commentFromWgMenuItem(false),
|
|
1163
1174
|
relationsMenuItem(true),
|
|
1164
1175
|
removeFromWgMenuItem(SDKUI_Localizator.RemoveFromWorkgroup),
|
|
1165
|
-
printMenuItem()
|
|
1176
|
+
...(!isMobile ? [printMenuItem()] : [])
|
|
1166
1177
|
].sort((a, b) => a.name.localeCompare(b.name));
|
|
1167
1178
|
return [
|
|
1168
1179
|
...sortedItems,
|
|
@@ -1186,7 +1197,7 @@ export const useDocumentOperations = (props) => {
|
|
|
1186
1197
|
downloadFileMenuItem(),
|
|
1187
1198
|
downloadXMLAttachmentsMenuItem(),
|
|
1188
1199
|
...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
|
|
1189
|
-
printMenuItem()
|
|
1200
|
+
...(!isMobile ? [printMenuItem()] : [])
|
|
1190
1201
|
]
|
|
1191
1202
|
},
|
|
1192
1203
|
signatureMenuItem(),
|
|
@@ -1213,7 +1224,7 @@ export const useDocumentOperations = (props) => {
|
|
|
1213
1224
|
downloadFileMenuItem(),
|
|
1214
1225
|
downloadXMLAttachmentsMenuItem(),
|
|
1215
1226
|
...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
|
|
1216
|
-
printMenuItem()
|
|
1227
|
+
...(!isMobile ? [printMenuItem()] : [])
|
|
1217
1228
|
]
|
|
1218
1229
|
},
|
|
1219
1230
|
signatureMenuItem(),
|