@topconsultnpm/sdkui-react 6.22.0-dev3.2 → 6.22.0-dev3.20

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 (137) hide show
  1. package/lib/components/NewComponents/ContextMenu/styles.d.ts +43 -17
  2. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +78 -19
  3. package/lib/components/base/Styled.d.ts +79 -27
  4. package/lib/components/base/Styled.js +7 -5
  5. package/lib/components/base/TMCounterBar.d.ts +2 -2
  6. package/lib/components/base/TMCounterContainer.d.ts +2 -1
  7. package/lib/components/base/TMCustomButton.d.ts +1 -1
  8. package/lib/components/base/TMDataGrid.d.ts +2 -0
  9. package/lib/components/base/TMDataGrid.js +34 -6
  10. package/lib/components/base/TMDataGridExportForm.d.ts +2 -1
  11. package/lib/components/base/TMFileManager.d.ts +2 -1
  12. package/lib/components/base/TMFileManagerDataGridView.d.ts +2 -1
  13. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +1 -1
  14. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +1 -1
  15. package/lib/components/base/TMFileManagerUtils.d.ts +3 -1
  16. package/lib/components/base/TMLayout.d.ts +4 -4
  17. package/lib/components/base/TMList.d.ts +2 -1
  18. package/lib/components/base/TMListView.d.ts +1 -1
  19. package/lib/components/base/TMPanel.js +167 -167
  20. package/lib/components/base/TMSpinner.d.ts +2 -1
  21. package/lib/components/base/TMTab.d.ts +4 -3
  22. package/lib/components/base/TMTabControl.d.ts +106 -0
  23. package/lib/components/base/TMTabControl.js +664 -0
  24. package/lib/components/base/TMTooltip.d.ts +1 -1
  25. package/lib/components/base/TMTreeView.d.ts +13 -5
  26. package/lib/components/base/TMTreeView.js +19 -1
  27. package/lib/components/base/TMUserAvatar.d.ts +2 -1
  28. package/lib/components/base/TMVilViewer.d.ts +2 -1
  29. package/lib/components/base/TMWaitPanel.d.ts +3 -2
  30. package/lib/components/base/TMWaitPanel.js +1 -1
  31. package/lib/components/choosers/TMDistinctValues.js +27 -18
  32. package/lib/components/choosers/TMDynDataListItemChooser.d.ts +1 -1
  33. package/lib/components/choosers/TMInvoiceRetrieveFormats.d.ts +2 -1
  34. package/lib/components/choosers/TMOrderRetrieveFormats.d.ts +2 -1
  35. package/lib/components/choosers/TMQuickSearchInfo.d.ts +2 -1
  36. package/lib/components/choosers/TMRelationChooser.d.ts +3 -3
  37. package/lib/components/choosers/TMUserChooser.d.ts +2 -2
  38. package/lib/components/editors/TMEditorStyled.d.ts +15 -5
  39. package/lib/components/editors/TMFormulaEditor.d.ts +1 -1
  40. package/lib/components/editors/TMHtmlContentDisplay.d.ts +2 -1
  41. package/lib/components/editors/TMHtmlEditor.d.ts +2 -1
  42. package/lib/components/editors/TMMetadataValues.js +5 -5
  43. package/lib/components/editors/TMTreeDropDown.d.ts +1 -1
  44. package/lib/components/features/archive/TMArchive.js +7 -2
  45. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +1 -1
  46. package/lib/components/features/blog/TMBlogCommentForm.d.ts +2 -1
  47. package/lib/components/features/documents/TMCopyToFolderForm.js +18 -7
  48. package/lib/components/features/documents/TMDcmtForm.js +3 -2
  49. package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +1 -1
  50. package/lib/components/features/documents/TMDcmtIcon.d.ts +2 -1
  51. package/lib/components/features/documents/TMDcmtPreview.d.ts +7 -3
  52. package/lib/components/features/documents/TMDcmtTasks.d.ts +2 -1
  53. package/lib/components/features/documents/TMDragDropOverlay.d.ts +1 -1
  54. package/lib/components/features/documents/TMFileUploader.js +26 -26
  55. package/lib/components/features/documents/TMMasterDetailDcmts.js +40 -13
  56. package/lib/components/features/documents/TMMasterInfoFields.d.ts +2 -1
  57. package/lib/components/features/documents/TMMergeToPdfForm.d.ts +2 -1
  58. package/lib/components/features/documents/TMMergeToPdfForm.js +8 -7
  59. package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.d.ts +2 -1
  60. package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.js +13 -15
  61. package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.d.ts +4 -4
  62. package/lib/components/features/documents/TMRelationViewer.d.ts +21 -3
  63. package/lib/components/features/documents/TMRelationViewer.js +140 -104
  64. package/lib/components/features/documents/relationTreeState.d.ts +32 -0
  65. package/lib/components/features/documents/relationTreeState.js +89 -0
  66. package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +2 -1
  67. package/lib/components/features/search/TMMetadataOutputForm.d.ts +2 -1
  68. package/lib/components/features/search/TMMetadataSorterForm.d.ts +2 -1
  69. package/lib/components/features/search/TMSavedQuerySelector.d.ts +2 -2
  70. package/lib/components/features/search/TMSearch.d.ts +1 -1
  71. package/lib/components/features/search/TMSearch.js +68 -9
  72. package/lib/components/features/search/TMSearchQueryPanel.d.ts +9 -3
  73. package/lib/components/features/search/TMSearchResult.d.ts +5 -0
  74. package/lib/components/features/search/TMSearchResult.js +13 -4
  75. package/lib/components/features/search/TMSearchResultFloatingActionButton.d.ts +1 -1
  76. package/lib/components/features/search/TMSignatureInfoContent.d.ts +2 -1
  77. package/lib/components/features/search/TMTreeSelector.js +37 -35
  78. package/lib/components/features/search/TMViewHistoryDcmt.d.ts +2 -1
  79. package/lib/components/features/tasks/TMTaskForm.d.ts +1 -1
  80. package/lib/components/features/tasks/TMTaskFormUtils.d.ts +10 -10
  81. package/lib/components/features/tasks/TMTasksAgenda.d.ts +1 -1
  82. package/lib/components/features/tasks/TMTasksCalendar.d.ts +1 -1
  83. package/lib/components/features/tasks/TMTasksHeader.d.ts +1 -1
  84. package/lib/components/features/tasks/TMTasksPanelContent.d.ts +1 -1
  85. package/lib/components/features/tasks/TMTasksUtilsView.d.ts +5 -5
  86. package/lib/components/features/tasks/TMTasksView.d.ts +1 -1
  87. package/lib/components/features/tasks/TMTasksView.js +6 -12
  88. package/lib/components/features/wg/TMWGsCopyMoveForm.d.ts +3 -2
  89. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +8 -7
  90. package/lib/components/features/workflow/diagram/WorkitemRecipientsEditor.d.ts +3 -1
  91. package/lib/components/forms/Login/ChangePasswordInputs.d.ts +3 -1
  92. package/lib/components/forms/Login/Chooser.d.ts +2 -2
  93. package/lib/components/forms/TMChooserForm.d.ts +2 -1
  94. package/lib/components/forms/TMResultDialog.js +1 -1
  95. package/lib/components/forms/TMSaveForm.d.ts +4 -4
  96. package/lib/components/grids/TMBlogAttachments.d.ts +2 -1
  97. package/lib/components/grids/TMBlogHeader.d.ts +1 -1
  98. package/lib/components/grids/TMBlogsPost.d.ts +1 -1
  99. package/lib/components/grids/TMBlogsPostUtils.d.ts +9 -9
  100. package/lib/components/grids/TMValidationItemsList.d.ts +2 -1
  101. package/lib/components/index.d.ts +2 -0
  102. package/lib/components/index.js +2 -0
  103. package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +2 -1
  104. package/lib/components/layout/panelManager/TMPanelManagerContext.d.ts +2 -2
  105. package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +4 -2
  106. package/lib/components/layout/panelManager/TMPanelManagerWithPersistenceProvider.d.ts +2 -2
  107. package/lib/components/layout/panelManager/TMPanelWrapper.d.ts +2 -2
  108. package/lib/components/pages/TMPage.d.ts +1 -1
  109. package/lib/components/query/TMQueryEditor.d.ts +12 -4
  110. package/lib/components/settings/SettingsAppearance.d.ts +2 -1
  111. package/lib/components/sidebar/TMAboutApp.d.ts +2 -1
  112. package/lib/components/sidebar/TMCommandsPanel.d.ts +3 -1
  113. package/lib/components/sidebar/TMHeader.d.ts +3 -3
  114. package/lib/components/viewers/TMDataListItemViewer.d.ts +3 -2
  115. package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +3 -2
  116. package/lib/components/viewers/TMMidViewer.d.ts +2 -2
  117. package/lib/components/viewers/TMTidViewer.d.ts +2 -2
  118. package/lib/helper/Enum_Localizator.js +1 -0
  119. package/lib/helper/SDKUI_Localizator.d.ts +6 -0
  120. package/lib/helper/SDKUI_Localizator.js +60 -0
  121. package/lib/helper/TMAppUpdatedModal.d.ts +2 -1
  122. package/lib/helper/TMAppUpdatedModal.js +93 -93
  123. package/lib/helper/TMCommandsContextMenu.d.ts +1 -1
  124. package/lib/helper/TMIcons.d.ts +280 -280
  125. package/lib/helper/TMPdfViewer.d.ts +2 -1
  126. package/lib/helper/TMToppyMessage.d.ts +2 -2
  127. package/lib/helper/TMUtils.d.ts +10 -4
  128. package/lib/helper/helpers.d.ts +1 -1
  129. package/lib/hooks/useDcmtOperations.js +94 -56
  130. package/lib/hooks/useDocumentOperations.d.ts +1 -0
  131. package/lib/hooks/useDocumentOperations.js +2 -2
  132. package/lib/hooks/useInputDialog.d.ts +2 -1
  133. package/lib/hooks/usePreventFileDrop.js +9 -0
  134. package/lib/services/caseflow/CaseFlowService.d.ts +32 -1
  135. package/lib/services/caseflow/CaseFlowService.js +58 -1
  136. package/lib/services/platform_services.d.ts +3 -2
  137. package/package.json +22 -22
