@topconsultnpm/sdkui-react 6.20.0-dev1.4 → 6.20.0-dev1.40

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 (73) hide show
  1. package/lib/components/NewComponents/ContextMenu/TMContextMenu.d.ts +4 -0
  2. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +248 -0
  3. package/lib/components/NewComponents/ContextMenu/hooks.d.ts +12 -0
  4. package/lib/components/NewComponents/ContextMenu/hooks.js +52 -0
  5. package/lib/components/NewComponents/ContextMenu/index.d.ts +2 -0
  6. package/lib/components/NewComponents/ContextMenu/index.js +1 -0
  7. package/lib/components/NewComponents/ContextMenu/styles.d.ts +31 -0
  8. package/lib/components/NewComponents/ContextMenu/styles.js +336 -0
  9. package/lib/components/NewComponents/ContextMenu/types.d.ts +38 -0
  10. package/lib/components/NewComponents/ContextMenu/types.js +1 -0
  11. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.d.ts +4 -0
  12. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +471 -0
  13. package/lib/components/NewComponents/FloatingMenuBar/index.d.ts +2 -0
  14. package/lib/components/NewComponents/FloatingMenuBar/index.js +2 -0
  15. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +47 -0
  16. package/lib/components/NewComponents/FloatingMenuBar/styles.js +346 -0
  17. package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +29 -0
  18. package/lib/components/NewComponents/FloatingMenuBar/types.js +1 -0
  19. package/lib/components/base/TMCustomButton.js +61 -17
  20. package/lib/components/base/TMDataGrid.d.ts +7 -4
  21. package/lib/components/base/TMDataGrid.js +112 -11
  22. package/lib/components/choosers/TMMetadataChooser.js +8 -1
  23. package/lib/components/editors/TMHtmlEditor.js +1 -1
  24. package/lib/components/editors/TMMetadataValues.js +20 -2
  25. package/lib/components/features/documents/TMDcmtBlog.d.ts +1 -7
  26. package/lib/components/features/documents/TMDcmtBlog.js +29 -2
  27. package/lib/components/features/documents/TMDcmtForm.js +269 -169
  28. package/lib/components/features/documents/TMDcmtPreview.js +37 -66
  29. package/lib/components/features/documents/TMMasterDetailDcmts.js +1 -1
  30. package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +8 -0
  31. package/lib/components/features/search/{TMSearchResultCheckoutInfoForm.js → TMDcmtCheckoutInfoForm.js} +6 -11
  32. package/lib/components/features/search/TMSearch.js +30 -5
  33. package/lib/components/features/search/TMSearchQueryPanel.js +13 -12
  34. package/lib/components/features/search/TMSearchResult.js +71 -120
  35. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +3 -3
  36. package/lib/components/features/search/TMSearchResultsMenuItems.js +216 -180
  37. package/lib/components/features/search/TMSignSettingsForm.js +1 -1
  38. package/lib/components/features/search/TMSignatureInfoContent.d.ts +6 -0
  39. package/lib/components/features/search/TMSignatureInfoContent.js +140 -0
  40. package/lib/components/features/search/TMViewHistoryDcmt.js +1 -1
  41. package/lib/components/features/tasks/TMTasksView.js +2 -2
  42. package/lib/components/forms/Login/LoginValidatorService.d.ts +2 -0
  43. package/lib/components/forms/Login/LoginValidatorService.js +7 -2
  44. package/lib/components/forms/Login/TMLoginForm.js +34 -6
  45. package/lib/components/forms/TMChooserForm.js +1 -1
  46. package/lib/components/index.d.ts +0 -1
  47. package/lib/components/index.js +0 -1
  48. package/lib/css/tm-sdkui.css +1 -1
  49. package/lib/helper/SDKUI_Globals.d.ts +19 -14
  50. package/lib/helper/SDKUI_Globals.js +9 -0
  51. package/lib/helper/SDKUI_Localizator.d.ts +8 -0
  52. package/lib/helper/SDKUI_Localizator.js +98 -0
  53. package/lib/helper/TMIcons.d.ts +1 -0
  54. package/lib/helper/TMIcons.js +3 -0
  55. package/lib/helper/TMPdfViewer.d.ts +8 -0
  56. package/lib/helper/TMPdfViewer.js +187 -0
  57. package/lib/helper/TMUtils.d.ts +3 -1
  58. package/lib/helper/TMUtils.js +51 -0
  59. package/lib/helper/checkinCheckoutManager.d.ts +85 -0
  60. package/lib/helper/checkinCheckoutManager.js +348 -0
  61. package/lib/helper/devextremeCustomMessages.d.ts +30 -0
  62. package/lib/helper/devextremeCustomMessages.js +30 -0
  63. package/lib/helper/helpers.js +7 -1
  64. package/lib/helper/index.d.ts +2 -0
  65. package/lib/helper/index.js +2 -0
  66. package/lib/helper/queryHelper.js +29 -0
  67. package/lib/hooks/useCheckInOutOperations.d.ts +28 -0
  68. package/lib/hooks/useCheckInOutOperations.js +223 -0
  69. package/lib/services/platform_services.d.ts +1 -1
  70. package/package.json +5 -2
  71. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.d.ts +0 -8
  72. package/lib/helper/cicoHelper.d.ts +0 -31
  73. package/lib/helper/cicoHelper.js +0 -155
