@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
@@ -1,12 +1,12 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { SavedQueryCacheService, DcmtTypeListCacheService, SDK_Localizator, LayoutModes } from '@topconsultnpm/sdk-ts';
4
4
  import TMSavedQuerySelector from './TMSavedQuerySelector';
5
5
  import TMTreeSelector from './TMTreeSelector';
6
- import { TabPanel, Item } from 'devextreme-react/tab-panel';
7
6
  import TMSearchQueryPanel, { refreshLastSearch } from './TMSearchQueryPanel';
8
7
  import { getSysAllDcmtsSQD, SYS_ALL_DCMTS_SQD_ID, IconFilter, IconRecentlyViewed, IconSavedQuery, IconTree, mergeSearchResultsAppend, removeMruTid, SDKUI_Globals, SDKUI_Localizator, updateMruTids } from '../../../helper';
9
8
  import TMSearchResult from './TMSearchResult';
9
+ import TMTabControl, { TMTabPanel, useTMTabs } from '../../base/TMTabControl';
10
10
  import TMRecentsManager from '../../grids/TMRecentsManager';
11
11
  import { SearchResultContext } from '../../../ts';
12
12
  import { useDeviceType, DeviceType } from '../../base/TMDeviceProvider';
@@ -20,7 +20,7 @@ var TMSearchViews;
20
20
  TMSearchViews[TMSearchViews["Search"] = 0] = "Search";
21
21
  TMSearchViews[TMSearchViews["Result"] = 1] = "Result";
22
22
  })(TMSearchViews || (TMSearchViews = {}));
23
- const TMSearch = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, openInOffice, isVisible, inputTID, inputSqdID, inputMids, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, floatingActionConfig, onFileOpened, onRefreshAfterAddDcmtToFavs, onTaskCreateRequest, openWGsCopyMoveForm, editPdfForm = false, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, openFileUploaderPdfEditor, showTodoDcmtForm, showToppyDraggableHelpCenter = true, toppyHelpCenterUsePortal = false, passToArchiveCallback, onCurrentTIDChangedCallback, onlyShowSearchQueryPanel, onReferenceClick, refreshFavoriteSavedQueries, inputDID, formAutoOpen, fetchRemoteCertificates, graphometricManager }) => {
23
+ const TMSearchInstance = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, openInOffice, isVisible, inputTID, inputSqdID, inputMids, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, floatingActionConfig, onFileOpened, onRefreshAfterAddDcmtToFavs, onTaskCreateRequest, openWGsCopyMoveForm, editPdfForm = false, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, openFileUploaderPdfEditor, showTodoDcmtForm, showToppyDraggableHelpCenter = true, toppyHelpCenterUsePortal = false, passToArchiveCallback, onCurrentTIDChangedCallback, onlyShowSearchQueryPanel, onReferenceClick, refreshFavoriteSavedQueries, inputDID, formAutoOpen, fetchRemoteCertificates, graphometricManager, onSelectedNameChanged }) => {
24
24
  const [allSQDs, setAllSQDs] = useState([]);
25
25
  const [filteredByTIDSQDs, setFilteredByTIDSQDs] = useState([]);
26
26
  const [currentSQD, setCurrentSQD] = useState();
@@ -34,6 +34,20 @@ const TMSearch = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTask
34
34
  const [lastQdSearched, setLastQdSearched] = useState();
35
35
  const [showSearchResults, setShowSearchResults] = useState(!onlyShowSearchQueryPanel);
36
36
  const [maxDcmtsToBeReturned, setMaxDcmtsToBeReturned] = useState(SDKUI_Globals.userSettings.searchSettings?.maxDcmtsToBeReturned ?? 1000);
37
+ // Il titolo del tab e' il nome del tipo documento dell'ultima scelta dell'utente, sia questa fatta
38
+ // dall'albero, dalle scorciatoie o da una ricerca rapida (di cui conta il tipo documento, non il nome).
39
+ // La callback sta in un ref cosi non entra nelle dipendenze di effetti e memo.
40
+ const selectedNameRef = useRef(onSelectedNameChanged);
41
+ selectedNameRef.current = onSelectedNameChanged;
42
+ // Il nome del tipo documento scelto arriva dal descrittore, che qui e' gia' in cache
43
+ const notifySelectedTIDAsync = useCallback(async (tid) => {
44
+ if (!tid || !selectedNameRef.current)
45
+ return;
46
+ const dtd = await DcmtTypeListCacheService.GetAsync(tid);
47
+ const name = dtd?.nameLoc ?? dtd?.name;
48
+ if (name)
49
+ selectedNameRef.current(name);
50
+ }, []);
37
51
  const deviceType = useDeviceType();
38
52
  useEffect(() => {
39
53
  if (onCurrentTIDChangedCallback) {
@@ -47,6 +61,7 @@ const TMSearch = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTask
47
61
  useEffect(() => {
48
62
  if (!inputTID)
49
63
  return;
64
+ notifySelectedTIDAsync(inputTID);
50
65
  setCurrentTID(inputTID);
51
66
  setCurrentSearchView(TMSearchViews.Search);
52
67
  }, [inputTID]);
@@ -54,6 +69,7 @@ const TMSearch = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTask
54
69
  const loadSqd = async () => {
55
70
  try {
56
71
  const resultSqd = await SavedQueryCacheService.GetAsync(inputSqdID);
72
+ notifySelectedTIDAsync(resultSqd?.masterTID);
57
73
  await setSQDAsync(resultSqd);
58
74
  // Mostra la vista Search per visualizzare i filtri della SavedQuery caricata
59
75
  setCurrentSearchView(TMSearchViews.Search);
@@ -141,12 +157,13 @@ const TMSearch = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTask
141
157
  setCurrentMruTID(0);
142
158
  };
143
159
  const onSQDItemClick = useCallback(async (sqd, setSqdAsync) => {
160
+ notifySelectedTIDAsync(sqd.masterTID);
144
161
  // Forza ricaricamento completo se la query è già selezionata
145
162
  if (sqd.id === currentSQD?.id) {
146
163
  await setSqdAsync(undefined);
147
164
  }
148
165
  await setSqdAsync(sqd);
149
- }, [currentSQD]);
166
+ }, [currentSQD, notifySelectedTIDAsync]);
150
167
  const onSQDDeleted = useCallback(async (sqd, sqdToBeSet, setSqdAsync) => {
151
168
  await loadDataSQDsAsync(true, sqd.masterTID);
152
169
  if (sqdToBeSet)
@@ -230,30 +247,35 @@ const TMSearch = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTask
230
247
  const isTabletOrMobile = deviceType === DeviceType.TABLET || deviceType === DeviceType.MOBILE;
231
248
  // --- JSX WRAPPERS ---
232
249
  const tmTreeSelectorElement = useMemo(() => _jsx(TMTreeSelectorWrapper, { isMobile: isTabletOrMobile, onSelectedTIDChanged: (tid) => {
250
+ notifySelectedTIDAsync(tid);
233
251
  setCurrentTID(tid);
234
252
  if (tid && mruTIDs.includes(tid))
235
253
  setCurrentMruTID(tid);
236
254
  else
237
255
  setCurrentMruTID(0);
238
- } }), [isTabletOrMobile, mruTIDs]);
256
+ } }), [isTabletOrMobile, mruTIDs, notifySelectedTIDAsync]);
239
257
  const tmRecentsManagerElement = useMemo(() => _jsx(TMRecentsManagerWrapper, { mruTIDs: mruTIDs, currentMruTID: currentMruTID, deviceType: deviceType, onSelectedTID: (tid) => {
258
+ notifySelectedTIDAsync(tid);
240
259
  setCurrentMruTID(tid);
241
260
  setCurrentTID(tid);
242
261
  }, onDeletedTID: (tid) => {
243
262
  let newMruTIDS = removeMruTid(SDKUI_Globals.userSettings.searchSettings.mruTIDs, tid);
244
263
  SDKUI_Globals.userSettings.searchSettings.mruTIDs = newMruTIDS;
245
264
  setMruTIDs(newMruTIDS);
246
- } }), [mruTIDs, currentMruTID, deviceType]);
265
+ } }), [mruTIDs, currentMruTID, deviceType, notifySelectedTIDAsync]);
247
266
  const tmSearchQueryPanelElement = useMemo(() => _jsx(TMSearchQueryPanelWrapper, { isSearchViewOnScreen: currentSearchView === TMSearchViews.Search, passToArchiveCallback: passToArchiveCallback, isExpertMode: isExpertMode, showBackToResultButton: searchResult.length > 0, fromDTD: fromDTD, SQD: currentSQD, inputMids: inputMids, maxDcmtsToBeReturned: maxDcmtsToBeReturned, onBackToResult: () => { if (onlyShowSearchQueryPanel)
248
267
  setShowSearchResults(true); setCurrentSearchView(TMSearchViews.Result); }, onSearchCompleted: handleSearchCompleted, onRefreshRequested: refreshSearchQueryPanelAsync, onDcmtTypeReloaded: handleDcmtTypeReloaded, onSqdSaved: async (newSqd) => {
249
268
  await loadDataSQDsAsync(true, newSqd.masterTID);
250
269
  await setSQDAsync(newSqd);
251
270
  } }), [fromDTD, showSearchResults, setShowSearchResults, currentSQD, currentSearchView, isExpertMode, mruTIDs, searchResult, passToArchiveCallback, inputMids, maxDcmtsToBeReturned, handleSearchCompleted, refreshSearchQueryPanelAsync, handleDcmtTypeReloaded, onlyShowSearchQueryPanel]);
