@topconsultnpm/sdkui-react 6.21.0-dev2.57 → 6.21.0-dev2.58

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.
@@ -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) {
@@ -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?";
@@ -72,4 +72,5 @@ export type MergePdfManagerType = {
72
72
  pageCount: number;
73
73
  }>;
74
74
  };
75
+ export declare const isConvertibleToPdfExt: (ext: string | undefined | null) => boolean;
75
76
  export {};
@@ -358,3 +358,21 @@ 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
+ 'pdf',
371
+ 'doc', 'docx', 'dot', 'dotx', 'docm', 'dotm', 'odt', 'rtf', 'txt',
372
+ 'csv', 'xls', 'xlsx',
373
+ 'ppt', 'pptx', 'ppsx',
374
+ 'htm', 'html', 'xml',
375
+ 'bmp', 'jpg', 'jpeg', 'tif', 'tiff',
376
+ 'eml', 'msg'
377
+ ].includes(normalized);
378
+ };
@@ -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,78 @@ 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
+ const isPdf = firstDoc?.FILEEXT?.toLowerCase() === "pdf";
654
+ const isConvertible = isConvertibleToPdfExt(firstDoc?.FILEEXT);
655
+ const canPrint = isPdf || isConvertible;
656
+ const executePrint = async () => {
657
+ const handlePrint = async (file, _dcmtInfo) => {
658
+ const fileURL = window.URL.createObjectURL(file);
659
+ // Usa un iframe nascosto con sandbox per:
660
+ // 1. Bloccare l'esecuzione di JavaScript nel PDF
661
+ // 2. Non aprire un nuovo tab
662
+ const printFrame = document.createElement('iframe');
663
+ printFrame.style.position = 'fixed';
664
+ printFrame.style.right = '0';
665
+ printFrame.style.bottom = '0';
666
+ printFrame.style.width = '0';
667
+ printFrame.style.height = '0';
668
+ printFrame.style.border = 'none';
669
+ printFrame.src = fileURL;
670
+ document.body.appendChild(printFrame);
671
+ printFrame.onload = () => {
672
+ try {
673
+ printFrame.contentWindow?.focus();
674
+ printFrame.contentWindow?.print();
675
+ }
676
+ catch (e) {
677
+ console.error('Errore durante la stampa:', e);
678
+ }
679
+ // Cleanup dopo un delay per permettere la stampa
680
+ setTimeout(() => {
681
+ document.body.removeChild(printFrame);
682
+ window.URL.revokeObjectURL(fileURL);
683
+ }, 60000);
684
+ };
685
+ };
686
+ const rfo = new RetrieveFileOptions();
687
+ rfo.retrieveReason = DcmtOpers.Print;
688
+ rfo.generalRetrieveFormat = GeneralRetrieveFormats.OriginalUnsigned;
689
+ rfo.cvtFormat = FileFormats.PDF;
690
+ rfo.invoiceRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.invoiceRetrieveFormat;
691
+ rfo.orderRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.orderRetrieveFormat;
692
+ await downloadDcmtsAsync(selectedDcmtInfos, DownloadTypes.Dcmt, "download", handlePrint, undefined, true, rfo, true, false);
693
+ };
694
+ return {
695
+ id: 'print',
696
+ icon: _jsx("i", { className: "dx-icon-print", style: { fontSize: '20px' } }),
697
+ name: SDKUI_Localizator.Print,
698
+ operationType: 'singleRow',
699
+ disabled: !canPrint || isDisabledForSingleRow(),
700
+ onClick: canPrint ? async () => {
701
+ // Se non è un PDF nativo ma è convertibile, chiedi conferma
702
+ if (!isPdf && isConvertible) {
703
+ TMMessageBoxManager.show({
704
+ title: SDKUI_Localizator.Print,
705
+ 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 })] })),
706
+ buttons: [ButtonNames.YES, ButtonNames.NO],
707
+ showToppy: false,
708
+ onButtonClick: async (e) => {
709
+ if (e === ButtonNames.YES) {
710
+ await executePrint();
711
+ }
712
+ }
713
+ });
714
+ }
715
+ else {
716
+ await executePrint();
717
+ }
718
+ } : undefined,
719
+ };
720
+ };
649
721
  const checkinMenuItem = () => {
650
722
  // Take the first document (used for validation checks)
651
723
  let dcmt = focusedItem;
@@ -1082,6 +1154,7 @@ export const useDocumentOperations = (props) => {
1082
1154
  batchUpdateMenuItem(),
1083
1155
  passToArchive(),
1084
1156
  ...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
1157
+ ...(!isMobile ? [printMenuItem()] : [])
1085
1158
  ]
1086
1159
  },
1087
1160
  signatureMenuItem(),
@@ -1125,6 +1198,7 @@ export const useDocumentOperations = (props) => {
1125
1198
  commentFromWgMenuItem(false),
1126
1199
  relationsMenuItem(true),
1127
1200
  removeFromWgMenuItem(SDKUI_Localizator.RemoveFromWorkgroup),
1201
+ ...(!isMobile ? [printMenuItem()] : [])
1128
1202
  ].sort((a, b) => a.name.localeCompare(b.name));
1129
1203
  return [
1130
1204
  ...sortedItems,
@@ -1148,6 +1222,7 @@ export const useDocumentOperations = (props) => {
1148
1222
  downloadFileMenuItem(),
1149
1223
  downloadXMLAttachmentsMenuItem(),
1150
1224
  ...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
1225
+ ...(!isMobile ? [printMenuItem()] : [])
1151
1226
  ]
1152
1227
  },
1153
1228
  signatureMenuItem(),
@@ -1173,7 +1248,8 @@ export const useDocumentOperations = (props) => {
1173
1248
  ...(SDK_Globals.tmSession?.SessionDescr?.appModuleID === AppModules.SURFER ? [createContextualTaskMenuItem()] : []),
1174
1249
  downloadFileMenuItem(),
1175
1250
  downloadXMLAttachmentsMenuItem(),
1176
- ...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : [])
1251
+ ...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
1252
+ ...(!isMobile ? [printMenuItem()] : [])
1177
1253
  ]
1178
1254
  },
1179
1255
  signatureMenuItem(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react",
3
- "version": "6.21.0-dev2.57",
3
+ "version": "6.21.0-dev2.58",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",