@@ -13,6 +13,7 @@ import TMDcmtIcon from './TMDcmtIcon';
13
13
  import TMDataUserIdItemViewer from '../../viewers/TMDataUserIdItemViewer';
14
14
  import TMTooltip from '../../base/TMTooltip';
15
15
  import TMSpinner from '../../base/TMSpinner';
16
+ import { applyRelationTreeState, collectRelationTreeState, findRelationNodeByPath } from './relationTreeState';
16
17
  /**
17
18
  * Check if document type has detail relations
18
19
  */
@@ -67,8 +68,10 @@ export const getDisplayValueByColumn = (col, value) => {
67
68
  };
68
69
  /**
69
70
  * Convert SearchResultDescriptor to structured data source with metadata
70
- * For each document, fetches complete metadata using GetMetadataAsync to ensure
71
- * all metadata properties (isSpecialSearchOutput, permissions, etc.) are available
71
+ * I valori dei documenti sono GIÀ presenti nelle righe restituite dalla ricerca:
72
+ * qui vengono solo abbinati ai rispettivi MetadataDescriptor (perm,
73
+ * isSpecialSearchOutput, ...), risolti UNA SOLA VOLTA per tipo documento.
74
+ * Nessuna chiamata al server per riga.
72
75
  */
73
76
  export const searchResultToDataSource = async (searchResult, hideSysMetadata, signal) => {
74
77
  const rows = searchResult?.dtdResult?.rows ?? [];
@@ -77,27 +80,28 @@ export const searchResultToDataSource = async (searchResult, hideSysMetadata, si
77
80
  const columns = searchResult?.dtdResult?.columns ?? [];
78
81
  const tidColIndex = columns.findIndex(col => col.caption?.toUpperCase() === 'TID');
79
82
  const didColIndex = columns.findIndex(col => col.caption?.toUpperCase() === 'DID');
83
+ const firstRow = rows[0] ?? [];
84
+ const tid = tidColIndex >= 0 && firstRow.length > 0 ? Number(firstRow[tidColIndex]) : searchResult?.fromTID;
85
+ const firstDid = didColIndex >= 0 && firstRow.length > 0 ? Number(firstRow[didColIndex]) : undefined;
86
+ const dtdWithMetadata = await DcmtTypeListCacheService.GetWithNotGrantedAsync(tid, firstDid, searchResult);
87
+ const mdList = dtdWithMetadata?.metadata ?? [];
88
+ // Posizione di ogni MID nelle colonne del risultato: identica per tutte le righe,
89
+ // quindi calcolata una volta sola invece di una find() per metadato per riga.
90
+ const mids = columns.map(col => Number(col.extendedProperties?.["MID"] ?? "0"));
91
+ const columnByMid = new Map();
92
+ columns.forEach((col, i) => { if (!columnByMid.has(mids[i]))
93
+ columnByMid.set(mids[i], col); });
94
+ const dtdResult = searchResult?.dtdResult;
80
95
  for (let index = 0; index < rows.length; index++) {
81
96
  // Interruzione richiesta dall'utente: restituisce i documenti già elaborati
82
97
  if (signal?.aborted)
83
98
  break;
84
99
  const row = rows[index];
85
- // Extract TID and DID from row
86
- const tid = tidColIndex >= 0 ? Number(row[tidColIndex]) : searchResult?.fromTID;
87
- const did = didColIndex >= 0 ? Number(row[didColIndex]) : undefined;
88
- // Fetch complete metadata for this specific document (like getFilteredMetadata does)
89
- const metadata = await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(tid, did, true);
90
- if (metadata) {
91
- // Get full DTD with metadata for this document
92
- const dtdResult = metadata.dtdResult;
93
- const metadataRows = dtdResult?.rows?.[0] ?? [];
94
- const mids = metadata.selectMIDs;
95
- const dtdWithMetadata = await DcmtTypeListCacheService.GetWithNotGrantedAsync(tid, did, metadata);
96
- const mdList = dtdWithMetadata?.metadata ?? [];
100
+ const item = { rowIndex: index };
101
+ if (mdList.length > 0) {
97
102
  // Convert to MetadataValueDescriptorEx array
98
- const metadataList = searchResultToMetadataValues(tid, dtdResult, metadataRows, mids, mdList, LayoutModes.Update);
103
+ const metadataList = searchResultToMetadataValues(tid, dtdResult, row, mids, mdList, LayoutModes.Update);
99
104
  // Convert to DcmtMetadataMap format (like getFilteredMetadata does)
100
- const item = { rowIndex: index };
101
105
  for (const mvd of metadataList) {
102
106
  if (hideSysMetadata && mvd.mid !== undefined && mvd.mid < 100)
103
107
  continue;
@@ -106,23 +110,18 @@ export const searchResultToDataSource = async (searchResult, hideSysMetadata, si
106
110
  : (mvd.md?.name ?? '');
107
111
  if (key) {
108
112
  // Find the corresponding column by MID to format the value
109
- const column = dtdResult?.columns?.find(c => Number(c.extendedProperties?.["MID"] ?? "0") === mvd.mid);
110
113
  item[key] = {
111
114
  md: mvd.md,
112
- value: getDisplayValueByColumn(column, mvd.value)
115
+ value: getDisplayValueByColumn(columnByMid.get(mvd.mid ?? 0), mvd.value)
113
116
  };
114
117
  }
115
118
  }
116
- output.push(item);
117
119
  }
118
120
  else {
119
- // Fallback: use original row data with basic parsing
120
- const item = { rowIndex: index };
121
- const fallbackTid = searchResult?.fromTID;
122
- const dtd = await DcmtTypeListCacheService.GetWithNotGrantedAsync(fallbackTid, undefined, searchResult);
121
+ // Fallback: il DTD non è risolvibile, usa le colonne grezze del risultato
123
122
  for (let i = 0; i < row.length; i++) {
124
- const column = searchResult?.dtdResult?.columns?.[i];
125
- const mid = Number(column?.extendedProperties?.["MID"] ?? "0");
123
+ const column = columns[i];
124
+ const mid = mids[i];
126
125
  if (hideSysMetadata && mid < 100)
127
126
  continue;
128
127
  let key = column?.caption ?? '';
@@ -134,20 +133,18 @@ export const searchResultToDataSource = async (searchResult, hideSysMetadata, si
134
133
  key = `${key}_${mid}`;
135
134
  }
136
135
  }
137
- const value = row[i];
138
- const md = dtd?.metadata?.find(o => o.id == mid);
139
136
  item[key] = {
140
- md: md,
141
- value: getDisplayValueByColumn(column, value)
137
+ md: undefined,
138
+ value: getDisplayValueByColumn(column, row[i])
142
139
  };
143
140
  }
144
- output.push(item);
145
141
  }
142
+ output.push(item);
146
143
  }
147
144
  return output;
148
145
  };
149
146
  export const DEFAULT_RELATION_EXPAND_LEVEL = 4; // Default maximum depth level for expansion (can be adjusted)
150
- const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndicator = true, allowShowZeroDcmts = true, initialShowZeroDcmts = false, allowedTIDs, allowMultipleSelection = false, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onAllItemsChanged, onDocumentDoubleClick, customItemRender, customDocumentStyle, customMainContainerContent, customDocumentContent, showMetadataNames = false, maxDepthLevel = 2, invertMasterNavigation = true, additionalStaticItems, showMainDocument = true, labelMainContainer, onNoRelationsFound, onItemContextMenu, focusedItemFormData = [], showExpandAllButton = false, defaultExpandAll = false, onLoadingStateChanged, onStopCalculationReady, onCalculationStopped }) => {
147
+ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndicator = true, allowShowZeroDcmts = true, initialShowZeroDcmts = false, allowedTIDs, allowMultipleSelection = false, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onAllItemsChanged, onDocumentDoubleClick, customItemRender, customDocumentStyle, customMainContainerContent, customDocumentContent, showMetadataNames = false, maxDepthLevel = 2, invertMasterNavigation = true, additionalStaticItems, showMainDocument = true, labelMainContainer, onNoRelationsFound, onItemContextMenu, focusedItemFormData = [], showExpandAllButton = false, defaultExpandAll = false, onLoadingStateChanged, onLoadingProgress, onStopCalculationReady, onCalculationStopped, initialTreeState, onTreeStateChange }) => {
151
148
  // State
152
149
  const [dcmtTypes, setDcmtTypes] = useState([]);
153
150
  const [treeData, setTreeData] = useState([]);
@@ -181,6 +178,14 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
181
178
  const userInteractedWithStaticItemsRef = React.useRef(false);
182
179
  // Ref to track the last inputKey for which we set the focused item
183
180
  const lastFocusedInputRef = React.useRef('');
181
+ // Catturato al mount (il padre lo aggiorna di continuo) e azzerato dopo l'uso,
182
+ // così vale solo per il primo caricamento
183
+ const stateToRestoreRef = React.useRef(initialTreeState);
184
+ // Parte dallo stato ricevuto: il padre azzera il fuoco prima di rimontare, quindi
185
+ // la prima notifica dopo il rimontaggio lo perderebbe
186
+ const lastReportedStateRef = React.useRef(initialTreeState);
187
+ // Percorso su cui rimettere il fuoco dopo un ripristino
188
+ const pendingFocusPathRef = React.useRef(undefined);
184
189
  // State for all users (used for checkout status display)
185
190
  const [allUsers, setAllUsers] = useState([]);
186
191
  // Load all users for checkout status resolution
@@ -196,6 +201,11 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
196
201
  const isLoading = showWaitPanel || showExpansionWaitPanel;
197
202
  onLoadingStateChanged?.(isLoading);
198
203
  }, [showWaitPanel, showExpansionWaitPanel, onLoadingStateChanged]);