252
- const tmSavedQuerySelectorElement = useMemo(() => _jsxs(TabPanel, { width: "100%", height: "100%", showNavButtons: true, repaintChangesOnly: true, selectedIndex: currentSQDMode, onSelectedIndexChange: (index) => setCurrentSQDMode(index), children: [(currentTID || currentSQD) ? _jsx(Item, { title: fromDTD?.nameLoc, children: _jsx(TMSavedQuerySelectorWrapper, { allowShowSearch: false, items: filteredByTIDSQDs, selectedId: currentSQD?.id, onRefreshData: () => { loadDataSQDsAsync(true); }, onItemClick: (sqd) => {
271
+ // I due tab delle ricerche rapide nell'ordine in cui compaiono: il primo c'e' solo con un tipo
272
+ // documento o una ricerca rapida correnti. currentSQDMode resta la posizione nell'elenco visibile.
273
+ const sqdTabIds = useMemo(() => (currentTID || currentSQD) ? ['byTID', 'all'] : ['all'], [currentTID, currentSQD]);
274
+ const tmSavedQuerySelectorElement = useMemo(() => _jsxs(TMTabControl, { variant: 'module', style: { height: '100%', width: '100%' }, contentStyle: { display: 'flex', flexDirection: 'column', flex: 1, minHeight: 0 }, selectedId: sqdTabIds[currentSQDMode] ?? sqdTabIds[sqdTabIds.length - 1], onSelectedIdChange: (id) => setCurrentSQDMode(sqdTabIds.indexOf(id)), children: [_jsx(TMTabPanel, { id: 'byTID', label: fromDTD?.nameLoc, visible: !!(currentTID || currentSQD), children: _jsx(TMSavedQuerySelectorWrapper, { allowShowSearch: false, items: filteredByTIDSQDs, selectedId: currentSQD?.id, onRefreshData: () => { loadDataSQDsAsync(true); }, onItemClick: (sqd) => {
253
275
  onSQDItemClick(sqd, setSQDAsync);
254
- }, onDeleted: (sqd) => onSQDDeleted(sqd, sqd.id == currentSQD?.id ? filteredByTIDSQDs.find(o => o.id == 1) : currentSQD, setSQDAsync), refreshFavoriteSavedQueries: refreshFavoriteSavedQueries }) }) : _jsx(_Fragment, {}), _jsx(Item, { title: SDKUI_Localizator.AllFemale, children: _jsx(TMSavedQuerySelectorWrapper, { allowShowSearch: true, items: allSQDs, manageDefault: false, onItemClick: (sqd) => {
276
+ }, onDeleted: (sqd) => onSQDDeleted(sqd, sqd.id == currentSQD?.id ? filteredByTIDSQDs.find(o => o.id == 1) : currentSQD, setSQDAsync), refreshFavoriteSavedQueries: refreshFavoriteSavedQueries }) }), _jsx(TMTabPanel, { id: 'all', label: SDKUI_Localizator.AllFemale, children: _jsx(TMSavedQuerySelectorWrapper, { allowShowSearch: true, items: allSQDs, manageDefault: false, onItemClick: (sqd) => {
255
277
  onSQDItemClick(sqd, setSQDAsync);
256
- }, onDeleted: (sqd) => onSQDDeleted(sqd, sqd.id == currentSQD?.id ? undefined : currentSQD, setSQDAsync), refreshFavoriteSavedQueries: refreshFavoriteSavedQueries }) })] }), [currentSQDMode, currentTID, currentSQD, fromDTD, filteredByTIDSQDs, allSQDs]);
278
+ }, onDeleted: (sqd) => onSQDDeleted(sqd, sqd.id == currentSQD?.id ? undefined : currentSQD, setSQDAsync), refreshFavoriteSavedQueries: refreshFavoriteSavedQueries }) })] }), [currentSQDMode, sqdTabIds, currentTID, currentSQD, fromDTD, filteredByTIDSQDs, allSQDs]);
257
279
  // Returns the current panelLayout from user settings, falling back to an empty object if not present.
