@topconsultnpm/sdkui-react 6.20.0 → 6.21.0-dev1.3

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 (35) hide show
  1. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +7 -1
  2. package/lib/components/base/TMTreeView.d.ts +2 -1
  3. package/lib/components/base/TMTreeView.js +8 -3
  4. package/lib/components/base/TMWaitPanel.js +6 -5
  5. package/lib/components/features/archive/TMArchive.d.ts +1 -1
  6. package/lib/components/features/archive/TMArchive.js +2 -2
  7. package/lib/components/features/documents/TMDcmtBlog.d.ts +1 -0
  8. package/lib/components/features/documents/TMDcmtBlog.js +2 -1
  9. package/lib/components/features/documents/TMDcmtForm.d.ts +42 -34
  10. package/lib/components/features/documents/TMDcmtForm.js +280 -639
  11. package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +34 -0
  12. package/lib/components/features/documents/TMDcmtFormActionButtons.js +124 -0
  13. package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +27 -2
  14. package/lib/components/features/documents/TMMasterDetailDcmts.js +160 -18
  15. package/lib/components/features/documents/TMRelationViewer.d.ts +6 -0
  16. package/lib/components/features/documents/TMRelationViewer.js +7 -5
  17. package/lib/components/features/search/TMSearch.d.ts +2 -2
  18. package/lib/components/features/search/TMSearch.js +3 -3
  19. package/lib/components/features/search/TMSearchResult.d.ts +27 -26
  20. package/lib/components/features/search/TMSearchResult.js +349 -486
  21. package/lib/components/features/tasks/TMTaskForm.d.ts +2 -1
  22. package/lib/components/features/tasks/TMTaskForm.js +2 -2
  23. package/lib/helper/checkinCheckoutManager.js +6 -2
  24. package/lib/hooks/useCheckInOutOperations.d.ts +7 -6
  25. package/lib/hooks/useCheckInOutOperations.js +9 -16
  26. package/lib/hooks/useDcmtOperations.d.ts +3 -2
  27. package/lib/hooks/useDcmtOperations.js +2 -2
  28. package/lib/hooks/useDocumentOperations.d.ts +139 -0
  29. package/lib/hooks/useDocumentOperations.js +1309 -0
  30. package/lib/hooks/useRelatedDocuments.d.ts +1 -1
  31. package/lib/ts/types.d.ts +2 -1
  32. package/lib/ts/types.js +1 -0
  33. package/package.json +55 -55
  34. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +0 -11
  35. package/lib/components/features/search/TMSearchResultsMenuItems.js +0 -758
@@ -1,54 +1,37 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
- import { SDK_Globals, DataColumnTypes, MetadataDataDomains, DataListViewModes, MetadataFormats, LayoutModes, DcmtTypeListCacheService, SystemMIDsAsNumber, RetrieveFileOptions, DcmtOpers, GeneralRetrieveFormats, AccessLevelsEx, LayoutCacheService, UserListCacheService, AppModules } from '@topconsultnpm/sdk-ts';
4
3
  import styled from 'styled-components';
5
- import { getAllFieldSelectedDcmtsOrFocused, getCommandsMenuItems, getSelectedDcmtsOrFocused } from './TMSearchResultsMenuItems';
6
- import { genUniqueId, IconShow, IconBoard, IconDcmtTypeSys, SDKUI_Localizator, IconDelete, IconRefresh, IconMenuVertical, deepCompare, generateUniqueColumnKeys, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, IconSearchCheck, TMImageLibrary, convertSearchResultDescriptorToFileItems, IconCustom, isApprovalWorkflowView, SDKUI_Globals, getMoreInfoTasksForDocument, IconPlatform, getSearchToolbarVisibility } from '../../../helper';
7
- import { useDcmtOperations } from '../../../hooks/useDcmtOperations';
8
- import { useInputAttachmentsDialog, useInputCvtFormatDialog } from '../../../hooks/useInputDialog';
9
- import { useRelatedDocuments } from '../../../hooks/useRelatedDocuments';
10
- import { DcmtOperationTypes, SearchResultContext } from '../../../ts';
4
+ import { LoadIndicator } from 'devextreme-react';
5
+ import { AppModules, DataColumnTypes, DataListViewModes, DcmtTypeListCacheService, LayoutCacheService, LayoutModes, MetadataDataDomains, MetadataFormats, SDK_Globals, SystemMIDsAsNumber, UserListCacheService, } from '@topconsultnpm/sdk-ts';
6
+ import { deepCompare, generateUniqueColumnKeys, genUniqueId, getSearchToolbarVisibility, IconBoard, IconDcmtTypeSys, IconDelete, IconMenuVertical, IconPlatform, IconRefresh, IconSearchCheck, IconShow, isApprovalWorkflowView, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, SDKUI_Globals, SDKUI_Localizator, } from '../../../helper';
7
+ import { getDcmtCicoStatus } from '../../../helper/checkinCheckoutManager';
8
+ import { DcmtOperationTypes, SearchResultContext, } from '../../../ts';
11
9
  import { Gutters } from '../../../utils/theme';
12
- import { StyledModalContainer, StyledMultiViewPanel } from '../../base/Styled';
10
+ import { useDataListItem } from '../../../hooks/useDataListItem';
11
+ import { useDataUserIdItem } from '../../../hooks/useDataUserIdItem';
12
+ import { getSelectedDcmtsOrFocused, useDocumentOperations } from '../../../hooks/useDocumentOperations';
13
+ import ShowAlert from '../../base/TMAlert';
14
+ import TMAccordionNew from '../../base/TMAccordionNew';
13
15
  import TMButton from '../../base/TMButton';
14
16
  import TMDataGrid, { TMDataGridPageSize } from '../../base/TMDataGrid';
15
- import { useDeviceType, DeviceType } from '../../base/TMDeviceProvider';
16
- import { TMSplitterLayout, TMLayoutItem } from '../../base/TMLayout';
17
- import { TMMessageBoxManager, ButtonNames, TMExceptionBoxManager } from '../../base/TMPopUp';
17
+ import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
18
+ import { TMLayoutItem, TMSplitterLayout } from '../../base/TMLayout';
19
+ import { ButtonNames, TMExceptionBoxManager, TMMessageBoxManager } from '../../base/TMPopUp';
20
+ import TMSpinner from '../../base/TMSpinner';
21
+ import { StyledMultiViewPanel } from '../../base/Styled';
18
22
  import { TMLayoutWaitingContainer } from '../../base/TMWaitPanel';
19
23
  import TMMetadataValues from '../../editors/TMMetadataValues';
20
24
  import TMTidViewer from '../../viewers/TMTidViewer';
21
- import TMDcmtPreview from '../documents/TMDcmtPreview';
22
- import TMFloatingMenuBar from '../../NewComponents/FloatingMenuBar/TMFloatingMenuBar';
25
+ import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/panelManager/TMPanelManagerContext';
26
+ import TMPanelManagerContainer from '../../layout/panelManager/TMPanelManagerContainer';
23
27
  import TMContextMenu from '../../NewComponents/ContextMenu/TMContextMenu';
24
- import { WorkFlowApproveRejectPopUp, WorkFlowMoreInfoPopUp, WorkFlowOperationButtons, WorkFlowReAssignPopUp } from '../workflow/TMWorkflowPopup';
25
- import TMMasterDetailDcmts from '../documents/TMMasterDetailDcmts';
26
- import TMBatchUpdateForm from '../../features/documents/TMBatchUpdateForm';
27
- import TMDcmtForm from '../documents/TMDcmtForm';
28
+ import TMToppyDraggableHelpCenter from '../assistant/TMToppyDraggableHelpCenter';
28
29
  import TMDcmtBlog from '../documents/TMDcmtBlog';
29
30
  import TMDcmtIcon from '../documents/TMDcmtIcon';
30
- import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/panelManager/TMPanelManagerContext';
31
- import TMPanelManagerContainer from '../../layout/panelManager/TMPanelManagerContainer';
32
- import TMAccordionNew from '../../base/TMAccordionNew';
33
- import TMDataGridExportForm from '../../base/TMDataGridExportForm';
31
+ import TMDcmtPreview from '../documents/TMDcmtPreview';
32
+ import { WorkFlowOperationButtons } from '../workflow/TMWorkflowPopup';
33
+ // Local
34
34
  import TMSearchResultFloatingActionButton from './TMSearchResultFloatingActionButton';
35
- import ShowAlert from '../../base/TMAlert';
36
- import TMSpinner from '../../base/TMSpinner';
37
- import TMChooserForm from '../../forms/TMChooserForm';
38
- import TMModal from '../../base/TMModal';
39
- import TMSearch from './TMSearch';
40
- import TMArchive from '../archive/TMArchive';
41
- import TMCustomButton from '../../base/TMCustomButton';
42
- import { getDcmtCicoStatus } from '../../../helper/checkinCheckoutManager';
43
- import TMViewHistoryDcmt from './TMViewHistoryDcmt';
44
- import TMBlogCommentForm from '../blog/TMBlogCommentForm';
45
- import { useCheckInOutOperations } from '../../../hooks/useCheckInOutOperations';
46
- import { useFloatingBarPinnedItems } from '../../../hooks/useFloatingBarPinnedItems';
47
- import TMDcmtCheckoutInfoForm from './TMDcmtCheckoutInfoForm';
48
- import { useDataListItem } from '../../../hooks/useDataListItem';
49
- import { useDataUserIdItem } from '../../../hooks/useDataUserIdItem';
50
- import { LoadIndicator } from 'devextreme-react';
51
- import TMToppyDraggableHelpCenter from '../assistant/TMToppyDraggableHelpCenter';
52
35
  let abortControllerLocal = new AbortController();
53
36
  //#region Helper Methods
54
37
  export const getSearchResultCountersSingleCategory = (searchResults) => {
@@ -67,74 +50,321 @@ const orderByName = (array) => {
67
50
  return 1;
68
51
  } return 0; });
69
52
  };