204
+ // Notifica al padre l'avanzamento del caricamento iniziale (documenti processati
205
+ // sul totale), così può mostrarlo nel proprio overlay che copre il wait panel interno
206
+ useEffect(() => {
207
+ onLoadingProgress?.(waitPanelValuePrimary, waitPanelMaxValuePrimary);
208
+ }, [waitPanelValuePrimary, waitPanelMaxValuePrimary, onLoadingProgress]);
199
209
  // Mantiene l'AbortController dell'espansione in corso accessibile da callback stabili
200
210
  const expansionAbortControllerRef = React.useRef(undefined);
201
211
  useEffect(() => {
@@ -478,6 +488,26 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
478
488
  return { ...node, hidden: shouldHide, items: updatedItems };
479
489
  });
480
490
  }, [showZeroDcmts]);
491
+ /** Messaggio informativo in testa se tutti i figli sono nascosti dal filtro; senza figli il nodo resta vuoto (nessuna freccina). */
492
+ const applyZeroFilterInfoMessage = useCallback((nodeKey, items) => {
493
+ const cleaned = items.filter(child => !(child.isInfoMessage && child.key?.startsWith('__info__')));
494
+ if (showZeroDcmts)
495
+ return cleaned;
496
+ const realChildren = cleaned.filter(child => !child.isInfoMessage);
497
+ if (realChildren.length === 0 || !realChildren.every(child => child.hidden))
498
+ return cleaned;
499
+ return [
500
+ {
501
+ key: `__info__${nodeKey}`,
502
+ name: SDKUI_Localizator.NoRelatedDocumentsToDisplay,
503
+ isContainer: false,
504
+ isDcmt: false,
505
+ isInfoMessage: true,
506
+ isExpandible: false
507
+ },
508
+ ...cleaned // Keep hidden containers so they can be shown when toggling
509
+ ];
510
+ }, [showZeroDcmts]);
481
511
  /**
482
512
  * Helper function to set up initial tree expansion state.
483
513
  * Called after all data is loaded but before setTreeData.
@@ -565,6 +595,18 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
565
595
  });
566
596
  return result;
567
597
  };
598
+ /**
599
+ * Carica i figli di un documento durante il ripristino. Usa i loader e non
600
+ * calculateItemsForNode, che accenderebbe il wait panel di espansione mentre
601
+ * è già attivo quello del caricamento principale.
602
+ */
603
+ const loadChildrenForRestore = async (node) => {
604
+ if (!node.tid || !node.did)
605
+ return [];
606
+ if (isForMaster && invertMasterNavigation)
607
+ return await getMasterDcmtsAsync(node.tid, node.did, 1, abortController.signal);
608
+ return await getDetailDcmtsAsync(node.tid, node.did, 1, abortController.signal);
609
+ };
568
610
  /**
569
611
  * Main data loading function
570
612
  */