258
280
  const getPanelLayoutSetting = () => {
259
281
  return SDKUI_Globals.userSettings.searchSettings.panelLayout ?? {};
@@ -347,6 +369,43 @@ const TMSearch = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTask
347
369
  : _jsx(StyledMultiViewPanel, { $isVisible: currentSearchView === TMSearchViews.Search, children: _jsx(TMPanelManagerWithPersistenceProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'TMRecentsManager', isPersistenceEnabled: !isMobile ? hasSavedLayout() : false, persistPanelStates: !isMobile ? (state) => persistPanelStates(state) : undefined, persistedPanelStates: getPersistedPanelStates(), children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true, minPanelSizePx: !isMobile ? 250 : 150 }) }) }), showSearchResults && _jsx(TMSearchResult, { isVisible: isVisible && currentSearchView === TMSearchViews.Result, context: SearchResultContext.METADATA_SEARCH, searchResults: searchResult, floatingActionConfig: floatingActionConfig, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, openInOffice: openInOffice, onRefreshSearchAsyncDatagrid: onRefreshSearchAsyncDatagrid, onClose: () => { if (onlyShowSearchQueryPanel)
348
370
  setShowSearchResults(false); setCurrentSearchView(TMSearchViews.Search); }, backCaption: onlyShowSearchQueryPanel ? SDKUI_Localizator.BackToSearch : undefined, onFileOpened: onFileOpened, onTaskCreateRequest: onTaskCreateRequest, openWGsCopyMoveForm: openWGsCopyMoveForm, editPdfForm: editPdfForm, onOpenPdfEditorRequest: onOpenPdfEditorRequest, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, openFileUploaderPdfEditor: openFileUploaderPdfEditor, passToArchiveCallback: passToArchiveCallback, onSelectedTIDChanged: onCurrentTIDChangedCallback, showTodoDcmtForm: showTodoDcmtForm, showToppyDraggableHelpCenter: showToppyDraggableHelpCenter, toppyHelpCenterUsePortal: toppyHelpCenterUsePortal, onReferenceClick: onReferenceClick, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, inputDID: inputDID, formAutoOpen: formAutoOpen, fetchRemoteCertificates: fetchRemoteCertificates, graphometricManager: graphometricManager })] }));
349
371
  };
372
+ const ENABLE_SEARCH_TABS = false;
373
+ // Ogni tab e' un TMSearch completo e indipendente: TMTabControl li tiene tutti montati, cosi piu ricerche
374
+ // restano vive insieme, ognuna con i suoi tipi documento, i suoi filtri e i suoi risultati.
375
+ const TMSearch = (props) => {
376
+ const { isVisible, inputTID, inputSqdID, inputDID, onlyShowSearchQueryPanel, onCurrentTIDChangedCallback } = props;
377
+ const tabs = useTMTabs({ label: SDKUI_Localizator.Search });
378
+ // Tab attivo leggibile senza rilanciare l'effetto qui sotto a ogni cambio tab
379
+ const activeIdRef = useRef(tabs.activeId);
380
+ activeIdRef.current = tabs.activeId;
381
+ // Titoli correnti leggibili dalla callback senza rigenerarla a ogni rinomina
382
+ const itemsRef = useRef(tabs.items);
383
+ itemsRef.current = tabs.items;
384
+ // Il titolo del tab e' il nome appena selezionato; se un altro tab ha gia' quel titolo si numera
385
+ // tra parentesi a partire da 2: NomeTipoDocumento, NomeTipoDocumento (2), NomeTipoDocumento (3)...
386
+ const setTabTitle = useCallback((id, name) => {
387
+ const used = new Set(itemsRef.current.filter(t => t.id !== id).map(t => t.label));
388
+ let label = name;
389
+ for (let i = 2; used.has(label); i++)
390
+ label = `${name} (${i})`;
391
+ tabs.rename(id, label);
392
+ }, [tabs.rename]);
393
+ // Una richiesta dall'esterno (tipo documento, ricerca rapida, documento) riguarda il tab a video in
394
+ // quel momento: gli altri restano sulla ricerca che stanno svolgendo.
395
+ const [inputsTabId, setInputsTabId] = useState(tabs.activeId);
396
+ useEffect(() => { setInputsTabId(activeIdRef.current); }, [inputTID, inputSqdID, inputDID]);
397
+ // Nella modalita a solo pannello di ricerca (es. abbinamento molti a molti) i tab non servono,
398
+ // cosi come non servono finche' i tab non vengono rilasciati
399
+ if (!ENABLE_SEARCH_TABS || onlyShowSearchQueryPanel)
400
+ return _jsx(TMSearchInstance, { ...props });
401
+ return (_jsx(TMTabControl, { ...tabs.controlProps, contentAnimation: 'none', onTabRename: undefined, variant: 'module', style: { height: '100%', width: '100%' }, contentStyle: { display: 'flex', flex: 1, minHeight: 0, position: 'relative' }, children: tabs.items.map(t => {
402
+ const isActiveTab = t.id === tabs.activeId;
403
+ const hasInputs = t.id === inputsTabId;
404
+ return (_jsx(TMTabPanel, { id: t.id, label: t.label, children: _jsx(TMSearchInstance, { ...props, isVisible: isVisible && isActiveTab, inputTID: hasInputs ? inputTID : undefined, inputSqdID: hasInputs ? inputSqdID : undefined, inputDID: hasInputs ? inputDID : undefined,
405
+ // Il tipo documento corrente lo comunica solo il tab a video
406
+ onCurrentTIDChangedCallback: isActiveTab ? onCurrentTIDChangedCallback : undefined, onSelectedNameChanged: (name) => setTabTitle(t.id, name) }) }, t.id));
407
+ }) }));
408
+ };
350
409
  export default TMSearch;
