@topconsultnpm/sdkui-react 6.20.0-dev1.13 → 6.20.0-dev1.130

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 (202) hide show
  1. package/lib/assets/Toppy-help-center.png +0 -0
  2. package/lib/assets/headergradient.svg +87 -0
  3. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +322 -30
  4. package/lib/components/NewComponents/ContextMenu/hooks.d.ts +8 -1
  5. package/lib/components/NewComponents/ContextMenu/hooks.js +80 -8
  6. package/lib/components/NewComponents/ContextMenu/index.d.ts +3 -0
  7. package/lib/components/NewComponents/ContextMenu/index.js +2 -0
  8. package/lib/components/NewComponents/ContextMenu/styles.d.ts +9 -1
  9. package/lib/components/NewComponents/ContextMenu/styles.js +146 -47
  10. package/lib/components/NewComponents/ContextMenu/types.d.ts +22 -3
  11. package/lib/components/NewComponents/ContextMenu/useLongPress.d.ts +21 -0
  12. package/lib/components/NewComponents/ContextMenu/useLongPress.js +112 -0
  13. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +620 -125
  14. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +25 -5
  15. package/lib/components/NewComponents/FloatingMenuBar/styles.js +215 -59
  16. package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +12 -3
  17. package/lib/components/base/TMAccordionNew.js +35 -14
  18. package/lib/components/base/TMButton.js +6 -0
  19. package/lib/components/base/TMClosableList.js +4 -0
  20. package/lib/components/base/TMCustomButton.js +61 -17
  21. package/lib/components/base/TMDataGrid.d.ts +7 -4
  22. package/lib/components/base/TMDataGrid.js +153 -11
  23. package/lib/components/base/TMDropDownMenu.js +21 -18
  24. package/lib/components/base/TMFileManager.d.ts +4 -3
  25. package/lib/components/base/TMFileManager.js +32 -24
  26. package/lib/components/base/TMFileManagerDataGridView.d.ts +3 -2
  27. package/lib/components/base/TMFileManagerDataGridView.js +1 -11
  28. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +7 -1
  29. package/lib/components/base/TMFileManagerThumbnailItems.js +5 -2
  30. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +17 -4
  31. package/lib/components/base/TMFileManagerThumbnailsView.js +18 -6
  32. package/lib/components/base/TMFileManagerUtils.d.ts +0 -12
  33. package/lib/components/base/TMListView.js +33 -15
  34. package/lib/components/base/TMPanel.d.ts +1 -1
  35. package/lib/components/base/TMPanel.js +4 -2
  36. package/lib/components/base/TMPopUp.js +6 -0
  37. package/lib/components/base/TMToolbarCard.js +2 -0
  38. package/lib/components/base/TMTreeView.d.ts +2 -1
  39. package/lib/components/base/TMTreeView.js +33 -26
  40. package/lib/components/choosers/TMDataListItemChooser.d.ts +2 -0
  41. package/lib/components/choosers/TMDataListItemChooser.js +8 -2
  42. package/lib/components/choosers/TMDcmtTypeChooser.d.ts +1 -0
  43. package/lib/components/choosers/TMDcmtTypeChooser.js +11 -3
  44. package/lib/components/choosers/TMDistinctValues.js +2 -2
  45. package/lib/components/choosers/TMDynDataListItemChooser.d.ts +2 -0
  46. package/lib/components/choosers/TMDynDataListItemChooser.js +8 -2
  47. package/lib/components/choosers/TMInvoiceRetrieveFormats.js +1 -1
  48. package/lib/components/choosers/TMMetadataChooser.d.ts +2 -0
  49. package/lib/components/choosers/TMMetadataChooser.js +19 -4
  50. package/lib/components/choosers/TMOrderRetrieveFormats.js +1 -1
  51. package/lib/components/choosers/TMUserChooser.d.ts +2 -5
  52. package/lib/components/choosers/TMUserChooser.js +33 -47
  53. package/lib/components/editors/TMCheckBox.js +2 -0
  54. package/lib/components/editors/TMDateBox.js +18 -9
  55. package/lib/components/editors/TMEditorStyled.js +7 -0
  56. package/lib/components/editors/TMLocalizedTextBox.d.ts +3 -1
  57. package/lib/components/editors/TMLocalizedTextBox.js +16 -14
  58. package/lib/components/editors/TMMetadataEditor.d.ts +1 -0
  59. package/lib/components/editors/TMMetadataEditor.js +4 -4
  60. package/lib/components/editors/TMMetadataTextBox.d.ts +9 -0
  61. package/lib/components/editors/TMMetadataTextBox.js +92 -0
  62. package/lib/components/editors/TMMetadataValues.d.ts +2 -0
  63. package/lib/components/editors/TMMetadataValues.js +26 -8
  64. package/lib/components/editors/TMRadioButton.js +2 -0
  65. package/lib/components/editors/TMTextArea.js +18 -30
  66. package/lib/components/editors/TMTextBox.d.ts +1 -1
  67. package/lib/components/editors/TMTextBox.js +29 -4
  68. package/lib/components/editors/TMTextExpression.js +6 -91
  69. package/lib/components/features/archive/TMArchive.js +2 -2
  70. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +15 -0
  71. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.js +462 -0
  72. package/lib/components/features/assistant/TMToppySpeechBubble.d.ts +11 -0
  73. package/lib/components/features/assistant/TMToppySpeechBubble.js +126 -0
  74. package/lib/components/features/documents/TMDcmtBlog.js +1 -1
  75. package/lib/components/features/documents/TMDcmtForm.d.ts +14 -2
  76. package/lib/components/features/documents/TMDcmtForm.js +576 -292
  77. package/lib/components/features/documents/TMDcmtPreview.js +42 -155
  78. package/lib/components/features/documents/TMDcmtTasks.js +9 -9
  79. package/lib/components/features/documents/TMMasterDetailDcmts.js +38 -53
  80. package/lib/components/features/documents/TMRelationViewer.d.ts +1 -1
  81. package/lib/components/features/documents/TMRelationViewer.js +2 -2
  82. package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +8 -0
  83. package/lib/components/features/search/{TMSearchResultCheckoutInfoForm.js → TMDcmtCheckoutInfoForm.js} +2 -2
  84. package/lib/components/features/search/TMSavedQuerySelector.js +72 -67
  85. package/lib/components/features/search/TMSearch.d.ts +3 -0
  86. package/lib/components/features/search/TMSearch.js +50 -11
  87. package/lib/components/features/search/TMSearchQueryEditor.d.ts +1 -0
  88. package/lib/components/features/search/TMSearchQueryEditor.js +10 -10
  89. package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -0
  90. package/lib/components/features/search/TMSearchQueryPanel.js +40 -25
  91. package/lib/components/features/search/TMSearchResult.d.ts +3 -0
  92. package/lib/components/features/search/TMSearchResult.js +370 -252
  93. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +3 -3
  94. package/lib/components/features/search/TMSearchResultsMenuItems.js +227 -171
  95. package/lib/components/features/search/TMSignSettingsForm.js +1 -1
  96. package/lib/components/features/search/TMSignatureInfoContent.d.ts +6 -0
  97. package/lib/components/features/search/TMSignatureInfoContent.js +140 -0
  98. package/lib/components/features/search/TMViewHistoryDcmt.js +47 -52
  99. package/lib/components/features/tasks/TMTaskForm.js +75 -25
  100. package/lib/components/features/tasks/TMTasksAgenda.d.ts +3 -1
  101. package/lib/components/features/tasks/TMTasksAgenda.js +48 -9
  102. package/lib/components/features/tasks/TMTasksCalendar.d.ts +2 -0
  103. package/lib/components/features/tasks/TMTasksCalendar.js +19 -7
  104. package/lib/components/features/tasks/TMTasksUtils.d.ts +2 -2
  105. package/lib/components/features/tasks/TMTasksUtils.js +57 -37
  106. package/lib/components/features/tasks/TMTasksView.js +28 -19
  107. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +33 -2
  108. package/lib/components/features/workflow/TMWorkflowPopup.js +140 -34
  109. package/lib/components/features/workflow/diagram/DiagramItemComponent.d.ts +2 -0
  110. package/lib/components/features/workflow/diagram/DiagramItemComponent.js +14 -7
  111. package/lib/components/features/workflow/diagram/DiagramItemForm.js +1 -1
  112. package/lib/components/features/workflow/diagram/RecipientList.js +3 -2
  113. package/lib/components/features/workflow/diagram/WFDiagram.d.ts +4 -0
  114. package/lib/components/features/workflow/diagram/WFDiagram.js +164 -13
  115. package/lib/components/forms/Login/LoginValidatorService.d.ts +2 -0
  116. package/lib/components/forms/Login/LoginValidatorService.js +7 -2
  117. package/lib/components/forms/Login/TMLoginForm.js +35 -7
  118. package/lib/components/forms/TMChooserForm.js +1 -1
  119. package/lib/components/grids/TMBlogsPost.js +56 -31
  120. package/lib/components/grids/TMRecentsManager.js +20 -10
  121. package/lib/components/grids/TMValidationItemsList.js +6 -0
  122. package/lib/components/index.d.ts +6 -3
  123. package/lib/components/index.js +6 -3
  124. package/lib/components/layout/panelManager/TMPanelManagerContext.js +13 -5
  125. package/lib/components/query/TMQueryEditor.d.ts +6 -1
  126. package/lib/components/query/TMQueryEditor.js +105 -101
  127. package/lib/components/settings/SettingsAppearance.d.ts +2 -1
  128. package/lib/components/settings/SettingsAppearance.js +99 -30
  129. package/lib/components/sidebar/TMHeader.js +11 -7
  130. package/lib/components/sidebar/TMSidebar.d.ts +0 -1
  131. package/lib/components/sidebar/TMSidebar.js +16 -44
  132. package/lib/components/sidebar/TMSidebarItem.js +36 -17
  133. package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -1
  134. package/lib/components/viewers/TMDataListItemViewer.js +35 -71
  135. package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +8 -0
  136. package/lib/components/viewers/TMDataUserIdItemViewer.js +39 -0
  137. package/lib/css/tm-sdkui.css +1 -1
  138. package/lib/helper/SDKUI_Globals.d.ts +22 -0
  139. package/lib/helper/SDKUI_Globals.js +10 -1
  140. package/lib/helper/SDKUI_Localizator.d.ts +21 -3
  141. package/lib/helper/SDKUI_Localizator.js +196 -10
  142. package/lib/helper/TMCommandsContextMenu.d.ts +4 -2
  143. package/lib/helper/TMCommandsContextMenu.js +15 -4
  144. package/lib/helper/TMIcons.d.ts +4 -0
  145. package/lib/helper/TMIcons.js +13 -3
  146. package/lib/helper/TMPdfViewer.d.ts +8 -0
  147. package/lib/helper/TMPdfViewer.js +373 -0
  148. package/lib/helper/TMToppyMessage.js +4 -0
  149. package/lib/helper/checkinCheckoutManager.d.ts +31 -1
  150. package/lib/helper/checkinCheckoutManager.js +112 -30
  151. package/lib/helper/devextremeCustomMessages.d.ts +30 -0
  152. package/lib/helper/devextremeCustomMessages.js +30 -0
  153. package/lib/helper/helpers.d.ts +30 -2
  154. package/lib/helper/helpers.js +132 -4
  155. package/lib/helper/index.d.ts +2 -0
  156. package/lib/helper/index.js +2 -0
  157. package/lib/helper/queryHelper.d.ts +2 -2
  158. package/lib/helper/queryHelper.js +80 -24
  159. package/lib/helper/workItemsHelper.d.ts +6 -0
  160. package/lib/helper/workItemsHelper.js +230 -0
  161. package/lib/hooks/useCheckInOutOperations.d.ts +28 -0
  162. package/lib/hooks/useCheckInOutOperations.js +223 -0
  163. package/lib/hooks/useDataListItem.d.ts +12 -0
  164. package/lib/hooks/useDataListItem.js +132 -0
  165. package/lib/hooks/useDataUserIdItem.d.ts +10 -0
  166. package/lib/hooks/useDataUserIdItem.js +96 -0
  167. package/lib/hooks/useFloatingBarPinnedItems.d.ts +11 -0
  168. package/lib/hooks/useFloatingBarPinnedItems.js +54 -0
  169. package/lib/hooks/useMetadataExpression.d.ts +19 -0
  170. package/lib/hooks/useMetadataExpression.js +99 -0
  171. package/lib/hooks/useSettingsFeedback.d.ts +11 -0
  172. package/lib/hooks/useSettingsFeedback.js +38 -0
  173. package/lib/hooks/useWorkflowApprove.d.ts +4 -0
  174. package/lib/hooks/useWorkflowApprove.js +14 -1
  175. package/lib/index.d.ts +1 -0
  176. package/lib/index.js +3 -2
  177. package/lib/services/platform_services.d.ts +3 -3
  178. package/lib/ts/types.d.ts +61 -1
  179. package/lib/utils/theme.d.ts +1 -1
  180. package/lib/utils/theme.js +1 -1
  181. package/package.json +6 -5
  182. package/lib/components/NewComponents/Notification/Notification.d.ts +0 -4
  183. package/lib/components/NewComponents/Notification/Notification.js +0 -60
  184. package/lib/components/NewComponents/Notification/NotificationContainer.d.ts +0 -8
  185. package/lib/components/NewComponents/Notification/NotificationContainer.js +0 -33
  186. package/lib/components/NewComponents/Notification/index.d.ts +0 -2
  187. package/lib/components/NewComponents/Notification/index.js +0 -2
  188. package/lib/components/NewComponents/Notification/styles.d.ts +0 -21
  189. package/lib/components/NewComponents/Notification/styles.js +0 -180
  190. package/lib/components/NewComponents/Notification/types.d.ts +0 -18
  191. package/lib/components/NewComponents/Notification/types.js +0 -1
  192. package/lib/components/base/TMContextMenu.d.ts +0 -25
  193. package/lib/components/base/TMContextMenu.js +0 -109
  194. package/lib/components/base/TMContextMenuOLD.d.ts +0 -26
  195. package/lib/components/base/TMContextMenuOLD.js +0 -56
  196. package/lib/components/base/TMFloatingToolbar.d.ts +0 -9
  197. package/lib/components/base/TMFloatingToolbar.js +0 -101
  198. package/lib/components/features/assistant/ToppyDraggableHelpCenter.d.ts +0 -30
  199. package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +0 -482
  200. package/lib/components/features/assistant/ToppySpeechBubble.d.ts +0 -9
  201. package/lib/components/features/assistant/ToppySpeechBubble.js +0 -117
  202. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.d.ts +0 -8