@@ -638,6 +680,11 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
638
680
  }
639
681
  }
640
682
  }
683
+ // Interruzione richiesta dall'utente: il documento corrente non è stato
684
+ // caricato per intero, quindi non viene aggiunto all'albero. Il parziale
685
+ // resta così a granularità di documento (es. 3 completi su 10).
686
+ if (abortController.signal.aborted)
687
+ break;
641
688
  // Aggiungi i master come root, raggruppando per TID e relationId
642
689
  for (const masterContainer of masterDocs) {
643
690
  const existingContainer = tree.find(c => c.tid === masterContainer.tid && c.relationId === masterContainer.relationId && c.isContainer);
@@ -666,6 +713,9 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
666
713
  const relatedDocs = isForMaster
667
714
  ? await getMasterDcmtsAsync(dcmt.TID, dcmt.DID, maxDepthLevel, abortController.signal)
668
715
  : await getDetailDcmtsAsync(dcmt.TID, dcmt.DID, maxDepthLevel, abortController.signal);
716
+ // Interruzione richiesta dall'utente
717
+ if (abortController.signal.aborted)
718
+ break;
669
719
  // Se showMainDocument è false, mostra i container dei dettagli direttamente sotto il container principale
670
720
  if (!showMainDocument) {
671
721
  // Check if a container for this TID already exists in the tree
@@ -817,7 +867,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
817
867
  const wasStopped = abortController.signal.aborted;
818
868
  if (wasStopped) {
819
869
  setLoadStoppedByUser(true);
820
- onCalculationStopped?.();
870
+ onCalculationStopped?.(processedCount, inputDcmts.length);
821
871
  }
822
872
  // If no relations found, notify parent
823
873
  if (!wasStopped && hasNoRelations && onNoRelationsFound) {
@@ -843,12 +893,20 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
843
893
  }
844
894
  // FIRST setup initial expansion state (root container expanded, first document expanded with focus, first correlation folder expanded)
845
895
  // This must run BEFORE updateHiddenProperty so that infoMessage logic sees expanded=true
846
- const expandedTree = setupInitialTreeExpansion(tree);
896
+ let expandedTree = setupInitialTreeExpansion(tree);
897
+ // Stato precedente da ripristinare (rimontaggio dopo un'operazione): si riapplica
898
+ // sopra l'espansione iniziale, che resta necessaria perché marca isRoot.
899
+ const stateToRestore = stateToRestoreRef.current;
900
+ stateToRestoreRef.current = undefined;
901
+ if (stateToRestore && stateToRestore.inputKey === getInputKey()) {
902
+ expandedTree = await applyRelationTreeState(expandedTree, stateToRestore, loadChildrenForRestore, () => abortController.signal.aborted);
903
+ pendingFocusPathRef.current = stateToRestore.focusedPath;
904
+ }
847
905
  // THEN apply hidden property transformations (creates new objects, adds infoMessage where needed)
848
906
  // Now it will correctly detect expanded nodes and add infoMessage if all children are hidden
849
907
  const processedTree = updateHiddenProperty(expandedTree);
850
908
  setTreeData(processedTree);
851
- }, [inputDcmts, dcmtTypes, maxDepthLevel, isForMaster, invertMasterNavigation, getDetailDcmtsAsync, getMasterDcmtsAsync, abortController, updateHiddenProperty, showMainDocument, labelMainContainer, onNoRelationsFound, onCalculationStopped]);
909
+ }, [inputDcmts, dcmtTypes, maxDepthLevel, isForMaster, invertMasterNavigation, getDetailDcmtsAsync, getMasterDcmtsAsync, abortController, updateHiddenProperty, showMainDocument, labelMainContainer, onNoRelationsFound, onCalculationStopped, getInputKey]);
852
910
  /**
853
911
  * Merge main tree data with additional static items
854
912
  */