351
410
  const TMTreeSelectorWrapper = ({ isMobile, onSelectedTIDChanged }) => {
352
411
  const { setPanelVisibilityById, toggleMaximize, countVisibleLeafPanels } = useTMPanelManagerContext();
@@ -29,6 +29,12 @@ interface ITMSearchQueryPanelProps {
29
29
  declare const TMSearchQueryPanel: React.FunctionComponent<ITMSearchQueryPanelProps>;
30
30
  export default TMSearchQueryPanel;
31
31
  export declare const refreshLastSearch: (qd: QueryDescriptor | undefined) => Promise<SearchResultDescriptor[] | undefined>;
32
- export declare const StyledToppyTextContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
33
- export declare const StyledToppyText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
34
- export declare const StyledToppyImage: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, never>> & string;
32
+ export declare const StyledToppyTextContainer: import("styled-components/dist/types").IStyledComponentBase<"web", Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
33
+ style?: React.CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
34
+ }> & string;
35
+ export declare const StyledToppyText: import("styled-components/dist/types").IStyledComponentBase<"web", Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "style"> & {
36
+ style?: React.CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
37
+ }> & string;
38
+ export declare const StyledToppyImage: import("styled-components/dist/types").IStyledComponentBase<"web", Omit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, "style"> & {
39
+ style?: React.CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
40
+ }> & string;
@@ -23,6 +23,11 @@ interface ITMSearchResultProps {
23
23
  openDcmtFormAsModal?: boolean;
24
24
  showSearchResultSidebar?: boolean;
25
25
  showDcmtFormSidebar?: boolean;
26
+ /** Mostra accanto alla griglia il selettore dei tipi documento trovati:
27
+ * su desktop sono affiancati (30/70),
28
+ * su mobile si naviga a step tra selettore e risultati.
29
+ * Se il risultato ha un solo tipo documento il selettore resta chiuso
30
+ * e lo spazio va tutto alla griglia, riapribile dal menu "Altro" */
26
31
  showSelector?: boolean;
27
32
  showToolbarHeader?: boolean;
28
33
  showBackButton?: boolean;
@@ -362,6 +362,7 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
362
362
  allowRelations,
363
363
  showTodoDcmtForm,
364
364
  graphometricManager,
365
+ showSelector,
365
366
  },
366
367
  tasks: {
367
368
  allTasks: allTasks,
@@ -621,11 +622,11 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
621
622
  }, [currentMetadataValues]);
622
623
  const getTitleHeader = () => {
623
624
  let counters = (showSelector && disableAccordionIfSingleCategory && searchResults.length > 1) ? getSearchResultCountersSingleCategory(searchResults) : "";
624
- if (title)
625
- return title + counters;
626
625
  // Nome del tipo documento selezionato, accodato al titolo
627
626
  const selectedDcmtTypeName = selectedSearchResult?.fromName ?? (searchResults?.length === 1 ? searchResults[0]?.fromName : undefined);
628
627
  const withSelectedDcmtTypeName = (baseTitle) => selectedDcmtTypeName ? `${baseTitle} - ${selectedDcmtTypeName}` : baseTitle;
628
+ if (title)
629
+ return withSelectedDcmtTypeName(title) + counters;
629
630
  let titleHeader = withSelectedDcmtTypeName('Ricerca per metadati');
630
631
  switch (context) {
631
632
  case SearchResultContext.MASTER_DETAIL:
@@ -770,7 +771,7 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
770
771
  const tmSearchResult = useMemo(() => (!searchResults || searchResults.length <= 0)
771
772
  ? _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 }) })] })
772
773
  :
773
- _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 && !isSteppedLayout && !isSelectorCollapsed, start: splitterSizes, children: [showSelector ?
774
+ _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: isSteppedLayout ? 'hidden' : 'visible', separatorSize: Gutters.getGutters(), separatorActiveColor: 'transparent', separatorColor: 'transparent', min: ['0', '0'], showSeparator: showSelector && !isSteppedLayout && !isSelectorCollapsed, start: splitterSizes, children: [showSelector ?
774
775
  _jsx(TMLayoutItem, { children: _jsx(TMSearchResultSelector, { searchResults: currentSearchResults, disableAccordionIfSingleCategory: disableAccordionIfSingleCategory, selectedTID: selectedSearchResultTID, selectedSearchResult: selectedSearchResult, autoSelectFirst: !isMobile || hasSingleDcmtType, onSelectionChanged: onSearchResultSelectionChanged }) })
775
776
  :
776
777
  _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, showCounterConfig: showCounterConfig, counterConfig: counterConfig, showActionsColumn: showActionsColumn, compactPager: compactPager, onRowActionRequest: requestRowAction }) })] }), 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: () => {
@@ -1392,6 +1393,14 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, i
1392
1393
  let newDataSource = searchResultDescriptorToSimpleArray(searchResult);
1393
1394
  setDataSource(newDataSource);
1394
1395
  }, [lastUpdateSearchTime]);
1396
+ const gridSorting = useMemo(() => ({ mode: 'multiple' }), []);
1397
+ const gridSelection = useMemo(() => ({ mode: allowMultipleSelection ? 'multiple' : 'single' }), [allowMultipleSelection]);
1398
+ const useNativeScrollbar = SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar === 1;
1399
+ const gridScrolling = useMemo(() => ({
1400
+ columnRenderingMode: 'virtual',
1401
+ rowRenderingMode: 'standard',
1402
+ useNative: useNativeScrollbar
1403
+ }), [useNativeScrollbar]);
1395
1404
  // Handles selection change in the data grid