@@ -4,31 +4,68 @@ import TMModal from './TMModal';
4
4
  import styled from 'styled-components';
5
5
  import { SDKUI_Localizator, TMLayoutWaitingContainer } from '../..';
6
6
  import { getButtonAttributes, getSelectedItem } from '../../helper/dcmtsHelper';
7
+ import { DeviceType, useDeviceType } from './TMDeviceProvider';
7
8
  const IframeContainer = styled.div `
8
9
  display: flex;
9
10
  height: 100%;
10
11
  flex-direction: column;
11
- padding-left: 15px;
12
+ position: relative;
12
13
  `;
13
14
  const StyledIframe = styled.iframe `
14
15
  border: none;
15
16
  flex: 1;
16
17
  `;
18
+ const LoadingOverlay = styled.div `
19
+ position: absolute;
20
+ top: 0;
21
+ left: 0;
22
+ right: 0;
23
+ bottom: 0;
24
+ background-color: rgba(128, 128, 128, 0.3);
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ z-index: 1000;
29
+
30
+ &::after {
31
+ content: '';
32
+ width: 40px;
33
+ height: 40px;
34
+ border: 4px solid rgba(255, 255, 255, 0.3);
35
+ border-top-color: #fff;
36
+ border-radius: 50%;
37
+ animation: spin 0.8s linear infinite;
38
+ }
39
+
40
+ @keyframes spin {
41
+ to {
42
+ transform: rotate(360deg);
43
+ }
44
+ }
45
+ `;
17
46
  const TMCustomButton = (props) => {
18
47
  const { button, isModal = true, formData, selectedItems, onClose } = props;
19
48
  const { appName: scriptUrl, arguments: args } = button;
49
+ const Device = useDeviceType();
20
50
  const iframeRef = useRef(null);
21
51
  const attributes = useMemo(() => getButtonAttributes(args, formData, selectedItems), [args, formData, selectedItems]);
22
52
  const RunOnce = button.mode === "RunOnce";
23
53
  const [loading, setLoading] = useState(true);
24
54
  const [error, setError] = useState(false);
25
- const selectedItemsCount = selectedItems?.length || 0;
55
+ const itemsToProcess = useMemo(() => selectedItems && selectedItems.length > 0 ? selectedItems : [attributes], [selectedItems, attributes]);
26
56
  // Stati per il wait panel
27
- const [showWaitPanel, setShowWaitPanel] = useState(selectedItemsCount > 0 && !RunOnce);
28
- const [waitPanelText, setWaitPanelText] = useState(SDKUI_Localizator.CustomButtonActions.replaceParams(1, selectedItemsCount));
57
+ const [showWaitPanel, setShowWaitPanel] = useState(itemsToProcess.length > 0 && !RunOnce);
58
+ const [waitPanelText, setWaitPanelText] = useState(SDKUI_Localizator.CustomButtonActions.replaceParams(1, itemsToProcess.length));
29
59
  const [waitPanelValue, setWaitPanelValue] = useState(0);
30
- const [waitPanelMaxValue, setWaitPanelMaxValue] = useState(selectedItemsCount);
60
+ const [waitPanelMaxValue, setWaitPanelMaxValue] = useState(itemsToProcess.length);
31
61
  const [abortController, setAbortController] = useState(undefined);
62
+ // Aggiungi timestamp all'URL per evitare cache
63
+ const iframeUrl = useMemo(() => {
64
+ if (!scriptUrl)
65
+ return '';
66
+ const separator = scriptUrl.includes('?') ? '&' : '?';
67
+ return `${scriptUrl}${separator}t=${Date.now()}`;
68
+ }, [scriptUrl]);
32
69
  const targetOrigin = useMemo(() => {
33
70
  if (!scriptUrl)
34
71
  return '*';
@@ -41,26 +78,35 @@ const TMCustomButton = (props) => {
41
78
  }
42
79
  }, [scriptUrl]);
43
80
  const handleLoad = () => setLoading(false);
81
+ const isMobile = Device === DeviceType.MOBILE;
44
82
  const handleError = () => {
45
83
  setLoading(false);
46
84
  setError(true);
47
85
  };
48
86
  const executeSequentially = async (controller) => {
49
- if (!selectedItems)
87
+ if (!itemsToProcess)
50
88
  return;
51
- for (const [index, item] of selectedItems.entries()) {
89
+ for (const [index, item] of itemsToProcess.entries()) {
52
90
  if (controller.signal.aborted)
53
91
  break;
54
- setWaitPanelText(SDKUI_Localizator.CustomButtonActions.replaceParams(index + 1, selectedItemsCount));
92
+ setWaitPanelText(SDKUI_Localizator.CustomButtonActions.replaceParams(index + 1, itemsToProcess.length));
55
93
  setWaitPanelValue(index);
56
94
  // Attendi che l'iframe sia pronto e invia il messaggio
57
95
  await new Promise((resolve) => {
58
96
  const checkIframe = setInterval(() => {
59
97
  if (iframeRef.current?.contentWindow) {
60
98
  clearInterval(checkIframe);
61
- //devo convertire item in formData
62
- const processedItem = getSelectedItem(args, formData, item);
63
- postMessageIframe(processedItem);
99
+ if (selectedItems && selectedItems.length > 0) {
100
+ //devo convertire item in formData
101
+ const processedItem = getSelectedItem(args, formData, item);
102
+ postMessageIframe(processedItem);
103
+ }
104
+ else {
105
+ postMessageIframe(item);
106
+ }
107
+ //imposta 100% se sono all'ultimo item
108
+ if (index === itemsToProcess.length - 1)
109
+ setWaitPanelValue(index + 1);
64
110
  // Attendi prima di passare al prossimo
65
111
  setTimeout(() => {
66
112
  setWaitPanelValue(index + 1);
@@ -82,8 +128,7 @@ const TMCustomButton = (props) => {
82
128
  useEffect(() => {
83
129
  if (loading || error)
84
130
  return;
85
- //if(error) clearTimeout(timeoutIframe);
86
- if (!RunOnce && selectedItemsCount > 0) {
131
+ if (!RunOnce && itemsToProcess.length > 0) {
87
132
  // esegui per ogni item selezionato
88
133
  const controller = new AbortController();
89
134
  controller.signal.addEventListener('abort', () => {
@@ -91,7 +136,7 @@ const TMCustomButton = (props) => {
91
136
  onClose?.();
92
137
  });
93
138
  setAbortController(controller);
94
- setWaitPanelMaxValue(selectedItemsCount);
139
+ setWaitPanelMaxValue(itemsToProcess.length);
95
140
  executeSequentially(controller);
96
141
  }
97
142
  else {
@@ -103,7 +148,6 @@ const TMCustomButton = (props) => {
103
148
  onClose?.();
104
149
  }, 2000);
105
150
  }
106
- //clearTimeout(timeoutIframe);
107
151
  }
108
152
  }, [loading, error, RunOnce]);
109
153
  useEffect(() => {
@@ -112,7 +156,7 @@ const TMCustomButton = (props) => {
112
156
  onClose?.();
113
157
  }
114
158
  }, []);
115
- const iframeContent = (_jsxs(IframeContainer, { style: !RunOnce ? { visibility: 'hidden' } : {}, children: [error && _jsx("div", { children: "Si \u00E8 verificato un errore nel caricamento del contenuto." }), !error && _jsx(StyledIframe, { ref: iframeRef, loading: 'lazy', onLoad: handleLoad, onError: handleError, src: scriptUrl })] }));
116
- return isModal && RunOnce ? (_jsx(TMModal, { title: button.title, width: '60%', height: '70%', resizable: true, expandable: true, onClose: onClose, children: iframeContent })) : !RunOnce && (_jsxs(_Fragment, { children: [_jsx(TMLayoutWaitingContainer, { showWaitPanel: showWaitPanel, waitPanelTitle: SDKUI_Localizator.CustomButtonAction, showWaitPanelPrimary: true, waitPanelTextPrimary: waitPanelText, waitPanelValuePrimary: waitPanelValue, waitPanelMaxValuePrimary: waitPanelMaxValue, showWaitPanelSecondary: false, isCancelable: true, abortController: abortController, children: undefined }), iframeContent] }));
159
+ const iframeContent = (_jsxs(IframeContainer, { style: !RunOnce ? { visibility: 'hidden' } : {}, children: [loading && _jsx(LoadingOverlay, {}), error && _jsx("div", { children: "Si \u00E8 verificato un errore nel caricamento del contenuto." }), !error && _jsx(StyledIframe, { ref: iframeRef, loading: 'lazy', onLoad: handleLoad, onError: handleError, src: iframeUrl })] }));
160
+ return isModal && RunOnce ? (_jsx(TMModal, { title: button.title, width: isMobile ? '95%' : '60%', height: isMobile ? '95%' : '70%', resizable: isMobile ? false : true, expandable: isMobile ? false : true, onClose: onClose, children: iframeContent })) : !RunOnce && (_jsxs(_Fragment, { children: [_jsx(TMLayoutWaitingContainer, { showWaitPanel: showWaitPanel, waitPanelTitle: SDKUI_Localizator.CustomButtonAction, showWaitPanelPrimary: true, waitPanelTextPrimary: waitPanelText, waitPanelValuePrimary: waitPanelValue, waitPanelMaxValuePrimary: waitPanelMaxValue, showWaitPanelSecondary: false, isCancelable: true, abortController: abortController, children: undefined }), iframeContent] }));
117
161
  };
118
162
  export default TMCustomButton;
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { IColumnProps, IDataGridOptions, IMasterDetailProps } from 'devextreme-react/data-grid';
3
3
  import dxDataGrid from 'devextreme/ui/data_grid';
4
4
  import { ITMCounterContainerProps } from './TMCounterContainer';
5
+ import { TMContextMenuItemProps } from '../NewComponents/ContextMenu/types';
5
6
  export interface TMDataGridContextMenuItem {
6
7
  text: string;
7
8
  icon: string;
@@ -31,16 +32,16 @@ export interface TMDataGridProps<T> extends IDataGridOptions {
31
32
  pageSize?: TMDataGridPageSize;
32
33
  /** Configures the search panel position in the toolbar */
33
34
  searchPanelToolbarPosition?: 'before' | 'default';
34
- /** if visible, set focus on SearchPanel */
35
- searchPanelFocusStarting?: boolean;
35
+ /** Trigger to set focus on SearchPanel (only if visible) - change the number to trigger focus */
36
+ searchPanelFocusTrigger?: number;
36
37
  /** Show the header filter */
37
38
  showHeaderFilter?: boolean;
38
39
  /** Show the filter panel */
39
40
  showFilterPanel?: boolean;
40
41
  /** Show the load panel */
41
42
  showLoadPanel?: boolean;
42
- /** Show the column chooser */
43
- showColumnChooser?: boolean;
43
+ /** Show the header column chooser in context menu */
44
+ showHeaderColumnChooser?: boolean;
44
45
  /** Show the search panel */
45
46
  showSearchPanel?: boolean;
46
47
  /** Show the group panel */
@@ -51,6 +52,8 @@ export interface TMDataGridProps<T> extends IDataGridOptions {
51
52
  masterDetail?: IMasterDetailProps;
52
53
  /** On Has Filters Change */
53
54
  onHasFiltersChange?: (hasFilters: boolean) => void;
55
+ /** Custom context menu items - when provided, replaces DevExtreme's native context menu with TMContextMenu */
56
+ customContextMenuItems?: TMContextMenuItemProps[];
54
57
  }
55
58
  declare const TMDataGrid: React.ForwardRefExoticComponent<TMDataGridProps<unknown> & React.RefAttributes<dxDataGrid<any, any>>>;
56
59
  export default TMDataGrid;
@@ -1,9 +1,11 @@
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';
8
+ import { useLongPress } from '../NewComponents/ContextMenu/useLongPress';
7
9
  ;
8
10
  export var TMDataGridPageSize;
9
11
  (function (TMDataGridPageSize) {
@@ -16,9 +18,9 @@ const TMDataGrid = React.forwardRef((props, ref) => {
16
18
  // main properties
17
19
  keyExpr = 'id', dataSource, focusedRowEnabled = true, hoverStateEnabled = true, focusedRowKey, selectedRowKeys = [],
18
20
  // 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,
21
+ 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
22
  // 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,
23
+ 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
24
  // other properties
23
25
  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
26
  // styles
@@ -29,10 +31,84 @@ const TMDataGrid = React.forwardRef((props, ref) => {
29
31
  const [totalRecordCount, setTotalRecordCount] = useState(0);
30
32
  const [visibleItemsCount, setVisibleItemsCount] = useState(0);
31
33
  const [hasFilters, setHasFilters] = useState(false);
34
+ // Custom context menu states
35
+ const [customContextMenuVisible, setCustomContextMenuVisible] = useState(false);
36
+ const [customContextMenuPosition, setCustomContextMenuPosition] = useState({ x: 0, y: 0 });
37
+ const [customContextMenuRowKey, setCustomContextMenuRowKey] = useState(undefined);
38
+ const gridContainerRef = useRef(null);
32
39
  useEffect(() => {
33
40
  const count = getRecordCount(dataSource);
34
41
  setTotalRecordCount(count);
35
42
  }, [dataSource]);
43
+ // Handle search panel focus when trigger changes
44
+ useEffect(() => {
45
+ if (!searchPanelFocusTrigger || searchPanelFocusTrigger <= 0 || !showSearchPanel || !internalRef.current)
46
+ return;
47
+ setTimeout(() => {
48
+ const searchInput = internalRef.current?.instance().element().querySelector('.dx-datagrid-search-panel input');
49
+ if (searchInput) {
50
+ searchInput.focus();
51
+ }
52
+ }, 100);
53
+ }, [searchPanelFocusTrigger, showSearchPanel]);
54
+ // Handle custom context menu (only when customContextMenuItems is provided)
55
+ useEffect(() => {
56
+ if (!customContextMenuItems || !gridContainerRef.current)
57
+ return;
58
+ const gridContainer = gridContainerRef.current;
59
+ const handleContextMenu = (e) => {
60
+ e.preventDefault();
61
+ e.stopPropagation();
62
+ // Get the clicked row (if any)
63
+ const target = e.target;
64
+ const rowElement = target.closest('.dx-data-row');
65
+ if (rowElement && internalRef.current) {
66
+ // Clicked on a row - focus that row
67
+ const rowIndex = Array.from(rowElement.parentElement?.children || []).indexOf(rowElement);
68
+ const rowKey = internalRef.current.instance().getKeyByRowIndex(rowIndex);
69
+ internalRef.current.instance().option('focusedRowKey', rowKey);
70
+ setCustomContextMenuRowKey(rowKey);
71
+ }
72
+ else {
73
+ setCustomContextMenuRowKey(focusedRowKey);
74
+ }
75
+ setCustomContextMenuVisible(true);
76
+ setCustomContextMenuPosition({ x: e.clientX, y: e.clientY });
77
+ };
78
+ gridContainer.addEventListener('contextmenu', handleContextMenu);
79
+ return () => {
80
+ gridContainer.removeEventListener('contextmenu', handleContextMenu);
81
+ };
82
+ }, [customContextMenuItems, focusedRowKey]);
83
+ // iOS-specific: Handle touch for focused row change and long-press for context menu
84
+ useLongPress({
85
+ containerRef: gridContainerRef,
86
+ targetSelector: '.dx-data-row',
87
+ enabled: !!customContextMenuItems,
88
+ onTouchStart: ({ rowElement }) => {
89
+ // Change focused row immediately on touch (fixes focus issue)
90
+ if (!internalRef.current)
91
+ return;
92
+ const rowIndex = Array.from(rowElement.parentElement?.children || []).indexOf(rowElement);
93
+ const rowKey = internalRef.current.instance().getKeyByRowIndex(rowIndex);
94
+ if (rowKey !== undefined && rowKey !== focusedRowKey) {
95
+ internalRef.current.instance().option('focusedRowKey', rowKey);
96
+ }
97
+ },
98
+ onLongPress: ({ clientX, clientY, target }) => {
99
+ if (!internalRef.current)
100
+ return;
101
+ const rowElement = target.closest('.dx-data-row');
102
+ if (!rowElement)
103
+ return;
104
+ const rowIndex = Array.from(rowElement.parentElement?.children || []).indexOf(rowElement);
105
+ const rowKey = internalRef.current.instance().getKeyByRowIndex(rowIndex);
106
+ // Show context menu
107
+ setCustomContextMenuVisible(true);
108
+ setCustomContextMenuPosition({ x: clientX, y: clientY });
109
+ setCustomContextMenuRowKey(rowKey);
110
+ },
111
+ });
36
112
  // Creating a ref to store the timestamp of the last selection change
37
113
  const lastSelectionChangeTime = useRef(Date.now());
38
114
  useEffect(() => {
@@ -101,6 +177,8 @@ const TMDataGrid = React.forwardRef((props, ref) => {
101
177
  }
102
178
  return {
103
179
  ...item,
180
+ // Ensure icon is not null/undefined to prevent DevExtreme errors
181
+ icon: item.icon || '',
104
182
  disabled: disabled || disabledCalculation, // An item is disabled if it's explicitly set to `true` or if the calculation above determines so
105
183
  // Define the behavior when the menu item is clicked
106
184
  onClick: () => {
@@ -132,12 +210,68 @@ const TMDataGrid = React.forwardRef((props, ref) => {
132
210
  };
133
211
  });
134
212
  }, [focusedRowEnabled, focusedRowKey, selectedRowKeys]);
135
- // Handle context menu preparation
213
+ // Process custom context menu items (for TMContextMenuItemProps)
214
+ const processCustomContextMenuItems = useCallback((items, rowID) => {
215
+ return items.map(item => {
216
+ let disabled = item.disabled ?? false;
217
+ let disabledCalculation = false;
218
+ const id = focusedRowEnabled ? focusedRowKey : rowID;
219
+ if (item.operationType === 'singleRow') {
220
+ disabledCalculation = selectedRowKeys.length > 1 || id === undefined;
221
+ }
222
+ if (item.operationType === 'multiRow') {
223
+ disabledCalculation = selectedRowKeys.length === 0 && id === undefined;
224
+ }
225
+ const originalOnClick = item.onClick;
226
+ return {
227
+ ...item,
228
+ disabled: disabled || disabledCalculation,
229
+ onClick: originalOnClick ? () => {
230
+ if (item.operationType === 'singleRow' && id !== undefined) {
231
+ originalOnClick(id);
232
+ }
233
+ else if (item.operationType === 'multiRow' && id !== undefined) {
234
+ if (selectedRowKeys.length > 0) {
235
+ originalOnClick(selectedRowKeys);
236
+ }
237
+ else {
238
+ originalOnClick([id]);
239
+ }
240
+ }
241
+ else {
242
+ originalOnClick();
243
+ }
244
+ } : undefined,
245
+ submenu: item.submenu ? processCustomContextMenuItems(item.submenu, id) : undefined,
246
+ };
247
+ });
248
+ }, [focusedRowEnabled, focusedRowKey, selectedRowKeys]);
249
+ // Gestisce la preparazione del menu contestuale della griglia (header e righe)
136
250
  const onContextMenuPreparingCallback = useCallback((e) => {
137
251
  if (e === undefined)
138
252
  return;
253
+ // MENU DELL'HEADER: Aggiunge l'opzione "Mostra/nascondi colonne" al menu contestuale dell'intestazione
254
+ if (e.target === 'header' && showHeaderColumnChooser) {
255
+ e.items = e.items || [];
256
+ e.items.push({
257
+ text: SDKUI_Localizator.ShowColumnSelection,
258
+ icon: 'columnchooser',
259
+ onItemClick: () => {
260
+ internalRef.current?.instance().showColumnChooser();
261
+ }
262
+ });
263
+ }
264
+ // MENU PERSONALIZZATO: Se è configurato un menu custom, disabilita completamente il menu nativo di DevExtreme
265
+ // Il menu custom (TMContextMenu) viene gestito separatamente tramite event listener e stato locale
266
+ if (customContextMenuItems && e.target === 'content') {
267
+ e.items = undefined;
268
+ return;
269
+ }
270
+ // Chiama il callback esterno se fornito (permette personalizzazioni aggiuntive dal parent)
139
271
  if (onContextMenuPreparing)
140
272
  onContextMenuPreparing(e);
273
+ // MENU NATIVO DELLE RIGHE: Aggiorna lo stato (enabled/disabled) delle voci in base alla selezione
274
+ // Applica la logica per operazioni singleRow (1 riga) e multiRow (1+ righe)
141
275
  if (e.target === 'content') {
142
276
  e.items = e.items || [];
143
277
  if (e.items.length > 0) {
@@ -146,7 +280,7 @@ const TMDataGrid = React.forwardRef((props, ref) => {
146
280
  e.items = [...updatedContextMenuItems];
147
281
  }
148
282
  }
149
- }, [updateContextMenuItems, onContextMenuPreparing]);
283
+ }, [updateContextMenuItems, onContextMenuPreparing, showHeaderColumnChooser, customContextMenuItems]);
150
284
  // Handle toolbar preparation, especially for the search panel
151
285
  const onToolbarPreparingCallback = useCallback((e) => {
152
286
  if (e === undefined || e.toolbarOptions === undefined || e.toolbarOptions.items === undefined)
@@ -171,10 +305,9 @@ const TMDataGrid = React.forwardRef((props, ref) => {
171
305
  return;
172
306
  // Update state with the current number of visible rows in the DataGrid
173
307
  setVisibleItemsCount(internalRef.current.instance()?.getVisibleRows()?.length ?? 0);
174
- // Focusing SearchPanel
175
- if (showSearchPanel && searchPanelFocusStarting) {
308
+ // Focusing SearchPanel on content ready
309
+ if (showSearchPanel && searchPanelFocusTrigger && searchPanelFocusTrigger > 0) {
176
310
  // 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
311
  setTimeout(() => {
179
312
  const searchInput = internalRef.current?.instance().element().querySelector('.dx-datagrid-search-panel input');
180
313
  if (searchInput) {
@@ -182,7 +315,7 @@ const TMDataGrid = React.forwardRef((props, ref) => {
182
315
  }
183
316
  }, 100);
184
317
  }
185
- }, [onContentReady]);
318
+ }, [onContentReady, showSearchPanel, searchPanelFocusTrigger]);
186
319
  const onOptionChangedCallback = useCallback((e) => {
187
320
  // Assicurati che component esista
188
321
  const grid = e.component;
@@ -215,7 +348,7 @@ const TMDataGrid = React.forwardRef((props, ref) => {
215
348
  // Propaga l'evento originale
216
349
  onOptionChanged?.(e);
217
350
  }, [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' : ''}`,
351
+ 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
352
  // main properties
220
353
  keyExpr: keyExpr, dataSource: dataSource, selectedRowKeys: selectedRowKeys, focusedRowEnabled: focusedRowEnabled, hoverStateEnabled: hoverStateEnabled,
221
354
  // events and callbacks
@@ -223,7 +356,16 @@ const TMDataGrid = React.forwardRef((props, ref) => {
223
356
  // other properties
224
357
  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
358
  // 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 }) })] });
359
+ width: width, height: height, style: {
360
+ userSelect: 'none',
361
+ // Temporary: iOS-specific styles to prevent default long-press menu and text selection
362
+ WebkitTouchCallout: 'none',
363
+ WebkitUserSelect: 'none'
364
+ }, 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, { target: ".dx-data-row", items: processCustomContextMenuItems(customContextMenuItems, customContextMenuRowKey), externalControl: {
365
+ visible: customContextMenuVisible,
366
+ position: customContextMenuPosition,
367
+ onClose: () => setCustomContextMenuVisible(false)
368
+ } }))] });
227
369
  });
228
370
  export default TMDataGrid;
229
371
  const getRecordCount = (dataSource) => {
@@ -1,9 +1,8 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useEffect, useState, forwardRef, useRef, useImperativeHandle } from 'react';
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef, useRef, useImperativeHandle } from 'react';
3
3
  import styled from 'styled-components';
4
- import ContextMenu from 'devextreme-react/context-menu';
5
- import { FontSize, TMColors } from '../../utils/theme';
6
- import { genUniqueId } from '../../helper';
4
+ import { ContextMenu as TMContextMenu } from '../NewComponents/ContextMenu';
5
+ import { TMColors } from '../../utils/theme';
7
6
  const StyledContent = styled.div `
8
7
  cursor: pointer;
9
8
  border-radius: ${props => props.$borderRadius};
@@ -13,6 +12,8 @@ const StyledContent = styled.div `
13
12
  opacity: ${props => props.$disabled ? 0.4 : 1};
14
13
  pointer-events: ${props => props.$disabled ? 'none' : ''};
15
14
  user-select: none;
15
+ -webkit-touch-callout: none;
16
+ -webkit-user-select: none;
16
17
  display: flex;
17
18
  align-items: center;
18
19
 
@@ -22,24 +23,26 @@ const StyledContent = styled.div `
22
23
  border-bottom-color: ${TMColors.primary};
23
24
  }
24
25
  `;
25
- const StyledMenuItem = styled.div `
26
- display: flex;
27
- align-items: center;
28
- justify-content: space-between;
29
- gap: 6px;
30
- width: 100%;
31
- font-size: ${FontSize.defaultFontSize};
32
- `;
33
26
  const TMDropDownMenu = forwardRef(({ content, items, disabled = false, color = TMColors.text_normal, backgroundColor = TMColors.default_background, borderRadius, onMenuShown }, ref) => {
34
- const [id, setID] = useState('');
35
- const dropDownMenuElementRef = useRef(null); // Ref all'elemento DOM div principale
36
- useEffect(() => { setID(genUniqueId()); }, [content]);
27
+ const dropDownMenuElementRef = useRef(null);
37
28
  useImperativeHandle(ref, () => ({
38
29
  focus: () => {
39
30
  dropDownMenuElementRef.current?.focus();
40
31
  },
41
32
  }));
42
- const renderItemTemplate = (itemData) => (_jsxs(StyledMenuItem, { children: [itemData.icon && _jsx("div", { style: { display: 'flex', alignItems: 'center' }, children: itemData.icon }), _jsx("span", { style: { flexGrow: 1 }, children: itemData.text }), itemData.items && _jsx("span", { className: "dx-icon-spinright dx-icon", style: { marginLeft: '10px' } })] }));
43
- return (_jsxs(_Fragment, { children: [_jsx(StyledContent, { id: `idContainer${id}`, ref: dropDownMenuElementRef, tabIndex: disabled ? -1 : 0, "$disabled": disabled, "$color": color, "$backgroundColor": backgroundColor, "$borderRadius": borderRadius, children: content }), _jsx(ContextMenu, { target: `#idContainer${id}`, dataSource: items, showEvent: 'click', itemRender: renderItemTemplate, onShown: (e) => onMenuShown?.(), onHidden: (e) => dropDownMenuElementRef.current?.focus() })] }));
33
+ // Converter function: ITMDropDownMenuItem -> TMContextMenuItemProps
34
+ const convertToContextMenuItems = (dropDownItems) => {
35
+ if (!dropDownItems)
36
+ return [];
37
+ return dropDownItems.map(item => ({
38
+ name: item.text,
39
+ icon: item.icon,
40
+ disabled: item.disabled,
41
+ beginGroup: item.beginGroup,
42
+ onClick: item.onClick,
43
+ submenu: item.items ? convertToContextMenuItems(item.items) : undefined,
44
+ }));
45
+ };
46
+ return (_jsx(TMContextMenu, { items: convertToContextMenuItems(items), trigger: "left", children: _jsx(StyledContent, { ref: dropDownMenuElementRef, tabIndex: disabled ? -1 : 0, "$disabled": disabled, "$color": color, "$backgroundColor": backgroundColor, "$borderRadius": borderRadius, children: content }) }));
44
47
  });
45
48
  export default TMDropDownMenu;
@@ -1,4 +1,5 @@
1
- import { FileItem, TMFileManagerContextMenuItem } from "./TMFileManagerUtils";
1
+ import { FileItem } from "./TMFileManagerUtils";
2
+ import { TMContextMenuItemProps } from '../NewComponents/ContextMenu/types';
2
3
  interface TMFileManagerProps {
3
4
  /** The currently focused file */
4
5
  focusedFile: FileItem | undefined;
@@ -17,9 +18,9 @@ interface TMFileManagerProps {
17
18
  /** Represents the file system tree structure */
18
19
  treeFs: FileItem;
19
20
  /** Context menu items for folders */
20
- folderContextMenuItems: Array<TMFileManagerContextMenuItem>;
21
+ folderContextMenuItems: Array<TMContextMenuItemProps>;
21
22
  /** Context menu items for files */
22
- fileContextMenuItems: Array<TMFileManagerContextMenuItem>;
23
+ fileContextMenuItems: Array<TMContextMenuItemProps>;
23
24
  /** Optional: Callback to handle folder selection changes */
24
25
  handleSelectedFolder?: (folderItem: FileItem | undefined) => void;
25
26
  /** Optional: Callback for handling double-click events on a file */