@topconsultnpm/sdkui-react 6.21.0-dev4.8 → 6.21.0-dev5.1

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.
Files changed (112) hide show
  1. package/lib/components/NewComponents/ContextMenu/styles.d.ts +43 -19
  2. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +79 -27
  3. package/lib/components/base/Styled.d.ts +77 -41
  4. package/lib/components/base/TMCounterBar.d.ts +2 -2
  5. package/lib/components/base/TMCounterContainer.d.ts +2 -1
  6. package/lib/components/base/TMCustomButton.d.ts +1 -1
  7. package/lib/components/base/TMDataGridExportForm.d.ts +2 -1
  8. package/lib/components/base/TMFileManager.d.ts +2 -1
  9. package/lib/components/base/TMFileManagerDataGridView.d.ts +2 -1
  10. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +1 -1
  11. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +1 -1
  12. package/lib/components/base/TMFileManagerUtils.d.ts +6 -2
  13. package/lib/components/base/TMLayout.d.ts +4 -4
  14. package/lib/components/base/TMList.d.ts +2 -1
  15. package/lib/components/base/TMListView.d.ts +1 -1
  16. package/lib/components/base/TMSpinner.d.ts +2 -1
  17. package/lib/components/base/TMTab.d.ts +4 -3
  18. package/lib/components/base/TMTooltip.d.ts +1 -1
  19. package/lib/components/base/TMTreeView.d.ts +21 -16
  20. package/lib/components/base/TMTreeView.js +230 -64
  21. package/lib/components/base/TMUserAvatar.d.ts +2 -1
  22. package/lib/components/base/TMVilViewer.d.ts +2 -1
  23. package/lib/components/base/TMWaitPanel.d.ts +3 -2
  24. package/lib/components/choosers/TMDynDataListItemChooser.d.ts +1 -1
  25. package/lib/components/choosers/TMInvoiceRetrieveFormats.d.ts +2 -1
  26. package/lib/components/choosers/TMOrderRetrieveFormats.d.ts +2 -1
  27. package/lib/components/choosers/TMRelationChooser.d.ts +3 -3
  28. package/lib/components/choosers/TMUserChooser.d.ts +2 -2
  29. package/lib/components/editors/TMEditorStyled.d.ts +42 -10
  30. package/lib/components/editors/TMFormulaEditor.d.ts +1 -1
  31. package/lib/components/editors/TMHtmlContentDisplay.d.ts +2 -1
  32. package/lib/components/editors/TMHtmlEditor.d.ts +2 -1
  33. package/lib/components/editors/TMTreeDropDown.d.ts +1 -1
  34. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +1 -1
  35. package/lib/components/features/blog/TMBlogCommentForm.d.ts +2 -1
  36. package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +1 -1
  37. package/lib/components/features/documents/TMDcmtIcon.d.ts +4 -1
  38. package/lib/components/features/documents/TMDcmtIcon.js +5 -32
  39. package/lib/components/features/documents/TMDcmtPreview.d.ts +6 -4
  40. package/lib/components/features/documents/TMDcmtTasks.d.ts +2 -1
  41. package/lib/components/features/documents/TMDragDropOverlay.d.ts +1 -1
  42. package/lib/components/features/documents/TMFileUploader.js +1 -1
  43. package/lib/components/features/documents/TMMasterDetailDcmts.js +50 -11
  44. package/lib/components/features/documents/TMMergeToPdfForm.d.ts +2 -1
  45. package/lib/components/features/documents/TMMergeToPdfForm.js +91 -48
  46. package/lib/components/features/documents/TMRelationViewer.d.ts +12 -10
  47. package/lib/components/features/documents/TMRelationViewer.js +400 -96
  48. package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +4 -3
  49. package/lib/components/features/documents/copyAndMergeDcmtsShared.js +47 -23
  50. package/lib/components/features/documents/mergePdfUtils.d.ts +52 -0
  51. package/lib/components/features/documents/mergePdfUtils.js +268 -0
  52. package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +2 -1
  53. package/lib/components/features/search/TMMetadataOutputForm.d.ts +2 -1
  54. package/lib/components/features/search/TMMetadataSorterForm.d.ts +2 -1
  55. package/lib/components/features/search/TMSavedQuerySelector.d.ts +2 -2
  56. package/lib/components/features/search/TMSearchQueryPanel.d.ts +3 -3
  57. package/lib/components/features/search/TMSearchResult.js +20 -5
  58. package/lib/components/features/search/TMSearchResultFloatingActionButton.d.ts +1 -1
  59. package/lib/components/features/search/TMSignatureInfoContent.d.ts +2 -1
  60. package/lib/components/features/search/TMViewHistoryDcmt.d.ts +2 -1
  61. package/lib/components/features/tasks/TMTaskForm.d.ts +1 -1
  62. package/lib/components/features/tasks/TMTaskFormUtils.d.ts +10 -10
  63. package/lib/components/features/tasks/TMTasksAgenda.d.ts +1 -1
  64. package/lib/components/features/tasks/TMTasksCalendar.d.ts +1 -1
  65. package/lib/components/features/tasks/TMTasksHeader.d.ts +1 -1
  66. package/lib/components/features/tasks/TMTasksPanelContent.d.ts +1 -1
  67. package/lib/components/features/tasks/TMTasksUtilsView.d.ts +5 -5
  68. package/lib/components/features/tasks/TMTasksView.d.ts +1 -1
  69. package/lib/components/features/wg/TMWGsCopyMoveForm.d.ts +3 -2
  70. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +8 -7
  71. package/lib/components/features/workflow/diagram/WorkitemRecipientsEditor.d.ts +1 -1
  72. package/lib/components/forms/Login/ChangePasswordInputs.d.ts +1 -1
  73. package/lib/components/forms/Login/Chooser.d.ts +2 -2
  74. package/lib/components/forms/TMChooserForm.d.ts +2 -1
  75. package/lib/components/forms/TMSaveForm.d.ts +4 -4
  76. package/lib/components/grids/TMBlogAttachments.d.ts +2 -1
  77. package/lib/components/grids/TMBlogHeader.d.ts +1 -1
  78. package/lib/components/grids/TMBlogsPost.d.ts +1 -1
  79. package/lib/components/grids/TMBlogsPostUtils.d.ts +9 -9
  80. package/lib/components/grids/TMValidationItemsList.d.ts +2 -1
  81. package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +2 -1
  82. package/lib/components/layout/panelManager/TMPanelManagerContext.d.ts +2 -2
  83. package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +6 -3
  84. package/lib/components/layout/panelManager/TMPanelManagerWithPersistenceProvider.d.ts +2 -2
  85. package/lib/components/layout/panelManager/TMPanelWrapper.d.ts +2 -2
  86. package/lib/components/pages/TMPage.d.ts +1 -1
  87. package/lib/components/query/TMQueryEditor.d.ts +10 -6
  88. package/lib/components/settings/SettingsAppearance.d.ts +2 -1
  89. package/lib/components/sidebar/TMAboutApp.d.ts +2 -1
  90. package/lib/components/sidebar/TMCommandsPanel.d.ts +4 -2
  91. package/lib/components/sidebar/TMHeader.d.ts +3 -3
  92. package/lib/components/viewers/TMDataListItemViewer.d.ts +3 -2
  93. package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +3 -2
  94. package/lib/components/viewers/TMMidViewer.d.ts +2 -2
  95. package/lib/components/viewers/TMTidViewer.d.ts +2 -2
  96. package/lib/components/viewers/TMTidViewer.js +14 -2
  97. package/lib/helper/SDKUI_Globals.d.ts +1 -0
  98. package/lib/helper/SDKUI_Globals.js +1 -0
  99. package/lib/helper/SDKUI_Localizator.d.ts +28 -0
  100. package/lib/helper/SDKUI_Localizator.js +292 -12
  101. package/lib/helper/TMCommandsContextMenu.d.ts +1 -1
  102. package/lib/helper/TMIcons.d.ts +278 -278
  103. package/lib/helper/TMPdfViewer.d.ts +2 -1
  104. package/lib/helper/TMToppyMessage.d.ts +2 -2
  105. package/lib/helper/TMUtils.d.ts +37 -5
  106. package/lib/helper/TMUtils.js +104 -1
  107. package/lib/helper/helpers.d.ts +1 -1
  108. package/lib/helper/helpers.js +9 -0
  109. package/lib/hooks/useDocumentOperations.js +1 -1
  110. package/lib/hooks/useInputDialog.d.ts +2 -1
  111. package/lib/services/platform_services.d.ts +3 -2
  112. package/package.json +3 -4
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { MetadataDescriptor } from '@topconsultnpm/sdk-ts';
2
3
  import { DcmtInfo } from '../../../ts';