@@ -1,9 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
3
- import DataGrid, { Column, HeaderFilter, Selection, Scrolling, LoadPanel, SearchPanel, Pager, Sorting, Paging, FilterPanel, ColumnChooser, Grouping, GroupPanel, Summary, Editing, FilterRow, StateStoring, RowDragging, MasterDetail } from 'devextreme-react/data-grid';
3
+ import DataGrid, { Column, HeaderFilter, Selection, Scrolling, LoadPanel, SearchPanel, Pager, Sorting, Paging, FilterPanel, ColumnChooser, Grouping, GroupPanel, Summary, Editing, FilterRow, StateStoring, RowDragging, MasterDetail, Position, ColumnChooserSearch, ColumnChooserSelection } from 'devextreme-react/data-grid';
4
4
  import DataSource from 'devextreme/data/data_source';
5
5
  import { IconAll, IconSelected, IconVisible, SDKUI_Globals, SDKUI_Localizator } from '../../helper';
6
6
  import TMCounterContainer, { CounterItemKey } from './TMCounterContainer';
7
+ import TMContextMenu from '../NewComponents/ContextMenu/TMContextMenu';
7
8
  ;
8
9
  export var TMDataGridPageSize;
9
10
  (function (TMDataGridPageSize) {
@@ -16,9 +17,9 @@ const TMDataGrid = React.forwardRef((props, ref) => {
16
17
  // main properties
17
18
  keyExpr = 'id', dataSource, focusedRowEnabled = true, hoverStateEnabled = true, focusedRowKey, selectedRowKeys = [],
18
19
  // custom options
19
- dataColumns = [], pageSize = TMDataGridPageSize.Large, showHeaderFilter = true, showFilterPanel = true, showLoadPanel = true, showSearchPanel = true, searchPanelToolbarPosition = 'before', searchPanelFocusStarting = false, counterConfig = { show: false, items: new Map() }, onHasFiltersChange,
20
+ dataColumns = [], pageSize = TMDataGridPageSize.Large, showHeaderFilter = true, showFilterPanel = true, showHeaderColumnChooser = false, showLoadPanel = true, showSearchPanel = true, searchPanelToolbarPosition = 'before', searchPanelFocusTrigger = 0, counterConfig = { show: false, items: new Map() }, onHasFiltersChange, customContextMenuItems,
20
21
  // events and callbacks
21
- onSelectionChanged, onFocusedRowChanged, onRowDblClick, onRowClick, onCellClick, onCellDblClick, onOptionChanged, onContentReady, onContextMenuPreparing, onInitialized, onEditorPreparing, onCellPrepared, onRowPrepared, onRowUpdating, onRowExpanded, onRowCollapsed, onRowUpdated, onSaved, onEditCanceled, onEditingStart, onEditingChange, customizeColumns, onKeyDown, scrolling = { mode: 'standard', useNative: SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar === 1 }, paging = { enabled: true, pageSize: pageSize }, pager = { visible: true, showInfo: true, showNavigationButtons: true }, selection = { mode: 'multiple', showCheckBoxesMode: "always", selectAllMode: "allPages" }, sorting, summary, stateStoring, columnChooser, grouping, groupPanel, filterRow, headerFilter, editing, rowDragging, masterDetail,
22
+ onSelectionChanged, onFocusedRowChanged, onRowDblClick, onRowClick, onCellClick, onCellDblClick, onOptionChanged, onContentReady, onContextMenuPreparing, onInitialized, onEditorPreparing, onCellPrepared, onRowPrepared, onRowUpdating, onRowExpanded, onRowCollapsed, onRowUpdated, onSaved, onEditCanceled, onEditingStart, onEditingChange, customizeColumns, onKeyDown, scrolling = { mode: 'standard', useNative: SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar === 1 }, paging = { enabled: true, pageSize: pageSize }, pager = { visible: true, showInfo: true, showNavigationButtons: true }, selection = { mode: 'multiple', showCheckBoxesMode: "always", selectAllMode: "allPages" }, sorting, summary, stateStoring, grouping, groupPanel, filterRow, headerFilter, editing, rowDragging, masterDetail,
22
23
  // other properties
23
24
  disabled = false, autoNavigateToFocusedRow = true, columnResizingMode = 'widget', columnHidingEnabled = true, columnAutoWidth = true, allowColumnResizing = true, allowColumnReordering = true, showBorders = true, showRowLines = SDKUI_Globals.userSettings?.themeSettings.gridSettings.showRowLines === 1, showColumnLines = SDKUI_Globals.userSettings?.themeSettings.gridSettings.showColumnLines === 1, showColumnHeaders = true, rowAlternationEnabled = false, wordWrapEnabled = false, noDataText,
24
25
  // styles
@@ -29,10 +30,53 @@ const TMDataGrid = React.forwardRef((props, ref) => {
29
30
  const [totalRecordCount, setTotalRecordCount] = useState(0);
30
31
  const [visibleItemsCount, setVisibleItemsCount] = useState(0);
31
32
  const [hasFilters, setHasFilters] = useState(false);
33
+ // Custom context menu states
34
+ const [customContextMenuVisible, setCustomContextMenuVisible] = useState(false);
35
+ const [customContextMenuPosition, setCustomContextMenuPosition] = useState({ x: 0, y: 0 });
36
+ const [customContextMenuRowKey, setCustomContextMenuRowKey] = useState(undefined);
37
+ const gridContainerRef = useRef(null);
32
38
  useEffect(() => {
33
39
  const count = getRecordCount(dataSource);
34
40
  setTotalRecordCount(count);
35
41
  }, [dataSource]);
42
+ // Handle search panel focus when trigger changes
43
+ useEffect(() => {
44
+ if (!searchPanelFocusTrigger || searchPanelFocusTrigger <= 0 || !showSearchPanel || !internalRef.current)
45
+ return;
46
+ setTimeout(() => {
47
+ const searchInput = internalRef.current?.instance().element().querySelector('.dx-datagrid-search-panel input');
48
+ if (searchInput) {
49
+ searchInput.focus();
50
+ }
51
+ }, 100);
52
+ }, [searchPanelFocusTrigger, showSearchPanel]);
53
+ // Handle custom context menu (only when customContextMenuItems is provided)
54
+ useEffect(() => {
55
+ if (!customContextMenuItems || !gridContainerRef.current)
56
+ return;
57
+ const gridContainer = gridContainerRef.current;
58
+ const handleContextMenu = (e) => {
59
+ e.preventDefault();
60
+ e.stopPropagation();
61
+ // Get the clicked row
62
+ const target = e.target;
63
+ const rowElement = target.closest('.dx-data-row');
64
+ if (rowElement && internalRef.current) {
65
+ const rowIndex = Array.from(rowElement.parentElement?.children || []).indexOf(rowElement);
66
+ const rowKey = internalRef.current.instance().getKeyByRowIndex(rowIndex);
67
+ // Change focused row
68
+ internalRef.current.instance().option('focusedRowKey', rowKey);
69
+ // Show custom context menu
70
+ setCustomContextMenuVisible(true);
71
+ setCustomContextMenuPosition({ x: e.clientX, y: e.clientY });
72
+ setCustomContextMenuRowKey(rowKey);
73
+ }
74
+ };
75
+ gridContainer.addEventListener('contextmenu', handleContextMenu);
76
+ return () => {
77
+ gridContainer.removeEventListener('contextmenu', handleContextMenu);
78
+ };
79
+ }, [customContextMenuItems]);
36
80
  // Creating a ref to store the timestamp of the last selection change
37
81
  const lastSelectionChangeTime = useRef(Date.now());
38
82
  useEffect(() => {
@@ -101,6 +145,8 @@ const TMDataGrid = React.forwardRef((props, ref) => {
101
145
  }
102
146
  return {
103
147
  ...item,
148
+ // Ensure icon is not null/undefined to prevent DevExtreme errors
149
+ icon: item.icon || '',
104
150
  disabled: disabled || disabledCalculation, // An item is disabled if it's explicitly set to `true` or if the calculation above determines so
105
151
  // Define the behavior when the menu item is clicked
106
152
  onClick: () => {
@@ -132,10 +178,51 @@ const TMDataGrid = React.forwardRef((props, ref) => {
132
178
  };
133
179
  });
134
180
  }, [focusedRowEnabled, focusedRowKey, selectedRowKeys]);
181
+ // Process custom context menu items (for TMContextMenuItemProps)
182
+ const processCustomContextMenuItems = useCallback((items, rowID) => {
183
+ return items.map(item => {
184
+ let disabled = item.disabled ?? false;
185
+ let disabledCalculation = false;
186
+ const id = focusedRowEnabled ? focusedRowKey : rowID;
187
+ if (item.operationType === 'singleRow') {
188
+ disabledCalculation = selectedRowKeys.length > 1 || id === undefined;
189
+ }
190
+ if (item.operationType === 'multiRow') {
191
+ disabledCalculation = selectedRowKeys.length === 0 && id === undefined;
192
+ }
193
+ const originalOnClick = item.onClick;
194
+ return {
195
+ ...item,
196
+ disabled: disabled || disabledCalculation,
197
+ onClick: originalOnClick ? () => {
198
+ if (item.operationType === 'singleRow' && id !== undefined) {
199
+ originalOnClick(id);
200
+ }
201
+ else if (item.operationType === 'multiRow' && id !== undefined) {
202
+ if (selectedRowKeys.length > 0) {
203
+ originalOnClick(selectedRowKeys);
204
+ }
205
+ else {
206
+ originalOnClick([id]);
207
+ }
208
+ }
209
+ else {
210
+ originalOnClick();
211
+ }
212
+ } : undefined,
213
+ submenu: item.submenu ? processCustomContextMenuItems(item.submenu, id) : undefined,
214
+ };
215
+ });
216
+ }, [focusedRowEnabled, focusedRowKey, selectedRowKeys]);
135
217
  // Handle context menu preparation
136
218
  const onContextMenuPreparingCallback = useCallback((e) => {
137
219
  if (e === undefined)
138
220
  return;
221
+ // If custom context menu is enabled, completely disable DevExtreme's native context menu
222
+ if (customContextMenuItems && e.target === 'content') {
223
+ e.items = undefined;
224
+ return;
225
+ }
139
226
  if (onContextMenuPreparing)
140
227
  onContextMenuPreparing(e);
141
228
  if (e.target === 'content') {
@@ -146,7 +233,18 @@ const TMDataGrid = React.forwardRef((props, ref) => {
146
233
  e.items = [...updatedContextMenuItems];
147
234
  }
148
235
  }
149
- }, [updateContextMenuItems, onContextMenuPreparing]);
236
+ // Add column chooser to header context menu
237
+ if (e.target === 'header' && showHeaderColumnChooser) {
238
+ e.items = e.items || [];
239
+ e.items.push({
240
+ text: SDKUI_Localizator.ShowColumnSelection,
241
+ icon: 'columnchooser',
242
+ onItemClick: () => {
243
+ internalRef.current?.instance().showColumnChooser();
244
+ }
245
+ });
246
+ }
247
+ }, [updateContextMenuItems, onContextMenuPreparing, showHeaderColumnChooser, customContextMenuItems]);
150
248
  // Handle toolbar preparation, especially for the search panel
151
249
  const onToolbarPreparingCallback = useCallback((e) => {
152
250
  if (e === undefined || e.toolbarOptions === undefined || e.toolbarOptions.items === undefined)
@@ -171,10 +269,9 @@ const TMDataGrid = React.forwardRef((props, ref) => {
171
269
  return;
172
270
  // Update state with the current number of visible rows in the DataGrid
173
271
  setVisibleItemsCount(internalRef.current.instance()?.getVisibleRows()?.length ?? 0);
174
- // Focusing SearchPanel
175
- if (showSearchPanel && searchPanelFocusStarting) {
272
+ // Focusing SearchPanel on content ready
273
+ if (showSearchPanel && searchPanelFocusTrigger && searchPanelFocusTrigger > 0) {
176
274
  // Use a small delay to ensure the DOM is fully rendered before trying to focus
177
- // This can prevent issues with the focus not being set correctly
178
275
  setTimeout(() => {
179
276
  const searchInput = internalRef.current?.instance().element().querySelector('.dx-datagrid-search-panel input');
180
277
  if (searchInput) {
@@ -182,7 +279,7 @@ const TMDataGrid = React.forwardRef((props, ref) => {
182
279
  }
183
280
  }, 100);
184
281
  }
185
- }, [onContentReady]);
282
+ }, [onContentReady, showSearchPanel, searchPanelFocusTrigger]);
186
283
  const onOptionChangedCallback = useCallback((e) => {
187
284
  // Assicurati che component esista
188
285
  const grid = e.component;
@@ -215,15 +312,19 @@ const TMDataGrid = React.forwardRef((props, ref) => {
215
312
  // Propaga l'evento originale
216
313
  onOptionChanged?.(e);
217
314
  }, [onOptionChanged, onHasFiltersChange]);
218
- return _jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx("div", { style: { width: "100%", height: counterConfig.show ? "calc(100% - 25px)" : "100%" }, children: _jsxs(DataGrid, { ref: internalRef, id: id, className: `tm-datagrid ${hasFilters ? 'has-filters' : ''}`,
315
+ return _jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx("div", { ref: gridContainerRef, style: { width: "100%", height: counterConfig.show ? "calc(100% - 25px)" : "100%" }, children: _jsxs(DataGrid, { ref: internalRef, id: id, className: `tm-datagrid ${hasFilters ? 'has-filters' : ''}`,
219
316
  // main properties
220
317
  keyExpr: keyExpr, dataSource: dataSource, selectedRowKeys: selectedRowKeys, focusedRowEnabled: focusedRowEnabled, hoverStateEnabled: hoverStateEnabled,
221
318
  // events and callbacks
222
- onSelectionChanged: onSelectionChangedCallback, onRowDblClick: onRowDblClickCallback, onRowPrepared: onRowPrepared, onContextMenuPreparing: onContextMenuPreparingCallback, onToolbarPreparing: onToolbarPreparingCallback, onFocusedRowChanged: onFocusedRowChanged, onRowClick: onRowClick, onCellClick: onCellClick, onCellDblClick: onCellDblClick, onOptionChanged: onOptionChangedCallback, onContentReady: onContentReadyCallback, onInitialized: onInitialized, customizeColumns: customizeColumns, onEditorPreparing: onEditorPreparing, onCellPrepared: onCellPrepared, onRowUpdating: onRowUpdating, onRowExpanded: onRowExpanded, onRowCollapsed: onRowCollapsed, onRowUpdated: onRowUpdated, onSaved: onSaved, onEditCanceled: onEditCanceled, onEditingStart: onEditingStart, onEditingChange: onEditingChange, onKeyDown: onKeyDown,
319
+ onSelectionChanged: onSelectionChangedCallback, onRowDblClick: onRowDblClickCallback, onRowPrepared: onRowPrepared, onContextMenuPreparing: customContextMenuItems ? undefined : onContextMenuPreparingCallback, onToolbarPreparing: onToolbarPreparingCallback, onFocusedRowChanged: onFocusedRowChanged, onRowClick: onRowClick, onCellClick: onCellClick, onCellDblClick: onCellDblClick, onOptionChanged: onOptionChangedCallback, onContentReady: onContentReadyCallback, onInitialized: onInitialized, customizeColumns: customizeColumns, onEditorPreparing: onEditorPreparing, onCellPrepared: onCellPrepared, onRowUpdating: onRowUpdating, onRowExpanded: onRowExpanded, onRowCollapsed: onRowCollapsed, onRowUpdated: onRowUpdated, onSaved: onSaved, onEditCanceled: onEditCanceled, onEditingStart: onEditingStart, onEditingChange: onEditingChange, onKeyDown: onKeyDown,
223
320
  // other properties
224
321
  disabled: disabled, autoNavigateToFocusedRow: autoNavigateToFocusedRow, focusedRowKey: focusedRowKey, columnHidingEnabled: columnHidingEnabled, columnResizingMode: columnResizingMode, columnAutoWidth: columnAutoWidth, allowColumnResizing: allowColumnResizing, allowColumnReordering: allowColumnReordering, showBorders: showBorders, showRowLines: showRowLines, showColumnLines: showColumnLines, showColumnHeaders: showColumnHeaders, rowAlternationEnabled: rowAlternationEnabled, wordWrapEnabled: wordWrapEnabled, noDataText: noDataText,
225
322
  // styles
226
- width: width, height: height, style: { userSelect: 'none' }, children: [dataColumns.map((column, index) => (_jsx(Column, { ...column }, column.caption + index.toString()))), sorting && _jsx(Sorting, { ...sorting }), selection && _jsx(Selection, { ...selection }), scrolling && _jsx(Scrolling, { ...scrolling }), summary && _jsx(Summary, { ...summary }), showHeaderFilter && _jsx(HeaderFilter, { visible: true, ...headerFilter }), rowDragging && _jsx(RowDragging, { ...rowDragging }), filterRow && _jsx(FilterRow, { ...filterRow }), showFilterPanel && _jsx(FilterPanel, { visible: true }), columnChooser && _jsx(ColumnChooser, { ...columnChooser }), stateStoring && _jsx(StateStoring, { ...stateStoring }), groupPanel && _jsx(GroupPanel, { ...groupPanel }), _jsx(Grouping, { contextMenuEnabled: true, ...grouping }), _jsx(LoadPanel, { enabled: showLoadPanel }), _jsx(SearchPanel, { visible: showSearchPanel, searchVisibleColumnsOnly: true, highlightSearchText: true }), editing && _jsx(Editing, { ...editing }), paging && _jsx(Paging, { ...paging }), pager && _jsx(Pager, { ...pager, visible: totalRecordCount > pageSize }), masterDetail && _jsx(MasterDetail, { ...masterDetail })] }) }), counterConfig.show && _jsx("div", { style: { width: "100%", height: "25px", display: "flex", alignItems: "center", gap: "15px", backgroundColor: "#e0e0e0" }, children: _jsx(TMCounterContainer, { items: counterValues, bgColorContainer: counterConfig.bgColorContainer, bgColorItem: counterConfig.bgColorItem, hoverColorItem: counterConfig.hoverColorItem, textColorItem: counterConfig.textColorItem }) })] });
323
+ width: width, height: height, style: { userSelect: 'none' }, children: [dataColumns.map((column, index) => (_jsx(Column, { ...column }, column.caption + index.toString()))), sorting && _jsx(Sorting, { ...sorting }), selection && _jsx(Selection, { ...selection }), scrolling && _jsx(Scrolling, { ...scrolling }), summary && _jsx(Summary, { ...summary }), showHeaderFilter && _jsx(HeaderFilter, { visible: true, ...headerFilter }), rowDragging && _jsx(RowDragging, { ...rowDragging }), filterRow && _jsx(FilterRow, { ...filterRow }), showFilterPanel && _jsx(FilterPanel, { visible: true }), showHeaderColumnChooser && _jsxs(ColumnChooser, { height: "400px", enabled: !showHeaderColumnChooser, mode: "select", children: [_jsx(Position, { my: "center", at: "center", of: window }), _jsx(ColumnChooserSearch, { enabled: true }), _jsx(ColumnChooserSelection, { allowSelectAll: false, selectByClick: true, recursive: true })] }), stateStoring && _jsx(StateStoring, { ...stateStoring }), groupPanel && _jsx(GroupPanel, { ...groupPanel }), _jsx(Grouping, { contextMenuEnabled: true, ...grouping }), _jsx(LoadPanel, { enabled: showLoadPanel }), _jsx(SearchPanel, { visible: showSearchPanel, searchVisibleColumnsOnly: true, highlightSearchText: true }), editing && _jsx(Editing, { ...editing }), paging && _jsx(Paging, { ...paging }), pager && _jsx(Pager, { ...pager, visible: totalRecordCount > pageSize }), masterDetail && _jsx(MasterDetail, { ...masterDetail })] }) }), counterConfig.show && _jsx("div", { style: { width: "100%", height: "25px", display: "flex", alignItems: "center", gap: "15px", backgroundColor: "#e0e0e0" }, children: _jsx(TMCounterContainer, { items: counterValues, bgColorContainer: counterConfig.bgColorContainer, bgColorItem: counterConfig.bgColorItem, hoverColorItem: counterConfig.hoverColorItem, textColorItem: counterConfig.textColorItem }) }), customContextMenuItems && (_jsx(TMContextMenu, { items: processCustomContextMenuItems(customContextMenuItems, customContextMenuRowKey), externalControl: {
324
+ visible: customContextMenuVisible,
325
+ position: customContextMenuPosition,
326
+ onClose: () => setCustomContextMenuVisible(false)
327
+ } }))] });
227
328
  });
228
329
  export default TMDataGrid;
229
330
  const getRecordCount = (dataSource) => {
@@ -13,8 +13,15 @@ import TMChooserForm from '../forms/TMChooserForm';
13
13
  import TMSpinner from '../base/TMSpinner';
14
14
  const TMMetadataChooser = ({ tmSession, dataSource, showEditButton = true, buttons = [], disabled, validationItems, getColorIndex, showCompleteMetadataName, qdShowOnlySelectItems, borderRadius = '4px', fontSize = FontSize.defaultFontSize, backgroundColor, openEditorOnSummaryClick, showBorder = true, showId = false, elementStyle, allowMultipleSelection, allowSysMetadata, showSysMetadataDirectly, value, values, isModifiedWhen, tids, label, width, height, showClearButton, qd, placeHolder, filterMetadata, onValueChanged }) => {
15
15
  const [showChooser, setShowChooser] = useState(false);
16
+ const getinputMd = () => {
17
+ if (values && values.length > 0 && values[0].mid && values[0].mid < 0) {
18
+ let md = dataSource?.find((md) => md.id === values[0].mid);
19
+ return md;
20
+ }
21
+ return undefined;
22
+ };
16
23
  const renderTemplate = useMemo(() => {
17
- return (_jsxs(StyledDivHorizontal, { style: { width: 'max-content', height: '100%' }, children: [values && _jsx(TMMidViewer, { tmSession: tmSession, tid_mid: values[0], showIcon: true, showId: showId, showCompleteName: showCompleteMetadataName }), values && values.length > 1 && _jsx("p", { style: { marginLeft: '10px' }, children: `(+${values.length - 1} ${values.length == 2 ? 'altro' : 'altri'})` }), (values == undefined || values.length == 0) && _jsx("p", { children: placeHolder })] }));
24
+ return (_jsxs(StyledDivHorizontal, { style: { width: 'max-content', height: '100%' }, children: [values && values.length > 0 && values[0].mid && values[0].mid > 0 && _jsx(TMMidViewer, { tmSession: tmSession, tid_mid: values[0], showIcon: true, showId: showId, showCompleteName: showCompleteMetadataName }), values && values.length > 0 && values[0].mid && values[0].mid < 0 && _jsx(TMMidViewer, { tmSession: tmSession, tid_mid: values[0], inputMd: getinputMd(), showIcon: true, showId: showId, showCompleteName: showCompleteMetadataName }), values && values.length > 1 && _jsx("p", { style: { marginLeft: '10px' }, children: `(+${values.length - 1} ${values.length == 2 ? 'altro' : 'altri'})` }), (values == undefined || values.length == 0) && _jsx("p", { children: placeHolder })] }));
18
25
  }, [values, tmSession, showId, showCompleteMetadataName, placeHolder]);
19
26
  return (_jsxs(_Fragment, { children: [_jsx(TMSummary, { label: label, width: width, height: height, disabled: disabled, validationItems: validationItems, backgroundColor: backgroundColor, buttons: buttons, placeHolder: placeHolder, fontSize: fontSize, showBorder: showBorder, borderRadius: borderRadius, hasValue: values && values.length > 0, showClearButton: showClearButton, showEditButton: showEditButton, iconEditButton: _jsx(IconSearch, { fontSize: 16 }), openEditorOnSummaryClick: openEditorOnSummaryClick, onEditorClick: () => !disabled && setShowChooser(true), elementStyle: elementStyle, isModifiedWhen: isModifiedWhen, template: renderTemplate, onClearClick: showClearButton ? () => { onValueChanged?.([]); } : undefined }), showChooser &&
20
27
  _jsx(TMMetadataChooserForm, { tmSession: tmSession, allowMultipleSelection: allowMultipleSelection, height: '500px', width: '600px', allowSysMetadata: allowSysMetadata, showSysMetadataDirectly: showSysMetadataDirectly, getColorIndex: getColorIndex, dataSource: dataSource, tids: tids, qd: qd, qdShowOnlySelectItems: qdShowOnlySelectItems, filterMetadata: filterMetadata, selectedIDs: values, onClose: () => setShowChooser(false), onChoose: (tid_mids) => { onValueChanged?.(tid_mids); } })] }));
@@ -170,7 +170,7 @@ const TMHtmlEditor = (props) => {
170
170
  justifyContent: 'flex-end',
171
171
  fontSize: 12,
172
172
  color: '#6c757d',
173
- marginTop: 4,
173
+ marginTop: showInfoIcon ? 0 : 4,
174
174
  gap: 4,
175
175
  }, children: [`${Math.max(charactersRemaining, 0)} ${SDKUI_Localizator.CharactersRemaining}`, showInfoIcon && (_jsx(TMTooltip, { content: 'Markup HTML', children: _jsx("span", { className: "dx-icon-codeblock", style: { fontSize: 22, cursor: 'pointer' }, onClick: () => {
176
176
  TMMessageBoxManager.show({
@@ -389,17 +389,35 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
389
389
  return (_jsxs("div", { style: { width: '100%' }, children: [draftData.length > 0 && _jsx(TMAccordion, { title: SDKUI_Localizator.Draft, children: draftData.map(item => renderMetadataItem(item, isReadOnly)) }), checkOutData.length > 0 && _jsx(TMAccordion, { title: `${SDKUI_Localizator.CheckIn}/${SDKUI_Localizator.CheckOut}`, children: checkOutData.map(item => renderMetadataItem(item, true)) })] }));
390
390
  }, [metadataValues, showCheckBoxes, showNullValueCheckBoxes, isReadOnly, dynDataListsToBeRefreshed, validationItems, selectedMID, isOpenDistinctValues, openChooserBySingleClick, metadataValuesOrig]);
391
391
  const layoutChronology = useMemo(() => {
392
- const chronologyData = [];
392
+ // Definiamo l'ordine desiderato: Version, Tipo, Dimensione, Autore, Data Ultima modifica
393
+ const desiredChronologyOrder = [
394
+ ChronologyMIDs.Ver,
395
+ SystemMIDsAsNumber.FileExt,
396
+ SystemMIDsAsNumber.FileSize,
397
+ ChronologyMIDs.AuthorID,
398
+ ChronologyMIDs.CheckInTime,
399
+ ];
400
+ const tempChronologyDataMap = {};
393
401
  metadataValues.forEach(item => {
394
402
  switch (item.md?.id) {
395
403
  case ChronologyMIDs.Ver:
396
404
  case ChronologyMIDs.AuthorID:
397
- chronologyData.push(item);
405
+ case ChronologyMIDs.CheckInTime:
406
+ case SystemMIDsAsNumber.FileExt:
407
+ case SystemMIDsAsNumber.FileSize:
408
+ tempChronologyDataMap[item.md.id] = item;
398
409
  break;
399
410
  default:
400
411
  break;
401
412
  }
402
413
  });
414
+ // Visualizziamo nell'ordine desiderato
415
+ const chronologyData = [];
416
+ desiredChronologyOrder.forEach(id => {
417
+ if (tempChronologyDataMap[id]) {
418
+ chronologyData.push(tempChronologyDataMap[id]);
419
+ }
420
+ });
403
421
  return (_jsx("div", { style: { width: '100%' }, children: chronologyData.length > 0 && chronologyData.map(item => renderMetadataItem(item, isReadOnly)) }));
404
422
  }, [metadataValues, showCheckBoxes, showNullValueCheckBoxes, isReadOnly, dynDataListsToBeRefreshed, validationItems, selectedMID, isOpenDistinctValues, openChooserBySingleClick, metadataValuesOrig]);
405
423
  const layoutDsAttachs = useMemo(() => {
@@ -1,16 +1,10 @@
1
1
  import React from 'react';
2
2
  import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
3
3
  interface ITMDcmtBlogProps {
4
- blogsDatasource: HomeBlogPost[];
5
- setBlogsDatasource: (posts: HomeBlogPost[]) => void;
6
- hasLoadedDataOnce: boolean;
7
- setHasLoadedDataOnce: (loaded: boolean) => void;
8
- lastLoadedDid: number | undefined;
9
- setLastLoadedDid: (did: number | undefined) => void;
10
4
  tid: number | undefined;
11
5
  did: number | undefined;
12
- fetchBlogDataAsync: (tid: number | undefined, did: number | undefined) => Promise<void>;
13
6
  isVisible?: boolean;
7
+ fetchBlogDataTrigger?: number;
14
8
  allTasks?: Array<TaskDescriptor>;
15
9
  getAllTasks?: () => Promise<void>;
16
10
  deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
@@ -6,13 +6,40 @@ import { TMNothingToShow } from './TMDcmtPreview';
6
6
  import { IconBoard, SDKUI_Localizator } from '../../../helper';
7
7
  import TMBlogCommentForm from '../blog/TMBlogCommentForm';
8
8
  import TMBlogsPost from '../../grids/TMBlogsPost';
9
- const TMDcmtBlog = ({ blogsDatasource, setBlogsDatasource, hasLoadedDataOnce, setHasLoadedDataOnce, lastLoadedDid, setLastLoadedDid, tid, did, fetchBlogDataAsync, isVisible, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
9
+ import TMSpinner from '../../base/TMSpinner';
10
+ import { TMExceptionBoxManager } from '../../base/TMPopUp';
11
+ const TMDcmtBlog = ({ tid, did, isVisible, fetchBlogDataTrigger, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
12
+ const [blogsDatasource, setBlogsDatasource] = useState([]);
13
+ const [hasLoadedDataOnce, setHasLoadedDataOnce] = useState(false); //traccia se *qualsiasi* dato è stato caricato per la prima volta
14
+ const [lastLoadedDid, setLastLoadedDid] = useState(undefined); // `lastLoadedDid` tiene traccia dell'ultimo `did` per cui abbiamo caricato i dati
10
15
  // State to manage show comment form selected file
11
16
  const [showCommentForm, setShowCommentForm] = useState(false);
12
17
  const [externalBlogPost, setExternalBlogPost] = useState(undefined);
18
+ const fetchBlogDataAsync = useCallback(async (tid, did) => {
19
+ try {
20
+ TMSpinner.show({ description: 'Caricamento - Bacheca...' });
21
+ const res = await SDK_Globals.tmSession?.NewSearchEngine().BlogRetrieveAsync(tid, did);
22
+ setBlogsDatasource(res ?? []);
23
+ setHasLoadedDataOnce(true);
24
+ setLastLoadedDid(did);
25
+ }
26
+ catch (e) {
27
+ let err = e;
28
+ TMExceptionBoxManager.show({ exception: err });
29
+ }
30
+ finally {
31
+ TMSpinner.hide();
32
+ }
33
+ }, []);
13
34
  const showCommentFormCallback = useCallback(() => {
14
35
  setShowCommentForm(true);
15
36
  }, []);
37
+ // useEffect per triggerare il fetch dall'esterno tramite props
38
+ useEffect(() => {
39
+ if (fetchBlogDataTrigger !== undefined && fetchBlogDataTrigger > 0) {
40
+ fetchBlogDataAsync(tid, did);
41
+ }
42
+ }, [fetchBlogDataTrigger, fetchBlogDataAsync, tid, did]);
16
43
  useEffect(() => {
17
44
  if (!tid || !did) {
18
45
  setBlogsDatasource([]);
@@ -21,7 +48,7 @@ const TMDcmtBlog = ({ blogsDatasource, setBlogsDatasource, hasLoadedDataOnce, se
21
48
  }
22
49
  // Condizione per eseguire il fetch:
23
50
  // 1. Il pannello è visibile
24
- // 2. E (non abbiamo ancora caricato dati O il `did` è cambiato rispetto all'ultima volta)
51
+ // 2. E (non abbiamo ancora caricato dati o il `did` è cambiato rispetto all'ultima volta)
25
52
  const shouldFetch = isVisible && (!hasLoadedDataOnce || did !== lastLoadedDid);
26
53
  // Esegui la chiamata API solo se il pannello è visibile E i dati non sono già stati caricati
27
54
  // O, se vuoi ricaricare ogni volta che diventa visibile (ma è meno efficiente per "pesante")