@topconsultnpm/sdkui-react 6.21.0-dev2.51 → 6.21.0-dev2.53
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/TMMergeToPdfForm.js +1 -1
- package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +17 -0
- package/lib/components/features/documents/copyAndMergeDcmtsShared.js +56 -14
- package/lib/helper/SDKUI_Localizator.d.ts +1 -0
- package/lib/helper/SDKUI_Localizator.js +10 -0
- package/lib/hooks/useDocumentOperations.js +41 -1
- package/package.json +1 -1
|
@@ -144,7 +144,7 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
144
144
|
const pdfFiles = [];
|
|
145
145
|
const rfo = new RetrieveFileOptions();
|
|
146
146
|
rfo.retrieveReason = DcmtOpers.None;
|
|
147
|
-
rfo.generalRetrieveFormat = GeneralRetrieveFormats.
|
|
147
|
+
rfo.generalRetrieveFormat = GeneralRetrieveFormats.OriginalUnsigned;
|
|
148
148
|
rfo.cvtFormat = FileFormats.PDF;
|
|
149
149
|
rfo.invoiceRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.invoiceRetrieveFormat;
|
|
150
150
|
rfo.orderRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.orderRetrieveFormat;
|
|
@@ -16,6 +16,23 @@ export declare const isDirectoryPickerSupported: () => boolean;
|
|
|
16
16
|
* Verifica se un'estensione (con o senza punto iniziale, case-insensitive) è "pdf".
|
|
17
17
|
*/
|
|
18
18
|
export declare const isPdfExt: (ext: string | null | undefined) => boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Estrae l'estensione completa da un nome file, gestendo estensioni composite
|
|
21
|
+
* come .PDF.P7M, .DOCX.p7m, .xml.p7m, etc.
|
|
22
|
+
*
|
|
23
|
+
* Esempi:
|
|
24
|
+
* - "documento.pdf" -> ".pdf"
|
|
25
|
+
* - "DCMT_123.PDF.P7M" -> ".PDF.P7M"
|
|
26
|
+
* - "fattura.xml.p7m" -> ".xml.p7m"
|
|
27
|
+
* - "file.tar.gz" -> ".gz" (tar.gz non è gestito come firma)
|
|
28
|
+
* - "file" -> ""
|
|
29
|
+
*/
|
|
30
|
+
export declare const getFullFileExtension: (fileName: string) => string;
|
|
31
|
+
/**
|
|
32
|
+
* Estrae il nome base del file (senza estensione completa).
|
|
33
|
+
* Gestisce estensioni composite come .PDF.P7M
|
|
34
|
+
*/
|
|
35
|
+
export declare const getFileBaseName: (fileName: string) => string;
|
|
19
36
|
/** Sanitizza il nome file per Windows (rimuove caratteri illegali e limita la lunghezza) */
|
|
20
37
|
export declare const sanitizeFileName: (fileName: string, fallbackName: string, maxLength?: number) => string;
|
|
21
38
|
/** Verifica se un file esiste nella cartella (FileSystemDirectoryHandle) */
|
|
@@ -58,6 +58,53 @@ export const isPdfExt = (ext) => {
|
|
|
58
58
|
const normalized = ext.trim().toLowerCase().replace(/^\./, '');
|
|
59
59
|
return normalized === 'pdf';
|
|
60
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* Estensioni di firma/marca temporale note che possono avvolgere altre estensioni.
|
|
63
|
+
* Es: file.pdf.p7m, file.xml.p7m, file.docx.p7m
|
|
64
|
+
*/
|
|
65
|
+
const SIGNATURE_EXTENSIONS = new Set(['p7m', 'p7s', 'm7m', 'tsd', 'tsr']);
|
|
66
|
+
/**
|
|
67
|
+
* Estrae l'estensione completa da un nome file, gestendo estensioni composite
|
|
68
|
+
* come .PDF.P7M, .DOCX.p7m, .xml.p7m, etc.
|
|
69
|
+
*
|
|
70
|
+
* Esempi:
|
|
71
|
+
* - "documento.pdf" -> ".pdf"
|
|
72
|
+
* - "DCMT_123.PDF.P7M" -> ".PDF.P7M"
|
|
73
|
+
* - "fattura.xml.p7m" -> ".xml.p7m"
|
|
74
|
+
* - "file.tar.gz" -> ".gz" (tar.gz non è gestito come firma)
|
|
75
|
+
* - "file" -> ""
|
|
76
|
+
*/
|
|
77
|
+
export const getFullFileExtension = (fileName) => {
|
|
78
|
+
if (!fileName)
|
|
79
|
+
return '';
|
|
80
|
+
const lastDotIndex = fileName.lastIndexOf('.');
|
|
81
|
+
if (lastDotIndex <= 0)
|
|
82
|
+
return '';
|
|
83
|
+
const lastExtension = fileName.substring(lastDotIndex + 1).toLowerCase();
|
|
84
|
+
// Se l'ultima estensione è una firma/marca, cerca anche l'estensione precedente
|
|
85
|
+
if (SIGNATURE_EXTENSIONS.has(lastExtension)) {
|
|
86
|
+
const nameWithoutSignature = fileName.substring(0, lastDotIndex);
|
|
87
|
+
const secondLastDotIndex = nameWithoutSignature.lastIndexOf('.');
|
|
88
|
+
if (secondLastDotIndex > 0) {
|
|
89
|
+
// Restituisce entrambe le estensioni: .PDF.P7M
|
|
90
|
+
return fileName.substring(secondLastDotIndex);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Estensione singola
|
|
94
|
+
return fileName.substring(lastDotIndex);
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Estrae il nome base del file (senza estensione completa).
|
|
98
|
+
* Gestisce estensioni composite come .PDF.P7M
|
|
99
|
+
*/
|
|
100
|
+
export const getFileBaseName = (fileName) => {
|
|
101
|
+
if (!fileName)
|
|
102
|
+
return '';
|
|
103
|
+
const fullExtension = getFullFileExtension(fileName);
|
|
104
|
+
if (!fullExtension)
|
|
105
|
+
return fileName;
|
|
106
|
+
return fileName.substring(0, fileName.length - fullExtension.length);
|
|
107
|
+
};
|
|
61
108
|
// ============================================================
|
|
62
109
|
// Sanitizzazione e gestione nomi file
|
|
63
110
|
// ============================================================
|
|
@@ -72,10 +119,9 @@ export const sanitizeFileName = (fileName, fallbackName, maxLength = 255) => {
|
|
|
72
119
|
.trim();
|
|
73
120
|
sanitized = sanitized.replace(/[. ]+$/, '');
|
|
74
121
|
if (sanitized.length > maxLength) {
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
77
|
-
const
|
|
78
|
-
const baseName = sanitized.substring(0, lastDotIndex);
|
|
122
|
+
const extension = getFullFileExtension(sanitized);
|
|
123
|
+
if (extension) {
|
|
124
|
+
const baseName = getFileBaseName(sanitized);
|
|
79
125
|
const maxBaseLength = maxLength - extension.length;
|
|
80
126
|
sanitized = baseName.substring(0, maxBaseLength) + extension;
|
|
81
127
|
}
|
|
@@ -101,14 +147,9 @@ export const fileExists = async (dirHandle, fileName) => {
|
|
|
101
147
|
};
|
|
102
148
|
/** Genera un nome file univoco aggiungendo un suffisso numerico se già esistente */
|
|
103
149
|
export const generateUniqueFileName = async (dirHandle, originalName) => {
|
|
104
|
-
const splitName = (name) => {
|
|
105
|
-
const lastDotIndex = name.lastIndexOf('.');
|
|
106
|
-
const baseName = lastDotIndex > 0 ? name.substring(0, lastDotIndex) : name;
|
|
107
|
-
const extension = lastDotIndex > 0 ? name.substring(lastDotIndex) : '';
|
|
108
|
-
return { baseName, extension };
|
|
109
|
-
};
|
|
110
150
|
try {
|
|
111
|
-
const
|
|
151
|
+
const baseName = getFileBaseName(originalName);
|
|
152
|
+
const extension = getFullFileExtension(originalName);
|
|
112
153
|
const MAX_ATTEMPTS = 1000;
|
|
113
154
|
for (let counter = 1; counter <= MAX_ATTEMPTS; counter++) {
|
|
114
155
|
const candidateName = counter === 1 ? originalName : `${baseName} (${counter - 1})${extension}`;
|
|
@@ -122,7 +163,8 @@ export const generateUniqueFileName = async (dirHandle, originalName) => {
|
|
|
122
163
|
return `${baseName}_${Date.now()}${extension}`;
|
|
123
164
|
}
|
|
124
165
|
catch {
|
|
125
|
-
const
|
|
166
|
+
const baseName = getFileBaseName(originalName);
|
|
167
|
+
const extension = getFullFileExtension(originalName);
|
|
126
168
|
return `${baseName}_${Date.now()}${extension}`;
|
|
127
169
|
}
|
|
128
170
|
};
|
|
@@ -174,8 +216,8 @@ export const getFilteredMetadata = async (tid, did, separatorChar) => {
|
|
|
174
216
|
/** Genera il nome file di destinazione in base alle impostazioni di naming */
|
|
175
217
|
export const generateTargetFileName = async (file, dcmtInfo, options) => {
|
|
176
218
|
const { fileNamingMode, separatorChar } = options;
|
|
177
|
-
|
|
178
|
-
const fileExtension =
|
|
219
|
+
// Usa getFullFileExtension per gestire estensioni composite come .PDF.P7M, .DOCX.p7m
|
|
220
|
+
const fileExtension = getFullFileExtension(file.name);
|
|
179
221
|
const fallbackName = dcmtInfo.DID + fileExtension;
|
|
180
222
|
let targetFileName = file.name;
|
|
181
223
|
switch (fileNamingMode) {
|
|
@@ -597,6 +597,7 @@ export declare class SDKUI_Localizator {
|
|
|
597
597
|
static get Previous(): "Vorherige" | "Previous" | "Anterior" | "Précédent" | "Precedente";
|
|
598
598
|
static get Priority(): string;
|
|
599
599
|
static get PriorityLegend(): "Legende der Prioritäten" | "Priority Legend" | "Leyenda de prioridades" | "Légende des priorités" | "Lenda das prioridades" | "Legenda delle priorità";
|
|
600
|
+
static get Print(): "Drucken" | "Print" | "Imprimir" | "Imprimer" | "Stampa";
|
|
600
601
|
static get ProceedAnyway(): "Dennoch fortfahren?" | "Proceed anyway?" | "¿Proceder de todos modos?" | "Procéder quand même ?" | "Prosseguir mesmo assim?" | "Procedere comunque?";
|
|
601
602
|
static get ProcessedItems(): "Durchdachte Elemente" | "Processed items" | "Elementos elaborados" | "Items traités" | "Itens processados" | "Elementi elaborati";
|
|
602
603
|
static get Properties(): "Eigenschaften" | "Properties" | "Propiedades" | "Propriétés" | "Propriedades" | "Proprietà";
|
|
@@ -5942,6 +5942,16 @@ export class SDKUI_Localizator {
|
|
|
5942
5942
|
default: return "Legenda delle priorità";
|
|
5943
5943
|
}
|
|
5944
5944
|
}
|
|
5945
|
+
static get Print() {
|
|
5946
|
+
switch (this._cultureID) {
|
|
5947
|
+
case CultureIDs.De_DE: return "Drucken";
|
|
5948
|
+
case CultureIDs.En_US: return "Print";
|
|
5949
|
+
case CultureIDs.Es_ES: return "Imprimir";
|
|
5950
|
+
case CultureIDs.Fr_FR: return "Imprimer";
|
|
5951
|
+
case CultureIDs.Pt_PT: return "Imprimir";
|
|
5952
|
+
default: return "Stampa";
|
|
5953
|
+
}
|
|
5954
|
+
}
|
|
5945
5955
|
static get ProceedAnyway() {
|
|
5946
5956
|
switch (this._cultureID) {
|
|
5947
5957
|
case CultureIDs.De_DE: return "Dennoch fortfahren?";
|
|
@@ -23,6 +23,7 @@ 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";
|
|
26
27
|
import TMCopyToFolderForm from "../components/features/documents/TMCopyToFolderForm";
|
|
27
28
|
import TMMergeToPdfForm from "../components/features/documents/TMMergeToPdfForm";
|
|
28
29
|
export const getSelectedDcmtsOrFocused = (selectedItems, focusedItem, fileFormat) => {
|
|
@@ -567,6 +568,41 @@ export const useDocumentOperations = (props) => {
|
|
|
567
568
|
onClick: () => openEditPdfCallback(selectedDcmtInfos, refreshDocumentPreview),
|
|
568
569
|
};
|
|
569
570
|
};
|
|
571
|
+
const printMenuItem = () => {
|
|
572
|
+
const isPdf = isPdfExt(selectedDcmtInfos?.[0]?.FILEEXT);
|
|
573
|
+
return {
|
|
574
|
+
id: 'print',
|
|
575
|
+
icon: _jsx("i", { className: "dx-icon-print", style: { fontSize: '20px' } }),
|
|
576
|
+
name: SDKUI_Localizator.Print,
|
|
577
|
+
operationType: 'singleRow',
|
|
578
|
+
disabled: !isPdf || isDisabledForSingleRow(),
|
|
579
|
+
onClick: isPdf ? async () => {
|
|
580
|
+
const handlePrint = async (file, _dcmtInfo) => {
|
|
581
|
+
const fileURL = window.URL.createObjectURL(file);
|
|
582
|
+
// Usa un iframe nascosto per stampare senza aprire un nuovo tab
|
|
583
|
+
const iframe = document.createElement('iframe');
|
|
584
|
+
iframe.style.position = 'fixed';
|
|
585
|
+
iframe.style.right = '0';
|
|
586
|
+
iframe.style.bottom = '0';
|
|
587
|
+
iframe.style.width = '0';
|
|
588
|
+
iframe.style.height = '0';
|
|
589
|
+
iframe.style.border = 'none';
|
|
590
|
+
iframe.src = fileURL;
|
|
591
|
+
document.body.appendChild(iframe);
|
|
592
|
+
iframe.onload = () => {
|
|
593
|
+
iframe.contentWindow?.focus();
|
|
594
|
+
iframe.contentWindow?.print();
|
|
595
|
+
// Rimuovi l'iframe dopo un breve delay per permettere la stampa
|
|
596
|
+
setTimeout(() => {
|
|
597
|
+
document.body.removeChild(iframe);
|
|
598
|
+
window.URL.revokeObjectURL(fileURL);
|
|
599
|
+
}, 1000);
|
|
600
|
+
};
|
|
601
|
+
};
|
|
602
|
+
await downloadDcmtsAsync(selectedDcmtInfos, DownloadTypes.Dcmt, "download", handlePrint, undefined, true);
|
|
603
|
+
} : undefined,
|
|
604
|
+
};
|
|
605
|
+
};
|
|
570
606
|
const handleSignApprove = () => {
|
|
571
607
|
if (!onOpenS4TViewerRequest) {
|
|
572
608
|
ShowAlert({
|
|
@@ -1082,6 +1118,7 @@ export const useDocumentOperations = (props) => {
|
|
|
1082
1118
|
batchUpdateMenuItem(),
|
|
1083
1119
|
passToArchive(),
|
|
1084
1120
|
...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
|
|
1121
|
+
printMenuItem()
|
|
1085
1122
|
]
|
|
1086
1123
|
},
|
|
1087
1124
|
signatureMenuItem(),
|
|
@@ -1125,6 +1162,7 @@ export const useDocumentOperations = (props) => {
|
|
|
1125
1162
|
commentFromWgMenuItem(false),
|
|
1126
1163
|
relationsMenuItem(true),
|
|
1127
1164
|
removeFromWgMenuItem(SDKUI_Localizator.RemoveFromWorkgroup),
|
|
1165
|
+
printMenuItem()
|
|
1128
1166
|
].sort((a, b) => a.name.localeCompare(b.name));
|
|
1129
1167
|
return [
|
|
1130
1168
|
...sortedItems,
|
|
@@ -1148,6 +1186,7 @@ export const useDocumentOperations = (props) => {
|
|
|
1148
1186
|
downloadFileMenuItem(),
|
|
1149
1187
|
downloadXMLAttachmentsMenuItem(),
|
|
1150
1188
|
...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
|
|
1189
|
+
printMenuItem()
|
|
1151
1190
|
]
|
|
1152
1191
|
},
|
|
1153
1192
|
signatureMenuItem(),
|
|
@@ -1173,7 +1212,8 @@ export const useDocumentOperations = (props) => {
|
|
|
1173
1212
|
...(SDK_Globals.tmSession?.SessionDescr?.appModuleID === AppModules.SURFER ? [createContextualTaskMenuItem()] : []),
|
|
1174
1213
|
downloadFileMenuItem(),
|
|
1175
1214
|
downloadXMLAttachmentsMenuItem(),
|
|
1176
|
-
...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : [])
|
|
1215
|
+
...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
|
|
1216
|
+
printMenuItem()
|
|
1177
1217
|
]
|
|
1178
1218
|
},
|
|
1179
1219
|
signatureMenuItem(),
|