@topconsultnpm/sdkui-react 6.20.0-dev1.13 → 6.20.0-dev1.131
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.
- package/lib/assets/Toppy-help-center.png +0 -0
- package/lib/assets/headergradient.svg +87 -0
- package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +322 -30
- package/lib/components/NewComponents/ContextMenu/hooks.d.ts +8 -1
- package/lib/components/NewComponents/ContextMenu/hooks.js +80 -8
- package/lib/components/NewComponents/ContextMenu/index.d.ts +3 -0
- package/lib/components/NewComponents/ContextMenu/index.js +2 -0
- package/lib/components/NewComponents/ContextMenu/styles.d.ts +9 -1
- package/lib/components/NewComponents/ContextMenu/styles.js +146 -47
- package/lib/components/NewComponents/ContextMenu/types.d.ts +22 -3
- package/lib/components/NewComponents/ContextMenu/useLongPress.d.ts +21 -0
- package/lib/components/NewComponents/ContextMenu/useLongPress.js +112 -0
- package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +620 -125
- package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +25 -5
- package/lib/components/NewComponents/FloatingMenuBar/styles.js +215 -59
- package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +12 -3
- package/lib/components/base/TMAccordionNew.js +35 -14
- package/lib/components/base/TMButton.js +6 -0
- package/lib/components/base/TMClosableList.js +4 -0
- package/lib/components/base/TMCustomButton.js +61 -17
- package/lib/components/base/TMDataGrid.d.ts +7 -4
- package/lib/components/base/TMDataGrid.js +153 -11
- package/lib/components/base/TMDropDownMenu.js +21 -18
- package/lib/components/base/TMFileManager.d.ts +4 -3
- package/lib/components/base/TMFileManager.js +32 -24
- package/lib/components/base/TMFileManagerDataGridView.d.ts +3 -2
- package/lib/components/base/TMFileManagerDataGridView.js +1 -11
- package/lib/components/base/TMFileManagerThumbnailItems.d.ts +7 -1
- package/lib/components/base/TMFileManagerThumbnailItems.js +5 -2
- package/lib/components/base/TMFileManagerThumbnailsView.d.ts +17 -4
- package/lib/components/base/TMFileManagerThumbnailsView.js +18 -6
- package/lib/components/base/TMFileManagerUtils.d.ts +0 -12
- package/lib/components/base/TMListView.js +33 -15
- package/lib/components/base/TMPanel.d.ts +1 -1
- package/lib/components/base/TMPanel.js +4 -2
- package/lib/components/base/TMPopUp.js +6 -0
- package/lib/components/base/TMToolbarCard.js +2 -0
- package/lib/components/base/TMTreeView.d.ts +2 -1
- package/lib/components/base/TMTreeView.js +33 -26
- package/lib/components/choosers/TMDataListItemChooser.d.ts +2 -0
- package/lib/components/choosers/TMDataListItemChooser.js +8 -2
- package/lib/components/choosers/TMDcmtTypeChooser.d.ts +1 -0
- package/lib/components/choosers/TMDcmtTypeChooser.js +11 -3
- package/lib/components/choosers/TMDistinctValues.js +2 -2
- package/lib/components/choosers/TMDynDataListItemChooser.d.ts +2 -0
- package/lib/components/choosers/TMDynDataListItemChooser.js +8 -2
- package/lib/components/choosers/TMInvoiceRetrieveFormats.js +1 -1
- package/lib/components/choosers/TMMetadataChooser.d.ts +2 -0
- package/lib/components/choosers/TMMetadataChooser.js +19 -4
- package/lib/components/choosers/TMOrderRetrieveFormats.js +1 -1
- package/lib/components/choosers/TMUserChooser.d.ts +2 -5
- package/lib/components/choosers/TMUserChooser.js +33 -47
- package/lib/components/editors/TMCheckBox.js +2 -0
- package/lib/components/editors/TMDateBox.js +18 -9
- package/lib/components/editors/TMEditorStyled.js +7 -0
- package/lib/components/editors/TMLocalizedTextBox.d.ts +3 -1
- package/lib/components/editors/TMLocalizedTextBox.js +16 -14
- package/lib/components/editors/TMMetadataEditor.d.ts +1 -0
- package/lib/components/editors/TMMetadataEditor.js +4 -4
- package/lib/components/editors/TMMetadataTextBox.d.ts +9 -0
- package/lib/components/editors/TMMetadataTextBox.js +92 -0
- package/lib/components/editors/TMMetadataValues.d.ts +2 -0
- package/lib/components/editors/TMMetadataValues.js +26 -8
- package/lib/components/editors/TMRadioButton.js +2 -0
- package/lib/components/editors/TMTextArea.js +18 -30
- package/lib/components/editors/TMTextBox.d.ts +1 -1
- package/lib/components/editors/TMTextBox.js +29 -4
- package/lib/components/editors/TMTextExpression.js +6 -91
- package/lib/components/features/archive/TMArchive.js +2 -2
- package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +15 -0
- package/lib/components/features/assistant/TMToppyDraggableHelpCenter.js +462 -0
- package/lib/components/features/assistant/TMToppySpeechBubble.d.ts +11 -0
- package/lib/components/features/assistant/TMToppySpeechBubble.js +126 -0
- package/lib/components/features/documents/TMDcmtBlog.js +1 -1
- package/lib/components/features/documents/TMDcmtForm.d.ts +14 -2
- package/lib/components/features/documents/TMDcmtForm.js +576 -292
- package/lib/components/features/documents/TMDcmtPreview.js +42 -155
- package/lib/components/features/documents/TMDcmtTasks.js +9 -9
- package/lib/components/features/documents/TMMasterDetailDcmts.js +38 -53
- package/lib/components/features/documents/TMRelationViewer.d.ts +1 -1
- package/lib/components/features/documents/TMRelationViewer.js +2 -2
- package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +8 -0
- package/lib/components/features/search/{TMSearchResultCheckoutInfoForm.js → TMDcmtCheckoutInfoForm.js} +2 -2
- package/lib/components/features/search/TMSavedQuerySelector.js +72 -67
- package/lib/components/features/search/TMSearch.d.ts +3 -0
- package/lib/components/features/search/TMSearch.js +50 -11
- package/lib/components/features/search/TMSearchQueryEditor.d.ts +1 -0
- package/lib/components/features/search/TMSearchQueryEditor.js +10 -10
- package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -0
- package/lib/components/features/search/TMSearchQueryPanel.js +40 -25
- package/lib/components/features/search/TMSearchResult.d.ts +3 -0
- package/lib/components/features/search/TMSearchResult.js +370 -252
- package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +3 -3
- package/lib/components/features/search/TMSearchResultsMenuItems.js +227 -171
- package/lib/components/features/search/TMSignSettingsForm.js +1 -1
- package/lib/components/features/search/TMSignatureInfoContent.d.ts +6 -0
- package/lib/components/features/search/TMSignatureInfoContent.js +140 -0
- package/lib/components/features/search/TMViewHistoryDcmt.js +47 -52
- package/lib/components/features/tasks/TMTaskForm.js +75 -25
- package/lib/components/features/tasks/TMTasksAgenda.d.ts +3 -1
- package/lib/components/features/tasks/TMTasksAgenda.js +48 -9
- package/lib/components/features/tasks/TMTasksCalendar.d.ts +2 -0
- package/lib/components/features/tasks/TMTasksCalendar.js +19 -7
- package/lib/components/features/tasks/TMTasksUtils.d.ts +2 -2
- package/lib/components/features/tasks/TMTasksUtils.js +57 -37
- package/lib/components/features/tasks/TMTasksView.js +28 -19
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +33 -2
- package/lib/components/features/workflow/TMWorkflowPopup.js +140 -34
- package/lib/components/features/workflow/diagram/DiagramItemComponent.d.ts +2 -0
- package/lib/components/features/workflow/diagram/DiagramItemComponent.js +14 -7
- package/lib/components/features/workflow/diagram/DiagramItemForm.js +1 -1
- package/lib/components/features/workflow/diagram/RecipientList.js +3 -2
- package/lib/components/features/workflow/diagram/WFDiagram.d.ts +4 -0
- package/lib/components/features/workflow/diagram/WFDiagram.js +164 -13
- package/lib/components/forms/Login/LoginValidatorService.d.ts +2 -0
- package/lib/components/forms/Login/LoginValidatorService.js +7 -2
- package/lib/components/forms/Login/TMLoginForm.js +35 -7
- package/lib/components/forms/TMChooserForm.js +1 -1
- package/lib/components/grids/TMBlogsPost.js +56 -31
- package/lib/components/grids/TMRecentsManager.js +20 -10
- package/lib/components/grids/TMValidationItemsList.js +6 -0
- package/lib/components/index.d.ts +6 -3
- package/lib/components/index.js +6 -3
- package/lib/components/layout/panelManager/TMPanelManagerContext.js +13 -5
- package/lib/components/query/TMQueryEditor.d.ts +6 -1
- package/lib/components/query/TMQueryEditor.js +105 -101
- package/lib/components/settings/SettingsAppearance.d.ts +2 -1
- package/lib/components/settings/SettingsAppearance.js +99 -30
- package/lib/components/sidebar/TMHeader.js +11 -7
- package/lib/components/sidebar/TMSidebar.d.ts +0 -1
- package/lib/components/sidebar/TMSidebar.js +16 -44
- package/lib/components/sidebar/TMSidebarItem.js +36 -17
- package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -1
- package/lib/components/viewers/TMDataListItemViewer.js +35 -71
- package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +8 -0
- package/lib/components/viewers/TMDataUserIdItemViewer.js +39 -0
- package/lib/css/tm-sdkui.css +1 -1
- package/lib/helper/SDKUI_Globals.d.ts +22 -0
- package/lib/helper/SDKUI_Globals.js +10 -1
- package/lib/helper/SDKUI_Localizator.d.ts +21 -3
- package/lib/helper/SDKUI_Localizator.js +196 -10
- package/lib/helper/TMCommandsContextMenu.d.ts +4 -2
- package/lib/helper/TMCommandsContextMenu.js +15 -4
- package/lib/helper/TMIcons.d.ts +4 -0
- package/lib/helper/TMIcons.js +13 -3
- package/lib/helper/TMPdfViewer.d.ts +8 -0
- package/lib/helper/TMPdfViewer.js +373 -0
- package/lib/helper/TMToppyMessage.js +4 -0
- package/lib/helper/checkinCheckoutManager.d.ts +31 -1
- package/lib/helper/checkinCheckoutManager.js +112 -30
- package/lib/helper/devextremeCustomMessages.d.ts +30 -0
- package/lib/helper/devextremeCustomMessages.js +30 -0
- package/lib/helper/helpers.d.ts +30 -2
- package/lib/helper/helpers.js +132 -4
- package/lib/helper/index.d.ts +2 -0
- package/lib/helper/index.js +2 -0
- package/lib/helper/queryHelper.d.ts +2 -2
- package/lib/helper/queryHelper.js +80 -24
- package/lib/helper/workItemsHelper.d.ts +6 -0
- package/lib/helper/workItemsHelper.js +230 -0
- package/lib/hooks/useCheckInOutOperations.d.ts +28 -0
- package/lib/hooks/useCheckInOutOperations.js +223 -0
- package/lib/hooks/useDataListItem.d.ts +12 -0
- package/lib/hooks/useDataListItem.js +132 -0
- package/lib/hooks/useDataUserIdItem.d.ts +10 -0
- package/lib/hooks/useDataUserIdItem.js +96 -0
- package/lib/hooks/useFloatingBarPinnedItems.d.ts +11 -0
- package/lib/hooks/useFloatingBarPinnedItems.js +54 -0
- package/lib/hooks/useMetadataExpression.d.ts +19 -0
- package/lib/hooks/useMetadataExpression.js +99 -0
- package/lib/hooks/useSettingsFeedback.d.ts +11 -0
- package/lib/hooks/useSettingsFeedback.js +38 -0
- package/lib/hooks/useWorkflowApprove.d.ts +4 -0
- package/lib/hooks/useWorkflowApprove.js +14 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -2
- package/lib/services/platform_services.d.ts +3 -3
- package/lib/ts/types.d.ts +61 -1
- package/lib/utils/theme.d.ts +1 -1
- package/lib/utils/theme.js +1 -1
- package/package.json +8 -6
- package/lib/components/NewComponents/Notification/Notification.d.ts +0 -4
- package/lib/components/NewComponents/Notification/Notification.js +0 -60
- package/lib/components/NewComponents/Notification/NotificationContainer.d.ts +0 -8
- package/lib/components/NewComponents/Notification/NotificationContainer.js +0 -33
- package/lib/components/NewComponents/Notification/index.d.ts +0 -2
- package/lib/components/NewComponents/Notification/index.js +0 -2
- package/lib/components/NewComponents/Notification/styles.d.ts +0 -21
- package/lib/components/NewComponents/Notification/styles.js +0 -180
- package/lib/components/NewComponents/Notification/types.d.ts +0 -18
- package/lib/components/NewComponents/Notification/types.js +0 -1
- package/lib/components/base/TMContextMenu.d.ts +0 -25
- package/lib/components/base/TMContextMenu.js +0 -109
- package/lib/components/base/TMContextMenuOLD.d.ts +0 -26
- package/lib/components/base/TMContextMenuOLD.js +0 -56
- package/lib/components/base/TMFloatingToolbar.d.ts +0 -9
- package/lib/components/base/TMFloatingToolbar.js +0 -101
- package/lib/components/features/assistant/ToppyDraggableHelpCenter.d.ts +0 -30
- package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +0 -482
- package/lib/components/features/assistant/ToppySpeechBubble.d.ts +0 -9
- package/lib/components/features/assistant/ToppySpeechBubble.js +0 -117
- 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
|
-
|
|
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
|
|
55
|
+
const itemsToProcess = useMemo(() => selectedItems && selectedItems.length > 0 ? selectedItems : [attributes], [selectedItems, attributes]);
|
|
26
56
|
// Stati per il wait panel
|
|
27
|
-
const [showWaitPanel, setShowWaitPanel] = useState(
|
|
28
|
-
const [waitPanelText, setWaitPanelText] = useState(SDKUI_Localizator.CustomButtonActions.replaceParams(1,
|
|
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(
|
|
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 (!
|
|
87
|
+
if (!itemsToProcess)
|
|
50
88
|
return;
|
|
51
|
-
for (const [index, item] of
|
|
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,
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
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(
|
|
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:
|
|
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
|
-
/**
|
|
35
|
-
|
|
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
|
-
|
|
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',
|
|
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,
|
|
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
|
-
//
|
|
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 &&
|
|
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: {
|
|
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
|
|
2
|
-
import {
|
|
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 '
|
|
5
|
-
import {
|
|
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
|
|
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
|
-
|
|
43
|
-
|
|
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
|
|
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<
|
|
21
|
+
folderContextMenuItems: Array<TMContextMenuItemProps>;
|
|
21
22
|
/** Context menu items for files */
|
|
22
|
-
fileContextMenuItems: Array<
|
|
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 */
|