@topconsultnpm/sdkui-react 6.21.0-dev2.57 → 6.21.0-dev2.59
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 -15
- package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +4 -1
- package/lib/components/features/documents/copyAndMergeDcmtsShared.js +5 -2
- package/lib/helper/SDKUI_Localizator.d.ts +2 -0
- package/lib/helper/SDKUI_Localizator.js +20 -0
- package/lib/helper/TMUtils.d.ts +1 -0
- package/lib/helper/TMUtils.js +17 -0
- package/lib/hooks/useDocumentOperations.js +80 -2
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useRef, useState } from 'react';
|
|
3
3
|
import { DownloadTypes } from '../../../ts';
|
|
4
|
-
import { calcResponsiveSizes, IconFolderOpen, IconPlay, IconUndo, SDKUI_Globals, SDKUI_Localizator, } from '../../../helper';
|
|
4
|
+
import { calcResponsiveSizes, IconFolderOpen, IconPlay, IconUndo, isConvertibleToPdfExt, SDKUI_Globals, SDKUI_Localizator, } from '../../../helper';
|
|
5
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';
|
|
@@ -72,20 +72,6 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
|
|
|
72
72
|
if (!pdfFileName.trim()) {
|
|
73
73
|
pdfValidationItems.push(new ValidationItem(ResultTypes.ERROR, SDKUI_Localizator.PdfFileName, SDKUI_Localizator.RequiredField));
|
|
74
74
|
}
|
|
75
|
-
// ---- Helper per file convertibili in PDF ----
|
|
76
|
-
const isConvertibleToPdfExt = (ext) => {
|
|
77
|
-
if (!ext)
|
|
78
|
-
return false;
|
|
79
|
-
const normalized = ext.toString().trim().toLowerCase().replace(/^\./, '');
|
|
80
|
-
return [
|
|
81
|
-
'doc', 'docx', 'dot', 'dotx', 'docm', 'dotm', 'odt', 'rtf', 'txt',
|
|
82
|
-
'csv', 'xls', 'xlsx',
|
|
83
|
-
'ppt', 'pptx', 'ppsx',
|
|
84
|
-
'htm', 'html', 'xml',
|
|
85
|
-
'bmp', 'jpg', 'jpeg', 'tif', 'tiff',
|
|
86
|
-
'eml', 'msg'
|
|
87
|
-
].includes(normalized);
|
|
88
|
-
};
|
|
89
75
|
// ---- Statistiche selezione PDF / convertibili / non-PDF ----
|
|
90
76
|
const convertibleSelectedItems = (() => {
|
|
91
77
|
if (showTMRelationViewer) {
|
|
@@ -13,7 +13,10 @@ export declare const dedupeByTidDid: (items: ReadonlyArray<IRelatedDcmt>) => Arr
|
|
|
13
13
|
/** Verifica se showDirectoryPicker è supportato (Chrome, Edge) */
|
|
14
14
|
export declare const isDirectoryPickerSupported: () => boolean;
|
|
15
15
|
/**
|
|
16
|
-
* Verifica se un'estensione (con o senza punto iniziale, case-insensitive) è "pdf"
|
|
16
|
+
* Verifica se un'estensione (con o senza punto iniziale, case-insensitive) è "pdf"
|
|
17
|
+
* o un PDF firmato (pdf.p7m, pdf.tsd, pdf.m7m).
|
|
18
|
+
* Questi formati firmati vengono trattati come PDF nativi perché con OriginalUnsigned
|
|
19
|
+
* il file viene restituito senza firma.
|
|
17
20
|
*/
|
|
18
21
|
export declare const isPdfExt: (ext: string | null | undefined) => boolean;
|
|
19
22
|
/**
|
|
@@ -50,13 +50,16 @@ export const isDirectoryPickerSupported = () => {
|
|
|
50
50
|
return 'showDirectoryPicker' in window;
|
|
51
51
|
};
|
|
52
52
|
/**
|
|
53
|
-
* Verifica se un'estensione (con o senza punto iniziale, case-insensitive) è "pdf"
|
|
53
|
+
* Verifica se un'estensione (con o senza punto iniziale, case-insensitive) è "pdf"
|
|
54
|
+
* o un PDF firmato (pdf.p7m, pdf.tsd, pdf.m7m).
|
|
55
|
+
* Questi formati firmati vengono trattati come PDF nativi perché con OriginalUnsigned
|
|
56
|
+
* il file viene restituito senza firma.
|
|
54
57
|
*/
|
|
55
58
|
export const isPdfExt = (ext) => {
|
|
56
59
|
if (!ext)
|
|
57
60
|
return false;
|
|
58
61
|
const normalized = ext.trim().toLowerCase().replace(/^\./, '');
|
|
59
|
-
return normalized === 'pdf';
|
|
62
|
+
return normalized === 'pdf' || normalized === 'pdf.p7m' || normalized === 'pdf.tsd' || normalized === 'pdf.m7m';
|
|
60
63
|
};
|
|
61
64
|
/**
|
|
62
65
|
* Estensioni di firma/marca temporale note che possono avvolgere altre estensioni.
|
|
@@ -598,6 +598,8 @@ export declare class SDKUI_Localizator {
|
|
|
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
600
|
static get Print(): "Drucken" | "Print" | "Imprimir" | "Imprimer" | "Stampa";
|
|
601
|
+
static get PrintConfirmConversion(): "Die Originaldatei kann nicht direkt gedruckt werden und wird in PDF konvertiert." | "The original file cannot be printed directly and will be converted to PDF." | "El archivo original no se puede imprimir directamente y se convertirá a PDF." | "Le fichier original ne peut pas être imprimé directement et sera converti en PDF." | "O arquivo original não pode ser impresso diretamente e será convertido para PDF." | "Il file originale non è stampabile direttamente e verrà convertito in PDF.";
|
|
602
|
+
static get PrintConfirmQuestion(): "Möchten Sie mit dem Drucken fortfahren?" | "Do you want to proceed with printing?" | "¿Desea continuar con la impresión?" | "Voulez-vous continuer l'impression ?" | "Deseja continuar com a impressão?" | "Vuoi procedere con la stampa?";
|
|
601
603
|
static get ProceedAnyway(): "Dennoch fortfahren?" | "Proceed anyway?" | "¿Proceder de todos modos?" | "Procéder quand même ?" | "Prosseguir mesmo assim?" | "Procedere comunque?";
|
|
602
604
|
static get ProcessedItems(): "Durchdachte Elemente" | "Processed items" | "Elementos elaborados" | "Items traités" | "Itens processados" | "Elementi elaborati";
|
|
603
605
|
static get Properties(): "Eigenschaften" | "Properties" | "Propiedades" | "Propriétés" | "Propriedades" | "Proprietà";
|
|
@@ -5952,6 +5952,26 @@ export class SDKUI_Localizator {
|
|
|
5952
5952
|
default: return "Stampa";
|
|
5953
5953
|
}
|
|
5954
5954
|
}
|
|
5955
|
+
static get PrintConfirmConversion() {
|
|
5956
|
+
switch (this._cultureID) {
|
|
5957
|
+
case CultureIDs.De_DE: return "Die Originaldatei kann nicht direkt gedruckt werden und wird in PDF konvertiert.";
|
|
5958
|
+
case CultureIDs.En_US: return "The original file cannot be printed directly and will be converted to PDF.";
|
|
5959
|
+
case CultureIDs.Es_ES: return "El archivo original no se puede imprimir directamente y se convertirá a PDF.";
|
|
5960
|
+
case CultureIDs.Fr_FR: return "Le fichier original ne peut pas être imprimé directement et sera converti en PDF.";
|
|
5961
|
+
case CultureIDs.Pt_PT: return "O arquivo original não pode ser impresso diretamente e será convertido para PDF.";
|
|
5962
|
+
default: return "Il file originale non è stampabile direttamente e verrà convertito in PDF.";
|
|
5963
|
+
}
|
|
5964
|
+
}
|
|
5965
|
+
static get PrintConfirmQuestion() {
|
|
5966
|
+
switch (this._cultureID) {
|
|
5967
|
+
case CultureIDs.De_DE: return "Möchten Sie mit dem Drucken fortfahren?";
|
|
5968
|
+
case CultureIDs.En_US: return "Do you want to proceed with printing?";
|
|
5969
|
+
case CultureIDs.Es_ES: return "¿Desea continuar con la impresión?";
|
|
5970
|
+
case CultureIDs.Fr_FR: return "Voulez-vous continuer l'impression ?";
|
|
5971
|
+
case CultureIDs.Pt_PT: return "Deseja continuar com a impressão?";
|
|
5972
|
+
default: return "Vuoi procedere con la stampa?";
|
|
5973
|
+
}
|
|
5974
|
+
}
|
|
5955
5975
|
static get ProceedAnyway() {
|
|
5956
5976
|
switch (this._cultureID) {
|
|
5957
5977
|
case CultureIDs.De_DE: return "Dennoch fortfahren?";
|
package/lib/helper/TMUtils.d.ts
CHANGED
package/lib/helper/TMUtils.js
CHANGED
|
@@ -358,3 +358,20 @@ export const getDcmtFormToolbarVisibility = (appModuleID) => {
|
|
|
358
358
|
};
|
|
359
359
|
}
|
|
360
360
|
};
|
|
361
|
+
// ---- Helper per file convertibili in PDF ----
|
|
362
|
+
export const isConvertibleToPdfExt = (ext) => {
|
|
363
|
+
if (!ext)
|
|
364
|
+
return false;
|
|
365
|
+
// Rimuove le estensioni di firma digitale (P7M, M7M, TSR, TSD, TS) prima di normalizzare
|
|
366
|
+
const normalized = ext.toString().trim().toUpperCase()
|
|
367
|
+
.replace(/\.P7M/g, '').replace(/\.M7M/g, '').replace(/\.TSR/g, '').replace(/\.TSD/g, '').replace(/\.TS/g, '')
|
|
368
|
+
.toLowerCase().replace(/^\./, '').split('.').pop() ?? '';
|
|
369
|
+
return [
|
|
370
|
+
'doc', 'docx', 'dot', 'dotx', 'docm', 'dotm', 'odt', 'rtf', 'txt',
|
|
371
|
+
'csv', 'xls', 'xlsx',
|
|
372
|
+
'ppt', 'pptx', 'ppsx',
|
|
373
|
+
'htm', 'html', 'xml',
|
|
374
|
+
'bmp', 'jpg', 'jpeg', 'tif', 'tiff',
|
|
375
|
+
'eml', 'msg'
|
|
376
|
+
].includes(normalized);
|
|
377
|
+
};
|
|
@@ -21,7 +21,7 @@ import { useDcmtOperations } from "./useDcmtOperations";
|
|
|
21
21
|
import useFloatingBarPinnedItems from "./useFloatingBarPinnedItems";
|
|
22
22
|
import { useInputAttachmentsDialog, useInputCvtFormatDialog } from "./useInputDialog";
|
|
23
23
|
import { useRelatedDocuments } from "./useRelatedDocuments";
|
|
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';
|
|
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, isConvertibleToPdfExt, isPdfEditorAvailable, SDKUI_Globals, SDKUI_Localizator, searchResultToMetadataValues, TMImageLibrary } from '../helper';
|
|
25
25
|
import { isXMLFileExt } from "../helper/dcmtsHelper";
|
|
26
26
|
import TMCopyToFolderForm from "../components/features/documents/TMCopyToFolderForm";
|
|
27
27
|
import TMMergeToPdfForm from "../components/features/documents/TMMergeToPdfForm";
|
|
@@ -646,6 +646,80 @@ export const useDocumentOperations = (props) => {
|
|
|
646
646
|
return;
|
|
647
647
|
copyCheckoutPathToClipboardCallback(firstDoc, dtd?.name ?? SDKUI_Localizator.SearchResult);
|
|
648
648
|
};
|
|
649
|
+
const printMenuItem = () => {
|
|
650
|
+
// Take the first document (used for validation checks)
|
|
651
|
+
const firstDoc = selectedDcmtInfos?.[0];
|
|
652
|
+
// Check if the selected document is a PDF or can be converted to PDF by the backend
|
|
653
|
+
// Include signed PDFs (p7m, tsd, m7m) since generalRetrieveFormat is OriginalUnsigned
|
|
654
|
+
const fileExtLower = firstDoc?.FILEEXT?.toLowerCase();
|
|
655
|
+
const isPdf = fileExtLower === "pdf" || fileExtLower === "pdf.p7m" || fileExtLower === "pdf.tsd" || fileExtLower === "pdf.m7m";
|
|
656
|
+
const isConvertible = isConvertibleToPdfExt(firstDoc?.FILEEXT);
|
|
657
|
+
const canPrint = isPdf || isConvertible;
|
|
658
|
+
const executePrint = async () => {
|
|
659
|
+
const handlePrint = async (file, _dcmtInfo) => {
|
|
660
|
+
const fileURL = window.URL.createObjectURL(file);
|
|
661
|
+
// Usa un iframe nascosto con sandbox per:
|
|
662
|
+
// 1. Bloccare l'esecuzione di JavaScript nel PDF
|
|
663
|
+
// 2. Non aprire un nuovo tab
|
|
664
|
+
const printFrame = document.createElement('iframe');
|
|
665
|
+
printFrame.style.position = 'fixed';
|
|
666
|
+
printFrame.style.right = '0';
|
|
667
|
+
printFrame.style.bottom = '0';
|
|
668
|
+
printFrame.style.width = '0';
|
|
669
|
+
printFrame.style.height = '0';
|
|
670
|
+
printFrame.style.border = 'none';
|
|
671
|
+
printFrame.src = fileURL;
|
|
672
|
+
document.body.appendChild(printFrame);
|
|
673
|
+
printFrame.onload = () => {
|
|
674
|
+
try {
|
|
675
|
+
printFrame.contentWindow?.focus();
|
|
676
|
+
printFrame.contentWindow?.print();
|
|
677
|
+
}
|
|
678
|
+
catch (e) {
|
|
679
|
+
console.error('Errore durante la stampa:', e);
|
|
680
|
+
}
|
|
681
|
+
// Cleanup dopo un delay per permettere la stampa
|
|
682
|
+
setTimeout(() => {
|
|
683
|
+
document.body.removeChild(printFrame);
|
|
684
|
+
window.URL.revokeObjectURL(fileURL);
|
|
685
|
+
}, 60000);
|
|
686
|
+
};
|
|
687
|
+
};
|
|
688
|
+
const rfo = new RetrieveFileOptions();
|
|
689
|
+
rfo.retrieveReason = DcmtOpers.Print;
|
|
690
|
+
rfo.generalRetrieveFormat = GeneralRetrieveFormats.OriginalUnsigned;
|
|
691
|
+
rfo.cvtFormat = FileFormats.PDF;
|
|
692
|
+
rfo.invoiceRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.invoiceRetrieveFormat;
|
|
693
|
+
rfo.orderRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.orderRetrieveFormat;
|
|
694
|
+
await downloadDcmtsAsync(selectedDcmtInfos, DownloadTypes.Dcmt, "download", handlePrint, undefined, true, rfo, true, false);
|
|
695
|
+
};
|
|
696
|
+
return {
|
|
697
|
+
id: 'print',
|
|
698
|
+
icon: _jsx("i", { className: "dx-icon-print", style: { fontSize: '20px' } }),
|
|
699
|
+
name: SDKUI_Localizator.Print,
|
|
700
|
+
operationType: 'singleRow',
|
|
701
|
+
disabled: !canPrint || isDisabledForSingleRow(),
|
|
702
|
+
onClick: canPrint ? async () => {
|
|
703
|
+
// Se non è un PDF nativo ma è convertibile, chiedi conferma
|
|
704
|
+
if (!isPdf && isConvertible) {
|
|
705
|
+
TMMessageBoxManager.show({
|
|
706
|
+
title: SDKUI_Localizator.Print,
|
|
707
|
+
message: (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '12px' }, children: [_jsx("p", { style: { margin: 0, color: '#333' }, children: SDKUI_Localizator.PrintConfirmConversion.split('PDF').map((part, i, arr) => (_jsxs("span", { children: [part, i < arr.length - 1 && _jsx("strong", { children: "PDF" })] }, i))) }), _jsx("p", { style: { margin: 0, fontWeight: 500, color: '#333' }, children: SDKUI_Localizator.PrintConfirmQuestion })] })),
|
|
708
|
+
buttons: [ButtonNames.YES, ButtonNames.NO],
|
|
709
|
+
showToppy: false,
|
|
710
|
+
onButtonClick: async (e) => {
|
|
711
|
+
if (e === ButtonNames.YES) {
|
|
712
|
+
await executePrint();
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
else {
|
|
718
|
+
await executePrint();
|
|
719
|
+
}
|
|
720
|
+
} : undefined,
|
|
721
|
+
};
|
|
722
|
+
};
|
|
649
723
|
const checkinMenuItem = () => {
|
|
650
724
|
// Take the first document (used for validation checks)
|
|
651
725
|
let dcmt = focusedItem;
|
|
@@ -1082,6 +1156,7 @@ export const useDocumentOperations = (props) => {
|
|
|
1082
1156
|
batchUpdateMenuItem(),
|
|
1083
1157
|
passToArchive(),
|
|
1084
1158
|
...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
|
|
1159
|
+
...(!isMobile ? [printMenuItem()] : [])
|
|
1085
1160
|
]
|
|
1086
1161
|
},
|
|
1087
1162
|
signatureMenuItem(),
|
|
@@ -1125,6 +1200,7 @@ export const useDocumentOperations = (props) => {
|
|
|
1125
1200
|
commentFromWgMenuItem(false),
|
|
1126
1201
|
relationsMenuItem(true),
|
|
1127
1202
|
removeFromWgMenuItem(SDKUI_Localizator.RemoveFromWorkgroup),
|
|
1203
|
+
...(!isMobile ? [printMenuItem()] : [])
|
|
1128
1204
|
].sort((a, b) => a.name.localeCompare(b.name));
|
|
1129
1205
|
return [
|
|
1130
1206
|
...sortedItems,
|
|
@@ -1148,6 +1224,7 @@ export const useDocumentOperations = (props) => {
|
|
|
1148
1224
|
downloadFileMenuItem(),
|
|
1149
1225
|
downloadXMLAttachmentsMenuItem(),
|
|
1150
1226
|
...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
|
|
1227
|
+
...(!isMobile ? [printMenuItem()] : [])
|
|
1151
1228
|
]
|
|
1152
1229
|
},
|
|
1153
1230
|
signatureMenuItem(),
|
|
@@ -1173,7 +1250,8 @@ export const useDocumentOperations = (props) => {
|
|
|
1173
1250
|
...(SDK_Globals.tmSession?.SessionDescr?.appModuleID === AppModules.SURFER ? [createContextualTaskMenuItem()] : []),
|
|
1174
1251
|
downloadFileMenuItem(),
|
|
1175
1252
|
downloadXMLAttachmentsMenuItem(),
|
|
1176
|
-
...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : [])
|
|
1253
|
+
...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
|
|
1254
|
+
...(!isMobile ? [printMenuItem()] : [])
|
|
1177
1255
|
]
|
|
1178
1256
|
},
|
|
1179
1257
|
signatureMenuItem(),
|