1396
1405
  const handleSelectionChange = useCallback((e) => {
1397
1406
  if (onSelectionChanged === undefined)
@@ -1506,7 +1515,7 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, i
1506
1515
  const gridCounterConfig = showCounterConfig
1507
1516
  ? { ...counterConfig, show: true, items: counterConfig?.items ?? defaultCounterItems }
1508
1517
  : { show: false };
1509
- 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, customizeColumns: customizeColumns, 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, compactPager: compactPager, onSelectionChanged: handleSelectionChange, onFocusedRowChanged: handleFocusedRowChange, onRowDblClick: onRowDblClick, onContentReady: onContentReady, showHeaderColumnChooser: true, onKeyDown: onKeyDown, customContextMenuItems: operationItems, counterConfig: gridCounterConfig })] });
1518
+ 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, customizeColumns: customizeColumns, repaintChangesOnly: true, selectedRowKeys: selectedRowKeys, focusedRowKey: disableAutoFocus ? undefined : Number(focusedItem?.rowIndex ?? 0), showSearchPanel: showSearchTMDatagrid, showFilterPanel: true, sorting: gridSorting, selection: gridSelection, scrolling: gridScrolling, pageSize: pageSize, compactPager: compactPager, onSelectionChanged: handleSelectionChange, onFocusedRowChanged: handleFocusedRowChange, onRowDblClick: onRowDblClick, onContentReady: onContentReady, showHeaderColumnChooser: true, onKeyDown: onKeyDown, customContextMenuItems: operationItems, counterConfig: gridCounterConfig })] });
1510
1519
  };
1511
1520
  //#region TMSearchResultSelector
1512
1521
  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,8 +1,9 @@
1
+ import React from "react";
1
2
  import { DcmtInfo, IGraphometricManagerProp } from "../../../ts";
2
3
  interface TMSignatureInfoContentProps {
3
4
  inputDcmt: DcmtInfo;
4
5
  graphometricManager?: IGraphometricManagerProp;
5
6
  onClose?: () => void;
6
7
  }
7
- declare const TMSignatureInfoContent: (props: TMSignatureInfoContentProps) => import("react/jsx-runtime").JSX.Element;
8
+ declare const TMSignatureInfoContent: (props: TMSignatureInfoContentProps) => React.JSX.Element;
8
9
  export default TMSignatureInfoContent;
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { DcmtTypeListCacheService, LayoutModes, SDK_Localizator, TreeCacheService, TreeItemTypes } from '@topconsultnpm/sdk-ts';
4
4
  import { TreeList, Column, Scrolling, Selection } from 'devextreme-react/tree-list';
@@ -22,9 +22,12 @@ const TMTreeDcmtTypeCell = ({ tid, isMobile }) => {
22
22
  }, [isMobile, dtd, tid]);
23
23
  return (_jsxs(StyledTreeDcmtTypeRow, { onMouseEnter: loadDTD, children: [_jsx("span", { style: { cursor: 'pointer', flex: 1, minWidth: 0 }, children: _jsx(TMTidViewer, { tid: tid, showIcon: false }) }), !isMobile && (_jsx("span", { className: 'info-icon', children: _jsx(TMDcmtTypeTooltip, { dtd: dtd, children: _jsx(IconInfo, { color: TMColors.info }) }) }))] }));
24
24
  };
25
+ // La ricerca e l'archiviazione hanno ciascuna il proprio albero predefinito: il contesto lo decide il layoutMode
26
+ const getDefaultTreeId = (layoutMode) => layoutMode == LayoutModes.Update
27
+ ? SDKUI_Globals.userSettings.searchSettings.defaultTree
28
+ : SDKUI_Globals.userSettings.archivingSettings.defaultTree;
25
29
  const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelectedTIDChanged, onClosePanel, allowMaximize = true, onMaximizePanel }) => {
26
30
  const [trees, setTrees] = useState([]);
27
- const [treeItems, setTreeItems] = useState([]);
28
31
  const [selectedTreeId, setSelectedTreeId] = useState(0);
29
32
  const [infoDTD, setInfoDTD] = useState();
30
33
  // State to store selected row keys
@@ -34,8 +37,11 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
34
37
  // Elemento selezionato nell'albero: dopo un refresh va riproposto se esiste ancora
35
38
  const [selectedTreeItemKey, setSelectedTreeItemKey] = useState(undefined);
36
39
  const selectedTreeItemKeys = useMemo(() => selectedTreeItemKey !== undefined ? [selectedTreeItemKey] : [], [selectedTreeItemKey]);
37
- const [isGridBoxOpened, setIsGridBoxOpened] = useState(false);
38
- const [defaultTreeId, setDefaultTreeId] = useState(-1);
40
+ // Finche' gli alberi non sono arrivati il pannello mostra il loader invece della lista vuota
41
+ const [isLoadingTrees, setIsLoadingTrees] = useState(true);
42
+ const [defaultTreeId, setDefaultTreeId] = useState(() => getDefaultTreeId(layoutMode));
43
+ const dropDownBoxRef = useRef(null);
44
+ const closeDropDown = useCallback(() => { dropDownBoxRef.current?.instance()?.option('opened', false); }, []);
39
45
  const deviceType = useDeviceType();
40
46
  const isMobile = deviceType === DeviceType.MOBILE;
41
47
  const panelRef = useOutsideClick(() => setInfoDTD(undefined));
@@ -48,6 +54,11 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
48
54
  const loadTreesAsync = useCallback(async (forceRefresh = false) => {
49
55
  const isSearchContext = layoutMode == LayoutModes.Update;
50
56
  if (forceRefresh) {
57
+ // Gli alberi arrivano dal server filtrati sui tipi documento della sessione: senza rileggerli
58
+ // prima (RetrieveAll con refreshCache rigenera anche la cache lato server) un tipo documento
59
+ // appena creato da Designer non comparirebbe tra gli elementi dell'albero
60
+ DcmtTypeListCacheService.RemoveAllWithoutMetadata();
61
+ await DcmtTypeListCacheService.GetAllWithoutMetadataAsync();
51
62
  if (isSearchContext)
52
63
  TreeCacheService.RemoveAllSearch();
53
64
  else
@@ -73,29 +84,24 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
73
84
  setSelectedRowKeys([currentTreeId]);
74
85
  return;
75
86
  }
76
- let defaultTree = SDKUI_Globals.userSettings.searchSettings.defaultTree;
77
- let initialTreeId;
78
- let treeToSelect;
79
- if (defaultTree > 0) {
80
- initialTreeId = defaultTree;
81
- treeToSelect = result.find(o => o.id == defaultTree);
82
- }
83
- else {
84
- initialTreeId = result[0]?.id ?? 0;
85
- treeToSelect = result[0];
86
- }
87
- setSelectedTreeId(initialTreeId);
87
+ // Il predefinito puo' non essere piu' tra gli alberi del contesto (cancellato, o permessi cambiati): si ripiega sul primo
88
+ const defaultTree = getDefaultTreeId(layoutMode);
89
+ const treeToSelect = (defaultTree > 0 ? result.find(o => o.id == defaultTree) : undefined) ?? result[0];
90
+ setSelectedTreeId(treeToSelect?.id ?? 0);
88
91
  if (treeToSelect?.id) {
89
92
  setSelectedRowKeys([treeToSelect.id]);
90
93
  }
91
94
  }, [layoutMode]);
92
- useEffect(() => { loadTreesAsync(); }, [loadTreesAsync]);
93
95
  useEffect(() => {
94
- let newTreeItems = trees.find(o => o.id == selectedTreeId)?.items ?? [];
95
- setTreeItems(newTreeItems);
96
+ setIsLoadingTrees(true);
97
+ loadTreesAsync().finally(() => setIsLoadingTrees(false));
98
+ }, [loadTreesAsync]);
99
+ // Derivato nello stesso render degli alberi: con uno state la TreeList mostrerebbe "Nessun dato" per un frame
100
+ const treeItems = useMemo(() => trees.find(o => o.id == selectedTreeId)?.items ?? [], [trees, selectedTreeId]);
101
+ useEffect(() => {
96
102
  // Mantiene la selezione dopo il refresh solo se l'elemento e' ancora presente (al cambio albero si azzera)
97
- setSelectedTreeItemKey(prev => prev !== undefined && newTreeItems.some(o => o.id == prev) ? prev : undefined);
98
- }, [selectedTreeId, trees]);
103
+ setSelectedTreeItemKey(prev => prev !== undefined && treeItems.some(o => o.id == prev) ? prev : undefined);
104
+ }, [treeItems]);
99
105
  const renderCell = useCallback((data) => {
100
106
  const treeItem = data.data;
101
107
  // Documento (DcmtType)
@@ -129,8 +135,8 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
129
135
  if (selectedKeys.length > 0)
130
136
  setSelectedTreeId(selectedKeys[0]);
131
137
  setSelectedRowKeys(selectedKeys);
132
- setIsGridBoxOpened(false);
133
- }, []);
138
+ closeDropDown();
139
+ }, [closeDropDown]);
134
140
  // Handles click on a tree row in the trees data grid: clicking the already selected tree