70
- const TMSearchResult = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, context = SearchResultContext.METADATA_SEARCH, isVisible = true, allowRelations = true, openDcmtFormAsModal = false, searchResults = [], showSearchResultSidebar = true, showDcmtFormSidebar = true, showSelector = false, groupId, title, isClosable = false, allowFloatingBar = true, showToolbarHeader = true, showBackButton = true, selectedSearchResultTID, workingGroupContext = undefined, disableAccordionIfSingleCategory = false, floatingActionConfig, openInOffice, onRefreshAfterAddDcmtToFavs, onRefreshSearchAsync, onSelectedTIDChanged, onWFOperationCompleted, onClose, onFileOpened, onTaskCreateRequest, openWGsCopyMoveForm, editPdfForm = false, openEditPdf, openCommentFormCallback, openAddDocumentForm, openS4TViewer = false, onOpenS4TViewerRequest, passToArchiveCallback, showTodoDcmtForm = false, showToppyDraggableHelpCenter = true, toppyHelpCenterUsePortal = false, showNoDcmtFoundMessage = true, onReferenceClick, }) => {
53
+ const TMSearchResult = ({
54
+ // Data
55
+ groupId, searchResults = [], context = SearchResultContext.METADATA_SEARCH, title, selectedSearchResultTID, floatingActionConfig, workingGroupContext = undefined,
56
+ // Boolean flags to enable/disable features
57
+ isVisible = true, allowRelations = true, openDcmtFormAsModal = false, showSearchResultSidebar = true, showDcmtFormSidebar = true, showSelector = false, isClosable = false, allowFloatingBar = true, showToolbarHeader = true, showBackButton = true, disableAccordionIfSingleCategory = false, editPdfForm = false, openS4TViewer = false, showTodoDcmtForm = false, showToppyDraggableHelpCenter = true, toppyHelpCenterUsePortal = false, showNoDcmtFoundMessage = true, enablePinIcons = true,
58
+ // Callbacks (optional)
59
+ openInOffice, onRefreshAfterAddDcmtToFavs, onRefreshSearchAsyncDatagrid, onSelectedTIDChanged, onWFOperationCompleted, onClose, onFileOpened, onTaskCreateRequest, openWGsCopyMoveForm, openCommentFormCallback, openAddDocumentForm, onOpenS4TViewerRequest, onOpenPdfEditorRequest, passToArchiveCallback, onReferenceClick,
60
+ // Tasks
61
+ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback,
62
+ // Navigation
63
+ handleNavigateToWGs, handleNavigateToDossiers, }) => {
64
+ // Ref for the floating bar container (used to position the floating action buttons)
65
+ const floatingBarContainerRef = useRef(null);
66
+ // ID state to force remount of components
71
67
  const [id, setID] = useState('');
72
- const [showApprovePopup, setShowApprovePopup] = useState(false);
73
- const [showRejectPopup, setShowRejectPopup] = useState(false);
74
- const [showReAssignPopup, setShowReAssignPopup] = useState(false);
75
- const [showMoreInfoPopup, setShowMoreInfoPopup] = useState(false);
76
- const [splitterSize, setSplitterSize] = useState(['100%', '0']);
77
- const [showFloatingBar, setShowFloatingBar] = useState(true);
78
- const [lastUpdateSearchTime, setLastUpdateSearchTime] = useState();
68
+ // Document type descriptor of the currently document
79
69
  const [fromDTD, setFromDTD] = useState();
70
+ const [currentDcmt, setCurrentDcmt] = useState();
71
+ // State to specify if the details form is open or not
72
+ const [splitterSize, setSplitterSize] = useState(['100%', '0']);
73
+ // State to control the selected search result
80
74
  const [selectedSearchResult, setSelectedSearchResult] = useState();
75
+ // State to control the search results to show in the datagrid
81
76
  const [currentSearchResults, setCurrentSearchResults] = useState(searchResults || []);
82
- const [showSearch, setShowSearch] = useState(false);
83
- const [sharedDcmtSearchResults, setSharedDcmtSearchResults] = useState([]);
84
- const [secondaryMasterDcmts, setSecondaryMasterDcmts] = useState([]);
85
- const [isOpenDcmtForm, setIsOpenDcmtForm] = useState(false);
86
- const [isOpenBatchUpdate, setIsOpenBatchUpdate] = useState(false);
87
- const [isOpenSharedArchive, setIsOpenSharedArchive] = useState(false);
88
- const [visibleItems, setVisibleItems] = useState([]);
77
+ // State to control the metadata values of the currently focused document
78
+ const [currentMetadataValues, setCurrentMetadataValues] = useState([]);
79
+ // Focused item state
89
80
  const [focusedItem, setFocusedItem] = useState();
81
+ // Selected items state
90
82
  const [selectedItems, setSelectedItems] = useState([]);
91
- const [currentDcmt, setCurrentDcmt] = useState();
92
- const [currentMetadataValues, setCurrentMetadataValues] = useState([]);
93
- const [dcmtFormLayoutMode, setDcmtFormLayoutMode] = useState(LayoutModes.Update);
94
- const [isModifiedBatchUpdate, setIsModifiedBatchUpdate] = useState(false);
95
- const [sharedDcmtFile, setSharedDcmtFile] = useState(undefined);
96
- // State to control whether the export form (for exporting to Excel/CSV/txt and others) should be shown
97
- const [showExportForm, setShowExportForm] = useState(false);
83
+ // State to control the visible items in the datagrid
84
+ const [visibleItems, setVisibleItems] = useState([]);
85
+ // State to control the columns and dataSource of the datagrid
86
+ const [dataColumnsFromDataGrid, setDataColumnsFromDataGrid] = useState([]);
87
+ const [dataSourceFromDataGrid, setDataSourceFromDataGrid] = useState([]);
88
+ // State to control the selected rows in the datagrid
89
+ const [selectedRowKeysFromDataGrid, setSelectedRowKeysFromDataGrid] = useState([]);
90
+ // Triggers TMDcmtBlog refresh after metadata or workflow changes
91
+ const [refreshBlogTrigger, setRefreshBlogTrigger] = useState(0);
92
+ // Trigger TMDcmtPreview refresh
93
+ const [refreshPreviewTrigger, setRefreshPreviewTrigger] = useState(0);
94
+ // Trigger operationItems refresh (after file substitution, etc.)
95
+ const [refreshOperationsTrigger, setRefreshOperationsTrigger] = useState(0);
96
+ // State to control the refresh of the search result after an operation in the workflow popups
97
+ const [lastUpdateSearchTime, setLastUpdateSearchTime] = useState();
98
98
  const [showIndexingInfo, setShowIndexingInfo] = useState(false);
99
99
  const [loadingIndexingInfo, setLoadingIndexingInfo] = useState(false);
100
100
  const [indexingInfo, setIndexingInfo] = useState('');
101
- const floatingBarContainerRef = useRef(null);
102
- const [confirmFormat, ConfirmFormatDialog] = useInputCvtFormatDialog();
103
- const { openConfirmAttachmentsDialog, ConfirmAttachmentsDialog } = useInputAttachmentsDialog();
104
- const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, runOperationAsync, getDcmtFileAsync } = useDcmtOperations();
105
- const { showHistory, showHistoryCallback, hideHistoryCallback, showCheckoutInformationForm, commentFormState, hideCommentFormCallback, showCheckoutInformationFormCallback, hideCheckoutInformationFormCallback, copyCheckoutPathToClipboardCallback, handleCheckOutCallback, handleCheckInCallback, refreshPreviewTrigger, showCicoWaitPanel, cicoWaitPanelTitle, showCicoPrimaryProgress, cicoPrimaryProgressText, cicoPrimaryProgressValue, cicoPrimaryProgressMax, } = useCheckInOutOperations();
106
- const relatedDocuments = useRelatedDocuments({ selectedSearchResult, focusedItem, currentSearchResults });
107
- const { relatedDcmts, showRelatedDcmtsChooser, archiveType, isOpenDetails, isOpenMaster, isOpenArchiveRelationForm, archiveRelatedDcmtFormTID, archiveRelatedDcmtFormMids, relatedDcmtsChooserDataSource, showPairDcmtsModal, isPairingManyToMany, pairedSearchResults, manyToManyRelations, selectedManyToManyRelation, showManyToManyChooser, manyToManyChooserDataSource, showPairSearchModal, pairSearchModalTargetTID, pairSearchModalParentTID, pairSearchModalParentDID, pairSearchModalRelation, pairSearchModalInputMids, currentTIDHasDetailRelations, currentTIDHasMasterRelations, canArchiveMasterRelation, canArchiveDetailRelation, hasManyToManyRelation, setIsOpenDetails, setIsOpenMaster, setShowRelatedDcmtsChooser, setShowManyToManyChooser, setShowPairDcmtsModal, setShowPairSearchModal, setIsOpenArchiveRelationForm, setArchiveType, setArchiveRelatedDcmtFormTID, setArchiveRelatedDcmtFormMids, pairFloatingActionConfig, pairSearchModalFloatingActionConfig, archiveMasterDocuments, archiveDetailDocuments, pairManyToMany, checkRelatedDcmtsArchiveCapability, checkManyToManyCapability, archiveRelatedDcmtHandler, executeManyToManyPairing, } = relatedDocuments;
101
+ // State to control the layout of the custom buttons
108
102
  const [customButtonsLayout, setCustomButtonsLayout] = useState();
109
- const [customButton, setCustomButton] = useState();
103
+ const [allUsers, setAllUsers] = useState([]);
104
+ useEffect(() => {
105
+ const fetchAllUsers = async () => {
106
+ const users = await UserListCacheService.GetAllAsync();
107
+ setAllUsers(users ?? []);
108
+ };
109
+ fetchAllUsers();
110
+ }, []);
111
+ const canNavigateHandler = (dir) => {
112
+ if (!focusedItem)
113
+ return false;
114
+ let index = -1;
115
+ if (visibleItems) {
116
+ index = visibleItems.findIndex(item => item.rowIndex === focusedItem.rowIndex);
117
+ }
118
+ switch (dir) {
119
+ case 'next': if (visibleItems && index < visibleItems.length - 1) {
120
+ return true;
121
+ }
122
+ else {
123
+ return false;
124
+ }
125
+ default: if (visibleItems && index > 0) {
126
+ return true;
127
+ }
128
+ else {
129
+ return false;
130
+ }
131
+ }
132
+ };
133
+ const onNavigateHandler = (dir) => {
134
+ let index = -1;
135
+ if (visibleItems && focusedItem) {
136
+ index = visibleItems.findIndex(item => item.rowIndex === focusedItem.rowIndex);
137
+ }
138
+ switch (dir) {
139
+ case 'next':
140
+ setFocusedItem(visibleItems[index + 1]);
141
+ break;
142
+ default:
143
+ setFocusedItem(visibleItems[index - 1]);
144
+ break;
145
+ }
146
+ };
147
+ const updateDataColumnsFromDataGrid = useCallback((dataColumns) => {
148
+ setDataColumnsFromDataGrid(dataColumns);
149
+ }, []);
150
+ // Increments trigger counter to force TMDcmtBlog to re-fetch data
151
+ const onRefreshBlogDatagrid = useCallback(async () => {
152
+ setRefreshBlogTrigger(prev => prev + 1);
153
+ }, []);
154
+ // Increments trigger counter to force TMDcmtPreview to re-fetch data
155
+ const onRefreshPreviewDatagrid = useCallback(async () => {
156
+ setRefreshPreviewTrigger(prev => prev + 1);
157
+ }, []);
158
+ // Increments trigger counter to force operationItems to re-calculate
159
+ const onRefreshOperationsDatagrid = useCallback(async () => {
160
+ setRefreshOperationsTrigger(prev => prev + 1);
161
+ }, []);
162
+ const updateDataSourceFromDataGrid = useCallback((dataSource) => {
163
+ setDataSourceFromDataGrid(dataSource);
164
+ }, []);
165
+ const updateSelectedRowKeysFromDataGrid = useCallback((selectedRowKeys) => {
166
+ setSelectedRowKeysFromDataGrid(selectedRowKeys);
167
+ }, []);
168
+ // Reloads metadata for a single document (by TID/DID) and updates or removes its row in the grid
169
+ const refreshFocusedDataRowAsync = async (tid, did, refreshUI, metadataResult) => {
170
+ if (!tid || !did)
171
+ return;
172
+ let currentResult = searchResults.length > 1 ? selectedSearchResult : searchResults[0];
173
+ let currentResultColIndexTID = currentResult?.dtdResult?.columns?.findIndex(o => o.caption == "TID");
174
+ if (currentResultColIndexTID == undefined)
175
+ return;
176
+ let currentResultColIndexDID = currentResult?.dtdResult?.columns?.findIndex(o => o.caption == "DID");
177
+ if (currentResultColIndexDID == undefined)
178
+ return;
179
+ let newDcmt;
180
+ // Se metadataResult è null (non undefined!), significa che GetMetadataAsync è già fallito
181
+ // nel form e l'errore è già stato mostrato all'utente, quindi non ritentiamo
182
+ if (metadataResult === null) {
183
+ newDcmt = undefined;
184
+ }
185
+ // Se metadataResult è un oggetto valido, usiamolo
186
+ else if (metadataResult !== undefined) {
187
+ newDcmt = metadataResult;
188
+ }
189
+ // Altrimenti (metadataResult === undefined), tentiamo di ottenerlo
190
+ else {
191
+ try {
192
+ newDcmt = await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(tid, did, true);
193
+ }
194
+ catch (error) {
195
+ newDcmt = undefined;
196
+ }
197
+ }
198
+ // Se newDcmt è undefined o non ha righe, significa che il documento non esiste più
199
+ // o non è più accessibile. Rimuovi la riga dal risultato della ricerca
200
+ if (!newDcmt || !newDcmt.dtdResult?.rows?.[0]) {
201
+ if (currentResult?.dtdResult?.rows) {
202
+ // IMPORTANTE: Modifica direttamente l'oggetto originale per mantenere la sincronizzazione
203
+ currentResult.dtdResult.rows = currentResult.dtdResult.rows.filter((row) => !(row[currentResultColIndexTID] == tid?.toString() && row[currentResultColIndexDID] == did?.toString()));
204
+ currentResult.dcmtsReturned = currentResult.dtdResult.rows.length;
205
+ currentResult.dcmtsFound = Math.max(0, (currentResult.dcmtsFound ?? 0) - 1);
206
+ // Se il documento rimosso era quello focalizzato, resetta il focus
207
+ if (focusedItem?.TID === tid && focusedItem?.DID === did) {
208
+ setFocusedItem(undefined);
209
+ setSelectedItems([]);
210
+ }
211
+ }
212
+ // IMPORTANTE: forza l'aggiornamento della griglia
213
+ if (refreshUI)
214
+ setLastUpdateSearchTime(new Date(Date.now()));
215
+ return;
216
+ }
217
+ // Se il documento esiste, aggiorna i valori come prima
218
+ let newDcmtRow = newDcmt.dtdResult.rows[0];
219
+ let currentDcmtRow = currentResult?.dtdResult?.rows?.filter((row) => row[currentResultColIndexTID] == tid?.toString() && row[currentResultColIndexDID] == did?.toString()) ?? [];
220
+ for (const row of currentDcmtRow) {
221
+ let mids = currentResult?.selectMIDs ?? [];
222
+ for (let i = 0; i < mids.length; i++) {
223
+ const mid = mids[i];
224
+ let newDcmtMidIndex = newDcmt?.selectMIDs?.findIndex(o => o == mid) ?? -1;
225
+ if (newDcmtMidIndex >= 0 && row[i] != newDcmtRow[newDcmtMidIndex]) {
226
+ row[i] = newDcmtRow[newDcmtMidIndex];
227
+ }
228
+ }
229
+ }
230
+ // Aggiorna focusedItem e selectedItems con i nuovi dati
231
+ if (focusedItem?.TID === tid && focusedItem?.DID === did) {
232
+ const updatedFocusedItem = searchResultDescriptorToSimpleArray(currentResult)?.find(item => item.TID === tid && item.DID === did);
233
+ if (updatedFocusedItem) {
234
+ setFocusedItem(updatedFocusedItem);
235
+ }
236
+ }
237
+ if (selectedItems.length > 0) {
238
+ const updatedSelectedItems = selectedItems.map(item => {
239
+ if (item.TID === tid && item.DID === did) {
240
+ const updatedItem = searchResultDescriptorToSimpleArray(currentResult)?.find(dataItem => dataItem.TID === tid && dataItem.DID === did);
241
+ return updatedItem || item;
242
+ }
243
+ return item;
244
+ });
245
+ setSelectedItems(updatedSelectedItems);
246
+ }
247
+ if (refreshUI)
248
+ setLastUpdateSearchTime(new Date(Date.now()));
249
+ };
250
+ // Refreshes metadata for selected documents (or focused one) and triggers grid re-render
251
+ const onRefreshDataRowsAsync = async () => {
252
+ let dcmts = getSelectedDcmtsOrFocused(selectedItems, focusedItem);
253
+ for (const dcmt of dcmts) {
254
+ await refreshFocusedDataRowAsync(dcmt.TID, dcmt.DID);
255
+ }
256
+ setLastUpdateSearchTime(new Date(Date.now()));
257
+ };
258
+ // Callback after document save: refreshes the row with fetched metadata
259
+ const onSavedAsyncCallback = useCallback(async (tid, did, metadataResult) => {
260
+ await refreshFocusedDataRowAsync(tid, did, true, metadataResult);
261
+ }, [refreshFocusedDataRowAsync]);
262
+ const openTaskFormHandler = (onTaskCreated) => {
263
+ if (selectedItems.length > 1)
264
+ return;
265
+ const item = selectedItems.length === 1 ? selectedItems[0] : focusedItem;
266
+ if (item?.TID && item?.DID) {
267
+ const createTaskFromDocumentOrWorkItem = async () => {
268
+ try {
269
+ const dtd = await DcmtTypeListCacheService.GetWithNotGrantedAsync(item.TID, item?.DID);
270
+ if (dtd) {
271
+ const isWorkItem = isApprovalWorkflowView(dtd);
272
+ const name = `${dtd.name ?? '-'} (DID: ${item.DID})`;
273
+ onTaskCreateRequest?.(isWorkItem
274
+ ? { workItem: { tid: item.TID, did: item.DID, name } }
275
+ : { document: { tid: item.TID, did: item.DID, name } }, onTaskCreated);
276
+ }
277
+ }
278
+ catch (error) {
279
+ console.error("Error fetching data:", error);
280
+ }
281
+ };
282
+ createTaskFromDocumentOrWorkItem();
283
+ }
284
+ };
285
+ const { operationItems, renderFloatingBar, renderDcmtOperations, features } = useDocumentOperations({
286
+ context: context,
287
+ documentData: {
288
+ dtd: fromDTD,
289
+ selectedItems,
290
+ focusedItem,
291
+ currentSearchResults,
292
+ currentMetadataValues,
293
+ allUsers,
294
+ searchResult: selectedSearchResult,
295
+ datagridUtility: {
296
+ visibleItems,
297
+ onRefreshSearchAsyncDatagrid,
298
+ onRefreshDataRowsAsync,
299
+ refreshFocusedDataRowAsync,
300
+ onRefreshBlogDatagrid,
301
+ onRefreshPreviewDatagrid,
302
+ refreshOperationsTrigger,
303
+ onRefreshOperationsDatagrid,
304
+ }
305
+ },
306
+ exportData: {
307
+ dataColumns: dataColumnsFromDataGrid,
308
+ dataSource: dataSourceFromDataGrid,
309
+ selectedRowKeys: selectedRowKeysFromDataGrid,
310
+ },
311
+ uiConfig: {
312
+ floatingBarContainerRef,
313
+ customButtonsLayout,
314
+ workingGroupContext,
315
+ openS4TViewer,
316
+ openDcmtFormAsModal,
317
+ showDcmtFormSidebar,
318
+ allowFloatingBar,
319
+ enablePinIcons,
320
+ allowRelations,
321
+ },
322
+ tasks: {
323
+ allTasks: allTasks,
324
+ getAllTasks: getAllTasks,
325
+ deleteTaskByIdsCallback: deleteTaskByIdsCallback,
326
+ addTaskCallback: addTaskCallback,
327
+ editTaskCallback: editTaskCallback
328
+ },
329
+ callbacks: {
330
+ // Refresh operations (data consistency)
331
+ onSavedAsyncCallback,
332
+ onRefreshAfterAddDcmtToFavs,
333
+ // Workflow operations
334
+ onWFOperationCompleted,
335
+ // Navigation
336
+ canNavigateHandler,
337
+ onNavigateHandler,
338
+ handleNavigateToWGs,
339
+ handleNavigateToDossiers,
340
+ onReferenceClick,
341
+ // Document forms/operations
342
+ openAddDocumentForm,
343
+ openCommentFormCallback,
344
+ onFileOpened,
345
+ passToArchiveCallback,
346
+ openWGsCopyMoveForm,
347
+ onOpenS4TViewerRequest,
348
+ onOpenPdfEditorRequest,
349
+ // Task related
350
+ onTaskCreateRequest,
351
+ openTaskFormHandler,
352
+ },
353
+ });
354
+ const { isOpenDcmtForm, openFormHandler, dcmtFormLayoutMode, onDcmtFormOpenChange, showSearchTMDatagrid, showExportForm, isOpenBatchUpdate, isModifiedBatchUpdate, updateBatchUpdateForm, handleSignApprove, checkoutInfo: { showCicoWaitPanel, cicoWaitPanelTitle, showCicoPrimaryProgress, cicoPrimaryProgressText, cicoPrimaryProgressValue, cicoPrimaryProgressMax, }, dcmtOperations: { abortController, showWaitPanel, showPrimary, waitPanelTitle, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, runOperationAsync, }, relatedDocumentsInfo: { isOpenDetails, isOpenMaster, checkRelatedDcmtsArchiveCapability, checkManyToManyCapability, }, toppyOperations: { showApprovePopup, showRejectPopup, showReAssignPopup, showMoreInfoPopup, updateShowApprovePopup, updateShowRejectPopup, updateShowReAssignPopup, updateShowMoreInfoPopup } } = features;
110
355
  const deviceType = useDeviceType();
111
356
  const isMobile = deviceType === DeviceType.MOBILE;
112
- const { pinnedItemIds, togglePin, setPinnedItemIds } = useFloatingBarPinnedItems();
113
357
  const selectedDocs = getSelectedDcmtsOrFocused(selectedItems, focusedItem);
114
- const allFieldSelectedDocs = useMemo(() => getAllFieldSelectedDcmtsOrFocused(selectedItems, focusedItem), [selectedItems, focusedItem]);
115
358
  // Disable the "Sign/Approve" button if:
116
359
  // 1. No document or multiple documents are selected, OR
117
360
  // 2. Exactly one document is selected but its FILEEXT property is null
118
361
  const disableSignApproveDisable = selectedDocs.length !== 1 || (selectedDocs.length === 1 && selectedDocs[0].FILEEXT === null);
119
362
  const dcmtsReturned = (searchResults?.length > 1 ? selectedSearchResult?.dcmtsReturned : searchResults[0]?.dcmtsReturned ?? 0);
120
363
  const dcmtsFound = (searchResults?.length > 1 ? selectedSearchResult?.dcmtsFound : searchResults[0]?.dcmtsFound ?? 0);
121
- const [allUsers, setAllUsers] = useState([]);
122
- // Stato per triggerare il refresh del blog dall'esterno
123
- const [refreshBlogTrigger, setRefreshBlogTrigger] = useState(0);
124
- const triggerBlogRefresh = useCallback(async () => {
125
- setRefreshBlogTrigger(prev => prev + 1);
126
- }, []);
127
- useEffect(() => {
128
- const fetchAllUsers = async () => {
129
- const users = await UserListCacheService.GetAllAsync();
130
- setAllUsers(users ?? []);
131
- };
132
- fetchAllUsers();
133
- }, []);
134
364
  useEffect(() => { setID(genUniqueId()); }, []);
135
365
  useEffect(() => {
136
366
  setSelectedItems([]);
137
- setIsOpenBatchUpdate(false);
367
+ updateBatchUpdateForm(false);
138
368
  setCurrentSearchResults(searchResults);
139
369
  if (searchResults.length <= 0) {
140
370
  setSelectedSearchResult(undefined);
@@ -205,110 +435,6 @@ const TMSearchResult = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, a
205
435
  };
206
436
  fetchLayout();
207
437
  }, [currentMetadataValues]);
208
- const openFormHandler = (layoutMode) => {
209
- // Verifica che ci sia un documento selezionato con TID e DID validi
210
- if (!focusedItem || focusedItem.TID === undefined || focusedItem.DID === undefined) {
211
- ShowAlert({
212
- message: SDKUI_Localizator.InvalidDcmt,
213
- mode: "warning",
214
- title: layoutMode === LayoutModes.Ark ? SDKUI_Localizator.Archive : SDKUI_Localizator.OpenTheDocument,
215
- duration: 3000
216
- });
217
- return;
218
- }
219
- setIsOpenDcmtForm(true);
220
- setDcmtFormLayoutMode(layoutMode);
221
- };
222
- const openSharedArchiveHandler = async () => {
223
- const dcmts = getSelectedDcmtsOrFocused(selectedItems, focusedItem);
224
- if (dcmts.length === 0) {
225
- ShowAlert({ message: "Nessun documento selezionato", mode: "warning", title: 'Archivio Condivisa', duration: 3000 });
226
- return;
227
- }
228
- if (fromDTD?.perm?.canArchive !== AccessLevelsEx.Yes && fromDTD?.perm?.canArchive !== AccessLevelsEx.Mixed) {
229
- ShowAlert({
230
- message: "Non hai i permessi per archiviare documenti di questo tipo.",
231
- mode: 'warning',
232
- title: 'Archivio Condivisa',
233
- duration: 5000
234
- });
235
- return;
236
- }
237
- try {
238
- const rfo = new RetrieveFileOptions();
239
- rfo.retrieveReason = DcmtOpers.None;
240
- rfo.generalRetrieveFormat = GeneralRetrieveFormats.OriginalUnsigned;
241
- let dcmtFile = await getDcmtFileAsync({ TID: focusedItem?.TID, DID: focusedItem?.DID }, rfo, 'Archiviazione Condivisa', false, true);
242
- if (dcmtFile) {
243
- setSharedDcmtFile(dcmtFile?.file);
244
- }
245
- setIsOpenSharedArchive(true);
246
- }
247
- catch (e) {
248
- TMExceptionBoxManager.show({ exception: e });
249
- }
250
- };
251
- const showSharedDcmtsHandler = async () => {
252
- try {
253
- TMSpinner.show({ description: "Caricamento documenti condivisi..." });
254
- const se = SDK_Globals.tmSession?.NewSearchEngine();
255
- const sharedDcmts = await se?.GetSharedDcmtsAsync(getSelectedDcmtsOrFocused(selectedItems, focusedItem)[0].TID, getSelectedDcmtsOrFocused(selectedItems, focusedItem)[0].DID);
256
- if (sharedDcmts && sharedDcmts.length > 0) {
257
- setSharedDcmtSearchResults(sharedDcmts);
258
- }
259
- else {
260
- ShowAlert({ message: "Nessun documento condiviso trovato.", mode: "info", title: 'Documenti Condivisi', duration: 5000 });
261
- }
262
- }
263
- catch (e) {
264
- TMExceptionBoxManager.show({ exception: e });
265
- }
266
- finally {
267
- TMSpinner.hide();
268
- }
269
- };
270
- const openTaskFormHandler = (onTaskCreated) => {
271
- if (selectedItems.length > 1)
272
- return;
273
- const item = selectedItems.length === 1 ? selectedItems[0] : focusedItem;
274
- if (item?.TID && item?.DID) {
275
- const fetchData = async () => {
276
- try {
277
- const dtd = await DcmtTypeListCacheService.GetWithNotGrantedAsync(item.TID, item?.DID);
278
- if (dtd) {
279
- const isWorkItem = isApprovalWorkflowView(dtd);
280
- const name = `${dtd.name ?? '-'} (DID: ${item.DID})`;
281
- onTaskCreateRequest?.(isWorkItem
282
- ? { workItem: { tid: item.TID, did: item.DID, name } }
283
- : { document: { tid: item.TID, did: item.DID, name } }, onTaskCreated);
284
- }
285
- }
286
- catch (error) {
287
- console.error("Error fetching data:", error);
288
- }
289
- };
290
- fetchData();
291
- }
292
- };
293
- const openDetailDcmtsFormHandler = (value) => { setIsOpenDetails(value); };
294
- const openMasterDcmtsFormHandler = (value) => { setIsOpenMaster(value); };
295
- const openBatchUpdateFormHandler = (value) => { setIsOpenBatchUpdate(value); };
296
- const openExportForm = useCallback(() => {
297
- setShowExportForm(true);
298
- }, []);
299
- const onCloseExportForm = useCallback(() => {
300
- setShowExportForm(false);
301
- }, []);
302
- const handleToggleSearch = () => {
303
- setShowSearch(prev => !prev);
304
- };
305
- const copyCheckoutPathToClipboardOperationCallback = () => {
306
- const selectedDocs = getSelectedDcmtsOrFocused(selectedItems, focusedItem);
307
- const firstDoc = selectedDocs?.[0];
308
- if (!firstDoc)
309
- return;
310
- copyCheckoutPathToClipboardCallback(firstDoc, fromDTD?.name ?? SDKUI_Localizator.SearchResult);
311
- };
312
438
  const getTitleHeader = () => {
313
439
  let counters = (showSelector && disableAccordionIfSingleCategory && searchResults.length > 1) ? getSearchResultCountersSingleCategory(searchResults) : "";
314
440
  if (title)
@@ -331,18 +457,6 @@ const TMSearchResult = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, a
331
457
  }
332
458
  return titleHeader + counters;
333
459
  };