3
4
  import { DocumentDownloadSettings, FileNamingMode } from '../../../helper';
4
5
  import { IRelatedDcmt } from './TMMasterDetailDcmts';
@@ -32,9 +33,9 @@ export declare const fileExists: (dirHandle: FileSystemDirectoryHandle, fileName
32
33
  export declare const generateUniqueFileName: (dirHandle: FileSystemDirectoryHandle, originalName: string) => Promise<string>;
33
34
  /** Recupera il nome leggibile del tipo documento (cache) */
34
35
  export declare const getTypeName: (tid: number | undefined) => Promise<string>;
35
- /** Formatta un valore convertendo le date in formato dd-MM-yyyy [HH-mm-ss] */
36
- export declare const formatMetadataValue: (value: string) => string;
37
- /** Recupera i metadati filtrati (primi 5 con mid > 100 e valore presente), concatenati con separatorChar */
36
+ /** Formatta un valore convertendo le date secondo il formato specificato in MetadataDescriptor.format */
37
+ export declare const formatMetadataValue: (value: string, md?: MetadataDescriptor) => string;
38
+ /** Recupera i metadati filtrati usando buildDcmtDisplayName, concatenati con separatorChar */
38
39
  export declare const getFilteredMetadata: (tid: number, did: number, separatorChar: string) => Promise<string | null>;
39
40
  /** Opzioni di naming necessarie per generare il nome del file di destinazione */
40
41
  export interface IFileNamingOptions {
@@ -1,5 +1,5 @@
1
- import { DcmtTypeListCacheService, LayoutModes, SDK_Globals } from '@topconsultnpm/sdk-ts';
2
- import { searchResultToMetadataValues, DocumentDownloadSettings, getFullFileExtension } from '../../../helper';
1
+ import { DcmtTypeListCacheService, LayoutModes, MetadataDataTypes, MetadataFormats, SDK_Globals } from '@topconsultnpm/sdk-ts';
2
+ import { searchResultToMetadataValues, DocumentDownloadSettings, getFullFileExtension, buildDcmtDisplayName } from '../../../helper';
3
3
  import { TMColors } from '../../../utils/theme';
4
4
  /** Numero minimo di file PDF necessari per poterli unire in un unico documento. */
5
5
  export const MIN_PDF_FOR_MERGE = 2;
@@ -82,7 +82,7 @@ export const sanitizeFileName = (fileName, fallbackName, maxLength = 255) => {
82
82
  const illegalCharsRegex = /[<>:"/\\|?*]/g;
83
83
  const controlCharsRegex = /[\x00-\x1F\x7F]/g;
84
84
  let sanitized = fileName
85
- .replace(illegalCharsRegex, '_')
85
+ .replace(illegalCharsRegex, '-')
86
86
  .replace(controlCharsRegex, '')
87
87
  .trim();
88
88
  sanitized = sanitized.replace(/[. ]+$/, '');
@@ -146,27 +146,40 @@ export const getTypeName = async (tid) => {
146
146
  const foundDtd = typeList.find(dtd => dtd.id?.toString() === tid?.toString());
147
147
  return foundDtd?.name ?? String(tid);
148
148
  };
149
- /** Formatta un valore convertendo le date in formato dd-MM-yyyy [HH-mm-ss] */
150
- export const formatMetadataValue = (value) => {
149
+ /** Formatta un valore convertendo le date secondo il formato specificato in MetadataDescriptor.format */
150
+ export const formatMetadataValue = (value, md) => {
151
+ // Formatta come data solo se il MetadataDescriptor indica tipo DateTime
152
+ if (md?.dataType !== MetadataDataTypes.DateTime) {
153
+ return value;
154
+ }
151
155
  const date = new Date(value);
152
- if (!isNaN(date.getTime())) {
153
- const day = date.getDate().toString().padStart(2, '0');
154
- const month = (date.getMonth() + 1).toString().padStart(2, '0');
155
- const year = date.getFullYear();
156
- const hours = date.getHours();
157
- const minutes = date.getMinutes();
158
- const seconds = date.getSeconds();
159
- if (hours !== 0 || minutes !== 0 || seconds !== 0) {
160
- const hh = hours.toString().padStart(2, '0');
161
- const mm = minutes.toString().padStart(2, '0');
162
- const ss = seconds.toString().padStart(2, '0');
163
- return `${day}-${month}-${year} ${hh}-${mm}-${ss}`;
164
- }
165
- return `${day}-${month}-${year}`;
156
+ if (isNaN(date.getTime())) {
157
+ return value;
158
+ }
159
+ const format = md.format?.format;
160
+ const formatCulture = md.format?.formatCulture ?? window.navigator.language;
161
+ switch (format) {
162
+ case MetadataFormats.ShortDate:
163
+ return date.toLocaleString(formatCulture, formatCulture === "it-IT" ? { year: "numeric", month: "2-digit", day: "2-digit" } : { dateStyle: 'short' });
164
+ case MetadataFormats.ShortTime:
165
+ return date.toLocaleString(formatCulture, { timeStyle: 'short' });
166
+ case MetadataFormats.ShortDateLongTime:
167
+ return date.toLocaleString(formatCulture, formatCulture === "it-IT" ? { year: "numeric", month: "2-digit", day: "2-digit", hour: '2-digit', minute: '2-digit', second: '2-digit' } : { dateStyle: 'short', timeStyle: 'medium' }).replace(',', '');
168
+ case MetadataFormats.ShortDateShortTime:
169
+ return date.toLocaleString(formatCulture, formatCulture === "it-IT" ? { year: "numeric", month: "2-digit", day: "2-digit", hour: '2-digit', minute: '2-digit' } : { dateStyle: 'short', timeStyle: 'short' }).replace(',', '');
170
+ case MetadataFormats.LongDate:
171
+ return date.toLocaleString(formatCulture, { weekday: "long", year: "numeric", month: "long", day: "numeric" });
172
+ case MetadataFormats.LongTime:
173
+ return date.toLocaleString(formatCulture, { timeStyle: 'medium' });
174
+ case MetadataFormats.LongDateLongTime:
175
+ return date.toLocaleString(formatCulture, { weekday: "long", year: "numeric", month: "long", day: "numeric", hour: '2-digit', minute: '2-digit', second: '2-digit' });
176
+ case MetadataFormats.LongDateShortTime:
177
+ return date.toLocaleString(formatCulture, { weekday: "long", year: "numeric", month: "long", day: "numeric", hour: '2-digit', minute: '2-digit' });
178
+ default:
179
+ return date.toLocaleString(formatCulture, formatCulture === "it-IT" ? { year: "numeric", month: "2-digit", day: "2-digit" } : { dateStyle: 'short' });
166
180
  }
167
- return value;
168
181
  };
169
- /** Recupera i metadati filtrati (primi 5 con mid > 100 e valore presente), concatenati con separatorChar */
182
+ /** Recupera i metadati filtrati usando buildDcmtDisplayName, concatenati con separatorChar */
170
183
  export const getFilteredMetadata = async (tid, did, separatorChar) => {
171
184
  const metadata = await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(tid, did, true);
172
185
  if (!metadata)
@@ -177,8 +190,18 @@ export const getFilteredMetadata = async (tid, did, separatorChar) => {
177
190
  const dtdWithMetadata = await DcmtTypeListCacheService.GetWithNotGrantedAsync(tid, did, metadata);
178
191
  const mdList = dtdWithMetadata?.metadata ?? [];
179
192
  const metadataList = searchResultToMetadataValues(tid, dtdResult, rows, mids, mdList, LayoutModes.Update);
180
- return metadataList
181
- .reduce((acc, md) => acc.length < 5 && md.mid && md.mid > 100 && md.value ? [...acc, formatMetadataValue(md.value)] : acc, [])
193
+ // Converte l'array di MetadataValueDescriptorEx in DcmtMetadataMap per buildDcmtDisplayName
194
+ const metadataMap = Object.fromEntries(metadataList.filter(mvd => mvd.md?.name).map(mvd => [mvd.md.name, { md: mvd.md, value: mvd.value }]));
195
+ // Usa buildDcmtDisplayName per ricavare i nomi dei metadati da visualizzare
196
+ const displayKeys = buildDcmtDisplayName(metadataMap);
197
+ if (displayKeys.length === 0)
198
+ return null;
199
+ return displayKeys
200
+ .map(key => {
201
+ const entry = metadataMap[key];
202
+ return entry?.value ? formatMetadataValue(String(entry.value), entry.md) : null;
203
+ })
204
+ .filter(Boolean)
182
205
  .join(separatorChar);
183
206
  };
184
207
  /** Genera il nome file di destinazione in base alle impostazioni di naming */
@@ -201,6 +224,7 @@ export const generateTargetFileName = async (file, dcmtInfo, options) => {
201
224
  case 'onlyCustomMetadata': {
202
225
  try {
203
226
  const filteredMetadata = await getFilteredMetadata(dcmtInfo.TID, dcmtInfo.DID, separatorChar);
227
+ console.log("filteredMetadata for TID:", dcmtInfo.TID, "DID:", dcmtInfo.DID, "is", filteredMetadata);
204
228
  if (filteredMetadata) {
205
229
  if (fileNamingMode === 'documentTypeAndCustomMetadata') {
206
230
  const typeName = await getTypeName(dcmtInfo.TID);
@@ -0,0 +1,52 @@
1
+ import { DcmtInfo } from '../../../ts';
2
+ import { IRelatedDcmt } from './TMMasterDetailDcmts';
3
+ /** Tipo per gli elementi con chiave e estensione */
4
+ export interface ISelectedItemInfo {
5
+ key: string;
6
+ ext: string | undefined;
7
+ }
8
+ /** Risultato delle statistiche di selezione per il merge PDF */
9
+ export interface IMergePdfSelectionStats {
10
+ /** Elementi con estensioni convertibili in PDF (non nativamente PDF) */
11
+ convertibleSelectedItems: Array<ISelectedItemInfo>;
12
+ /** True se ci sono elementi convertibili selezionati */
13
+ hasConvertibleSelected: boolean;
14
+ /** Elementi che NON sono PDF e NON sono convertibili */
15
+ nonPdfSelectedItems: Array<ISelectedItemInfo>;
16
+ /** True se ci sono elementi non-PDF selezionati */
17
+ hasNonPdfSelected: boolean;
18
+ /** Documenti di soli metadati (senza file allegato) */
19
+ metadataOnlySelectedItems: Array<ISelectedItemInfo>;
20
+ /** True se ci sono documenti di soli metadati selezionati */
21
+ hasMetadataOnlySelected: boolean;
22
+ /** Numero totale di file unibili (PDF nativi + convertibili) */
23
+ mergeableSelectedCount: number;
24
+ /** True se ci sono abbastanza file per il merge (>= MIN_PDF_FOR_MERGE) */
25
+ hasEnoughPdfForMerge: boolean;
26
+ }
27
+ /** Documento di soli metadati: FILEEXT null/undefined oppure FILECOUNT 0 (verrà convertito frontend) */
28
+ export declare const isMetadataOnlyDcmt: (fileExt: string | null | undefined, fileCount: string | number | null | undefined) => boolean;
29
+ /**
30
+ * Calcola tutte le statistiche di selezione necessarie per il merge PDF.
31
+ * Restituisce info su file convertibili, non-PDF e conteggio file unibili.
32
+ *
33
+ * @param selectedDcmtInfos - Lista dei DcmtInfo selezionati (usata se showTMRelationViewer è false)
34
+ * @param selectedItemsFull - Lista completa con FILEEXT e FILECOUNT per check documenti di soli metadati
35
+ * @param selectedItemsRelationViewer - Lista degli IRelatedDcmt selezionati nel RelationViewer
36
+ * @param showTMRelationViewer - Se true, usa selectedItemsRelationViewer, altrimenti selectedDcmtInfos
37
+ */
38
+ export declare const getMergePdfSelectionStats: (selectedDcmtInfos: Array<DcmtInfo>, selectedItemsFull: Array<any>, selectedItemsRelationViewer: Array<IRelatedDcmt>, showTMRelationViewer: boolean) => IMergePdfSelectionStats;
39
+ export interface IMetadataKeyValue {
40
+ label: string;
41
+ value: string;
42
+ }
43
+ export interface IMetadataPdfResult {
44
+ file: File;
45
+ blob: Blob;
46
+ bytes: Uint8Array;
47
+ }
48
+ /** Crea PDF con metadati documento (header + lista label=valore). Supporta wrapping e paginazione.
49
+ * @param dcmtInfo - Informazioni del documento
50
+ * @param showSystemMetadata - Se true, include i metadati di sistema (mid < 100). Default: false
51
+ */
52
+ export declare const createMetadataPdfFromDocument: (dcmtInfo: DcmtInfo, showSystemMetadata?: boolean) => Promise<IMetadataPdfResult | null>;
@@ -0,0 +1,268 @@
1
+ import { DcmtTypeListCacheService, LayoutModes, MetadataDataTypes, SDK_Globals } from '@topconsultnpm/sdk-ts';
2
+ import { Globalization, isConvertibleToPdfExt, searchResultToMetadataValues } from '../../../helper';
3
+ import { isPdfExt, MIN_PDF_FOR_MERGE } from './copyAndMergeDcmtsShared';
4
+ /** Documento di soli metadati: FILEEXT null/undefined oppure FILECOUNT 0 (verrà convertito frontend) */
5
+ export const isMetadataOnlyDcmt = (fileExt, fileCount) => {
6
+ if (!fileExt)
7
+ return true;
8
+ return Number(fileCount) === 0;
9
+ };
10
+ /**
11
+ * Calcola tutte le statistiche di selezione necessarie per il merge PDF.
12
+ * Restituisce info su file convertibili, non-PDF e conteggio file unibili.
13
+ *
14
+ * @param selectedDcmtInfos - Lista dei DcmtInfo selezionati (usata se showTMRelationViewer è false)
15
+ * @param selectedItemsFull - Lista completa con FILEEXT e FILECOUNT per check documenti di soli metadati
16
+ * @param selectedItemsRelationViewer - Lista degli IRelatedDcmt selezionati nel RelationViewer
17
+ * @param showTMRelationViewer - Se true, usa selectedItemsRelationViewer, altrimenti selectedDcmtInfos
18
+ */
19
+ export const getMergePdfSelectionStats = (selectedDcmtInfos, selectedItemsFull, selectedItemsRelationViewer, showTMRelationViewer) => {
20
+ // Mappa per lookup veloce di FILECOUNT da selectedItemsFull (usato solo per isMetadataOnly)
21
+ const fileCountMap = new Map(selectedItemsFull.map(d => [`${d.TID}_${d.DID}`, d.FILECOUNT]));
22
+ // Pre-calcolo delle informazioni sui documenti selezionati
23
+ const docs = showTMRelationViewer
24
+ ? selectedItemsRelationViewer
25
+ .filter(i => i.isDcmt)
26
+ .map(i => {
27
+ const ext = i.fileExt ?? undefined;
28
+ return {
29
+ key: `${i.tid}_${i.did}`,
30
+ ext,
31
+ isPdf: isPdfExt(ext),
32
+ isConvertible: isConvertibleToPdfExt(ext),
33
+ isMetadataOnly: isMetadataOnlyDcmt(ext, null)
34
+ };
35
+ })
36
+ : selectedDcmtInfos.map(d => {
37
+ const ext = d.FILEEXT ?? undefined;
38
+ const key = `${d.TID}_${d.DID}`;
39
+ const fileCount = fileCountMap.get(key);
40
+ return {
41
+ key,
42
+ ext,
43
+ isPdf: isPdfExt(ext),
44
+ isConvertible: isConvertibleToPdfExt(ext),
45
+ isMetadataOnly: isMetadataOnlyDcmt(ext, fileCount)
46
+ };
47
+ });
48
+ // Elementi convertibili: file con estensione convertibile (esclusi documenti di soli metadati)
49
+ const convertibleSelectedItems = docs
50
+ .filter(i => i.isConvertible && !i.isMetadataOnly)
51
+ .map(i => ({ key: i.key, ext: i.ext }));
52
+ // Elementi NON PDF e NON convertibili (esclusi documenti di soli metadati)
53
+ const nonPdfSelectedItems = docs
54
+ .filter(i => !i.isPdf && !i.isConvertible && !i.isMetadataOnly)
55
+ .map(i => ({ key: i.key, ext: i.ext }));
56
+ // Documenti di soli metadati (senza file allegato)
57
+ const metadataOnlySelectedItems = docs
58
+ .filter(i => i.isMetadataOnly)
59
+ .map(i => ({ key: i.key, ext: i.ext }));
60
+ // Conteggio file unibili: PDF nativi + convertibili + documenti di soli metadati
61
+ const mergeableSelectedCount = docs
62
+ .filter(i => i.isPdf || i.isConvertible || i.isMetadataOnly).length;
63
+ return {
64
+ convertibleSelectedItems,
65
+ hasConvertibleSelected: convertibleSelectedItems.length > 0,
66
+ nonPdfSelectedItems,
67
+ hasNonPdfSelected: nonPdfSelectedItems.length > 0,
68
+ metadataOnlySelectedItems,
69
+ hasMetadataOnlySelected: metadataOnlySelectedItems.length > 0,
70
+ mergeableSelectedCount,
71
+ hasEnoughPdfForMerge: mergeableSelectedCount >= MIN_PDF_FOR_MERGE,
72
+ };
73
+ };
74
+ // LAZY LOADING pdf-lib
75
+ let pdfLibModule = null;
76
+ const loadPdfLib = async () => {
77
+ if (!pdfLibModule) {
78
+ pdfLibModule = await import('pdf-lib');
79
+ }
80
+ return pdfLibModule;
81
+ };
82
+ // HELPER FUNCTIONS
83
+ /** Ottiene label localizzata del metadato (customName > nameLoc > name) */
84
+ const getMetadataLabel = (md, customName) => {
85
+ if (customName)
86
+ return customName;
87
+ if (!md)
88
+ return '';
89
+ return md.nameLoc || md.name || '';
90
+ };
91
+ /** Formatta valore metadato per PDF (null/undefined -> stringa vuota, datetime -> dd/MM/yyyy HH:mm) */
92
+ const formatMetadataValueForPdf = (value, md) => {
93
+ if (value === undefined || value === null)
94
+ return '';
95
+ // Se il metadato è di tipo DateTime, formatta in modo leggibile usando Globalization
96
+ if (md?.dataType === MetadataDataTypes.DateTime) {
97
+ return Globalization.getDateTimeDisplayValueCompact(value, undefined, md.format?.format);
98
+ }
99
+ return value.toString().trim();
100
+ };
101
+ // ============================================================================
102
+ // CREAZIONE PDF DA METADATI DOCUMENTO
103
+ // ============================================================================
104
+ /** Crea PDF con metadati documento (header + lista label=valore). Supporta wrapping e paginazione.
105
+ * @param dcmtInfo - Informazioni del documento
106
+ * @param showSystemMetadata - Se true, include i metadati di sistema (mid < 100). Default: false
107
+ */
108
+ export const createMetadataPdfFromDocument = async (dcmtInfo, showSystemMetadata = false) => {
109
+ // Configurazione ottimale per PDF A4
110
+ const pageWidth = 595; // A4 width in points
111
+ const pageHeight = 842; // A4 height in points
112
+ const margin = 50; // Margine confortevole
113
+ const titleFontSize = 14; // Titolo leggibile ma non troppo grande
114
+ const contentFontSize = 10; // Font contenuto ottimale per leggibilità
115
+ try {
116
+ // Recupera i metadati del documento
117
+ const metadata = await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(dcmtInfo.TID, dcmtInfo.DID, true);
118
+ if (!metadata) {
119
+ console.warn('createMetadataPdfFromDocument: impossibile recuperare i metadati');
120
+ return null;
121
+ }
122
+ const dtdResult = metadata.dtdResult;
123
+ const rows = dtdResult?.rows?.[0] ?? [];
124
+ const mids = metadata.selectMIDs;
125
+ // Recupera il tipo documento con metadati
126
+ const dtdWithMetadata = await DcmtTypeListCacheService.GetWithNotGrantedAsync(dcmtInfo.TID, dcmtInfo.DID, metadata);
127
+ if (!dtdWithMetadata) {
128
+ console.warn('createMetadataPdfFromDocument: impossibile recuperare il tipo documento');
129
+ return null;
130
+ }
131
+ const mdList = dtdWithMetadata.metadata ?? [];
132
+ // Converte i metadati in formato leggibile
133
+ const metadataList = searchResultToMetadataValues(dcmtInfo.TID, dtdResult, rows, mids, mdList, LayoutModes.Update);
134
+ // Ottiene il nome del tipo documento (localizzato se abilitato)
135
+ const dcmtTypeName = dtdWithMetadata.nameLoc || dtdWithMetadata.name || 'Documento';
136
+ // Prepara la lista di metadati chiave-valore
137
+ const metadataKeyValues = metadataList
138
+ .filter(mvd => mvd.md && mvd.mid && mvd.mid > 0) // Filtra solo metadati validi
139
+ .filter(mvd => showSystemMetadata || (mvd.mid && mvd.mid >= 100)) // Filtra metadati di sistema se showSystemMetadata è false
140
+ .map(mvd => ({
141
+ label: getMetadataLabel(mvd.md, mvd.customName),
142
+ value: formatMetadataValueForPdf(mvd.value, mvd.md)
143
+ }))
144
+ .filter(kv => kv.label.length > 0); // Rimuovi metadati senza label
145
+ // Carica pdf-lib on-demand
146
+ const { PDFDocument, StandardFonts, rgb } = await loadPdfLib();
147
+ // Crea il documento PDF
148
+ const pdfDoc = await PDFDocument.create();
149
+ const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica);
150
+ const helveticaBoldFont = await pdfDoc.embedFont(StandardFonts.HelveticaBold);
151
+ // Calcola dimensioni
152
+ const contentWidth = pageWidth - (margin * 2);
153
+ const lineHeight = contentFontSize + 5;
154
+ const titleLineHeight = titleFontSize + 6;
155
+ // Funzione per aggiungere una nuova pagina
156
+ const addPage = () => {
157
+ const page = pdfDoc.addPage([pageWidth, pageHeight]);
158
+ return { page, yPosition: pageHeight - margin };
159
+ };
160
+ // Funzione per calcolare la larghezza del testo
161
+ const getTextWidth = (text, font, size) => {
162
+ try {
163
+ return font.widthOfTextAtSize(text, size);
164
+ }
165
+ catch {
166
+ // Fallback per caratteri non supportati
167
+ return text.length * size * 0.5;
168
+ }
169
+ };
170
+ // Funzione per spezzare il testo in righe che entrano nella larghezza disponibile
171
+ const wrapText = (text, font, fontSize, maxWidth) => {
172
+ const lines = [];
173
+ const words = text.split(' ');
174
+ let currentLine = '';
175
+ for (const word of words) {
176
+ const testLine = currentLine ? `${currentLine} ${word}` : word;
177
+ const testWidth = getTextWidth(testLine, font, fontSize);
178
+ if (testWidth > maxWidth && currentLine) {
179
+ lines.push(currentLine);
180
+ currentLine = word;
181
+ }
182
+ else {
183
+ currentLine = testLine;
184
+ }
185
+ }
186
+ if (currentLine) {
187
+ lines.push(currentLine);
188
+ }
189
+ // Se una singola parola è troppo lunga, spezzala in più righe (carattere per carattere)
190
+ const result = [];
191
+ for (const line of lines) {
192
+ if (getTextWidth(line, font, fontSize) <= maxWidth) {
193
+ result.push(line);
194
+ }
195
+ else {
196
+ // Spezza la parola/linea troppo lunga carattere per carattere
197
+ let chunk = '';
198
+ for (const char of line) {
199
+ const testChunk = chunk + char;
200
+ if (getTextWidth(testChunk, font, fontSize) > maxWidth && chunk) {
201
+ result.push(chunk);
202
+ chunk = char;
203
+ }
204
+ else {
205
+ chunk = testChunk;
206
+ }
207
+ }
208
+ if (chunk) {
209
+ result.push(chunk);
210
+ }
211
+ }
212
+ }
213
+ return result;
214
+ };
215
+ // Sanitizza testo per Helvetica (solo ASCII)
216
+ const sanitize = (text) => text.replace(/[^\x20-\x7E]/g, '_');
217
+ let { page, yPosition } = addPage();
218
+ // Header (titolo centrato)
219
+ const titleText = sanitize(`${dcmtTypeName}`);
220
+ const titleWidth = getTextWidth(titleText, helveticaBoldFont, titleFontSize);
221
+ const titleX = Math.max(margin, margin + (contentWidth - titleWidth) / 2);
222
+ page.drawText(titleText, { x: titleX, y: yPosition, size: titleFontSize, font: helveticaBoldFont, color: rgb(0, 0, 0) });
223
+ yPosition -= titleLineHeight + 8;
224
+ // Metadati (label in grassetto, valore normale)
225
+ for (const kv of metadataKeyValues) {
226
+ const labelText = sanitize(kv.label) + ': ';
227
+ const labelWidth = getTextWidth(labelText, helveticaBoldFont, contentFontSize);
228
+ const valueMaxWidth = contentWidth - labelWidth;
229
+ const continuationIndent = labelWidth; // Indentazione per righe successive
230
+ // Wrappa il valore
231
+ const valueText = sanitize(kv.value);
232
+ const valueLines = wrapText(valueText, helveticaFont, contentFontSize, valueMaxWidth);
233
+ // Prima riga: label (bold) + primo pezzo di valore
234
+ if (yPosition < margin + lineHeight) {
235
+ ({ page, yPosition } = addPage());
236
+ }
237
+ page.drawText(labelText, { x: margin, y: yPosition, size: contentFontSize, font: helveticaBoldFont, color: rgb(0, 0, 0) });
238
+ if (valueLines.length > 0) {
239
+ page.drawText(valueLines[0], { x: margin + labelWidth, y: yPosition, size: contentFontSize, font: helveticaFont, color: rgb(0, 0, 0) });
240
+ }
241
+ yPosition -= lineHeight;
242
+ // Righe successive del valore (indentate)
243
+ for (let i = 1; i < valueLines.length; i++) {
244
+ if (yPosition < margin + lineHeight) {
245
+ ({ page, yPosition } = addPage());
246
+ }
247
+ page.drawText(valueLines[i], { x: margin + continuationIndent, y: yPosition, size: contentFontSize, font: helveticaFont, color: rgb(0, 0, 0) });
248
+ yPosition -= lineHeight;
249
+ }
250
+ }
251
+ // Salva il PDF
252
+ const pdfBytes = await pdfDoc.save();
253
+ // Converte in Blob e File
254
+ const pdfBuffer = pdfBytes.buffer.slice(pdfBytes.byteOffset, pdfBytes.byteOffset + pdfBytes.byteLength);
255
+ const blob = new Blob([pdfBuffer], { type: 'application/pdf' });
256
+ const finalFileName = `${dcmtTypeName}_${dcmtInfo.DID}.pdf`;
257
+ const file = new File([blob], finalFileName, { type: 'application/pdf' });
258
+ return {
259
+ file,
260
+ blob,
261
+ bytes: pdfBytes
262
+ };
263
+ }
264
+ catch (error) {
265
+ console.error('createMetadataPdfFromDocument: errore durante la creazione del PDF', error);
266
+ return null;
267
+ }
268
+ };
@@ -1,8 +1,9 @@
1
+ import React from "react";
1
2
  import { DcmtInfo } from "../../../ts";
2
3
  interface TMDcmtCheckoutInfoFormProps {
3
4
  dtdName: string;
4
5
  selectedDcmtOrFocused: DcmtInfo;
5
6
  onClose: () => void;
6
7
  }
7
- declare const TMDcmtCheckoutInfoForm: (props: TMDcmtCheckoutInfoFormProps) => import("react/jsx-runtime").JSX.Element;
8
+ declare const TMDcmtCheckoutInfoForm: (props: TMDcmtCheckoutInfoFormProps) => React.JSX.Element;
8
9
  export default TMDcmtCheckoutInfoForm;
@@ -1,3 +1,4 @@
1
+ import React from "react";
1
2
  import { MetadataDescriptor, QueryDescriptor, SelectItem } from "@topconsultnpm/sdk-ts";
2
3
  interface TMMetadataOutputFormProps {
3
4
  /** QueryDescriptor da cui estrarre i metadati disponibili */
@@ -13,5 +14,5 @@ interface TMMetadataOutputFormProps {
13
14
  /** Callback chiamata quando l'utente conferma la selezione dei SelectItem */
14
15
  onChoose?: (selectItems: SelectItem[] | undefined) => void;
15
16
  }
16
- declare const TMMetadataOutputForm: (props: TMMetadataOutputFormProps) => import("react/jsx-runtime").JSX.Element;
17
+ declare const TMMetadataOutputForm: (props: TMMetadataOutputFormProps) => React.JSX.Element;
17
18
  export default TMMetadataOutputForm;
@@ -1,3 +1,4 @@
1
+ import React from "react";
1
2
  import { MetadataDescriptor, OrderByItem, QueryDescriptor } from "@topconsultnpm/sdk-ts";
2
3
  interface TMMetadataSorterFormProps {
3
4
  /** QueryDescriptor da cui estrarre i metadati disponibili */
@@ -13,5 +14,5 @@ interface TMMetadataSorterFormProps {
13
14
  /** Callback chiamata quando l'utente conferma la selezione degli OrderByItem */
14
15
  onChoose?: (orderByItems: OrderByItem[] | undefined) => void;
15
16
  }
16
- declare const TMMetadataSorterForm: (props: TMMetadataSorterFormProps) => import("react/jsx-runtime").JSX.Element;
17
+ declare const TMMetadataSorterForm: (props: TMMetadataSorterFormProps) => React.JSX.Element;
17
18
  export default TMMetadataSorterForm;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { SavedQueryDescriptor } from '@topconsultnpm/sdk-ts';
3
- export declare const getTooltipBySqd: (sqd: SavedQueryDescriptor | undefined) => import("react/jsx-runtime").JSX.Element | null;
3
+ export declare const getTooltipBySqd: (sqd: SavedQueryDescriptor | undefined) => React.JSX.Element | null;
4
4
  interface ITMSavedQuerySelectorProps {
5
5
  height?: string;
6
6
  items?: SavedQueryDescriptor[];
@@ -12,5 +12,5 @@ interface ITMSavedQuerySelectorProps {
12
12
  refreshFavoriteSavedQueries?: (sqd: SavedQueryDescriptor) => void;
13
13
  onRefreshData?: () => void;
14
14
  }
15
- declare const TMSavedQuerySelector: React.MemoExoticComponent<({ items, selectedId, allowShowSearch, height, manageDefault, onItemClick, onDeleted, refreshFavoriteSavedQueries, onRefreshData }: ITMSavedQuerySelectorProps) => import("react/jsx-runtime").JSX.Element>;
15
+ declare const TMSavedQuerySelector: React.MemoExoticComponent<({ items, selectedId, allowShowSearch, height, manageDefault, onItemClick, onDeleted, refreshFavoriteSavedQueries, onRefreshData }: ITMSavedQuerySelectorProps) => React.JSX.Element>;
16
16
  export default TMSavedQuerySelector;
@@ -25,6 +25,6 @@ interface ITMSearchQueryPanelProps {
25
25
  declare const TMSearchQueryPanel: React.FunctionComponent<ITMSearchQueryPanelProps>;
26
26
  export default TMSearchQueryPanel;
27
27
  export declare const refreshLastSearch: (qd: QueryDescriptor | undefined) => Promise<SearchResultDescriptor[] | undefined>;
28
- export declare const StyledToppyTextContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
29
- export declare const StyledToppyText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
30
- export declare const StyledToppyImage: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, never>> & string;
28
+ export declare const StyledToppyTextContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
29
+ export declare const StyledToppyText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>>> & string;
30
+ export declare const StyledToppyImage: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, never>>> & string;
@@ -3,7 +3,8 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
3
3
  import styled from 'styled-components';
4
4
  import { LoadIndicator } from 'devextreme-react';
5
5
  import { AppModules, DataColumnTypes, DataListViewModes, DcmtTypeListCacheService, LayoutCacheService, LayoutModes, MetadataDataDomains, MetadataFormats, SDK_Globals, SystemMIDsAsNumber, UserListCacheService, } from '@topconsultnpm/sdk-ts';
6
- import { deepCompare, generateUniqueColumnKeys, genUniqueId, getSearchToolbarVisibility, IconBoard, IconDcmtTypeSys, IconDelete, IconMenuVertical, IconPlatform, IconRefresh, IconSearchCheck, IconShow, isApprovalWorkflowView, isSign4TopEnabled, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, SDKUI_Globals, SDKUI_Localizator } from '../../../helper';
6
+ import { deepCompare, generateUniqueColumnKeys, genUniqueId, getSearchToolbarVisibility, IconAll, IconBoard, IconDcmtTypeSys, IconDelete, IconMenuVertical, IconPlatform, IconRefresh, IconSearchCheck, IconShow, isApprovalWorkflowView, isSign4TopEnabled, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, SDKUI_Globals, SDKUI_Localizator } from '../../../helper';
7
+ import { CounterItemKey } from '../../base/TMCounterContainer';
7
8
  import { getDcmtCicoStatus } from '../../../helper/checkinCheckoutManager';
8
9
  import { DcmtOperationTypes, SearchResultContext, } from '../../../ts';
9
10
  import { Gutters } from '../../../utils/theme';
@@ -656,7 +657,7 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, }) => {
656
657
  && !openS4TViewer
657
658
  && !showTodoDcmtForm);
658
659
  }, [showToppyForApprove, showToppyDraggableHelpCenter, selectedDocs, showApprovePopup, showRejectPopup, showReAssignPopup, showMoreInfoPopup, editPdfForm, openS4TViewer, showTodoDcmtForm]);
659
- const searchResutlToolbar = _jsxs(_Fragment, { children: [(dcmtsReturned != dcmtsFound) && _jsx("p", { style: { textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${dcmtsReturned}/${dcmtsFound} restituiti` }), context === SearchResultContext.FAVORITES_AND_RECENTS &&
660
+ const searchResutlToolbar = _jsxs(_Fragment, { children: [context === SearchResultContext.FAVORITES_AND_RECENTS &&
660
661
  _jsx("div", { style: { display: 'flex', alignItems: 'center', gap: '5px' }, children: _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconDelete, { color: 'white' }), caption: "Rimuovi da " + (selectedSearchResult?.category === "Favorites" ? '"Preferiti"' : '"Recenti"'), disabled: getSelectedDcmtsOrFocused(selectedItems, focusedItem).length <= 0, onClick: removeDcmtFromFavsOrRecents }) }), _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconRefresh, { color: 'white' }), caption: SDKUI_Localizator.Refresh, onClick: onRefreshSearchAsyncDatagrid }), _jsx(TMContextMenu, { items: operationItems, trigger: "left", children: _jsx(IconMenuVertical, { color: 'white', cursor: 'pointer' }) })] });
661
662
  const tmSearchResult = useMemo(() => (!searchResults || searchResults.length <= 0)
662
663
  ? _jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%' }, children: [_jsx(IconBoard, { fontSize: 96 }), showNoDcmtFoundMessage && _jsx("div", { style: { fontSize: "15px", marginTop: "10px" }, children: SDKUI_Localizator.NoDcmtFound }), openAddDocumentForm && _jsx("div", { style: { marginTop: "10px" }, children: _jsx(TMButton, { fontSize: "15px", icon: _jsx("i", { className: 'dx-icon-share' }), caption: SDKUI_Localizator.Share, onClick: openAddDocumentForm }) })] })
@@ -664,7 +665,7 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, }) => {
664
665
  _jsxs(_Fragment, { children: [_jsxs(TMLayoutItem, { height: '100%', children: [_jsxs("div", { ref: floatingBarContainerRef, style: { position: 'relative', height: '100%', width: '100%' }, children: [_jsxs(TMSplitterLayout, { direction: 'horizontal', overflow: 'visible', separatorSize: Gutters.getGutters(), separatorActiveColor: 'transparent', separatorColor: 'transparent', min: ['0', '0'], showSeparator: showSelector && deviceType !== DeviceType.MOBILE, start: showSelector ? deviceType !== DeviceType.MOBILE ? ['30%', '70%'] : splitterSize : ['0%', '100%'], children: [showSelector ?
665
666
  _jsx(TMLayoutItem, { children: _jsx(TMSearchResultSelector, { searchResults: currentSearchResults, disableAccordionIfSingleCategory: disableAccordionIfSingleCategory, selectedTID: selectedSearchResultTID, selectedSearchResult: selectedSearchResult, autoSelectFirst: !isMobile || currentSearchResults.length === 1, onSelectionChanged: onSearchResultSelectionChanged }) })
666
667
  :
667
- _jsx(_Fragment, {}), _jsx(TMLayoutItem, { children: _jsx(TMSearchResultGrid, { openInOffice: openInOffice, fromDTD: fromDTD, operationItems: operationItems, allUsers: allUsers, inputFocusedItem: focusedItem, inputSelectedItems: selectedItems, showExportForm: showExportForm, onFocusedItemChanged: handleFocusedItemChangedFromGrid, onDownloadDcmtsAsync: async (inputDcmts, downloadType, downloadMode, _y, confirmAttachments) => await downloadDcmtsAsync({ inputDcmts, downloadType, downloadMode, onFileDownloaded: onFileOpened, confirmAttachments }), lastUpdateSearchTime: lastUpdateSearchTime, searchResult: searchResults.length > 1 ? selectedSearchResult : searchResults[0], onSelectionChanged: (items) => { setSelectedItems(items); }, onDblClick: () => openFormHandler(LayoutModes.Update), showSearchTMDatagrid: showSearchTMDatagrid, onVisibleItemChanged: setVisibleItems, updateDataColumnsFromDataGrid: updateDataColumnsFromDataGrid, updateDataSourceFromDataGrid: updateDataSourceFromDataGrid, updateSelectedRowKeysFromDataGrid: updateSelectedRowKeysFromDataGrid, disableAutoFocus: autoFocusFirstRow === false && isFirstAutoFocusRef.current }) })] }), renderFloatingBar] }), _jsx(TMToppyDraggableHelpCenter, { usePortal: toppyHelpCenterUsePortal, isVisible: isToppyHelpCenterVisible, content: _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: _jsx(WorkFlowOperationButtons, { dtd: fromDTD, deviceType: deviceType, onApprove: () => {
668
+ _jsx(_Fragment, {}), _jsx(TMLayoutItem, { children: _jsx(TMSearchResultGrid, { openInOffice: openInOffice, fromDTD: fromDTD, operationItems: operationItems, allUsers: allUsers, inputFocusedItem: focusedItem, inputSelectedItems: selectedItems, showExportForm: showExportForm, onFocusedItemChanged: handleFocusedItemChangedFromGrid, onDownloadDcmtsAsync: async (inputDcmts, downloadType, downloadMode, _y, confirmAttachments) => await downloadDcmtsAsync({ inputDcmts, downloadType, downloadMode, onFileDownloaded: onFileOpened, confirmAttachments }), lastUpdateSearchTime: lastUpdateSearchTime, searchResult: searchResults.length > 1 ? selectedSearchResult : searchResults[0], onSelectionChanged: (items) => { setSelectedItems(items); }, onDblClick: () => openFormHandler(LayoutModes.Update), showSearchTMDatagrid: showSearchTMDatagrid, onVisibleItemChanged: setVisibleItems, updateDataColumnsFromDataGrid: updateDataColumnsFromDataGrid, updateDataSourceFromDataGrid: updateDataSourceFromDataGrid, updateSelectedRowKeysFromDataGrid: updateSelectedRowKeysFromDataGrid, disableAutoFocus: autoFocusFirstRow === false && isFirstAutoFocusRef.current, dcmtsReturned: dcmtsReturned, dcmtsFound: dcmtsFound }) })] }), renderFloatingBar] }), _jsx(TMToppyDraggableHelpCenter, { usePortal: toppyHelpCenterUsePortal, isVisible: isToppyHelpCenterVisible, content: _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: _jsx(WorkFlowOperationButtons, { dtd: fromDTD, deviceType: deviceType, onApprove: () => {
668
669
  updateShowApprovePopup(true);
669
670
  }, onSignApprove: () => {
670
671
  handleSignApprove();
@@ -855,7 +856,7 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, }) => {
855
856
  _jsxs(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmSearchResult', children: [_jsx(PanelDisabledStateHandler, { isBoardDisabled: isBoardDisabled }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showSearchResultSidebar })] }) }) }) }), renderDcmtOperations] }));
856
857
  };
857
858
  export default TMSearchResult;
858
- const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, inputFocusedItem, allowMultipleSelection = true, showExportForm = false, onFocusedItemChanged, onDownloadDcmtsAsync, onVisibleItemChanged, inputSelectedItems = [], lastUpdateSearchTime, searchResult, onSelectionChanged, onDblClick, showSearchTMDatagrid, updateDataColumnsFromDataGrid, updateDataSourceFromDataGrid, updateSelectedRowKeysFromDataGrid, disableAutoFocus = false }) => {
859
+ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, inputFocusedItem, allowMultipleSelection = true, showExportForm = false, onFocusedItemChanged, onDownloadDcmtsAsync, onVisibleItemChanged, inputSelectedItems = [], lastUpdateSearchTime, searchResult, onSelectionChanged, onDblClick, showSearchTMDatagrid, updateDataColumnsFromDataGrid, updateDataSourceFromDataGrid, updateSelectedRowKeysFromDataGrid, disableAutoFocus = false, dcmtsReturned, dcmtsFound }) => {
859
860
  const [dataSource, setDataSource] = useState();
860
861
  const [columns, setColumns] = useState([]);
861
862
  const [selectedRowKeys, setSelectedRowKeys] = useState([]);
@@ -1267,7 +1268,21 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, i
1267
1268
  setVisibleItems(visibleData);
1268
1269
  }, []);
1269
1270
  useEffect(() => { onVisibleItemChanged?.(visibleItems); }, [visibleItems]);
1270
- return _jsxs("div", { style: { width: "100%", height: "100%" }, children: [!isDataGridReady && (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', gap: '10px' }, children: [_jsx(LoadIndicator, { height: 60, width: 60 }), _jsx("div", { children: SDKUI_Localizator.Loading })] })), isDataGridReady && _jsx(TMDataGrid, { ref: dataGridRef, id: "tm-search-result", keyExpr: "rowIndex", dataColumns: dataColumns, dataSource: dataSource, repaintChangesOnly: true, selectedRowKeys: selectedRowKeys, focusedRowKey: disableAutoFocus ? undefined : Number(focusedItem?.rowIndex ?? 0), showSearchPanel: showSearchTMDatagrid, showFilterPanel: true, sorting: { mode: "multiple" }, selection: { mode: allowMultipleSelection ? 'multiple' : 'single' }, pageSize: pageSize, onSelectionChanged: handleSelectionChange, onFocusedRowChanged: handleFocusedRowChange, onRowDblClick: onRowDblClick, onContentReady: onContentReady, showHeaderColumnChooser: true, onKeyDown: onKeyDown, customContextMenuItems: operationItems, counterConfig: { show: true } })] });
1271
+ return _jsxs("div", { style: { width: "100%", height: "100%" }, children: [!isDataGridReady && (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', gap: '10px' }, children: [_jsx(LoadIndicator, { height: 60, width: 60 }), _jsx("div", { children: SDKUI_Localizator.Loading })] })), isDataGridReady && _jsx(TMDataGrid, { ref: dataGridRef, id: "tm-search-result", keyExpr: "rowIndex", dataColumns: dataColumns, dataSource: dataSource, repaintChangesOnly: true, selectedRowKeys: selectedRowKeys, focusedRowKey: disableAutoFocus ? undefined : Number(focusedItem?.rowIndex ?? 0), showSearchPanel: showSearchTMDatagrid, showFilterPanel: true, sorting: { mode: "multiple" }, selection: { mode: allowMultipleSelection ? 'multiple' : 'single' }, pageSize: pageSize, onSelectionChanged: handleSelectionChange, onFocusedRowChanged: handleFocusedRowChange, onRowDblClick: onRowDblClick, onContentReady: onContentReady, showHeaderColumnChooser: true, onKeyDown: onKeyDown, customContextMenuItems: operationItems, counterConfig: {
1272
+ show: true,
1273
+ items: dcmtsReturned !== undefined && dcmtsFound !== undefined
1274
+ ? new Map([
1275
+ [CounterItemKey.allItems, {
1276
+ key: CounterItemKey.allItems,
1277
+ show: true,
1278
+ caption: `${dcmtsReturned} restituiti su ${dcmtsFound} trovati`,
1279
+ value: `${dcmtsReturned}/${dcmtsFound}`,
1280
+ icon: _jsx(IconAll, {}),
1281
+ order: -1
1282
+ }]
1283
+ ])
1284
+ : undefined
1285
+ } })] });
1271
1286
  };
1272
1287
  //#region TMSearchResultSelector
1273
1288
  const StyledItemTemplate = styled.div `
@@ -12,5 +12,5 @@ interface TMSearchResultFloatingActionButtonProps {
12
12
  selectedDcmtsOrFocused: Array<DcmtInfo>;
13
13
  config: TMSearchResultFloatingActionConfig;
14
14
  }
15
- export declare const TMSearchResultFloatingActionButton: (props: TMSearchResultFloatingActionButtonProps) => import("react/jsx-runtime").JSX.Element;
15
+ export declare const TMSearchResultFloatingActionButton: (props: TMSearchResultFloatingActionButtonProps) => React.JSX.Element;
16
16
  export default TMSearchResultFloatingActionButton;
@@ -1,6 +1,7 @@
1
+ import React from "react";
1
2
  import { DcmtInfo } from "../../../ts";
2
3
  interface TMSignatureInfoContentProps {
3
4
  inputDcmt: DcmtInfo;
4
5
  }
5
- declare const TMSignatureInfoContent: (props: TMSignatureInfoContentProps) => import("react/jsx-runtime").JSX.Element | null;
6
+ declare const TMSignatureInfoContent: (props: TMSignatureInfoContentProps) => React.JSX.Element | null;
6
7
  export default TMSignatureInfoContent;
@@ -1,3 +1,4 @@
1
+ import React from "react";
1
2
  import { DcmtInfo } from "../../../ts/types";
2
3
  import { DeviceType } from "../../base/TMDeviceProvider";
3
4
  import { DcmtTypeDescriptor, HomeBlogPost, TaskDescriptor } from "@topconsultnpm/sdk-ts";
@@ -14,5 +15,5 @@ interface TMViewHistoryDcmtProps {
14
15
  handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
15
16
  handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
16
17
  }
17
- declare const TMViewHistoryDcmt: (props: TMViewHistoryDcmtProps) => import("react/jsx-runtime").JSX.Element;
18
+ declare const TMViewHistoryDcmt: (props: TMViewHistoryDcmtProps) => React.JSX.Element;
18
19
  export default TMViewHistoryDcmt;
@@ -36,5 +36,5 @@ export interface TMTaskFormProps {
36
36
  onOpenPdfEditorRequest?: (dcmtInfo: Array<DcmtInfo>, refreshDocumentPreview?: () => Promise<void>) => void;
37
37
  s4TViewerDialogComponent?: React.ReactNode;
38
38
  }
39
- declare const TMTaskForm: (props: TMTaskFormProps) => import("react/jsx-runtime").JSX.Element;
39
+ declare const TMTaskForm: (props: TMTaskFormProps) => React.JSX.Element;
40
40
  export default TMTaskForm;