@@ -863,6 +921,18 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
863
921
  // and may contain custom properties that would be lost by the spread operator
864
922
  return [...treeData, ...itemsToMerge];
865
923
  }, [treeData, additionalStaticItems, staticItemsState]);
924
+ /** Notifica al padre lo stato dell'albero, così che possa restituirlo dopo un refresh. */
925
+ useEffect(() => {
926
+ if (!onTreeStateChange)
927
+ return;
928
+ // Ad albero vuoto (caricamento in corso) si sovrascriverebbe lo stato da ripristinare
929
+ if (treeData.length === 0)
930
+ return;
931
+ // Il padre azzera il fuoco all'avvio di un refresh: si conserva l'ultimo noto
932
+ const state = collectRelationTreeState(treeData, getInputKey(), focusedItem?.key, lastReportedStateRef.current?.focusedPath);
933
+ lastReportedStateRef.current = state;
934
+ onTreeStateChange(state);
935
+ }, [treeData, focusedItem, getInputKey, onTreeStateChange]);
866
936
  /**
867
937
  * Notify parent with a flattened list of all items whenever the merged tree data changes.
868
938
  */
@@ -942,6 +1012,18 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
942
1012
  if (lastFocusedInputRef.current === currentInputKey) {
943
1013
  return;
944
1014
  }
1015
+ // Ripristino dopo un refresh. Se il nodo non esiste più (es. documento cancellato
1016
+ // fisicamente) si prosegue con il fuoco predefinito sul root.
1017
+ const focusPathToRestore = pendingFocusPathRef.current;
1018
+ pendingFocusPathRef.current = undefined;
1019
+ if (focusPathToRestore) {
1020
+ const nodeToFocus = findRelationNodeByPath(treeData, focusPathToRestore);
1021
+ if (nodeToFocus) {
1022
+ onFocusedItemChanged(nodeToFocus);
1023
+ lastFocusedInputRef.current = currentInputKey;
1024
+ return;
1025
+ }
1026
+ }
945
1027
  // Helper function to recursively find the first document with isRoot=true
