@topconsultnpm/sdkui-react-beta 6.12.37 → 6.12.39

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 (61) hide show
  1. package/lib/components/base/Styled.d.ts +12 -0
  2. package/lib/components/base/Styled.js +49 -3
  3. package/lib/components/base/TMFloatingToolbar.d.ts +9 -0
  4. package/lib/components/base/TMFloatingToolbar.js +99 -0
  5. package/lib/components/base/TMRightSidebar.d.ts +0 -4
  6. package/lib/components/base/TMRightSidebar.js +2 -10
  7. package/lib/components/base/TMShowAllOrMaxItemsButton.d.ts +8 -0
  8. package/lib/components/base/TMShowAllOrMaxItemsButton.js +14 -0
  9. package/lib/components/base/TMTreeView.d.ts +27 -0
  10. package/lib/components/base/TMTreeView.js +199 -0
  11. package/lib/components/grids/TMBlogs.d.ts +84 -0
  12. package/lib/components/grids/TMBlogs.js +566 -0
  13. package/lib/components/grids/TMBlogsUtils.d.ts +83 -0
  14. package/lib/components/grids/TMBlogsUtils.js +258 -0
  15. package/lib/components/index.d.ts +2 -0
  16. package/lib/components/index.js +2 -0
  17. package/lib/components/query/TMBatchUpdateForm.d.ts +12 -0
  18. package/lib/components/query/TMBatchUpdateForm.js +149 -0
  19. package/lib/components/query/TMDcmtBlog.d.ts +7 -0
  20. package/lib/components/query/TMDcmtBlog.js +34 -0
  21. package/lib/components/query/TMDcmtForm.d.ts +32 -0
  22. package/lib/components/query/TMDcmtForm.js +544 -0
  23. package/lib/components/query/TMDcmtIcon.d.ts +10 -0
  24. package/lib/components/query/TMDcmtIcon.js +52 -0
  25. package/lib/components/query/TMDcmtPreview.d.ts +26 -0
  26. package/lib/components/query/TMDcmtPreview.js +200 -0
  27. package/lib/components/query/TMFileUploader.d.ts +11 -0
  28. package/lib/components/query/TMFileUploader.js +101 -0
  29. package/lib/components/query/TMMasterDetailDcmts.d.ts +23 -0
  30. package/lib/components/query/TMMasterDetailDcmts.js +475 -0
  31. package/lib/components/query/TMQueryEditor.js +2 -2
  32. package/lib/components/query/TMQueryResultForm.d.ts +1 -7
  33. package/lib/components/query/TMQueryResultForm.js +1 -9
  34. package/lib/components/query/TMWorkflowPopup.d.ts +29 -0
  35. package/lib/components/query/TMWorkflowPopup.js +131 -0
  36. package/lib/components/search/TMSearchResult.d.ts +31 -0
  37. package/lib/components/search/TMSearchResult.js +727 -0
  38. package/lib/components/search/TMSearchResultsMenuItems.d.ts +6 -0
  39. package/lib/components/search/TMSearchResultsMenuItems.js +376 -0
  40. package/lib/helper/Enum_Localizator.d.ts +2 -1
  41. package/lib/helper/Enum_Localizator.js +20 -1
  42. package/lib/helper/SDKUI_Localizator.d.ts +24 -0
  43. package/lib/helper/SDKUI_Localizator.js +240 -0
  44. package/lib/helper/dcmtsHelper.d.ts +4 -0
  45. package/lib/helper/dcmtsHelper.js +15 -0
  46. package/lib/helper/helpers.d.ts +2 -1
  47. package/lib/helper/helpers.js +74 -1
  48. package/lib/helper/queryHelper.d.ts +7 -1
  49. package/lib/helper/queryHelper.js +105 -1
  50. package/lib/hooks/useDcmtOperations.d.ts +24 -0
  51. package/lib/hooks/useDcmtOperations.js +387 -0
  52. package/lib/hooks/useInputDialog.d.ts +5 -0
  53. package/lib/hooks/useInputDialog.js +73 -0
  54. package/lib/hooks/usePreventFileDrop.d.ts +3 -0
  55. package/lib/hooks/usePreventFileDrop.js +37 -0
  56. package/lib/index.d.ts +0 -1
  57. package/lib/index.js +0 -1
  58. package/lib/services/platform_services.d.ts +1 -1
  59. package/lib/ts/types.d.ts +54 -1
  60. package/lib/ts/types.js +34 -0
  61. package/package.json +1 -1