135
141
  // does not raise onSelectionChanged, so the drop down must be closed here as well
136
142
  const onRowClickTrees = useCallback((e) => {
@@ -139,8 +145,8 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
139
145
  return;
140
146
  setSelectedTreeId(tree.id);
141
147
  setSelectedRowKeys([tree.id]);
142
- setIsGridBoxOpened(false);
143
- }, []);
148
+ closeDropDown();
149
+ }, [closeDropDown]);
144
150
  // Handles focus change in the data grid
145
151
  const onFocusedRowChanged = useCallback((e) => {
146
152
  setFocusedRowKey(e.row?.key);
@@ -150,12 +156,6 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
150
156
  if (treeItemDescriptor?.id)
151
157
  setSelectedRowKeys([treeItemDescriptor.id]);
152
158
  }, []);
153
- const onGridBoxOpened = useCallback((e) => {
154
- if (e.name === 'opened') {
155
- setIsGridBoxOpened(e.value);
156
- }
157
- ;
158
- }, []);
159
159
  // Callback function to handle double-click events on a tree view cell
160
160
  const onCellDblClickTreeView = useCallback((e) => {
161
161
  // Extract the data from the clicked cell and cast it to the TreeItemDescriptor type
@@ -187,7 +187,7 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
187
187
  const onSelectionChangedTreeView = useCallback((e) => {
188
188
  setSelectedTreeItemKey(e.selectedRowKeys?.[0]);
189
189
  }, []);
190
- return (_jsx(TMPanel, { title: SDK_Localizator.Trees, isVisible: isVisible, totalItems: trees.length, onClose: onClosePanel, allowMaximize: allowMaximize, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, onRefresh: () => loadTreesAsync(true), toolbar: _jsx(TMButton, { btnStyle: 'icon', caption: defaultTreeId == selectedTreeId ? SDKUI_Localizator.TreeRemoveDefault : SDKUI_Localizator.SetAsDefault, icon: defaultTreeId == selectedTreeId ? _jsx(IconStarRemove, { color: 'rgb(243, 114, 92)' }) : _jsx(IconStar, { color: 'rgb(248, 215, 117)' }), onClick: () => {
190
+ return (_jsx(TMPanel, { title: SDK_Localizator.Trees, isVisible: isVisible, totalItems: trees.length, onClose: onClosePanel, allowMaximize: allowMaximize, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, onRefresh: () => loadTreesAsync(true), isRefreshing: isLoadingTrees, toolbar: _jsx(TMButton, { btnStyle: 'icon', caption: defaultTreeId == selectedTreeId ? SDKUI_Localizator.TreeRemoveDefault : SDKUI_Localizator.SetAsDefault, icon: defaultTreeId == selectedTreeId ? _jsx(IconStarRemove, { color: 'rgb(243, 114, 92)' }) : _jsx(IconStar, { color: 'rgb(248, 215, 117)' }), onClick: () => {
191
191
  if (defaultTreeId == selectedTreeId) {
192
192
  if (layoutMode == LayoutModes.Update)
193
193
  SDKUI_Globals.userSettings.searchSettings.defaultTree = -1;
@@ -211,16 +211,18 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
211
211
  width: '100%',
212
212
  boxSizing: 'border-box',
213
213
  minHeight: 0,
214
- }, children: [_jsx("div", { style: { padding: '10px' }, children: _jsx(DropDownBox, { dropDownOptions: {
214
+ }, children: [_jsx("div", { style: { padding: '10px' }, children: _jsx(DropDownBox, { ref: dropDownBoxRef, dropDownOptions: {
215
215
  resizeEnabled: true,
216
216
  minWidth: "100%",
217
217
  height: trees.length <= 10 ? 300 : 500,
218
218
  maxWidth: "100%"
219
- }, value: selectedTreeId, opened: isGridBoxOpened, valueExpr: "id", displayExpr: "nameLoc", deferRendering: false, dataSource: trees, onValueChanged: syncDataGridSelection, onOptionChanged: onGridBoxOpened, style: { height: 30, padding: '5px' }, children: _jsx(TMDataGrid, { height: "100%", width: "100%", dataSource: trees, dataColumns: [
219
+ }, value: selectedTreeId, valueExpr: "id", displayExpr: "nameLoc", deferRendering: false, dataSource: trees, onValueChanged: syncDataGridSelection, style: { height: 30, padding: '5px' }, children: _jsx(TMDataGrid, { height: "100%", width: "100%", dataSource: trees, dataColumns: [
220
220
  { dataField: 'nameLoc', caption: SDKUI_Localizator.Name, width: 'auto' },
221
221
  { dataField: 'description', caption: SDKUI_Localizator.Description, width: 'auto' },
222
222
  ], selection: { mode: 'single', showCheckBoxesMode: "none" }, showHeaderFilter: false, selectedRowKeys: selectedRowKeys, onSelectionChanged: onSelectionChanged, onRowClick: onRowClickTrees, focusedRowKey: focusedRowKey, onFocusedRowChanged: onFocusedRowChanged }) }) }), _jsxs(StyledTreeListWrapper, { children: [_jsxs(TreeList, { height: "100%", dataSource: treeItems, showRowLines: false, showColumnLines: false, showBorders: false, columnAutoWidth: false, keyExpr: "id", parentIdExpr: "parentID", dataStructure: "plain", showColumnHeaders: false, selectedRowKeys: selectedTreeItemKeys, onSelectionChanged: onSelectionChangedTreeView, onCellDblClick: onCellDblClickTreeView, onRowClick: onRowClickTreeView, children: [_jsx(Column, { dataField: "nameLoc", caption: SDKUI_Localizator.Name, cellRender: renderCell, width: "100%" }), _jsx(Scrolling, { mode: "virtual", useNative: Number(SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar) === 1 }), _jsx(Selection, { mode: "single" })] }), _jsxs(StyledOffCanvasPanel, { ref: panelRef, $isOpen: isMobile && infoDTD !== undefined, children: [_jsxs(StyledDivHorizontal, { style: { gap: 10, padding: '10px 8px', width: '100%', alignItems: 'center' }, children: [_jsx("p", { style: { fontSize: '1.1rem', fontWeight: 'bold' }, children: `${SDKUI_Localizator.DcmtType} - ${SDKUI_Localizator.About}` }), _jsx(IconCloseOutline, { style: { marginLeft: 'auto', cursor: 'pointer' }, onClick: () => setInfoDTD(undefined) })] }), renderDTDTooltipContent(infoDTD)] })] })] })
223
- : _jsx("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', fontSize: '1.5rem' }, children: SDKUI_Localizator.TreesNoAvailable }) }));
223
+ : isLoadingTrees
224
+ ? _jsx(_Fragment, {})
225
+ : _jsx("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', fontSize: '1.5rem' }, children: SDKUI_Localizator.TreesNoAvailable }) }));
224
226
  };
225
227
  export default TMTreeSelector;
226
228
  const StyledTreeDcmtTypeRow = styled(StyledDivHorizontal) `
@@ -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;
@@ -8,7 +8,7 @@ interface TaskFormAssignmentNoticeSectionProps {
8
8
  users: Array<UserDescriptor>;
9
9
  requestMoreInfo?: boolean;
10
10
  }
11
- export declare const TaskFormAssignmentNoticeBadge: (props: TaskFormAssignmentNoticeSectionProps) => import("react/jsx-runtime").JSX.Element | null;
11
+ export declare const TaskFormAssignmentNoticeBadge: (props: TaskFormAssignmentNoticeSectionProps) => React.JSX.Element | null;
12
12
  interface RenderContextBlockParams {
13
13
  condition: boolean;
14
14
  pdg: PdGs;
@@ -19,7 +19,7 @@ interface TaskFormContextualAttachmentsProps {
19
19
  currentTask: TaskDescriptor | undefined;
20
20
  taskContext: TaskContext | undefined;
21
21
  }
22
- export declare const TaskFormContextualAttachments: (props: TaskFormContextualAttachmentsProps) => import("react/jsx-runtime").JSX.Element;
22
+ export declare const TaskFormContextualAttachments: (props: TaskFormContextualAttachmentsProps) => React.JSX.Element;
23
23
  interface TaskFormAssignedToProps {
24
24
  formMode: FormModes;
25
25
  formData: TaskDescriptor | undefined;
@@ -31,7 +31,7 @@ interface TaskFormAssignedToProps {
31
31
  label?: string;
32
32
  onValueChanged: (newValue: Array<number> | undefined) => void;
33
33
  }
34
- export declare const TaskAssigneeField: (props: TaskFormAssignedToProps) => import("react/jsx-runtime").JSX.Element;
34
+ export declare const TaskAssigneeField: (props: TaskFormAssignedToProps) => React.JSX.Element;
35
35
  interface RenderFieldBaseProps {
36
36
  fieldsReadOnly: IFieldsEditability;
37
37
  formDataOrig?: TaskDescriptor;
@@ -50,12 +50,12 @@ interface RenderDateFieldProps extends RenderFieldProps {
50
50
  label?: string;
51
51
  onContentReady?: () => void;
52
52
  }
53
- export declare const RenderNameField: ({ requestMoreInfo, validationItems, setFormData, formData, formDataOrig, fieldsReadOnly }: RenderFieldProps) => import("react/jsx-runtime").JSX.Element;
54
- export declare const RenderDescriptionField: ({ validationItems, setFormData, formData, formDataOrig, fieldsReadOnly }: RenderFieldProps) => import("react/jsx-runtime").JSX.Element;
55
- export declare const RenderPriorityField: ({ formData, formDataOrig, fieldsReadOnly, onPriorityValueChange }: RenderPriorityFieldProps) => import("react/jsx-runtime").JSX.Element;
56
- export declare const RenderStartDateField: ({ label, validationItems, setFormData, formData, formDataOrig, fieldsReadOnly, onContentReady }: RenderDateFieldProps) => import("react/jsx-runtime").JSX.Element;
57
- export declare const RenderEndDateField: ({ label, validationItems, setFormData, formData, formDataOrig, fieldsReadOnly, onContentReady }: RenderDateFieldProps) => import("react/jsx-runtime").JSX.Element;
58
- export declare const RenderRemindDateField: ({ validationItems, setFormData, formData, formDataOrig, fieldsReadOnly }: RenderFieldProps) => import("react/jsx-runtime").JSX.Element;
53
+ export declare const RenderNameField: ({ requestMoreInfo, validationItems, setFormData, formData, formDataOrig, fieldsReadOnly }: RenderFieldProps) => React.JSX.Element;
54
+ export declare const RenderDescriptionField: ({ validationItems, setFormData, formData, formDataOrig, fieldsReadOnly }: RenderFieldProps) => React.JSX.Element;
55
+ export declare const RenderPriorityField: ({ formData, formDataOrig, fieldsReadOnly, onPriorityValueChange }: RenderPriorityFieldProps) => React.JSX.Element;
56
+ export declare const RenderStartDateField: ({ label, validationItems, setFormData, formData, formDataOrig, fieldsReadOnly, onContentReady }: RenderDateFieldProps) => React.JSX.Element;
57
+ export declare const RenderEndDateField: ({ label, validationItems, setFormData, formData, formDataOrig, fieldsReadOnly, onContentReady }: RenderDateFieldProps) => React.JSX.Element;
58
+ export declare const RenderRemindDateField: ({ validationItems, setFormData, formData, formDataOrig, fieldsReadOnly }: RenderFieldProps) => React.JSX.Element;
59
59
  interface RenderTaskFormStateFieldProps {
60
60
  formDataOrig: TaskDescriptor | undefined;
61
61
  formData: TaskDescriptor | undefined;
@@ -71,7 +71,7 @@ interface TMChangeStateFormProps {
71
71
  handleShowChangeStateForm: (value: boolean) => void;
72
72
  setFormData: React.Dispatch<React.SetStateAction<TaskDescriptor | undefined>>;
73
73
  }
74
- export declare const TMChangeStateForm: (props: TMChangeStateFormProps) => import("react/jsx-runtime").JSX.Element;
74
+ export declare const TMChangeStateForm: (props: TMChangeStateFormProps) => React.JSX.Element;
75
75
  type TaskRole = "personal" | "sender" | "receiver";
76
76
  type StatusTransitionMap = {
77
77
  [key in Task_States]?: Task_States[];
@@ -15,5 +15,5 @@ interface TMTasksAgendaProps {
15
15
  handleFocusedRowChange: (row: TaskDescriptor | undefined) => void;
16
16
  menuItems: TMContextMenuItemProps[];
17
17
  }
18
- declare const TMTasksAgenda: (props: TMTasksAgendaProps) => import("react/jsx-runtime").JSX.Element;
18
+ declare const TMTasksAgenda: (props: TMTasksAgendaProps) => React.JSX.Element;
19
19
  export default TMTasksAgenda;
@@ -19,5 +19,5 @@ interface TMTasksCalendarProps {
19
19
  handleFocusedRowChange: (row: TaskDescriptor | undefined) => void;
20
20
  menuItems: TMContextMenuItemProps[];
21
21
  }
22
- declare const TMTasksCalendar: (props: TMTasksCalendarProps) => import("react/jsx-runtime").JSX.Element;
22
+ declare const TMTasksCalendar: (props: TMTasksCalendarProps) => React.JSX.Element;
23
23
  export default TMTasksCalendar;
@@ -10,5 +10,5 @@ interface TMTasksHeaderProps {
10
10
  color?: string;
11
11
  height?: string;
12
12
  }
13
- declare const TMTasksHeader: (props: TMTasksHeaderProps) => import("react/jsx-runtime").JSX.Element;
13
+ declare const TMTasksHeader: (props: TMTasksHeaderProps) => React.JSX.Element;
14
14
  export default TMTasksHeader;
@@ -16,5 +16,5 @@ interface TMTasksPanelContentProps {
16
16
  s4TViewerDialogComponent?: React.ReactNode;
17
17
  afterTaskSaved?: (task: TaskDescriptor | undefined, formMode: FormModes | undefined, forceRefresh?: boolean) => Promise<void>;
18
18
  }
19
- declare const TMTasksPanelContent: (props: TMTasksPanelContentProps) => import("react/jsx-runtime").JSX.Element;
19
+ declare const TMTasksPanelContent: (props: TMTasksPanelContentProps) => React.JSX.Element;
20
20
  export default TMTasksPanelContent;
@@ -1,4 +1,4 @@
1
- import { ReactNode } from "react";
1
+ import React, { ReactNode } from "react";
2
2
  import { PdGs, Task_States, TaskDescriptor } from '@topconsultnpm/sdk-ts';
3
3
  import { FormModes } from "../../../ts";
4
4
  export declare const taskStateIconMap: (fontSize?: number) => Map<Task_States, JSX.Element>;
@@ -12,15 +12,15 @@ export declare const renderTaskIcons: (taskData: {
12
12
  remTime: Date | undefined;
13
13
  isNew: boolean;
14
14
  numberOfDays: number;
15
- }) => import("react/jsx-runtime").JSX.Element;
15
+ }) => React.JSX.Element;
16
16
  interface TMActionCalendarProps {
17
17
  currentTask: TaskDescriptor;
18
18
  openTaskForm: (formMode: FormModes, task?: TaskDescriptor) => void;
19
19
  onDeleteCallback: (rowIds: Array<number>) => void;
20
20
  }
21
- export declare const TMActionCalendar: (props: TMActionCalendarProps) => import("react/jsx-runtime").JSX.Element;
22
- export declare const priorityLegend: () => import("react/jsx-runtime").JSX.Element;
23
- export declare const highlightTaskText: (text: string, search: string, taskId: number) => string | (string | import("react/jsx-runtime").JSX.Element)[];
21
+ export declare const TMActionCalendar: (props: TMActionCalendarProps) => React.JSX.Element;
22
+ export declare const priorityLegend: () => React.JSX.Element;
23
+ export declare const highlightTaskText: (text: string, search: string, taskId: number) => string | (string | React.JSX.Element)[];
24
24
  export declare const treeFilterDataSource: (allTasks: Array<TaskDescriptor>) => Array<{
25
25
  id: number;
26
26
  label: string;
@@ -36,5 +36,5 @@ interface TMTasksViewProps {
36
36
  s4TViewerDialogComponent?: React.ReactNode;
37
37
  afterTaskSaved?: (task: TaskDescriptor | undefined, formMode: FormModes | undefined, forceRefresh?: boolean) => Promise<void>;
38
38
  }
39
- declare const TMTasksView: (props: TMTasksViewProps) => import("react/jsx-runtime").JSX.Element;
39
+ declare const TMTasksView: (props: TMTasksViewProps) => React.JSX.Element;
40
40
  export default TMTasksView;