946
1028
  const findFirstRootDocument = (items) => {
947
1029
  for (const item of items) {
@@ -1019,29 +1101,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
1019
1101
  if (node.isLoaded && node.items) {
1020
1102
  // Apply current show/hide logic based on showZeroDcmts
1021
1103
  const updatedItems = updateHiddenProperty(node.items);
1022
- // If this is a container, check if we need to show info message
1023
- if (node.isContainer) {
1024
- // Remove any existing info messages
1025
- const filteredItems = updatedItems.filter(child => !(child.isInfoMessage && child.key?.startsWith('__info__')));
1026
- // Check if all real children are hidden
1027
- const realChildren = filteredItems.filter(child => !child.isInfoMessage);
1028
- const allChildrenHidden = realChildren.length > 0 && realChildren.every(child => child.hidden);
1029
- // If showZeroDcmts is false and all items are hidden, show info message + keep hidden containers
1030
- if (!showZeroDcmts && allChildrenHidden) {
1031
- return [
1032
- {
1033
- key: `__info__${node.key}`,
1034
- name: SDKUI_Localizator.NoRelatedDocumentsToDisplay,
1035
- isContainer: false,
1036
- isDcmt: false,
1037
- isInfoMessage: true,
1038
- isExpandible: false
1039
- },
1040
- ...filteredItems // Keep hidden containers so they can be shown when toggling
1041
- ];
1042
- }
1043
- }
1044
- return updatedItems;
1104
+ return applyZeroFilterInfoMessage(node.key, updatedItems);
1045
1105
  }
1046
1106
  // ============================================
1047
1107
  // CONTAINER: Show items immediately (no API calls)
@@ -1055,21 +1115,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
1055
1115
  if (!node.items)
1056
1116
  return [];
1057
1117
  const updatedItems = updateHiddenProperty(node.items);
1058
- // If showZeroDcmts is false and all items are hidden, add info message + keep hidden containers
1059
- if (!showZeroDcmts && updatedItems.length > 0 && updatedItems.every(item => item.hidden)) {
1060
- return [
1061
- {
1062
- key: `__info__${node.key}`,
1063
- name: SDKUI_Localizator.NoRelatedDocumentsToDisplay,
1064
- isContainer: false,
1065
- isDcmt: false,
1066
- isInfoMessage: true,
1067
- isExpandible: false
1068
- },
1069
- ...updatedItems // Keep hidden containers so they can be shown when toggling
1070
- ];
1071
- }
1072
- return updatedItems;
1118
+ return applyZeroFilterInfoMessage(node.key, updatedItems);
1073
1119
  }
1074
1120
  // ============================================
1075
1121
  // DOCUMENT: Load its children (relation containers) lazily
@@ -1110,21 +1156,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
1110
1156
  // - Relation type containers are always visible (even if empty)
1111
1157
  // - Other containers with zero items can be hidden based on showZeroDcmts
1112
1158
  const updatedItems = updateHiddenProperty(loadedItems);
1113
- // If showZeroDcmts is false and all items are hidden, add info message + keep hidden containers
1114
- if (!showZeroDcmts && updatedItems.length > 0 && updatedItems.every(item => item.hidden)) {
1115
- return [
1116
- {
1117
- key: `__info__${node.key}`,
1118
- name: SDKUI_Localizator.NoRelatedDocumentsToDisplay,
1119
- isContainer: false,
1120
- isDcmt: false,
1121
- isInfoMessage: true,
1122
- isExpandible: false
1123
- },
1124
- ...updatedItems // Keep hidden containers so they can be shown when toggling
1125
- ];
1126
- }
1127
- return updatedItems;
1159
+ return applyZeroFilterInfoMessage(node.key, updatedItems);
1128
1160
  }
1129
1161
  catch (error) {
1130
1162
  console.error('Error loading document relations:', error);
@@ -1137,7 +1169,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
1137
1169
  }
1138
1170
  // Default: return existing items
1139
1171
  return node.items;
1140
- }, [isForMaster, invertMasterNavigation, getDetailDcmtsAsync, getMasterDcmtsAsync, updateHiddenProperty, showZeroDcmts]);
1172
+ }, [isForMaster, invertMasterNavigation, getDetailDcmtsAsync, getMasterDcmtsAsync, updateHiddenProperty, applyZeroFilterInfoMessage, showZeroDcmts]);
1141
1173
  /**
1142
1174
  * Default item renderer with metadata display (adapted from TMMasterDetailDcmts.tsx)
1143
1175
  */
@@ -1170,8 +1202,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
1170
1202
  gap: '10px',
1171
1203
  height: '32px',
1172
1204
  padding: '6px 0',
1173
- opacity: item.isZero ? 0.99 : 1,
1174
- transition: 'opacity 0.2s ease-in-out'
1205
+ opacity: item.isZero ? 0.4 : 1,
1175
1206
  };
1176
1207
  // Se è il container principale (root) e showMainDocument è false,
1177
1208
  // non mostrare il badge perché conterrebbe il numero di sotto-container, non di documenti
@@ -1201,8 +1232,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
1201
1232
  alignItems: 'center',
1202
1233
  cursor: 'pointer',
1203
1234
  userSelect: 'none',
1204
- opacity: item.isZero ? 0.99 : 1,
1205
- transition: 'opacity 0.2s ease-in-out',
1235
+ opacity: item.isZero ? 0.4 : 1,
1206
1236
  textDecoration: isLogicallyDeleted ? 'line-through' : 'none'
1207
1237
  };
1208
1238
  const documentStyle = customDocumentStyle ? { ...defaultDocumentStyle, ...customDocumentStyle(item) } : defaultDocumentStyle;
@@ -1377,14 +1407,17 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
1377
1407
  const targetLevel = expandLevel;
1378
1408
  const newAbortController = new AbortController();
1379
1409
  setExpansionAbortController(newAbortController);
1410
+ // Denominatore subito: con maxValue = 0 TMWaitPanel disegna una barra ferma a 0%
1411
+ setExpansionWaitPanelMaxValue(100);
1412
+ setExpansionWaitPanelValue(0);
1380
1413
  // CONTATORI DINAMICI:
1381
1414
  // - totalNodes: cresce quando scopriamo nuovi nodi (evita che percentuale > 100%)
1382
1415
  // - processedNodes: quanti nodi abbiamo già processato
1383
- // - maxReachedProgress: percentuale massima raggiunta (evita che la barra torni indietro)
1416
+ // - shownProgress: percentuale mostrata, che non torna mai indietro
1384
1417
  let totalNodes = 0;
1385
1418
  let processedNodes = 0;
1386
1419
  let hasApiCalls = false;
1387
- let maxReachedProgress = 0;
1420
+ let shownProgress = 0;
1388
1421
  /**
1389
1422
  * Conta i nodi espandibili in un array (solo primo livello, non ricorsivo).
1390
1423
  * Usato per aggiornare totalNodes man mano che scopriamo nuovi figli.
@@ -1400,6 +1433,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
1400
1433
  };
1401
1434
  // Conta iniziale: solo i nodi al livello root
1402
1435
  totalNodes = countNodesAtLevel([...workingTreeData, ...workingStaticData]);
1436
+ const initialTotalNodes = totalNodes;
1403
1437
  /**
1404
1438
  * FUNZIONE RICORSIVA DI ESPANSIONE
1405
1439
  *
@@ -1470,7 +1504,8 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
1470
1504
  loadedItems = await getDetailDcmtsAsync(node.tid, node.did, 1, newAbortController.signal);
1471
1505
  }
1472
1506
  // Applica le regole di visibilità (showZeroDcmts)
1473
- expandedNode.items = updateHiddenProperty(loadedItems);
1507
+ // Stesse regole dell'espansione manuale (messaggio informativo se tutto nascosto)
1508
+ expandedNode.items = applyZeroFilterInfoMessage(node.key, updateHiddenProperty(loadedItems));
1474
1509
  expandedNode.isLoaded = true;
1475
1510
  expandedNode.itemsCount = loadedItems.length;
1476
1511
  // IMPORTANTE: Aggiungi i nuovi nodi scoperti al contatore totale
@@ -1497,14 +1532,15 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
1497
1532
  }
1498
1533
  // Aggiorna il progresso DOPO aver processato questo nodo
1499
1534
  processedNodes++;
1500
- // Calcola percentuale e aggiorna solo se è più alta di prima
1501
- // (evita che la barra di progresso torni indietro)
1502
- const currentProgress = totalNodes > 0 ? Math.floor((processedNodes / totalNodes) * 100) : 0;
1503
- if (currentProgress > maxReachedProgress) {
1504
- maxReachedProgress = currentProgress;
1505
- setExpansionWaitPanelValue(maxReachedProgress);
1506
- }
1507
- setExpansionWaitPanelText(SDKUI_Localizator.ExpansionProgress.replaceParams(processedNodes.toString(), totalNodes.toString()));
1535
+ // La barra non torna mai indietro: segue il valore reale quando sale, altrimenti avanza verso il 99%
1536
+ const realProgress = totalNodes > 0 ? (processedNodes / totalNodes) * 100 : 0;
1537
+ shownProgress = Math.min(99, realProgress > shownProgress
1538
+ ? realProgress
1539
+ : shownProgress + (99 - shownProgress) * 0.01);
1540
+ setExpansionWaitPanelValue(shownProgress);
1541
+ // Seconda riga: spiega perché percentuale e conteggio non vanno di pari passo
1542
+ setExpansionWaitPanelText(SDKUI_Localizator.ExpansionProgress.replaceParams(processedNodes.toString(), totalNodes.toString())
1543
+ + (totalNodes > initialTotalNodes ? `\n${SDKUI_Localizator.ExpansionProgressIsEstimated}` : ''));
1508
1544
  // ═══════════════════════════════════════════════════════════════════
1509
1545
  // PASSO 3: CHIAMATA RICORSIVA SUI FIGLI
1510
1546
  // Questo è il punto chiave: i nuovi nodi appena caricati vengono
@@ -1535,7 +1571,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
1535
1571
  setShowExpansionWaitPanel(false);
1536
1572
  setExpansionAbortController(undefined);
1537
1573
  }
1538
- }, [expandLevel, treeData, staticItemsState, isForMaster, invertMasterNavigation, getDetailDcmtsAsync, getMasterDcmtsAsync, updateHiddenProperty]);
1574
+ }, [expandLevel, treeData, staticItemsState, isForMaster, invertMasterNavigation, getDetailDcmtsAsync, getMasterDcmtsAsync, updateHiddenProperty, applyZeroFilterInfoMessage]);
1539
1575
  /**
1540
1576
  * Apply defaultExpandAll once on initial tree load.
1541
1577
  */