334
- const handleSignApprove = () => {
335
- if (onOpenS4TViewerRequest) {
336
- onOpenS4TViewerRequest(getSelectedDcmtsOrFocused(selectedItems, focusedItem), onRefreshSearchAsync);
337
- return;
338
- }
339
- ShowAlert({
340
- message: "Non è stato possibile proseguire con la firma e l'approvazione.",
341
- mode: "warning",
342
- duration: 3000,
343
- title: SDKUI_Localizator.SignatureAndApprove,
344
- });
345
- };
346
460
  const onBack = () => {
347
461
  if (isOpenBatchUpdate && isModifiedBatchUpdate) {
348
462
  TMMessageBoxManager.show({
@@ -356,7 +470,7 @@ const TMSearchResult = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, a
356
470
  });
357
471
  }
358
472
  else if (isOpenDcmtForm) {
359
- setIsOpenDcmtForm(false);
473
+ onDcmtFormOpenChange(false, LayoutModes.Update);
360
474
  }
361
475
  else {
362
476
  if (isMobile && currentSearchResults.length > 1) {
@@ -366,34 +480,6 @@ const TMSearchResult = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, a
366
480
  onClose?.();
367
481
  }
368
482
  };
369
- const customButtonMenuItems = () => {
370
- const customButtonsItems = customButtonsLayout?.customButtons?.filter((customButton) => customButton.isForSearchResult && customButton.isForSearchResult > 0)
371
- .map((customButton) => ({
372
- icon: TMImageLibrary({ imageID: customButton.glyphID }),
373
- name: customButton.title || 'Bottone personalizzato',
374
- onClick: () => setCustomButton(customButton)
375
- }));
376
- return customButtonsItems && customButtonsItems.length > 0 ? {
377
- icon: _jsx(IconCustom, {}),
378
- name: SDKUI_Localizator.CustomButtons,
379
- submenu: customButtonsItems
380
- } : {};
381
- };
382
- const handleCheckOutOperationCallback = async (checkout) => {
383
- const selectedDocs = getSelectedDcmtsOrFocused(selectedItems, focusedItem);
384
- const firstDoc = selectedDocs?.[0];
385
- if (!firstDoc)
386
- return;
387
- await handleCheckOutCallback(firstDoc, checkout, fromDTD?.name ?? SDKUI_Localizator.SearchResult, downloadDcmtsAsync, undefined, refreshFocusedDataRowAsync);
388
- };
389
- const handleCheckInOperationCallback = async () => {
390
- const selectedDocs = getSelectedDcmtsOrFocused(selectedItems, focusedItem);
391
- const firstDoc = selectedDocs?.[0];
392
- if (!firstDoc)
393
- return;
394
- firstDoc.fileName = fromDTD?.name ?? SDKUI_Localizator.SearchResult;
395
- await handleCheckInCallback(firstDoc, undefined, refreshFocusedDataRowAsync);
396
- };
397
483
  const refreshDataGridAfterRemoveAsync = async () => {
398
484
  let index = selectedSearchResult?.dtdResult?.columns?.findIndex(col => col.caption === 'DID');
399
485
  let selectedRows = [];
@@ -446,141 +532,6 @@ const TMSearchResult = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, a
446
532
  }
447
533
  onSelectedTIDChanged?.(e.fromTID);
448
534
  };