@@ -0,0 +1,727 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
3
+ import { SDK_Globals, DataColumnTypes, MetadataDataDomains, DataListViewModes, MetadataFormats, LayoutModes, RecentCategories, TemplateTIDs, DcmtTypeListCacheService, AccessLevels, SystemMIDsAsNumber, ArchiveConstraints } from '@topconsultnpm/sdk-ts-beta';
4
+ import styled from 'styled-components';
5
+ import { commandsMenuItems, getSelectedDcmtsOrFocused } from './TMSearchResultsMenuItems';
6
+ import { ContextMenu } from 'devextreme-react';
7
+ import { genUniqueId, IconShow, IconBoard, IconDcmtTypeSys, IconDetailDcmts, SDKUI_Localizator, IconTag, IconDetails, IconCommand, IconDelete, IconRefresh, IconMenuVertical, IconDownload, IconSignature, IconSave, deepCompare, getDataColumnName, searchResultDescriptorToSimpleArray, SDKUI_Globals, IconArchive, IconActivityLog, IconStar, IconFreeSearch, IconChevronDown, searchResultToMetadataValues } from '../../helper';
8
+ import { useDcmtOperations } from '../../hooks/useDcmtOperations';
9
+ import { useInputCvtFormatDialog } from '../../hooks/useInputDialog';
10
+ import { DcmtOperationTypes, FormModes, SearchResultContext } from '../../ts';
11
+ import { TMColors } from '../../utils/theme';
12
+ import { StyledModalContainer, StyledBadge, StyledMultiViewPanel } from '../base/Styled';
13
+ import ShowAlert from '../base/TMAlert';
14
+ import TMButton from '../base/TMButton';
15
+ import TMDataGrid, { TMDataGridPageSize } from '../base/TMDataGrid';
16
+ import { useDeviceType, DeviceType } from '../base/TMDeviceProvider';
17
+ import { TMSplitterLayout, TMLayoutItem } from '../base/TMLayout';
18
+ import { CustomListViewHeader } from '../base/TMListView';
19
+ import { TMMessageBoxManager, ButtonNames } from '../base/TMPopUp';
20
+ import TMToolbarCard from '../base/TMToolbarCard';
21
+ import TMTooltip from '../base/TMTooltip';
22
+ import { TMLayoutWaitingContainer } from '../base/TMWaitPanel';
23
+ import { TMUserIdViewer } from '../choosers/TMUserChooser';
24
+ import TMMetadataValues from '../editors/TMMetadataValues';
25
+ import { TMSaveFormButtonPrevious, TMSaveFormButtonNext } from '../forms/TMSaveForm';
26
+ import TMDataListItemViewer from '../viewers/TMDataListItemViewer';
27
+ import TMTidViewer from '../viewers/TMTidViewer';
28
+ import TMDcmtIcon from '../query/TMDcmtIcon';
29
+ import { hasDetailRelations, hasMasterRelations } from '../../helper/dcmtsHelper';
30
+ import TMDcmtPreview, { TMNothingToShow } from '../query/TMDcmtPreview';
31
+ import TMFloatingToolbar from '../base/TMFloatingToolbar';
32
+ import { WorkFlowApproveRejectPopUp, WorkFlowOperationButtons, WorkFlowReAssignPopUp } from '../query/TMWorkflowPopup';
33
+ import TMMasterDetailDcmts from '../query/TMMasterDetailDcmts';
34
+ import TMBatchUpdateForm from '../query/TMBatchUpdateForm';
35
+ import TMDcmtForm from '../query/TMDcmtForm';
36
+ import TMDcmtBlog from '../query/TMDcmtBlog';
37
+ //#endregion region Interfaces, Types and Enums
38
+ //#region Styled Components
39
+ const StyledContainer = styled.div ` overflow: hidden; background-color: #ffffff; width: calc(100%); height: calc(100%); display: flex; gap: 10px; `;
40
+ //#endregion Styled Components
41
+ //#region Internal Components
42
+ const CommandsContextMenu = React.memo(({ target, menuItems, allowPin }) => {
43
+ return (_jsx(ContextMenu, { showEvent: 'click', dataSource: menuItems, target: `${target}` }));
44
+ });
45
+ //#endregion Internal Components
46
+ //#region Helper Methods
47
+ const orderByName = (array) => {
48
+ let arr = [...array];
49
+ return arr.sort((a, b) => { if (a['fromName'] < b['fromName']) {
50
+ return -1;
51
+ } if (a['fromName'] > b['fromName']) {
52
+ return 1;
53
+ } return 0; });
54
+ };
55
+ //#endregion Helper Methods
56
+ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisible = true, searchResults = [], showSearchResultSidebar = true, showSelector = false, onClosePreview, showDcmtForm = false, showBoard = false, showPreview = false, title, showSysMetadata = false, isClosable = false, allowFloatingBar = true, showToolbarHeader = true, onRefreshAfterAddDcmtToFavs, onRefreshSearchAsync, onSelectedTIDChanged, onUpdate, onClose, onTaskCreateRequest }) => {
57
+ const [id, setID] = useState('');
58
+ const [showApprovePopup, setShowApprovePopup] = useState(false);
59
+ const [showRejectPopup, setShowRejectPopup] = useState(false);
60
+ const [showReAssignPopup, setShowReAssignPopup] = useState(false);
61
+ const [splitterSize, setSplitterSize] = useState(['100%', '0']);
62
+ const [showFloatingBar, setShowFloatingBar] = useState(true);
63
+ const [lastUpdateSearchTime, setLastUpdateSearchTime] = useState();
64
+ const [fromDTD, setFromDTD] = useState();
65
+ const [selectedSearchResult, setSelectedSearchResult] = useState();
66
+ const [isOpenDetails, setIsOpenDetails] = useState(false);
67
+ const [isOpenMaster, setIsOpenMaster] = useState(false);
68
+ const [secondaryMasterDcmts, setSecondaryMasterDcmts] = useState([]);
69
+ const [isOpenDcmtForm, setIsOpenDcmtForm] = useState(false);
70
+ const [isOpenPreview, setIsOpenPreview] = useState(false);
71
+ const [isOpenSysMetadata, setIsOpenSysMetadata] = useState(false);
72
+ const [isOpenBoard, setIsOpenBoard] = useState(false);
73
+ const [isOpenDistinctValues, setIsOpenDistinctValues] = useState(false);
74
+ const [isOpenTags, setIsOpenTags] = useState(false);
75
+ const [currentTIDHasDetailRelations, setCurrentTIDHasDetailRelations] = useState();
76
+ const [currentTIDHasMasterRelations, setCurrentTIDHasMasterRelations] = useState();
77
+ const [isOpenBatchUpdate, setIsOpenBatchUpdate] = useState(false);
78
+ const [visibleItems, setVisibleItems] = useState([]);
79
+ const [focusedItem, setFocusedItem] = useState();
80
+ const [selectedItems, setSelectedItems] = useState([]);
81
+ const [currentDcmt, setCurrentDcmt] = useState();
82
+ const [currentMetadataValues, setCurrentMetadataValues] = useState([]);
83
+ const [dcmtFormLayoutMode, setDcmtFormLayoutMode] = useState(LayoutModes.Update);
84
+ // const [allowMultipleSelection, setAllowMultipleSelection] = useState<boolean>(false);
85
+ const [isModifiedBatchUpdate, setIsModifiedBatchUpdate] = useState(false);
86
+ const [confirmFormat, ConfirmFormatDialog] = useInputCvtFormatDialog();
87
+ const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, runOperationAsync } = useDcmtOperations();
88
+ const deviceType = useDeviceType();
89
+ let disable = getSelectedDcmtsOrFocused(selectedItems, focusedItem).length === 0;
90
+ let dcmtsReturned = (searchResults?.length > 1 ? selectedSearchResult?.dcmtsReturned : searchResults[0]?.dcmtsReturned ?? 0);
91
+ let dcmtsFound = (searchResults?.length > 1 ? selectedSearchResult?.dcmtsFound : searchResults[0]?.dcmtsFound ?? 0);
92
+ useEffect(() => { setID(genUniqueId()); }, []);
93
+ useEffect(() => {
94
+ setSelectedItems([]);
95
+ setFocusedItem(undefined);
96
+ setIsOpenBatchUpdate(false);
97
+ if (searchResults.length <= 0)
98
+ return;
99
+ if (searchResults.length === 1) {
100
+ setSelectedSearchResult(searchResults[0]);
101
+ return;
102
+ }
103
+ setSelectedSearchResult(orderByName(searchResults)[0]);
104
+ }, [searchResults]);
105
+ useEffect(() => {
106
+ setFocusedItem(undefined);
107
+ setSelectedItems([]);
108
+ DcmtTypeListCacheService.GetAsync(selectedSearchResult?.fromTID).then((dtd) => {
109
+ setFromDTD(dtd);
110
+ });
111
+ hasDetailRelations(selectedSearchResult?.fromTID).then((value) => setCurrentTIDHasDetailRelations(value));
112
+ hasMasterRelations(selectedSearchResult?.fromTID).then((value) => setCurrentTIDHasMasterRelations(value));
113
+ }, [selectedSearchResult]);
114
+ useEffect(() => {
115
+ if (!focusedItem)
116
+ return;
117
+ if (!fromDTD)
118
+ return;
119
+ let dtd = searchResults.length > 1 ? searchResults.find(res => res.fromTID == focusedItem?.TID)?.dtdResult : searchResults[0]?.dtdResult;
120
+ if (!dtd)
121
+ return;
122
+ let rows = dtd.rows ? dtd.rows[focusedItem.rowIndex] : [];
123
+ let mids = searchResults.length > 1 ? searchResults.find(res => res.fromTID == focusedItem?.TID)?.selectMIDs : searchResults[0]?.selectMIDs;
124
+ let metadataList = searchResultToMetadataValues(focusedItem?.TID, dtd, rows, mids, fromDTD?.metadata, LayoutModes.Update);
125
+ setCurrentMetadataValues(metadataList);
126
+ }, [focusedItem, searchResults, fromDTD]);
127
+ useEffect(() => {
128
+ setCurrentDcmt({
129
+ tid: currentMetadataValues.find(o => o.mid == SystemMIDsAsNumber.TID)?.value,
130
+ did: currentMetadataValues.find(o => o.mid == SystemMIDsAsNumber.DID)?.value,
131
+ fileCount: currentMetadataValues.find(o => o.mid == SystemMIDsAsNumber.FileCount)?.value,
132
+ fileSize: currentMetadataValues.find(o => o.mid == SystemMIDsAsNumber.FileSize)?.value,
133
+ fileExt: currentMetadataValues.find(o => o.mid == SystemMIDsAsNumber.FileExt)?.value
134
+ });
135
+ }, [currentMetadataValues]);
136
+ useEffect(() => { setIsOpenBoard(showBoard); }, [showBoard]);
137
+ useEffect(() => { setIsOpenSysMetadata(showSysMetadata); }, [showSysMetadata]);
138
+ useEffect(() => { setIsOpenDcmtForm(showDcmtForm); }, [showDcmtForm]);
139
+ useEffect(() => { setIsOpenPreview(showPreview); }, [showPreview]);
140
+ const sideBarItems = [
141
+ { icon: _jsx(IconShow, {}), id: 'Preview', visibleName: 'Anteprima', isActive: isOpenPreview, onClick: () => { setIsOpenPreview(!isOpenPreview); }, disabled: isOpenBatchUpdate || fromDTD?.archiveConstraint === ArchiveConstraints.OnlyMetadata },
142
+ { icon: _jsx(IconBoard, {}), id: 'Board', visibleName: 'Bacheca', beginGroup: true, isActive: isOpenBoard, disabled: isOpenBatchUpdate, onClick: () => { closeMiddlePanel(); setIsOpenBoard(!isOpenBoard); } },
143
+ { icon: _jsx(IconDcmtTypeSys, {}), id: 'SystemMetadata', visibleName: 'Metadati di sistema', isActive: isOpenSysMetadata, disabled: isOpenBatchUpdate, onClick: () => { closeMiddlePanel(); setIsOpenSysMetadata(!isOpenSysMetadata); } },
144
+ { icon: _jsx(IconDetailDcmts, { fontSize: 20, transform: 'scale(-1, 1)' }), id: 'Master', beginGroup: true, visible: currentTIDHasMasterRelations, visibleName: SDKUI_Localizator.DcmtsMaster, disabled: isOpenBatchUpdate || !focusedItem?.DID, isActive: isOpenMaster, onClick: () => { setIsOpenMaster(!isOpenMaster); } },
145
+ { icon: _jsx(IconDetailDcmts, { fontSize: 20 }), id: 'Details', visibleName: SDKUI_Localizator.DcmtsDetail, disabled: isOpenBatchUpdate || (!focusedItem?.DID && selectedItems.length <= 0), isActive: isOpenDetails, visible: currentTIDHasDetailRelations, onClick: () => { setIsOpenDetails(!isOpenDetails); } },
146
+ // { icon: <IconBatchUpdate fontSize={18} />, id: 'BatchUpdate', visibleName: "Modifica multipla", disabled: selectedItems.length <= 0, isActive: isOpenBatchUpdate, onClick: () => { setIsOpenBatchUpdate(!isOpenBatchUpdate) } }
147
+ ];
148
+ const openFormHandler = (layoutMode) => { setIsOpenDcmtForm(true); setDcmtFormLayoutMode(layoutMode); };
149
+ const openTaskFormHandler = (value) => {
150
+ if (selectedItems.length > 1)
151
+ return;
152
+ const item = selectedItems.length === 1 ? selectedItems[0] : focusedItem;
153
+ if (item?.TID && item?.DID) {
154
+ const fetchData = async () => {
155
+ try {
156
+ const dtd = await DcmtTypeListCacheService.GetAsync(item.TID);
157
+ if (dtd) {
158
+ const name = `${dtd.name ?? '-'} (DID: ${item.DID})`;
159
+ onTaskCreateRequest?.({ tid: item.TID, did: item.DID, name });
160
+ }
161
+ }
162
+ catch (error) {
163
+ console.error("Error fetching data:", error);
164
+ }
165
+ };
166
+ fetchData();
167
+ }
168
+ };
169
+ const openDetailDcmtsFormHandler = (value) => { setIsOpenDetails(value); };
170
+ const openMasterDcmtsFormHandler = (value) => { setIsOpenMaster(value); };
171
+ const openBatchUpdateFormHandler = (value) => { setIsOpenBatchUpdate(value); };
172
+ const getTitleHeader = () => {
173
+ if (title)
174
+ return title;
175
+ let titleHeader = 'Ricerca per metadati';
176
+ switch (context) {
177
+ case SearchResultContext.METADATA_SEARCH:
178
+ titleHeader = `${searchResults?.length > 1 ? selectedSearchResult?.fromName : searchResults[0]?.fromName}`;
179
+ break;
180
+ case SearchResultContext.FAVORITES:
181
+ titleHeader = SDKUI_Localizator.Favorites;
182
+ break;
183
+ case SearchResultContext.RECENT:
184
+ titleHeader = SDKUI_Localizator.RecentDcmts;
185
+ break;
186
+ case SearchResultContext.WORKFLOW_APPROVE:
187
+ titleHeader = SDKUI_Localizator.WorkflowApproval;
188
+ break;
189
+ case SearchResultContext.FREE_SEARCH:
190
+ titleHeader = `Risultato della ricerca full text`;
191
+ break;
192
+ }
193
+ return titleHeader;
194
+ };
195
+ const allowBackButton = () => {
196
+ if (context === SearchResultContext.METADATA_SEARCH)
197
+ return true;
198
+ if (deviceType !== DeviceType.MOBILE)
199
+ return false;
200
+ return splitterSize[0] === '0';
201
+ };
202
+ const onBack = () => {
203
+ if (isOpenBatchUpdate && isModifiedBatchUpdate) {
204
+ TMMessageBoxManager.show({
205
+ title: SDKUI_Localizator.Cancel, message: SDKUI_Localizator.ConfirmOnCancel, buttons: [ButtonNames.YES, ButtonNames.NO],
206
+ onButtonClick: (e) => {
207
+ if (e !== ButtonNames.YES)
208
+ return;
209
+ setSplitterSize(['100%', '0']);
210
+ onClose?.();
211
+ }
212
+ });
213
+ }
214
+ else if (isOpenDcmtForm) {
215
+ setIsOpenDcmtForm(false);
216
+ }
217
+ else {
218
+ setSplitterSize(['100%', '0']);
219
+ onClose?.();
220
+ }
221
+ };
222
+ const onContextMenuPreparing = (e) => {
223
+ if (e === undefined)
224
+ return;
225
+ if (e.target === 'content') {
226
+ e.items = e.items || [];
227
+ const menuItems = commandsMenuItems(fromDTD, selectedItems, focusedItem, context, showFloatingBar, setShowFloatingBar, openFormHandler, downloadDcmtsAsync, runOperationAsync, onRefreshSearchAsync, refreshSelectionDataRowsAsync, onRefreshAfterAddDcmtToFavs, confirmFormat, openTaskFormHandler, openDetailDcmtsFormHandler, openMasterDcmtsFormHandler, openBatchUpdateFormHandler, true, true);
228
+ e.items.push(...menuItems);
229
+ }
230
+ };
231
+ const refreshDataGrid = async () => {
232
+ await onRefreshSearchAsync?.();
233
+ let index = selectedSearchResult?.dtdResult?.columns?.findIndex(col => col.caption === 'DID');
234
+ let selectedRows = [];
235
+ if (!index)
236
+ return;
237
+ for (let data of getSelectedDcmtsOrFocused(selectedItems, focusedItem)) {
238
+ selectedRows.push(selectedSearchResult?.dtdResult?.rows?.findIndex(row => row[index] === data.DID.toString()));
239
+ }
240
+ if (!selectedSearchResult?.dtdResult?.rows)
241
+ return;
242
+ let newRows = [];
243
+ for (let i = 0; i < selectedSearchResult.dtdResult.rows.length; i++) {
244
+ if (!selectedRows.includes(i))
245
+ newRows.push(selectedSearchResult.dtdResult.rows[i]);
246
+ }
247
+ let newSearchresult = structuredClone(selectedSearchResult);
248
+ let newDtd = structuredClone(selectedSearchResult.dtdResult);
249
+ newDtd.rows = newRows;
250
+ newSearchresult.dtdResult = newDtd;
251
+ setSelectedSearchResult(newSearchresult);
252
+ };
253
+ const removeDcmtFromFavsOrRecents = async () => {
254
+ switch (context) {
255
+ case SearchResultContext.FAVORITES:
256
+ await runOperationAsync(getSelectedDcmtsOrFocused(selectedItems, focusedItem), DcmtOperationTypes.RemoveFromFavs, refreshDataGrid);
257
+ break;
258
+ case SearchResultContext.RECENT:
259
+ {
260
+ let category = RecentCategories.None;
261
+ if (selectedSearchResult?.category === 'RecentArchive') {
262
+ category = RecentCategories.Archive;
263
+ }
264
+ else if (selectedSearchResult?.category === 'RecentView') {
265
+ category = RecentCategories.View;
266
+ }
267
+ await runOperationAsync(getSelectedDcmtsOrFocused(selectedItems, focusedItem, category), DcmtOperationTypes.RemoveFromRecents, refreshDataGrid);
268
+ break;
269
+ }
270
+ default: break;
271
+ }
272
+ };
273
+ const onSearchResultSelectionChanged = (e) => {
274
+ setSelectedSearchResult(e);
275
+ if (deviceType === DeviceType.MOBILE) {
276
+ setSplitterSize(['0', '100%']);
277
+ }
278
+ onSelectedTIDChanged?.(e.fromTID);
279
+ };
280
+ const refreshFocusedDataRowAsync = async (tid, did, refreshUI) => {
281
+ if (!tid || !did)
282
+ return;
283
+ let currentResult = searchResults.length > 1 ? selectedSearchResult : searchResults[0];
284
+ let currentResultColIndexTID = currentResult?.dtdResult?.columns?.findIndex(o => o.caption == "TID");
285
+ if (currentResultColIndexTID == undefined)
286
+ return;
287
+ let currentResultColIndexDID = currentResult?.dtdResult?.columns?.findIndex(o => o.caption == "DID");
288
+ if (currentResultColIndexDID == undefined)
289
+ return;
290
+ let newDcmt = await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(tid, did, true);
291
+ let newDcmtRow = newDcmt?.dtdResult?.rows?.[0] ?? [];
292
+ let currentDcmtRow = currentResult?.dtdResult?.rows?.filter((row) => row[currentResultColIndexTID] == tid?.toString() && row[currentResultColIndexDID] == did?.toString()) ?? [];
293
+ for (const row of currentDcmtRow) {
294
+ let mids = currentResult?.selectMIDs ?? [];
295
+ for (let i = 0; i < mids.length; i++) {
296
+ const mid = mids[i];
297
+ let newDcmtMidIndex = newDcmt?.selectMIDs?.findIndex(o => o == mid) ?? -1;
298
+ if (newDcmtMidIndex >= 0 && row[i] != newDcmtRow[newDcmtMidIndex]) {
299
+ row[i] = newDcmtRow[newDcmtMidIndex];
300
+ }
301
+ }
302
+ }
303
+ if (refreshUI)
304
+ setLastUpdateSearchTime(new Date(Date.now()));
305
+ };
306
+ const refreshSelectionDataRowsAsync = async () => {
307
+ let dcmts = getSelectedDcmtsOrFocused(selectedItems, focusedItem);
308
+ for (const dcmt of dcmts) {
309
+ await refreshFocusedDataRowAsync(dcmt.TID, dcmt.DID);
310
+ }
311
+ setLastUpdateSearchTime(new Date(Date.now()));
312
+ };
313
+ const isOpenMiddlePanel = () => isOpenSysMetadata || isOpenBoard || isOpenTags || isOpenDistinctValues;
314
+ const getSelectionDcmtInfo = () => { return getSelectedDcmtsOrFocused(selectedItems, focusedItem); };
315
+ const getPrimarySplitterStartLayout = () => {
316
+ let size = ['100%', '0'];
317
+ if (deviceType !== DeviceType.MOBILE) {
318
+ if (isOpenPreview || isOpenMiddlePanel() || isOpenBatchUpdate) {
319
+ size = ['50%', '50%'];
320
+ }
321
+ }
322
+ else {
323
+ size = (isOpenPreview || isOpenMiddlePanel() || isOpenBatchUpdate) ? ['0', '100%'] : ['100%', '0'];
324
+ }
325
+ return size;
326
+ };
327
+ const getSecondarySplitterStartLayout = () => {
328
+ if (isOpenPreview && !isOpenMiddlePanel()) {
329
+ return ['0', '100%'];
330
+ }
331
+ if (!isOpenPreview && isOpenMiddlePanel()) {
332
+ return ['100%', '0'];
333
+ }
334
+ return ['40%', '60%'];
335
+ };
336
+ const closeMiddlePanel = () => {
337
+ setIsOpenBoard(false);
338
+ setIsOpenSysMetadata(false);
339
+ setIsOpenTags(false);
340
+ setIsOpenDistinctValues(false);
341
+ };
342
+ const titleText = () => {
343
+ if (isOpenTags)
344
+ return 'Tags';
345
+ if (isOpenSysMetadata)
346
+ return 'Metadati di sistema';
347
+ if (isOpenBoard)
348
+ return 'Bacheca';
349
+ return '';
350
+ };
351
+ const canNavigateHandler = (dir) => {
352
+ if (!focusedItem)
353
+ return false;
354
+ let index = -1;
355
+ if (visibleItems) {
356
+ index = visibleItems.findIndex(item => item.rowIndex === focusedItem.rowIndex);
357
+ }
358
+ switch (dir) {
359
+ case 'next': if (visibleItems && index < visibleItems.length - 1) {
360
+ return true;
361
+ }
362
+ else {
363
+ return false;
364
+ }
365
+ default: if (visibleItems && index > 0) {
366
+ return true;
367
+ }
368
+ else {
369
+ return false;
370
+ }
371
+ }
372
+ };
373
+ const onNavigateHandler = (dir) => {
374
+ let index = -1;
375
+ if (visibleItems && focusedItem) {
376
+ index = visibleItems.findIndex(item => item.rowIndex === focusedItem.rowIndex);
377
+ }
378
+ switch (dir) {
379
+ case 'next':
380
+ setFocusedItem(visibleItems[index + 1]);
381
+ break;
382
+ default:
383
+ setFocusedItem(visibleItems[index - 1]);
384
+ break;
385
+ }
386
+ };
387
+ const middlePanelToolbar = _jsxs("div", { style: { width: 'max-content', display: 'flex', alignItems: 'center', gap: '10px' }, children: [_jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', isModified: false, iconColor: TMColors.default_background, formMode: FormModes.ReadOnly, canPrev: canNavigateHandler('prev'), onPrev: () => onNavigateHandler('prev') }), _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', isModified: false, iconColor: TMColors.default_background, formMode: FormModes.ReadOnly, canNext: canNavigateHandler('next'), onNext: () => onNavigateHandler('next') })] });
388
+ let notAvalableMsg = '';
389
+ let notAvalableIcon;
390
+ if (isOpenBoard) {
391
+ notAvalableMsg = 'Bacheca non disponibile.';
392
+ }
393
+ else if (isOpenTags) {
394
+ notAvalableMsg = 'Tags non disponibile.';
395
+ }
396
+ else if (isOpenDetails) {
397
+ notAvalableMsg = 'Documenti detail non disponibile.';
398
+ }
399
+ else if (isOpenMaster) {
400
+ notAvalableMsg = 'Documenti master non disponibile.';
401
+ }
402
+ else {
403
+ notAvalableMsg = 'Metadati di sistema non disponibile.';
404
+ }
405
+ if (isOpenBoard) {
406
+ notAvalableIcon = _jsx(IconBoard, { fontSize: 96 });
407
+ }
408
+ else if (isOpenTags) {
409
+ notAvalableIcon = _jsx(IconTag, { fontSize: 96 });
410
+ }
411
+ else if (isOpenDetails) {
412
+ notAvalableIcon = _jsx(IconDetails, { fontSize: 96 });
413
+ }
414
+ else if (isOpenMaster) {
415
+ notAvalableIcon = _jsx(IconCommand, { fontSize: 96 });
416
+ }
417
+ else {
418
+ notAvalableIcon = _jsx(IconDcmtTypeSys, { fontSize: 96 });
419
+ }
420
+ const handleAddItem = (tid, did) => {
421
+ let newItem = { TID: tid ?? 0, DID: did ?? 0 };
422
+ setSecondaryMasterDcmts((prevItems) => [...prevItems, newItem]);
423
+ };
424
+ const handleRemoveItem = (tid, did) => {
425
+ setSecondaryMasterDcmts((prevItems) => prevItems.filter(item => item.TID !== tid && item.DID !== did));
426
+ };
427
+ if (!searchResults || searchResults.length <= 0)
428
+ return _jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%' }, children: [_jsx(IconBoard, { fontSize: 96 }), _jsx("div", { style: { fontSize: "15px", marginTop: "10px" }, children: SDKUI_Localizator.NoDcmtFound })] });
429
+ return (_jsx(StyledMultiViewPanel, { "$isVisible": isVisible, children: _jsxs(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: [_jsxs(TMSplitterLayout, { separatorSize: 5, separatorColor: 'transparent', showSeparator: (isOpenPreview || isOpenMiddlePanel() || isOpenBatchUpdate) && deviceType !== DeviceType.MOBILE, start: getPrimarySplitterStartLayout(), min: deviceType !== DeviceType.MOBILE && isOpenDcmtForm ? ['150px', '0'] : ['0', '0'], direction: 'horizontal', children: [_jsx(TMLayoutItem, { children: _jsxs(TMToolbarCard, { toolbar: _jsxs(_Fragment, { children: [context !== SearchResultContext.METADATA_SEARCH && fromDTD?.templateTID === TemplateTIDs.WF_WIApprView && _jsx(WorkFlowOperationButtons, { deviceType: deviceType, onApprove: () => setShowApprovePopup(true), onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), approveDisable: disable, rejectDisable: disable, reassignDisable: disable, infoDisable: getSelectedDcmtsOrFocused(selectedItems, focusedItem).length !== 1 }), (dcmtsReturned != dcmtsFound) && _jsx("p", { style: { backgroundColor: `white`, color: TMColors.primaryColor, textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${dcmtsReturned}/${dcmtsFound} restituiti` }), (context === SearchResultContext.RECENT || context === SearchResultContext.FAVORITES) &&
430
+ _jsx("div", { style: { display: 'flex', alignItems: 'center', gap: '5px' }, children: _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconDelete, { color: 'white' }), caption: "Rimuovi da " + (context === SearchResultContext.RECENT ? '"Recenti"' : '"Preferiti"'), disabled: getSelectedDcmtsOrFocused(selectedItems, focusedItem).length <= 0, onClick: removeDcmtFromFavsOrRecents }) }), _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconRefresh, { color: 'white' }), caption: SDKUI_Localizator.Refresh, onClick: onRefreshSearchAsync }), _jsx(IconMenuVertical, { id: `commands-header-${id}`, color: 'white', cursor: 'pointer' }), _jsx(CommandsContextMenu, { target: `#commands-header-${id}`, menuItems: commandsMenuItems(fromDTD, selectedItems, focusedItem, context, showFloatingBar, setShowFloatingBar, openFormHandler, downloadDcmtsAsync, runOperationAsync, onRefreshSearchAsync, refreshSelectionDataRowsAsync, onRefreshAfterAddDcmtToFavs, confirmFormat, openTaskFormHandler, openDetailDcmtsFormHandler, openMasterDcmtsFormHandler, openBatchUpdateFormHandler, false, true) })] }), onBack: !isClosable && allowBackButton() ? onBack : undefined, onClose: isClosable && allowBackButton() ? onBack : undefined, items: showSearchResultSidebar ? sideBarItems : undefined, title: getTitleHeader(), showHeader: showToolbarHeader, children: [_jsxs(TMLayoutItem, { height: '100%', children: [_jsxs(TMSplitterLayout, { direction: 'horizontal', min: ['0', '0'], showSeparator: showSelector && deviceType !== DeviceType.MOBILE, start: showSelector ? deviceType !== DeviceType.MOBILE ? ['25%', '75%'] : splitterSize : ['0%', '100%'], children: [showSelector ?
431
+ _jsx(TMLayoutItem, { children: _jsx(TMSearchResultSelector, { searchResults: searchResults, onSelectionChanged: onSearchResultSelectionChanged }) })
432
+ :
433
+ _jsx(_Fragment, {}), _jsxs(TMLayoutItem, { children: [_jsx(TMSearchResultGrid
434
+ // allowMultipleSelection={allowMultipleSelection}
435
+ , {
436
+ // allowMultipleSelection={allowMultipleSelection}
437
+ inputFocusedItem: focusedItem, inputSelectedItems: selectedItems, searchResult: searchResults.length > 1 ? selectedSearchResult : searchResults[0], lastUpdateSearchTime: lastUpdateSearchTime, onDblClick: () => openFormHandler(LayoutModes.Update), onContextMenuPreparing: onContextMenuPreparing, onSelectionChanged: (items) => { setSelectedItems(items); }, onVisibleItemChanged: setVisibleItems, onFocusedItemChanged: setFocusedItem }), allowFloatingBar && showFloatingBar && deviceType !== DeviceType.MOBILE &&
438
+ _jsxs(TMFloatingToolbar, { backgroundColor: TMColors.primaryColor, initialLeft: '10px', initialTop: 'calc(100% - 75px)', children: [fromDTD?.perm?.canRetrieveFile === AccessLevels.Yes && _jsx(TMButton, { btnStyle: 'icon', caption: "Download file", disabled: fromDTD?.perm?.canRetrieveFile !== AccessLevels.Yes, icon: _jsx(IconDownload, { color: 'white' }), onClick: () => { downloadDcmtsAsync(getSelectedDcmtsOrFocused(selectedItems, focusedItem)); } }), _jsx(TMButton, { btnStyle: 'icon', caption: 'Firma e marca', icon: _jsx(IconSignature, { color: 'white' }), onClick: () => { ShowAlert({ message: "TODO Firma e marca ", mode: 'info', title: `${"TODO"}`, duration: 3000 }); } }), _jsx(TMButton, { btnStyle: 'icon', caption: 'Salva layout', icon: _jsx(IconSave, { color: 'white' }), onClick: () => { ShowAlert({ message: "TODO Salva visualizzazione ", mode: 'info', title: `${"TODO"}`, duration: 3000 }); } }), _jsx(IconMenuVertical, { id: `commands-floating-${id}`, color: 'white', cursor: 'pointer' }), _jsx(CommandsContextMenu, { target: `#commands-floating-${id}`, menuItems: commandsMenuItems(fromDTD, selectedItems, focusedItem, context, showFloatingBar, setShowFloatingBar, openFormHandler, downloadDcmtsAsync, runOperationAsync, onRefreshSearchAsync, refreshSelectionDataRowsAsync, onRefreshAfterAddDcmtToFavs, confirmFormat, openTaskFormHandler, openDetailDcmtsFormHandler, openMasterDcmtsFormHandler, openBatchUpdateFormHandler, false, true) })] })] })] }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onUpdate: onUpdate, selectedItems: getSelectedDcmtsOrFocused(selectedItems, focusedItem), op: 0, onClose: () => setShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onUpdate: onUpdate, selectedItems: getSelectedDcmtsOrFocused(selectedItems, focusedItem), op: 1, onClose: () => setShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onUpdate: onUpdate, selectedItems: getSelectedDcmtsOrFocused(selectedItems, focusedItem), onClose: () => setShowReAssignPopup(false) })] }), _jsx(ConfirmFormatDialog, {})] }) }), isOpenBatchUpdate ?
439
+ _jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMBatchUpdateForm, { inputDcmts: getSelectionDcmtInfo(), TID: focusedItem ? focusedItem?.TID : selectedItems[0]?.TID, DID: focusedItem ? focusedItem?.DID : selectedItems[0]?.DID, onBack: () => setIsOpenBatchUpdate(false), onSavedCallbackAsync: async () => {
440
+ setIsOpenBatchUpdate(false);
441
+ setIsModifiedBatchUpdate(false);
442
+ await refreshSelectionDataRowsAsync();
443
+ }, onStatusChanged: (isModified) => { setIsModifiedBatchUpdate(isModified); } }) })
444
+ :
445
+ isOpenPreview || isOpenMiddlePanel()
446
+ ? _jsx(TMLayoutItem, { children: _jsxs(TMSplitterLayout, { separatorSize: 5, direction: 'horizontal', showSeparator: deviceType !== DeviceType.MOBILE && (isOpenPreview && isOpenMiddlePanel()), start: getSecondarySplitterStartLayout(), min: ['0', '0'], separatorColor: 'transparent', children: [isOpenMiddlePanel()
447
+ ? _jsx(TMLayoutItem, { children: _jsx(TMToolbarCard, { padding: '0',
448
+ // color={TMColors.primaryColor}
449
+ // backgroundColor={`${TMColors.primaryColor}25`}
450
+ title: titleText(), toolbar: middlePanelToolbar, onClose: () => closeMiddlePanel(), children: (!focusedItem?.DID)
451
+ ?
452
+ _jsx(TMNothingToShow, { text: 'Nessun documento selezionato.', secondText: notAvalableMsg, icon: notAvalableIcon })
453
+ :
454
+ _jsxs(StyledContainer, { children: [isOpenBoard && _jsx(TMDcmtBlog, { tid: focusedItem?.TID, did: focusedItem?.DID }), isOpenSysMetadata &&
455
+ _jsx(TMMetadataValues, { layoutMode: LayoutModes.Update, openChooserBySingleClick: !isOpenDistinctValues, TID: focusedItem?.TID, deviceType: deviceType, metadataValues: currentMetadataValues.filter(o => (o.mid != undefined && o.mid <= 100)), metadataValuesOrig: currentMetadataValues.filter(o => (o.mid != undefined && o.mid <= 100)), validationItems: [] })] }) }) })
456
+ : _jsx(_Fragment, {}), isOpenPreview
457
+ ? _jsx(TMLayoutItem, { children: _jsx(TMDcmtPreview, { onClose: () => { setIsOpenPreview(false); onClosePreview?.(); }, dcmtData: currentDcmt, canNext: canNavigateHandler('next'), canPrev: canNavigateHandler('prev'), onNext: () => onNavigateHandler('next'), onPrev: () => onNavigateHandler('prev') }) })
458
+ : _jsx(_Fragment, {})] }) })
459
+ : _jsx(_Fragment, {})] }), isOpenDetails &&
460
+ _jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _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) }) }), isOpenMaster &&
461
+ _jsxs(StyledModalContainer, { style: { backgroundColor: 'white' }, children: [_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 }), secondaryMasterDcmts.length > 0 && secondaryMasterDcmts.map((dcmt, index) => {
462
+ 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 }) }, `${index}-${dcmt.DID}`));
463
+ })] }), isOpenDcmtForm &&
464
+ _jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMDcmtForm, { TID: focusedItem?.TID, DID: focusedItem?.DID, layoutMode: dcmtFormLayoutMode, showPreview: true, 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); }, onSavedAsyncCallback: async (tid, did) => { await refreshFocusedDataRowAsync(tid, did, true); } }) })] }) }));
465
+ };
466
+ export default TMSearchResult;
467
+ const renderDcmtIcon = (cellData) => _jsx(TMDcmtIcon, { fileExtension: cellData.data.FILEEXT, fileCount: cellData.data.FILECOUNT, isLexProt: cellData.data.IsLexProt, isMail: cellData.data.ISMAIL, isShared: cellData.data.ISSHARED, isSigned: cellData.data.ISSIGNED });
468
+ const TMSearchResultGrid = ({ inputFocusedItem, allowMultipleSelection = true, onFocusedItemChanged, onVisibleItemChanged, inputSelectedItems = [], lastUpdateSearchTime, searchResult, onContextMenuPreparing, onSelectionChanged, onDblClick }) => {
469
+ const [dataSource, setDataSource] = useState();
470
+ const [showFilterPanel, setShowFilterPanel] = useState(false);
471
+ const [columns, setColumns] = useState([]);
472
+ // State to store selected row keys
473
+ const [selectedRowKeys, setSelectedRowKeys] = useState([]);
474
+ const [focusedItem, setFocusedItem] = useState();
475
+ const [visibleItems, setVisibleItems] = useState([]);
476
+ useEffect(() => {
477
+ if (deepCompare(inputFocusedItem, focusedItem))
478
+ return;
479
+ setFocusedItem(inputFocusedItem);
480
+ }, [inputFocusedItem]);
481
+ useEffect(() => {
482
+ const inputSelectedItemsRowIndex = inputSelectedItems.map(e => e.rowIndex);
483
+ if (JSON.stringify(inputSelectedItemsRowIndex) === JSON.stringify(selectedRowKeys))
484
+ return;
485
+ setSelectedRowKeys(inputSelectedItemsRowIndex);
486
+ }, [inputSelectedItems]);
487
+ const cellRender = useCallback((cellData, dataDomain, dataListID, dataListViewMode) => {
488
+ if (!cellData || cellData.value === undefined)
489
+ return null;
490
+ const isLogDel = cellData.data.ISLOGDEL == 1;
491
+ const isLexProt = cellData.data.IsLexProt == 1;
492
+ let style = {};
493
+ if (isLogDel) {
494
+ style = { color: 'gray', textDecoration: 'line-through' };
495
+ }
496
+ else if (isLexProt)
497
+ style = { color: 'blue' };
498
+ let child = _jsx("div", { children: cellData.text });
499
+ if (dataDomain === MetadataDataDomains.DataList) {
500
+ child = _jsx(TMDataListItemViewer, { dataListId: dataListID, viewMode: dataListViewMode, value: cellData.value });
501
+ }
502
+ if (dataDomain === MetadataDataDomains.UserID) {
503
+ child = _jsx(TMUserIdViewer, { userId: cellData.value, showIcon: true, noneSelectionText: '' });
504
+ }
505
+ return _jsx("div", { style: style, children: child });
506
+ }, []);
507
+ const dataType = useCallback((col) => {
508
+ switch (col.dataType) {
509
+ case DataColumnTypes.DateTime: return "datetime";
510
+ case DataColumnTypes.Bool: return "boolean";
511
+ case DataColumnTypes.Number: return "number";
512
+ default: return "string";
513
+ }
514
+ }, []);
515
+ const getDisplayFormat = useCallback((col) => {
516
+ if (col.dataType === DataColumnTypes.Text)
517
+ return undefined;
518
+ const format = MetadataFormats[(col.extendedProperties?.["Format"] ?? "None")];
519
+ const formatCulture = col.extendedProperties?.["FormatCulture"] ?? window.navigator.language;
520
+ if (col.dataType === DataColumnTypes.DateTime) {
521
+ return {
522
+ formatter: function (value) {
523
+ switch (format) {
524
+ case MetadataFormats.ShortDate: return value.toLocaleString(formatCulture, formatCulture == "it-IT" ? { year: "numeric", month: "2-digit", day: "2-digit" } : { dateStyle: 'short' });
525
+ case MetadataFormats.ShortTime: return value.toLocaleString(formatCulture, { timeStyle: 'short' });
526
+ case MetadataFormats.ShortDateLongTime: return value.toLocaleString(formatCulture, formatCulture == "it-IT" ? { year: "numeric", month: "2-digit", day: "2-digit", hour: '2-digit', minute: '2-digit', second: '2-digit' } : { dateStyle: 'short', timeStyle: 'medium' }).replace(',', '');
527
+ case MetadataFormats.ShortDateShortTime: return value.toLocaleString(formatCulture, formatCulture == "it-IT" ? { year: "numeric", month: "2-digit", day: "2-digit", hour: '2-digit', minute: '2-digit' } : { dateStyle: 'short', timeStyle: 'short' }).replace(',', '');
528
+ case MetadataFormats.LongDate: return value.toLocaleString(formatCulture, { weekday: "long", year: "numeric", month: "long", day: "numeric" });
529
+ case MetadataFormats.LongTime: return value.toLocaleString(formatCulture, { timeStyle: 'medium' });
530
+ case MetadataFormats.LongDateLongTime: return value.toLocaleString(formatCulture, { weekday: "long", year: "numeric", month: "long", day: "numeric", hour: '2-digit', minute: '2-digit', second: '2-digit' });
531
+ case MetadataFormats.LongDateShortTime: return value.toLocaleString(formatCulture, { weekday: "long", year: "numeric", month: "long", day: "numeric", hour: '2-digit', minute: '2-digit' });
532
+ default: return value.toLocaleString(formatCulture, formatCulture == "it-IT" ? { year: "numeric", month: "2-digit", day: "2-digit" } : { dateStyle: 'short' });
533
+ }
534
+ }
535
+ };
536
+ }
537
+ if (col.dataType === DataColumnTypes.Number) {
538
+ return {
539
+ formatter: function (value) {
540
+ return value.toLocaleString(formatCulture, { useGrouping: format == MetadataFormats.NumberWithThousandsSeparator });
541
+ }
542
+ };
543
+ }
544
+ if (format == MetadataFormats.None)
545
+ return undefined;
546
+ if (format == MetadataFormats.CurrencyEuro)
547
+ return { type: 'currency', precision: 2, currency: "EUR" };
548
+ if (format == MetadataFormats.CurrencyDollar)
549
+ return { type: 'currency', precision: 2, currency: "USD" };
550
+ if (format == MetadataFormats.CurrencyPound)
551
+ return { type: 'currency', precision: 2, currency: "GBP" };
552
+ if (format == MetadataFormats.CurrencyYen)
553
+ return { type: 'currency', currency: "JPY" };
554
+ return undefined;
555
+ }, []);
556
+ useEffect(() => {
557
+ let cols = [];
558
+ searchResult?.dtdResult?.columns?.map((col, index) => {
559
+ let keyField = getDataColumnName(searchResult?.fromTID, col);
560
+ const isVisible = col.extendedProperties?.["Visibility"] != "Hidden";
561
+ const dataDomain = MetadataDataDomains[(col.extendedProperties?.["DataDomain"] ?? "None")];
562
+ const dataListID = Number(col.extendedProperties?.["DataListID"]);
563
+ const dataListViewMode = DataListViewModes[(col.extendedProperties?.["DataListViewMode"] ?? "None")];
564
+ cols.push({
565
+ dataField: keyField,
566
+ dataType: dataType(col),
567
+ visible: isVisible,
568
+ cellRender: (cellData) => cellRender(cellData, dataDomain, dataListID, dataListViewMode),
569
+ caption: col.caption,
570
+ format: getDisplayFormat(col)
571
+ });
572
+ });
573
+ setColumns(cols);
574
+ setDataSource(searchResultDescriptorToSimpleArray(searchResult));
575
+ }, [searchResult]);
576
+ useEffect(() => {
577
+ let newDataSource = searchResultDescriptorToSimpleArray(searchResult);
578
+ setDataSource(newDataSource);
579
+ setFocusedItem(newDataSource?.find(o => o?.rowIndex === focusedItem?.rowIndex));
580
+ }, [lastUpdateSearchTime]);
581
+ // Handles selection change in the data grid
582
+ const handleSelectionChange = useCallback((e) => {
583
+ if (onSelectionChanged === undefined)
584
+ return;
585
+ const selectedRowsData = e.component.getSelectedRowsData() ?? [];
586
+ onSelectionChanged(selectedRowsData);
587
+ }, [onSelectionChanged]);
588
+ // Handles focus change in the data grid
589
+ const handleFocusedRowChange = useCallback((e) => {
590
+ if (setFocusedItem === undefined)
591
+ return;
592
+ if (e.row === undefined) {
593
+ setFocusedItem(undefined);
594
+ return;
595
+ }
596
+ setFocusedItem(e.row.data);
597
+ }, [setFocusedItem]);
598
+ useEffect(() => {
599
+ onFocusedItemChanged?.(focusedItem);
600
+ }, [focusedItem]);
601
+ // Handler for double-click row event
602
+ const onRowDblClick = useCallback((e) => {
603
+ if (onDblClick === undefined)
604
+ return;
605
+ if (e.data === undefined)
606
+ return;
607
+ setFocusedItem(e.data);
608
+ onDblClick();
609
+ }, [onDblClick]);
610
+ const dataColumns = useMemo(() => {
611
+ return [
612
+ { dataType: "object", visible: true, width: 50, cellRender: renderDcmtIcon, allowResizing: false, },
613
+ ...columns
614
+ ];
615
+ }, [columns]);
616
+ const onContentReady = useCallback((e) => {
617
+ if (e === undefined)
618
+ return;
619
+ if (setVisibleItems === undefined)
620
+ return;
621
+ const visibleRows = e.component.getVisibleRows();
622
+ setVisibleItems(visibleRows.map((row) => { return row.data; }));
623
+ }, []);
624
+ useEffect(() => { onVisibleItemChanged?.(visibleItems); }, [visibleItems]);
625
+ const onOptionChanged = useCallback((e) => {
626
+ if (e === undefined)
627
+ return;
628
+ if (e.fullName === "filterValue") {
629
+ setShowFilterPanel(!!e.value);
630
+ }
631
+ }, []);
632
+ return _jsx(TMDataGrid, { id: "tm-search-result", keyExpr: "rowIndex", dataColumns: dataColumns, dataSource: dataSource, repaintChangesOnly: true, selectedRowKeys: selectedRowKeys, focusedRowKey: focusedItem?.rowIndex, showRowLines: SDKUI_Globals.dataGridShowRowLines, showColumnLines: SDKUI_Globals.dataGridShowColumnLines, showSearchPanel: false, showFilterPanel: showFilterPanel, sorting: { mode: "multiple" }, selection: { mode: allowMultipleSelection ? 'multiple' : 'single' }, pageSize: TMDataGridPageSize.Small, onSelectionChanged: handleSelectionChange, onFocusedRowChanged: handleFocusedRowChange, onRowDblClick: onRowDblClick, onContentReady: onContentReady, onOptionChanged: onOptionChanged, onContextMenuPreparing: onContextMenuPreparing, counterConfig: { show: true } });
633
+ };
634
+ //#region TMSearchResultSelector
635
+ const StyledGroupTemplate = styled.div `
636
+ cursor: pointer;
637
+ /* background-color: #f1f1f1; */
638
+ background: ${() => `linear-gradient(90deg, #f0f4fa, ${TMColors.primaryColor}66)`};
639
+ padding: 10px;
640
+ border-bottom: 1px solid #ccc;
641
+ display: flex;
642
+ flex-direction: row;
643
+ gap: 5px;
644
+ align-items: center;
645
+ font-size: 1rem;
646
+ `;
647
+ const StyledItemTemplate = styled.div `
648
+ background: ${(props) => props.$isSelected ? 'oklch(from var(--dx-color-primary) l c h / .2) !important' : 'transparent'};
649
+ cursor: pointer;
650
+ `;
651
+ const TMSearchResultSelector = ({ searchResults = [], onSelectionChanged }) => {
652
+ const [activeCategories, setActiveCategories] = useState([]);
653
+ const [selectedResult, setSelectedResult] = useState(null);
654
+ /** Group results by category */
655
+ const groupedResults = searchResults.reduce((acc, result) => {
656
+ const category = result.category ?? 'Uncategorized';
657
+ if (!acc[category]) {
658
+ acc[category] = [];
659
+ }
660
+ acc[category].push(result);
661
+ return acc;
662
+ }, {});
663
+ /** Sort categories alphabetically */
664
+ const sortedCategories = Object.keys(groupedResults).sort((a, b) => a.localeCompare(b));
665
+ /** Sort items within each category alphabetically by fromName */
666
+ sortedCategories.forEach((category) => {
667
+ groupedResults[category].sort((a, b) => (a.fromName ?? '').localeCompare(b.fromName ?? ''));
668
+ });
669
+ useEffect(() => {
670
+ if (sortedCategories.length > 0 && activeCategories.length === 0) {
671
+ const firstCategory = sortedCategories[0];
672
+ setActiveCategories([firstCategory]);
673
+ if (groupedResults[firstCategory].length > 0) {
674
+ setSelectedResult(groupedResults[firstCategory][0]);
675
+ onSelectionChanged?.(groupedResults[firstCategory][0]);
676
+ }
677
+ }
678
+ }, [sortedCategories.length]);
679
+ const toggleCategory = useCallback((category) => {
680
+ setActiveCategories((prevActiveCategories) => prevActiveCategories.includes(category)
681
+ ? prevActiveCategories.filter((cat) => cat !== category)
682
+ : [...prevActiveCategories, category]);
683
+ }, []);
684
+ const handleSelect = (result) => {
685
+ if (selectedResult !== result) {
686
+ setSelectedResult(result);
687
+ onSelectionChanged?.(result);
688
+ }
689
+ };
690
+ const resultDcmtCounter = (category) => {
691
+ let dcmts = searchResults.filter(res => res?.category === category);
692
+ if (!dcmts)
693
+ return 0;
694
+ let counter = 0;
695
+ for (let dcmt of dcmts) {
696
+ counter += dcmt.dcmtsFound ?? 0;
697
+ }
698
+ return counter;
699
+ };
700
+ const renderGroupTemplate = (category) => {
701
+ const getHeaderIcon = (category) => {
702
+ switch (category) {
703
+ case "RecentArchive": return _jsx(IconArchive, { style: { flexShrink: 0 }, fontSize: 14, color: TMColors.primaryColor });
704
+ case "RecentView": return _jsx(IconShow, { style: { flexShrink: 0 }, color: TMColors.primaryColor });
705
+ case "WFAppr": return _jsx(IconActivityLog, { style: { flexShrink: 0 }, color: TMColors.primaryColor });
706
+ case "Favorites": return _jsx(IconStar, { style: { flexShrink: 0 }, color: TMColors.primaryColor });
707
+ case "FullText": return _jsx(IconFreeSearch, { style: { flexShrink: 0 }, color: TMColors.primaryColor });
708
+ default: return null;
709
+ }
710
+ };
711
+ const getHeaderTitle = (category) => {
712
+ switch (category) {
713
+ case "RecentArchive": return SDKUI_Localizator.RecentDocs_Archived;
714
+ case "RecentView": return SDKUI_Localizator.RecentDocs_Visualized;
715
+ case "WFAppr": return SDKUI_Localizator.WorkflowApproval;
716
+ case "Favorites": return SDKUI_Localizator.Favorites;
717
+ case "FullText": return 'Full text';
718
+ default: return category;
719
+ }
720
+ };
721
+ return _jsx(CustomListViewHeader, { titleColor: TMColors.primaryColor, firstCounter: _jsx(TMTooltip, { content: 'Numero di tipi documento', children: _jsx(StyledBadge, { style: { width: 'max-content' }, "$backgroundColor": TMColors.primaryColor, children: searchResults.length > 1 && searchResults?.filter(data => data.category === category).length }) }), secondCounter: _jsx(TMTooltip, { content: 'Numero di tutti documenti', children: _jsx(StyledBadge, { style: { width: 'max-content' }, "$backgroundColor": TMColors.tertiary, children: resultDcmtCounter(category) }) }), headerIcon: getHeaderIcon(category), headerTitle: getHeaderTitle(category) });
722
+ };
723
+ const renderItemTemplate = (data) => {
724
+ return (_jsxs("div", { style: { width: '100%', padding: '5px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }, children: [_jsx(TMTidViewer, { tid: data.fromTID, showIcon: true }), _jsx("div", { style: { padding: 3, display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: 'white', color: 'gray', borderRadius: 3 }, children: data.dcmtsReturned })] }));
725
+ };
726
+ return (_jsx("div", { style: { height: '100%', width: '100%', overflow: 'auto' }, children: sortedCategories.map((category) => (_jsxs("div", { children: [_jsxs(StyledGroupTemplate, { onClick: () => toggleCategory(category), children: [activeCategories.includes(category) ? _jsx(IconChevronDown, {}) : _jsx(IconChevronDown, { transform: 'scale(-1, 1)' }), renderGroupTemplate(category)] }, category), activeCategories.includes(category) && (_jsx("div", { style: { padding: '5px' }, children: groupedResults[category].map((result, index) => (_jsx(StyledItemTemplate, { "$isSelected": selectedResult === result, onClick: () => handleSelect(result), children: renderItemTemplate(result) }, index))) }))] }, category))) }));
727
+ };