@@ -0,0 +1,32 @@
1
+ import type { RelationTreeItem } from './TMRelationViewer';
2
+ /**
3
+ * Conserva lo stato di un albero delle correlazioni (nodi espansi e fuoco) attraverso
4
+ * un refresh che ricarica i dati da zero. I nodi non sono confrontabili per `key`, che
5
+ * contiene un GUID rigenerato ad ogni caricamento: si usa un percorso costruito sui campi.
6
+ */
7
+ export interface RelationTreeState {
8
+ /** Documenti di input a cui lo stato si riferisce: non va applicato ad altri */
9
+ inputKey: string;
10
+ expandedPaths: string[];
11
+ /**
12
+ * Documenti espansi che avevano già i figli caricati. Quelli espansi ma vuoti
13
+ * (es. il root) non vanno ricaricati: mostrerebbero più di quanto c'era prima.
14
+ */
15
+ loadedPaths: string[];
16
+ focusedPath?: string;
17
+ }
18
+ /** Carica i figli di un documento durante il ripristino. */
19
+ export type LoadChildrenFn = (node: RelationTreeItem) => Promise<RelationTreeItem[]>;
20
+ /**
21
+ * Fotografa lo stato dell'albero.
22
+ * `previousFocusedPath` viene usato quando il fuoco è già stato azzerato dall'esterno.
23
+ */
24
+ export declare const collectRelationTreeState: (nodes: RelationTreeItem[], inputKey: string, focusedKey: string | undefined, previousFocusedPath?: string) => RelationTreeState;
25
+ /**
26
+ * Riapplica lo stato all'albero appena caricato. I nodi che non compaiono nello stato,
27
+ * o che non esistono più (es. documento cancellato), restano chiusi: il confronto per
28
+ * percorso è tollerante per costruzione.
29
+ */
30
+ export declare const applyRelationTreeState: (nodes: RelationTreeItem[], state: RelationTreeState, loadChildren: LoadChildrenFn, isAborted: () => boolean) => Promise<RelationTreeItem[]>;
31
+ /** Cerca un nodo per percorso, per rimettere il fuoco dov'era. */
32
+ export declare const findRelationNodeByPath: (nodes: RelationTreeItem[], path: string) => RelationTreeItem | null;
@@ -0,0 +1,89 @@
1
+ /** I nodi generati (messaggi informativi, separatori) non hanno identità stabile. */
2
+ const hasStableIdentity = (node) => !node.isInfoMessage && !node.isSeparator;
3
+ const getNodeIdentity = (node) => node.isDcmt
4
+ ? `d:${node.tid ?? ''}:${node.did ?? ''}:${node.relationId ?? ''}`
5
+ : `c:${node.tid ?? ''}:${node.relationId ?? ''}:${node.name ?? ''}`;
6
+ /** Il percorso include i padri: lo stesso documento può comparire sotto padri diversi. */
7
+ const getNodePath = (node, parentPath) => {
8
+ const identity = getNodeIdentity(node);
9
+ return parentPath ? `${parentPath}>${identity}` : identity;
10
+ };
11
+ /**
12
+ * Fotografa lo stato dell'albero.
13
+ * `previousFocusedPath` viene usato quando il fuoco è già stato azzerato dall'esterno.
14
+ */
15
+ export const collectRelationTreeState = (nodes, inputKey, focusedKey, previousFocusedPath) => {
16
+ const expandedPaths = [];
17
+ const loadedPaths = [];
18
+ let focusedPath;
19
+ const collect = (items, parentPath) => {
20
+ for (const node of items) {
21
+ if (!hasStableIdentity(node))
22
+ continue;
23
+ const path = getNodePath(node, parentPath);
24
+ if (node.expanded)
25
+ expandedPaths.push(path);
26
+ if (node.expanded && node.isDcmt && node.items)
27
+ loadedPaths.push(path);
28
+ // Entro la stessa istanza montata la key è univoca
29
+ if (focusedKey && node.key === focusedKey)
30
+ focusedPath = path;
31
+ if (node.items)
32
+ collect(node.items, path);
33
+ }
34
+ };
35
+ collect(nodes, '');
36
+ return { inputKey, expandedPaths, loadedPaths, focusedPath: focusedPath ?? previousFocusedPath };
37
+ };
38
+ /**
39
+ * Riapplica lo stato all'albero appena caricato. I nodi che non compaiono nello stato,
40
+ * o che non esistono più (es. documento cancellato), restano chiusi: il confronto per
41
+ * percorso è tollerante per costruzione.
42
+ */
43
+ export const applyRelationTreeState = async (nodes, state, loadChildren, isAborted) => {
44
+ const expandedPaths = new Set(state.expandedPaths);
45
+ const loadedPaths = new Set(state.loadedPaths);
46
+ const apply = async (items, parentPath) => {
47
+ const result = [];
48
+ for (const node of items) {
49
+ if (!hasStableIdentity(node)) {
50
+ result.push(node);
51
+ continue;
52
+ }
53
+ const path = getNodePath(node, parentPath);
54
+ const wasExpanded = expandedPaths.has(path);
55
+ let children = node.items;
56
+ let isLoaded = node.isLoaded;
57
+ let itemsCount = node.itemsCount;
58
+ // I figli dei documenti sono lazy: vanno ricaricati se l'utente li aveva aperti
59
+ if (wasExpanded && node.isDcmt && !children && loadedPaths.has(path) && !isAborted()) {
60
+ children = await loadChildren(node);
61
+ isLoaded = true;
62
+ itemsCount = children.length;
63
+ }
64
+ const updatedItems = children ? await apply(children, path) : children;
65
+ result.push({ ...node, expanded: wasExpanded, items: updatedItems, isLoaded, itemsCount });
66
+ }
67
+ return result;
68
+ };
69
+ return await apply(nodes, '');
70
+ };
71
+ /** Cerca un nodo per percorso, per rimettere il fuoco dov'era. */
72
+ export const findRelationNodeByPath = (nodes, path) => {
73
+ const find = (items, parentPath) => {
74
+ for (const node of items) {
75
+ if (!hasStableIdentity(node))
76
+ continue;
77
+ const currentPath = getNodePath(node, parentPath);
78
+ if (currentPath === path)
79
+ return node;
80
+ if (node.items) {
81
+ const found = find(node.items, currentPath);
82
+ if (found)
83
+ return found;
84
+ }
85
+ }
86
+ return null;
87
+ };
88
+ return find(nodes, '');
89
+ };
@@ -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;
@@ -46,5 +46,5 @@ interface ITMSearchProps {
46
46
  fetchRemoteCertificates?: (email: string) => Promise<IntesiCertificateData[]>;
47
47
  graphometricManager?: IGraphometricManagerProp;
48
48
  }
49
- declare const TMSearch: React.FunctionComponent<ITMSearchProps>;
49
+ declare const TMSearch: (props: ITMSearchProps) => React.JSX.Element;
50
50
  export default TMSearch;