449
- const refreshFocusedDataRowAsync = async (tid, did, refreshUI, metadataResult) => {
450
- if (!tid || !did)
451
- return;
452
- let currentResult = searchResults.length > 1 ? selectedSearchResult : searchResults[0];
453
- let currentResultColIndexTID = currentResult?.dtdResult?.columns?.findIndex(o => o.caption == "TID");
454
- if (currentResultColIndexTID == undefined)
455
- return;
456
- let currentResultColIndexDID = currentResult?.dtdResult?.columns?.findIndex(o => o.caption == "DID");
457
- if (currentResultColIndexDID == undefined)
458
- return;
459
- let newDcmt;
460
- // Se metadataResult è null (non undefined!), significa che GetMetadataAsync è già fallito
461
- // nel form e l'errore è già stato mostrato all'utente, quindi non ritentiamo
462
- if (metadataResult === null) {
463
- newDcmt = undefined;
464
- }
465
- // Se metadataResult è un oggetto valido, usiamolo
466
- else if (metadataResult !== undefined) {
467
- newDcmt = metadataResult;
468
- }
469
- // Altrimenti (metadataResult === undefined), tentiamo di ottenerlo
470
- else {
471
- try {
472
- newDcmt = await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(tid, did, true);
473
- }
474
- catch (error) {
475
- newDcmt = undefined;
476
- }
477
- }
478
- // Se newDcmt è undefined o non ha righe, significa che il documento non esiste più
479
- // o non è più accessibile. Rimuovi la riga dal risultato della ricerca
480
- if (!newDcmt || !newDcmt.dtdResult?.rows?.[0]) {
481
- if (currentResult?.dtdResult?.rows) {
482
- // IMPORTANTE: Modifica direttamente l'oggetto originale per mantenere la sincronizzazione
483
- currentResult.dtdResult.rows = currentResult.dtdResult.rows.filter((row) => !(row[currentResultColIndexTID] == tid?.toString() && row[currentResultColIndexDID] == did?.toString()));
484
- currentResult.dcmtsReturned = currentResult.dtdResult.rows.length;
485
- currentResult.dcmtsFound = Math.max(0, (currentResult.dcmtsFound ?? 0) - 1);
486
- // Se il documento rimosso era quello focalizzato, resetta il focus
487
- if (focusedItem?.TID === tid && focusedItem?.DID === did) {
488
- setFocusedItem(undefined);
489
- setSelectedItems([]);
490
- }
491
- }
492
- // IMPORTANTE: forza l'aggiornamento della griglia
493
- if (refreshUI)
494
- setLastUpdateSearchTime(new Date(Date.now()));
495
- return;
496
- }
497
- // Se il documento esiste, aggiorna i valori come prima
498
- let newDcmtRow = newDcmt.dtdResult.rows[0];
499
- let currentDcmtRow = currentResult?.dtdResult?.rows?.filter((row) => row[currentResultColIndexTID] == tid?.toString() && row[currentResultColIndexDID] == did?.toString()) ?? [];
500
- for (const row of currentDcmtRow) {
501
- let mids = currentResult?.selectMIDs ?? [];
502
- for (let i = 0; i < mids.length; i++) {
503
- const mid = mids[i];
504
- let newDcmtMidIndex = newDcmt?.selectMIDs?.findIndex(o => o == mid) ?? -1;
505
- if (newDcmtMidIndex >= 0 && row[i] != newDcmtRow[newDcmtMidIndex]) {
506
- row[i] = newDcmtRow[newDcmtMidIndex];
507
- }
508
- }
509
- }
510
- // Aggiorna focusedItem e selectedItems con i nuovi dati
511
- if (focusedItem?.TID === tid && focusedItem?.DID === did) {
512
- const updatedFocusedItem = searchResultDescriptorToSimpleArray(currentResult)?.find(item => item.TID === tid && item.DID === did);
513
- if (updatedFocusedItem) {
514
- setFocusedItem(updatedFocusedItem);
515
- }
516
- }
517
- if (selectedItems.length > 0) {
518
- const updatedSelectedItems = selectedItems.map(item => {
519
- if (item.TID === tid && item.DID === did) {
520
- const updatedItem = searchResultDescriptorToSimpleArray(currentResult)?.find(dataItem => dataItem.TID === tid && dataItem.DID === did);
521
- return updatedItem || item;
522
- }
523
- return item;
524
- });
525
- setSelectedItems(updatedSelectedItems);
526
- }
527
- if (refreshUI)
528
- setLastUpdateSearchTime(new Date(Date.now()));
529
- };
530
- const refreshSelectionDataRowsAsync = async () => {
531
- let dcmts = getSelectedDcmtsOrFocused(selectedItems, focusedItem);
532
- for (const dcmt of dcmts) {
533
- await refreshFocusedDataRowAsync(dcmt.TID, dcmt.DID);
534
- }
535
- setLastUpdateSearchTime(new Date(Date.now()));
536
- };
537
- const getSelectionDcmtInfo = () => { return getSelectedDcmtsOrFocused(selectedItems, focusedItem); };
538
- const canNavigateHandler = (dir) => {
539
- if (!focusedItem)
540
- return false;
541
- let index = -1;
542
- if (visibleItems) {
543
- index = visibleItems.findIndex(item => item.rowIndex === focusedItem.rowIndex);
544
- }
545
- switch (dir) {
546
- case 'next': if (visibleItems && index < visibleItems.length - 1) {
547
- return true;
548
- }
549
- else {
550
- return false;
551
- }
552
- default: if (visibleItems && index > 0) {
553
- return true;
554
- }
555
- else {
556
- return false;
557
- }
558
- }
559
- };
560
- const onNavigateHandler = (dir) => {
561
- let index = -1;
562
- if (visibleItems && focusedItem) {
563
- index = visibleItems.findIndex(item => item.rowIndex === focusedItem.rowIndex);
564
- }
565
- switch (dir) {
566
- case 'next':
567
- setFocusedItem(visibleItems[index + 1]);
568
- break;
569
- default:
570
- setFocusedItem(visibleItems[index - 1]);
571
- break;
572
- }
573
- };
574
- const handleAddItem = (tid, did) => {
575
- let newItem = { TID: tid ?? 0, DID: did ?? 0 };
576
- setSecondaryMasterDcmts((prevItems) => [...prevItems, newItem]);
577
- };
578
- const handleRemoveItem = (tid, did) => {
579
- setSecondaryMasterDcmts((prevItems) => prevItems.filter(item => item.TID !== tid && item.DID !== did));
580
- };
581
- const handleSavedAsyncCallback = useCallback(async (tid, did, metadataResult) => {
582
- await refreshFocusedDataRowAsync(tid, did, true, metadataResult);
583
- }, [refreshFocusedDataRowAsync]);
584
535
  const showToppyForApprove = useMemo(() => {
585
536
  return Boolean(isVisible && fromDTD && isApprovalWorkflowView(fromDTD) && !isOpenDcmtForm && !isOpenDetails && !isOpenMaster);
586
537
  }, [isVisible, fromDTD, isOpenDcmtForm, isOpenDetails, isOpenMaster]);
@@ -601,144 +552,55 @@ const TMSearchResult = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, a
601
552
  && !openS4TViewer
602
553
  && !showTodoDcmtForm);
603
554
  }, [showToppyForApprove, showToppyDraggableHelpCenter, selectedDocs, showApprovePopup, showRejectPopup, showReAssignPopup, showMoreInfoPopup, editPdfForm, openS4TViewer, showTodoDcmtForm]);
604
- const floatingMenuItems = useMemo(() => {
605
- const baseMenuItems = getCommandsMenuItems(isMobile, fromDTD, allUsers, selectedItems, focusedItem, context, showFloatingBar, workingGroupContext, showSearch, setShowFloatingBar, openFormHandler, openSharedArchiveHandler, showSharedDcmtsHandler, downloadDcmtsAsync, runOperationAsync, onRefreshSearchAsync, refreshSelectionDataRowsAsync, onRefreshAfterAddDcmtToFavs, confirmFormat, openConfirmAttachmentsDialog, openTaskFormHandler, openDetailDcmtsFormHandler, openMasterDcmtsFormHandler, openBatchUpdateFormHandler, openExportForm, handleToggleSearch, handleSignApprove, handleCheckOutOperationCallback, handleCheckInOperationCallback, showCheckoutInformationFormCallback, showHistoryCallback, copyCheckoutPathToClipboardOperationCallback, openWGsCopyMoveForm, openCommentFormCallback, openEditPdf, openAddDocumentForm, passToArchiveCallback, archiveMasterDocuments, archiveDetailDocuments, currentTIDHasMasterRelations, currentTIDHasDetailRelations, canArchiveMasterRelation, canArchiveDetailRelation, pairManyToMany, hasManyToManyRelation, pinnedItemIds, togglePin);
606
- const customButtons = customButtonMenuItems();
607
- return customButtons.name ? baseMenuItems.concat([customButtons]) : baseMenuItems;
608
- }, [
609
- isMobile, fromDTD, allUsers, selectedItems, focusedItem, context,
610
- showFloatingBar, workingGroupContext, showSearch, currentTIDHasMasterRelations,
611
- currentTIDHasDetailRelations, canArchiveMasterRelation, canArchiveDetailRelation,
612
- hasManyToManyRelation, customButtonsLayout, pinnedItemIds, togglePin
613
- ]);
614
555
  const searchResutlToolbar = _jsxs(_Fragment, { children: [(dcmtsReturned != dcmtsFound) && _jsx("p", { style: { textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${dcmtsReturned}/${dcmtsFound} restituiti` }), context === SearchResultContext.FAVORITES_AND_RECENTS &&
615
- _jsx("div", { style: { display: 'flex', alignItems: 'center', gap: '5px' }, children: _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconDelete, { color: 'white' }), caption: "Rimuovi da " + (selectedSearchResult?.category === "Favorites" ? '"Preferiti"' : '"Recenti"'), disabled: getSelectedDcmtsOrFocused(selectedItems, focusedItem).length <= 0, onClick: removeDcmtFromFavsOrRecents }) }), _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconRefresh, { color: 'white' }), caption: SDKUI_Localizator.Refresh, onClick: onRefreshSearchAsync }), _jsx(TMContextMenu, { items: floatingMenuItems, trigger: "left", children: _jsx(IconMenuVertical, { color: 'white', cursor: 'pointer' }) })] });
556
+ _jsx("div", { style: { display: 'flex', alignItems: 'center', gap: '5px' }, children: _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconDelete, { color: 'white' }), caption: "Rimuovi da " + (selectedSearchResult?.category === "Favorites" ? '"Preferiti"' : '"Recenti"'), disabled: getSelectedDcmtsOrFocused(selectedItems, focusedItem).length <= 0, onClick: removeDcmtFromFavsOrRecents }) }), _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconRefresh, { color: 'white' }), caption: SDKUI_Localizator.Refresh, onClick: onRefreshSearchAsyncDatagrid }), _jsx(TMContextMenu, { items: operationItems, trigger: "left", children: _jsx(IconMenuVertical, { color: 'white', cursor: 'pointer' }) })] });
616
557
  const tmSearchResult = useMemo(() => (!searchResults || searchResults.length <= 0)
617
558
  ? _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 }) })] })
618
559
  :
619
560
  _jsxs(_Fragment, { children: [_jsxs(TMLayoutItem, { height: '100%', children: [_jsxs("div", { ref: floatingBarContainerRef, style: { position: 'relative', height: '100%', width: '100%' }, children: [_jsxs(TMSplitterLayout, { direction: 'horizontal', overflow: 'visible', separatorSize: Gutters.getGutters(), separatorActiveColor: 'transparent', separatorColor: 'transparent', min: ['0', '0'], showSeparator: showSelector && deviceType !== DeviceType.MOBILE, start: showSelector ? deviceType !== DeviceType.MOBILE ? ['30%', '70%'] : splitterSize : ['0%', '100%'], children: [showSelector ?
620
561
  _jsx(TMLayoutItem, { children: _jsx(TMSearchResultSelector, { searchResults: currentSearchResults, disableAccordionIfSingleCategory: disableAccordionIfSingleCategory, selectedTID: selectedSearchResultTID, selectedSearchResult: selectedSearchResult, autoSelectFirst: !isMobile || currentSearchResults.length === 1, onSelectionChanged: onSearchResultSelectionChanged }) })
621
562
  :
622
- _jsx(_Fragment, {}), _jsx(TMLayoutItem, { children: _jsx(TMSearchResultGrid, { showSearch: showSearch, fromDTD: fromDTD, allUsers: allUsers, inputFocusedItem: focusedItem, inputSelectedItems: selectedItems, searchResult: searchResults.length > 1 ? selectedSearchResult : searchResults[0], lastUpdateSearchTime: lastUpdateSearchTime, openInOffice: openInOffice, onDblClick: () => openFormHandler(LayoutModes.Update), floatingMenuItems: floatingMenuItems, onSelectionChanged: (items) => { setSelectedItems(items); }, onVisibleItemChanged: setVisibleItems, onFocusedItemChanged: setFocusedItem, onDownloadDcmtsAsync: async (inputDcmts, downloadType, downloadMode, _y, confirmAttachments) => await downloadDcmtsAsync(inputDcmts, downloadType, downloadMode, onFileOpened, confirmAttachments), showExportForm: showExportForm, onCloseExportForm: onCloseExportForm }) })] }), allowFloatingBar && showFloatingBar && deviceType !== DeviceType.MOBILE &&
623
- _jsx(TMFloatingMenuBar, { containerRef: floatingBarContainerRef, contextMenuItems: floatingMenuItems, isConstrained: true, defaultPosition: { x: 1, y: 88 }, defaultPinnedItems: ['rel-det', 'rel-mst', 'dl'], defaultOrientation: 'horizontal', hasContextMenu: false, pinnedItemIds: pinnedItemIds, onPinChange: setPinnedItemIds })] }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: onWFOperationCompleted, selectedItems: getSelectedDcmtsOrFocused(selectedItems, focusedItem), isReject: 0, onClose: () => setShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: onWFOperationCompleted, selectedItems: getSelectedDcmtsOrFocused(selectedItems, focusedItem), isReject: 1, onClose: () => setShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onCompleted: onWFOperationCompleted, selectedItems: getSelectedDcmtsOrFocused(selectedItems, focusedItem), onClose: () => setShowReAssignPopup(false) }), showMoreInfoPopup && _jsx(WorkFlowMoreInfoPopUp, { fromDTD: fromDTD, TID: focusedItem?.TID, DID: focusedItem?.DID, deviceType: deviceType, onCompleted: onWFOperationCompleted, onClose: () => setShowMoreInfoPopup(false), getAllTasks: getAllTasks, triggerBlogRefresh: triggerBlogRefresh }), isOpenBatchUpdate && _jsx(TMBatchUpdateForm, { isModal: true, titleModal: `${SDKUI_Localizator.BatchUpdate} (${getSelectionDcmtInfo().length} documenti selezionati)`, inputDcmts: getSelectionDcmtInfo(), TID: focusedItem ? focusedItem?.TID : selectedItems[0]?.TID, DID: focusedItem ? focusedItem?.DID : selectedItems[0]?.DID, onBack: () => {
624
- setIsOpenBatchUpdate(false);
625
- }, onSavedCallbackAsync: async () => {
626
- setIsOpenBatchUpdate(false);
627
- setIsModifiedBatchUpdate(false);
628
- await refreshSelectionDataRowsAsync();
629
- }, onStatusChanged: (isModified) => { setIsModifiedBatchUpdate(isModified); } }), _jsx(TMToppyDraggableHelpCenter, { usePortal: toppyHelpCenterUsePortal, isVisible: isToppyHelpCenterVisible, content: _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: _jsx(WorkFlowOperationButtons, { dtd: fromDTD, deviceType: deviceType, onApprove: () => {
630
- setShowApprovePopup(true);
563
+ _jsx(_Fragment, {}), _jsx(TMLayoutItem, { children: _jsx(TMSearchResultGrid, { openInOffice: openInOffice, fromDTD: fromDTD, operationItems: operationItems, allUsers: allUsers, inputFocusedItem: focusedItem, inputSelectedItems: selectedItems, showExportForm: showExportForm, onFocusedItemChanged: setFocusedItem, onDownloadDcmtsAsync: async (inputDcmts, downloadType, downloadMode, _y, confirmAttachments) => await downloadDcmtsAsync(inputDcmts, downloadType, downloadMode, 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 }) })] }), 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: () => {
564
+ updateShowApprovePopup(true);
631
565
  }, onSignApprove: () => {
632
566
  handleSignApprove();
633
567
  }, onReject: () => {
634
- setShowRejectPopup(true);
568
+ updateShowRejectPopup(true);
635
569
  }, onReAssign: () => {
636
- setShowReAssignPopup(true);
570
+ updateShowReAssignPopup(true);
637
571
  }, onMoreInfo: () => {
638
- setShowMoreInfoPopup(true);
639
- }, approveDisable: selectedDocs.length === 0, signApproveDisable: disableSignApproveDisable, rejectDisable: selectedDocs.length === 0, reassignDisable: selectedDocs.length === 0, infoDisable: selectedDocs.length !== 1 }) }) })] }), _jsx(ConfirmFormatDialog, {}), _jsx(ConfirmAttachmentsDialog, {}), customButton && _jsx(TMCustomButton, { button: customButton, formData: currentMetadataValues, selectedItems: selectedItems, onClose: () => setCustomButton(undefined) }), showRelatedDcmtsChooser &&
640
- _jsx(TMChooserForm, { dataSource: relatedDcmtsChooserDataSource, onChoose: async (selectedRelation) => {
641
- try {
642
- setShowRelatedDcmtsChooser(false);
643
- TMSpinner.show({ description: SDKUI_Localizator.Loading });
644
- const relation = relatedDcmts?.find(r => r.id === selectedRelation[0]);
645
- if (!relation || !archiveType)
646
- return;
647
- await archiveRelatedDcmtHandler(relation, archiveType);
648
- }
649
- catch (error) {
650
- TMExceptionBoxManager.show({ exception: error });
651
- }
652
- finally {
653
- TMSpinner.hide();
654
- }
655
- }, onClose: () => setShowRelatedDcmtsChooser(false), manageUseLocalizedName: false }), showManyToManyChooser &&
656
- _jsx(TMChooserForm, { dataSource: manyToManyChooserDataSource, onChoose: async (selectedRelation) => {
657
- try {
658
- setShowManyToManyChooser(false);
659
- TMSpinner.show({ description: SDKUI_Localizator.Loading });
660
- const relation = manyToManyRelations?.find(r => r.id === selectedRelation[0]);
661
- if (!relation)
662
- return;
663
- await executeManyToManyPairing(relation, isPairingManyToMany);
664
- }
665
- catch (error) {
666
- TMExceptionBoxManager.show({ exception: error });
667
- }
668
- finally {
669
- TMSpinner.hide();
670
- }
671
- }, onClose: () => setShowManyToManyChooser(false), manageUseLocalizedName: false }), showPairDcmtsModal &&
672
- _jsx(TMModal, { title: (isPairingManyToMany ? "Abbina" : "Disabbina") + " documenti", onClose: () => setShowPairDcmtsModal(false), width: isMobile ? '90%' : '50%', height: isMobile ? '90%' : '70%', children: _jsx(TMSearchResult, { searchResults: pairedSearchResults, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, onRefreshSearchAsync: onRefreshSearchAsync, onFileOpened: onFileOpened, onTaskCreateRequest: onTaskCreateRequest, openWGsCopyMoveForm: openWGsCopyMoveForm, editPdfForm: editPdfForm, openEditPdf: openEditPdf, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, passToArchiveCallback: passToArchiveCallback, showTodoDcmtForm: showTodoDcmtForm, allowFloatingBar: false, floatingActionConfig: pairFloatingActionConfig, showBackButton: false, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, toppyHelpCenterUsePortal: toppyHelpCenterUsePortal, showToppyDraggableHelpCenter: showToppyDraggableHelpCenter }) }), showPairSearchModal &&
673
- _jsx(TMModal, { title: "Ricerca documenti", onClose: () => setShowPairSearchModal(false), width: isMobile ? '90%' : '50%', height: isMobile ? '90%' : '70%', children: _jsx(TMSearch, { onlyShowSearchQueryPanel: true, inputTID: pairSearchModalTargetTID, inputMids: pairSearchModalInputMids, floatingActionConfig: pairSearchModalFloatingActionConfig, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }), isOpenSharedArchive && _jsx(TMModal, { title: "Archiviazione condivisa", onClose: () => {
674
- setIsOpenSharedArchive(false);
675
- }, width: isMobile ? '90%' : '60%', height: isMobile ? '90%' : '80%', children: _jsx(TMArchive, { inputDID: focusedItem?.DID, inputTID: focusedItem?.TID, inputMids: currentMetadataValues.filter(md => md.mid && md.mid > 100).map(md => ({ mid: md.mid, value: md.value ?? '' })), isSharedArchive: true, inputFile: sharedDcmtFile, onSavedAsyncCallback: async (tid, did) => {
676
- setIsOpenSharedArchive(false);
677
- await onRefreshSearchAsync?.();
678
- }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }), sharedDcmtSearchResults.length > 0 &&
679
- _jsx(TMModal, { title: "Documenti condivisi", onClose: () => {
680
- setSharedDcmtSearchResults([]);
681
- }, width: isMobile ? '90%' : '60%', height: isMobile ? '90%' : '80%', children: _jsx(TMSearchResult, { searchResults: sharedDcmtSearchResults, allowFloatingBar: false, showSelector: true, disableAccordionIfSingleCategory: true, showBackButton: isMobile, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }), (showCheckoutInformationForm && fromDTD && getSelectedDcmtsOrFocused(selectedItems, focusedItem).length > 0) &&
682
- _jsx(TMDcmtCheckoutInfoForm, { dtdName: fromDTD.name ?? SDKUI_Localizator.SearchResult, selectedDcmtOrFocused: getSelectedDcmtsOrFocused(selectedItems, focusedItem)[0], onClose: hideCheckoutInformationFormCallback }), (floatingActionConfig && floatingActionConfig.isVisible) && _jsx(TMSearchResultFloatingActionButton, { selectedDcmtsOrFocused: getSelectedDcmtsOrFocused(selectedItems, focusedItem), config: floatingActionConfig })] }), [
572
+ updateShowMoreInfoPopup(true);
573
+ }, approveDisable: selectedDocs.length === 0, signApproveDisable: disableSignApproveDisable, rejectDisable: selectedDocs.length === 0, reassignDisable: selectedDocs.length === 0, infoDisable: selectedDocs.length !== 1 }) }) })] }), (floatingActionConfig && floatingActionConfig.isVisible) && _jsx(TMSearchResultFloatingActionButton, { selectedDcmtsOrFocused: getSelectedDcmtsOrFocused(selectedItems, focusedItem), config: floatingActionConfig })] }), [
683
574
  searchResults,
684
575
  selectedSearchResult,
685
576
  lastUpdateSearchTime,
686
577
  focusedItem,
687
578
  selectedItems,
688
579
  fromDTD,
689
- currentTIDHasDetailRelations,
690
- currentTIDHasMasterRelations,
691
- canArchiveMasterRelation,
692
- canArchiveDetailRelation,
693
580
  showApprovePopup,
694
581
  showRejectPopup,
695
582
  showReAssignPopup,
696
- showFloatingBar,
697
583
  isOpenBatchUpdate,
698
584
  isOpenDetails,
699
585
  isOpenMaster,
700
586
  isOpenDcmtForm,
701
- isOpenArchiveRelationForm,
702
587
  showToppyForApprove,
703
588
  floatingActionConfig,
704
589
  disableAccordionIfSingleCategory,
705
590
  getTitleHeader,
706
591
  openS4TViewer,
707
- showRelatedDcmtsChooser,
708
- relatedDcmts,
709
- setShowRelatedDcmtsChooser,
710
- relatedDcmtsChooserDataSource,
711
- showManyToManyChooser,
712
- manyToManyRelations,
713
- manyToManyChooserDataSource,
714
- showPairDcmtsModal,
715
- isPairingManyToMany,
716
- pairedSearchResults,
717
- selectedManyToManyRelation,
718
- pairFloatingActionConfig,
719
- hasManyToManyRelation,
720
- showPairSearchModal,
721
- pairSearchModalFloatingActionConfig,
722
- pairSearchModalTargetTID,
723
- pairSearchModalParentTID,
724
- pairSearchModalParentDID,
725
- pairSearchModalRelation,
726
- pairSearchModalInputMids,
727
- isOpenSharedArchive,
728
- sharedDcmtSearchResults,
729
592
  showBackButton,
730
593
  isMobile,
731
594
  currentMetadataValues,
732
- sharedDcmtFile,
733
- onRefreshSearchAsync,
595
+ onRefreshSearchAsyncDatagrid,
734
596
  handleNavigateToWGs,
735
597
  handleNavigateToDossiers,
736
598
  editPdfForm,
737
599
  showNoDcmtFoundMessage
738
600
  ]);
739
- const tmBlog = useMemo(() => _jsx(TMDcmtBlog, { tid: focusedItem?.TID, did: focusedItem?.DID, fetchBlogDataTrigger: refreshBlogTrigger, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), [focusedItem, allTasks, refreshBlogTrigger, handleNavigateToWGs, handleNavigateToDossiers]);
601
+ const tmBlog = useMemo(() => _jsx(TMDcmtBlog, { tid: focusedItem?.TID, did: focusedItem?.DID, fetchBlogDataTrigger: refreshBlogTrigger, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), [focusedItem, allTasks, refreshBlogTrigger, handleNavigateToWGs, handleNavigateToDossiers, onRefreshBlogDatagrid]);
740
602
  const tmSysMetadata = useMemo(() => _jsx(TMMetadataValues, { layoutMode: LayoutModes.Update, openChooserBySingleClick: true, TID: focusedItem?.TID, isReadOnly: true, deviceType: deviceType, metadataValues: currentMetadataValues.filter(o => (o.mid != undefined && o.mid <= 100)), metadataValuesOrig: currentMetadataValues.filter(o => (o.mid != undefined && o.mid <= 100)), validationItems: [] }), [focusedItem, currentMetadataValues, deviceType]);
741
- const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { currentDcmt: currentDcmt }, refreshPreviewTrigger), [currentDcmt, refreshPreviewTrigger]);
603
+ const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { refreshPreviewTrigger: refreshPreviewTrigger, currentDcmt: currentDcmt }), [currentDcmt, refreshPreviewTrigger]);
742
604
  // Auto-fetch indexing info when drawer is open and focusedItem changes
743
605
  useEffect(() => {
744
606
  if (!focusedItem || !showIndexingInfo)
@@ -865,32 +727,30 @@ const TMSearchResult = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, a
865
727
  }, children: _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showCicoWaitPanel, showWaitPanelPrimary: showCicoPrimaryProgress, waitPanelTitle: cicoWaitPanelTitle, waitPanelTextPrimary: cicoPrimaryProgressText, waitPanelValuePrimary: cicoPrimaryProgressValue, waitPanelMaxValuePrimary: cicoPrimaryProgressMax, isCancelable: true, abortController: abortControllerLocal, children: (groupId && groupId.length > 0) ?
866
728
  _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showSearchResultSidebar })
867
729
  :
868
- _jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmSearchResult', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showSearchResultSidebar }) }) }) }) }), _jsx(StyledMultiViewPanel, { "$isVisible": isOpenDetails, children: isOpenDetails && _jsx(TMMasterDetailDcmts, { deviceType: deviceType, isForMaster: false, inputDcmts: getSelectionDcmtInfo(), allowNavigation: focusedItem && selectedItems.length <= 0, canNext: canNavigateHandler('next'), canPrev: canNavigateHandler('prev'), onNext: () => onNavigateHandler('next'), onPrev: () => onNavigateHandler('prev'), onBack: () => setIsOpenDetails(false), allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }), _jsxs(StyledMultiViewPanel, { "$isVisible": isOpenMaster, children: [isOpenMaster && _jsx(TMMasterDetailDcmts, { deviceType: deviceType, inputDcmts: getSelectionDcmtInfo(), isForMaster: true, allowNavigation: focusedItem && selectedItems.length <= 0, canNext: canNavigateHandler('next'), canPrev: canNavigateHandler('prev'), onNext: () => onNavigateHandler('next'), onPrev: () => onNavigateHandler('prev'), onBack: () => setIsOpenMaster(false), appendMasterDcmts: handleAddItem, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), secondaryMasterDcmts.length > 0 && secondaryMasterDcmts.map((dcmt, index) => {
869
- return (_jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMMasterDetailDcmts, { deviceType: deviceType, inputDcmts: [dcmt], isForMaster: true, allowNavigation: false, onBack: () => handleRemoveItem(dcmt.TID, dcmt.DID), appendMasterDcmts: handleAddItem, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }, `${index}-${dcmt.DID}`));
870
- })] }), _jsx(StyledMultiViewPanel, { "$isVisible": isOpenDcmtForm, children: isOpenDcmtForm && focusedItem?.TID !== undefined && focusedItem?.DID !== undefined && _jsx(TMDcmtForm, { isModal: openDcmtFormAsModal || (dcmtFormLayoutMode === LayoutModes.Ark && focusedItem?.DID), titleModal: fromDTD?.name ?? '', TID: focusedItem.TID, DID: focusedItem.DID, allowButtonsRefs: true, layoutMode: dcmtFormLayoutMode, count: visibleItems.length, itemIndex: visibleItems.findIndex(o => o.rowIndex === focusedItem?.rowIndex) + 1, canNext: canNavigateHandler('next'), canPrev: canNavigateHandler('prev'), onNext: () => onNavigateHandler('next'), onPrev: () => onNavigateHandler('prev'), onClose: () => { setIsOpenDcmtForm(false); }, onWFOperationCompleted: onWFOperationCompleted, onTaskCreateRequest: onTaskCreateRequest, onSavedAsyncCallback: handleSavedAsyncCallback, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onReferenceClick: onReferenceClick, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, focusedItem?.TID, focusedItem?.DID), showDcmtFormSidebar: showDcmtFormSidebar }) }), isOpenArchiveRelationForm && _jsx(TMDcmtForm, { isModal: true, titleModal: SDKUI_Localizator.Archive + ' - ' + (archiveType === 'detail' ? SDKUI_Localizator.DcmtsDetail : SDKUI_Localizator.DcmtsMaster), TID: archiveRelatedDcmtFormTID, layoutMode: LayoutModes.Ark, inputMids: archiveRelatedDcmtFormMids, showBackButton: false, allowButtonsRefs: false, onClose: () => {
871
- setIsOpenArchiveRelationForm(false);
872
- setArchiveType(undefined);
873
- setArchiveRelatedDcmtFormTID(undefined);
874
- setArchiveRelatedDcmtFormMids([]);
875
- }, onSavedAsyncCallback: async (tid, did, metadataResult) => {
876
- setIsOpenArchiveRelationForm(false);
877
- setArchiveType(undefined);
878
- setArchiveRelatedDcmtFormTID(undefined);
879
- setArchiveRelatedDcmtFormMids([]);
880
- await onRefreshSearchAsync?.();
881
- }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, showDcmtFormSidebar: showDcmtFormSidebar }), (showHistory && fromDTD && getSelectedDcmtsOrFocused(selectedItems, focusedItem).length > 0) && _jsx(TMViewHistoryDcmt, { fromDTD: fromDTD, deviceType: deviceType, inputDcmt: getSelectedDcmtsOrFocused(selectedItems, focusedItem)[0], onClose: hideHistoryCallback, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), (commentFormState.show && getSelectedDcmtsOrFocused(selectedItems, focusedItem).length > 0) && _jsx(TMBlogCommentForm, { context: { engine: 'SearchEngine', object: { tid: getSelectedDcmtsOrFocused(selectedItems, focusedItem)[0].TID, did: getSelectedDcmtsOrFocused(selectedItems, focusedItem)[0].DID } }, onClose: hideCommentFormCallback, refreshCallback: triggerBlogRefresh, participants: [], showAttachmentsSection: true, allArchivedDocumentsFileItems: convertSearchResultDescriptorToFileItems(currentSearchResults ?? []), isCommentRequired: commentFormState.isRequired, removeAndEditAttachment: commentFormState.removeAndEditAttachment, selectedAttachmentDid: [Number(getSelectedDcmtsOrFocused(selectedItems, focusedItem)[0].DID)] })] }));
730
+ _jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmSearchResult', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showSearchResultSidebar }) }) }) }) }), renderDcmtOperations] }));
882
731
  };
883
732
  export default TMSearchResult;
884
- const TMSearchResultGrid = ({ openInOffice, fromDTD, allUsers, inputFocusedItem, showSearch, allowMultipleSelection = true, showExportForm = false, onCloseExportForm, onFocusedItemChanged, onDownloadDcmtsAsync, onVisibleItemChanged, inputSelectedItems = [], lastUpdateSearchTime, searchResult, floatingMenuItems, onSelectionChanged, onDblClick }) => {
733
+ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, inputFocusedItem, allowMultipleSelection = true, showExportForm = false, onFocusedItemChanged, onDownloadDcmtsAsync, onVisibleItemChanged, inputSelectedItems = [], lastUpdateSearchTime, searchResult, onSelectionChanged, onDblClick, showSearchTMDatagrid, updateDataColumnsFromDataGrid, updateDataSourceFromDataGrid, updateSelectedRowKeysFromDataGrid }) => {
885
734
  const [dataSource, setDataSource] = useState();
886
735
  const [columns, setColumns] = useState([]);
887
- // State to store selected row keys
888
736
  const [selectedRowKeys, setSelectedRowKeys] = useState([]);
889
737
  const [focusedItem, setFocusedItem] = useState();
890
738
  const [visibleItems, setVisibleItems] = useState([]);
891
739
  const [pageSize, setPageSize] = useState(SDKUI_Globals.userSettings.searchSettings?.pageSize ?? TMDataGridPageSize.Large);
892
740
  const [isDataGridReady, setIsDataGridReady] = useState(false);
893
741
  const dataGridRef = useRef(null);
742
+ // Sincronizza selectedRowKeys con il componente padre ad ogni modifica
743
+ useEffect(() => {
744
+ updateSelectedRowKeysFromDataGrid(selectedRowKeys);
745
+ }, [selectedRowKeys]);
746
+ // Sincronizza columns con il componente padre ad ogni modifica
747
+ useEffect(() => {
748
+ updateDataColumnsFromDataGrid(columns);
749
+ }, [columns]);
750
+ // Sincronizza dataSource con il componente padre ad ogni modifica
751
+ useEffect(() => {
752
+ updateDataSourceFromDataGrid(dataSource ?? []);
753
+ }, [dataSource]);
894
754
  const { loadDataListsAsync, renderDataListCell, dataListsCache } = useDataListItem();
895
755
  const { loadUsersAsync, renderUserIdViewer, usersCache } = useDataUserIdItem();
896
756
  useEffect(() => {
@@ -927,7 +787,8 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, allUsers, inputFocusedItem,
927
787
  const currentDataSource = dataSource ?? [];
928
788
  setTimeout(() => {
929
789
  // Remove the selected item from the data source by filtering it out.
930
- setDataSource(currentDataSource.filter((data) => data.rowIndex !== current.rowIndex));
790
+ const updatedDataSource = currentDataSource.filter((data) => data.rowIndex !== current.rowIndex);
791
+ setDataSource(updatedDataSource);
931
792
  // Clear any selection, focused item, and update callbacks.
932
793
  onSelectionChanged?.([]);
933
794
  setSelectedRowKeys([]);
@@ -954,7 +815,8 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, allUsers, inputFocusedItem,
954
815
  const currentDataSource = dataSource ?? [];
955
816
  setTimeout(() => {
956
817
  // Remove all selected items from the data source.
957
- setDataSource(currentDataSource.filter((data) => !dcmts.some((d) => d.rowIndex === data.rowIndex)));
818
+ const updatedDataSource = currentDataSource.filter((data) => !dcmts.some((d) => d.rowIndex === data.rowIndex));
819
+ setDataSource(updatedDataSource);
958
820
  // Clear selections and focus after deletion.
959
821
  onSelectionChanged?.([]);
960
822
  setSelectedRowKeys([]);
@@ -1250,10 +1112,11 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, allUsers, inputFocusedItem,
1250
1112
  if (setVisibleItems === undefined)
1251
1113
  return;
1252
1114
  const visibleRows = e.component.getVisibleRows();
1253
- setVisibleItems(visibleRows.map((row) => { return row.data; }));
1115
+ const visibleData = visibleRows.map((row) => row.data);
1116
+ setVisibleItems(visibleData);
1254
1117
  }, []);
1255
1118
  useEffect(() => { onVisibleItemChanged?.(visibleItems); }, [visibleItems]);
1256
- return _jsxs("div", { style: { width: "100%", height: "100%" }, children: [!isDataGridReady && (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', gap: '10px' }, children: [_jsx(LoadIndicator, { height: 60, width: 60 }), _jsx("div", { children: SDKUI_Localizator.Loading })] })), isDataGridReady && _jsx(TMDataGrid, { ref: dataGridRef, id: "tm-search-result", keyExpr: "rowIndex", dataColumns: dataColumns, dataSource: dataSource, repaintChangesOnly: true, selectedRowKeys: selectedRowKeys, focusedRowKey: Number(focusedItem?.rowIndex ?? 0), showSearchPanel: showSearch, showFilterPanel: true, sorting: { mode: "multiple" }, selection: { mode: allowMultipleSelection ? 'multiple' : 'single' }, pageSize: pageSize, onSelectionChanged: handleSelectionChange, onFocusedRowChanged: handleFocusedRowChange, onRowDblClick: onRowDblClick, onContentReady: onContentReady, showHeaderColumnChooser: true, onKeyDown: onKeyDown, customContextMenuItems: floatingMenuItems, counterConfig: { show: true } }), (showExportForm && searchResult && onCloseExportForm) && _jsx(TMDataGridExportForm, { dataColumns: dataColumns, dataSource: dataSource, selectedRowKeys: selectedRowKeys, onCloseExportForm: onCloseExportForm, searchResult: searchResult })] });
1119
+ return _jsxs("div", { style: { width: "100%", height: "100%" }, children: [!isDataGridReady && (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', gap: '10px' }, children: [_jsx(LoadIndicator, { height: 60, width: 60 }), _jsx("div", { children: SDKUI_Localizator.Loading })] })), isDataGridReady && _jsx(TMDataGrid, { ref: dataGridRef, id: "tm-search-result", keyExpr: "rowIndex", dataColumns: dataColumns, dataSource: dataSource, repaintChangesOnly: true, selectedRowKeys: selectedRowKeys, focusedRowKey: Number(focusedItem?.rowIndex ?? 0), showSearchPanel: showSearchTMDatagrid, showFilterPanel: true, sorting: { mode: "multiple" }, selection: { mode: allowMultipleSelection ? 'multiple' : 'single' }, pageSize: pageSize, onSelectionChanged: handleSelectionChange, onFocusedRowChanged: handleFocusedRowChange, onRowDblClick: onRowDblClick, onContentReady: onContentReady, showHeaderColumnChooser: true, onKeyDown: onKeyDown, customContextMenuItems: operationItems, counterConfig: { show: true } })] });
1257
1120
  };
1258
1121
  //#region TMSearchResultSelector
1259
1122
  const StyledItemTemplate = styled.div `
@@ -1366,7 +1229,7 @@ const TMSearchResultSelector = ({ searchResults = [], disableAccordionIfSingleCa
1366
1229
  renderItem: (result, isSelected) => (_jsxs("div", { style: { width: '100%', padding: '5px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }, children: [_jsx(TMTidViewer, { tid: result.fromTID, did: Number(result.dtdResult?.rows?.[0]?.[1]), showIcon: true }), _jsx("div", { style: { padding: 3, display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: 'white', color: 'gray', borderRadius: 3 }, children: result.dcmtsReturned })] })),
1367
1230
  itemHeight: 40
1368
1231
  })), [sortedCategories, groupedResults, searchResults]);
1369
- const renderCategoryItems = (category) => (_jsx("div", { style: { padding: '5px' }, children: groupedResults[category].map((result, index) => (_jsx(MemoizedStyledItemTemplate, { "$isSelected": selectedResult === result, onClick: () => handleSelect(result), children: renderItemTemplate(result) }, index))) }));
1232
+ const renderCategoryItems = (category) => (_jsx("div", { style: { padding: '5px', height: '100%', overflow: 'auto' }, children: groupedResults[category].map((result, index) => (_jsx(MemoizedStyledItemTemplate, { "$isSelected": selectedResult === result, onClick: () => handleSelect(result), children: renderItemTemplate(result) }, index))) }));
1370
1233
  if (disableAccordionIfSingleCategory && sortedCategories.length === 1) {
1371
1234
  const category = sortedCategories[0];
1372
1235
  return renderCategoryItems(category);
@@ -1374,11 +1237,11 @@ const TMSearchResultSelector = ({ searchResults = [], disableAccordionIfSingleCa
1374
1237
  return (_jsx(TMAccordionNew, { groups: accordionGroups, selectedItem: selectedResult, onSelectedItemChange: (result) => handleSelect(result) }));
1375
1238
  };
1376
1239
  //#endregion TMSearchResultSelector
1377
- const TMDcmtPreviewWrapper = ({ currentDcmt, isVisible }) => {
1240
+ const TMDcmtPreviewWrapper = ({ refreshPreviewTrigger, currentDcmt, isVisible }) => {
1378
1241
  const { setPanelVisibilityById, toggleMaximize, isResizingActive, countVisibleLeafPanels } = useTMPanelManagerContext();
1379
1242
  const deviceType = useDeviceType();
1380
1243
  const isMobile = deviceType === DeviceType.MOBILE;
1381
- return (_jsx(TMDcmtPreview, { onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("tmDcmtPreview") : undefined, dcmtData: currentDcmt, isResizingActive: isResizingActive, isVisible: isVisible }));
1244
+ return (_jsx(TMDcmtPreview, { dcmtData: currentDcmt, onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("tmDcmtPreview") : undefined, isResizingActive: isResizingActive, isVisible: isVisible }, refreshPreviewTrigger));
1382
1245
  };
1383
1246
  // Styled Components
1384
1247
  const StyledPlaceholder = styled.div `