@topconsultnpm/sdkui-react 6.20.0-test1 → 6.21.0-dev1.2
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/components/NewComponents/ContextMenu/styles.d.ts +3 -1
- package/lib/components/NewComponents/ContextMenu/styles.js +7 -5
- package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +7 -1
- package/lib/components/base/Styled.d.ts +4 -1
- package/lib/components/base/Styled.js +11 -3
- package/lib/components/base/TMPanel.js +6 -4
- package/lib/components/base/TMPopUp.js +4 -0
- package/lib/components/base/TMTreeView.d.ts +3 -1
- package/lib/components/base/TMTreeView.js +68 -21
- package/lib/components/base/TMWaitPanel.js +6 -5
- package/lib/components/choosers/TMDataListItemChooser.js +1 -1
- package/lib/components/choosers/TMDataListItemEditor.d.ts +11 -0
- package/lib/components/choosers/TMDataListItemEditor.js +130 -0
- package/lib/components/choosers/TMDataListItemFields.d.ts +11 -0
- package/lib/components/choosers/TMDataListItemFields.js +61 -0
- package/lib/components/choosers/TMDataListItemPicker.d.ts +2 -0
- package/lib/components/choosers/TMDataListItemPicker.js +182 -18
- package/lib/components/choosers/TMDynDataListItemChooser.js +11 -6
- package/lib/components/choosers/TMImageIDChooser.d.ts +16 -0
- package/lib/components/choosers/TMImageIDChooser.js +53 -0
- package/lib/components/choosers/TMMetadataChooser.js +1 -1
- package/lib/components/choosers/TMUserChooser.js +1 -1
- package/lib/components/editors/TMDateBox.js +1 -1
- package/lib/components/editors/TMHtmlEditor.js +1 -1
- package/lib/components/editors/TMLocalizedTextBox.d.ts +1 -0
- package/lib/components/editors/TMLocalizedTextBox.js +3 -3
- package/lib/components/editors/TMMetadataValues.js +203 -41
- package/lib/components/editors/TMTextArea.d.ts +1 -0
- package/lib/components/editors/TMTextArea.js +6 -6
- package/lib/components/editors/TMTextBox.js +9 -10
- package/lib/components/features/archive/TMArchive.d.ts +3 -1
- package/lib/components/features/archive/TMArchive.js +31 -44
- package/lib/components/features/blog/TMBlogCommentForm.d.ts +3 -0
- package/lib/components/features/blog/TMBlogCommentForm.js +42 -36
- package/lib/components/features/documents/TMDcmtBlog.d.ts +1 -0
- package/lib/components/features/documents/TMDcmtBlog.js +2 -1
- package/lib/components/features/documents/TMDcmtForm.d.ts +44 -34
- package/lib/components/features/documents/TMDcmtForm.js +365 -563
- package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +34 -0
- package/lib/components/features/documents/TMDcmtFormActionButtons.js +124 -0
- package/lib/components/features/documents/TMDcmtPreview.js +66 -13
- package/lib/components/features/documents/TMDcmtTasks.d.ts +3 -1
- package/lib/components/features/documents/TMDcmtTasks.js +2 -2
- package/lib/components/features/documents/TMFileUploader.d.ts +5 -0
- package/lib/components/features/documents/TMFileUploader.js +28 -6
- package/lib/components/features/documents/TMMasterDetailDcmts.js +31 -85
- package/lib/components/features/documents/TMRelationViewer.d.ts +7 -1
- package/lib/components/features/documents/TMRelationViewer.js +497 -111
- package/lib/components/features/search/TMSearch.d.ts +2 -2
- package/lib/components/features/search/TMSearch.js +3 -3
- package/lib/components/features/search/TMSearchQueryPanel.js +6 -6
- package/lib/components/features/search/TMSearchResult.d.ts +28 -25
- package/lib/components/features/search/TMSearchResult.js +445 -562
- package/lib/components/features/search/TMSignatureInfoContent.js +10 -6
- package/lib/components/features/search/TMTreeSelector.js +1 -1
- package/lib/components/features/tasks/TMTaskForm.d.ts +3 -1
- package/lib/components/features/tasks/TMTaskForm.js +61 -193
- package/lib/components/features/tasks/TMTaskFormUtils.d.ts +80 -0
- package/lib/components/features/tasks/TMTaskFormUtils.js +559 -0
- package/lib/components/features/tasks/TMTasksUtils.d.ts +3 -1
- package/lib/components/features/tasks/TMTasksUtils.js +46 -16
- package/lib/components/features/tasks/TMTasksUtilsView.d.ts +0 -7
- package/lib/components/features/tasks/TMTasksUtilsView.js +7 -14
- package/lib/components/features/tasks/TMTasksView.js +5 -3
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +20 -3
- package/lib/components/features/workflow/TMWorkflowPopup.js +21 -109
- package/lib/components/features/workflow/diagram/ConnectionComponent.d.ts +1 -0
- package/lib/components/features/workflow/diagram/ConnectionComponent.js +6 -2
- package/lib/components/features/workflow/diagram/DiagramItemForm.d.ts +2 -0
- package/lib/components/features/workflow/diagram/DiagramItemForm.js +32 -25
- package/lib/components/features/workflow/diagram/RecipientList.d.ts +3 -1
- package/lib/components/features/workflow/diagram/RecipientList.js +13 -9
- package/lib/components/features/workflow/diagram/WFDiagram.js +102 -5
- package/lib/components/features/workflow/diagram/workflowHelpers.js +31 -19
- package/lib/components/forms/Login/TMLoginForm.js +1 -1
- package/lib/components/forms/TMSaveForm.js +61 -13
- package/lib/components/grids/TMBlogsPost.js +8 -8
- package/lib/components/grids/TMBlogsPostUtils.js +2 -2
- package/lib/components/grids/TMRecentsManager.js +1 -1
- package/lib/components/index.d.ts +2 -0
- package/lib/components/index.js +2 -0
- package/lib/components/layout/panelManager/TMPanelManagerContainer.js +3 -2
- package/lib/components/pages/TMPage.js +4 -0
- package/lib/components/query/TMQueryEditor.d.ts +1 -0
- package/lib/components/query/TMQueryEditor.js +3 -3
- package/lib/components/viewers/TMMidViewer.js +2 -1
- package/lib/components/viewers/TMTidViewer.js +7 -3
- package/lib/helper/Enum_Localizator.js +5 -0
- package/lib/helper/GlobalStyles.js +3 -0
- package/lib/helper/SDKUI_Globals.d.ts +12 -0
- package/lib/helper/SDKUI_Globals.js +21 -1
- package/lib/helper/SDKUI_Localizator.d.ts +31 -7
- package/lib/helper/SDKUI_Localizator.js +286 -46
- package/lib/helper/TMIcons.d.ts +2 -1
- package/lib/helper/TMIcons.js +4 -1
- package/lib/helper/TMUtils.d.ts +33 -41
- package/lib/helper/TMUtils.js +157 -170
- package/lib/helper/checkinCheckoutManager.js +6 -2
- package/lib/helper/helpers.d.ts +6 -2
- package/lib/helper/helpers.js +24 -8
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/helper/queryHelper.js +1 -1
- package/lib/hooks/useBetaFeatures.d.ts +1 -0
- package/lib/hooks/useBetaFeatures.js +41 -0
- package/lib/hooks/useCheckInOutOperations.d.ts +7 -6
- package/lib/hooks/useCheckInOutOperations.js +9 -16
- package/lib/hooks/useDataUserIdItem.js +2 -2
- package/lib/hooks/useDcmtOperations.d.ts +3 -2
- package/lib/hooks/useDcmtOperations.js +16 -4
- package/lib/hooks/useDocumentOperations.d.ts +139 -0
- package/lib/hooks/useDocumentOperations.js +1275 -0
- package/lib/hooks/useRelatedDocuments.d.ts +1 -1
- package/lib/hooks/useRelatedDocuments.js +64 -42
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/services/platform_services.d.ts +1 -1
- package/lib/services/platform_services.js +4 -0
- package/lib/ts/types.d.ts +5 -1
- package/lib/ts/types.js +1 -0
- package/package.json +55 -55
- package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +0 -11
- package/lib/components/features/search/TMSearchResultsMenuItems.js +0 -770
- package/lib/components/features/search/TMSignSettingsForm.d.ts +0 -9
- package/lib/components/features/search/TMSignSettingsForm.js +0 -621
|
@@ -14,7 +14,9 @@ export declare const MenuItem: import("styled-components/dist/types").IStyledCom
|
|
|
14
14
|
$beginGroup?: boolean;
|
|
15
15
|
}>> & string;
|
|
16
16
|
export declare const MenuItemContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
17
|
-
export declare const IconWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>,
|
|
17
|
+
export declare const IconWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & {
|
|
18
|
+
ref?: ((instance: HTMLSpanElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLSpanElement> | null | undefined;
|
|
19
|
+
}>, never>, never>> & string;
|
|
18
20
|
export declare const MenuItemName: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
|
|
19
21
|
export declare const RightIconButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
|
|
20
22
|
ref?: ((instance: HTMLButtonElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLButtonElement> | null | undefined;
|
|
@@ -69,7 +69,7 @@ export const MenuContainer = styled.div `
|
|
|
69
69
|
`}
|
|
70
70
|
|
|
71
71
|
/* Reset color inheritance from parent with !important to override panel header styles */
|
|
72
|
-
& *:not(svg):not(.right-icon-btn):not(.right-icon-btn *) {
|
|
72
|
+
& *:not(svg):not(.right-icon-btn):not(.right-icon-btn *):not(.icon-wrapper):not(.icon-wrapper *) {
|
|
73
73
|
color: #1a1a1a !important;
|
|
74
74
|
}
|
|
75
75
|
|
|
@@ -80,7 +80,7 @@ export const MenuContainer = styled.div `
|
|
|
80
80
|
0 2px 8px rgba(0, 0, 0, 0.3);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
[data-theme='dark'] & *:not(svg):not(.right-icon-btn):not(.right-icon-btn *) {
|
|
83
|
+
[data-theme='dark'] & *:not(svg):not(.right-icon-btn):not(.right-icon-btn *):not(.icon-wrapper):not(.icon-wrapper *) {
|
|
84
84
|
color: #e0e0e0 !important;
|
|
85
85
|
}
|
|
86
86
|
|
|
@@ -174,7 +174,9 @@ export const MenuItemContent = styled.div `
|
|
|
174
174
|
gap: 10px;
|
|
175
175
|
flex: 1;
|
|
176
176
|
`;
|
|
177
|
-
export const IconWrapper = styled.span
|
|
177
|
+
export const IconWrapper = styled.span.attrs({
|
|
178
|
+
className: 'icon-wrapper'
|
|
179
|
+
}) `
|
|
178
180
|
display: flex;
|
|
179
181
|
align-items: center;
|
|
180
182
|
justify-content: center;
|
|
@@ -289,7 +291,7 @@ export const Submenu = styled.div `
|
|
|
289
291
|
}
|
|
290
292
|
|
|
291
293
|
/* Reset color inheritance from parent with !important to override panel header styles */
|
|
292
|
-
& *:not(svg):not(.right-icon-btn):not(.right-icon-btn *) {
|
|
294
|
+
& *:not(svg):not(.right-icon-btn):not(.right-icon-btn *):not(.icon-wrapper):not(.icon-wrapper *) {
|
|
293
295
|
color: #1a1a1a !important;
|
|
294
296
|
}
|
|
295
297
|
|
|
@@ -300,7 +302,7 @@ export const Submenu = styled.div `
|
|
|
300
302
|
0 2px 8px rgba(0, 0, 0, 0.3);
|
|
301
303
|
}
|
|
302
304
|
|
|
303
|
-
[data-theme='dark'] & *:not(svg):not(.right-icon-btn):not(.right-icon-btn *) {
|
|
305
|
+
[data-theme='dark'] & *:not(svg):not(.right-icon-btn):not(.right-icon-btn *):not(.icon-wrapper):not(.icon-wrapper *) {
|
|
304
306
|
color: #e0e0e0 !important;
|
|
305
307
|
}
|
|
306
308
|
|
|
@@ -146,6 +146,7 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
|
|
|
146
146
|
const isLocalChange = useRef(false);
|
|
147
147
|
const dragStartPosition = useRef(null);
|
|
148
148
|
const isItemsInitialized = useRef(false);
|
|
149
|
+
const hasReceivedNonEmptyExternalIds = useRef(false);
|
|
149
150
|
useEffect(() => {
|
|
150
151
|
floatingBarItemIds.current = new Set(state.items.map(i => i.id));
|
|
151
152
|
floatingBarItemNames.current = new Set(state.items.map(i => i.name));
|
|
@@ -264,9 +265,14 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
|
|
|
264
265
|
}
|
|
265
266
|
if (externalPinnedItemIds === undefined || !enableConfigMode)
|
|
266
267
|
return;
|
|
268
|
+
// Track if we've ever received non-empty external IDs
|
|
269
|
+
if (externalPinnedItemIds.length > 0) {
|
|
270
|
+
hasReceivedNonEmptyExternalIds.current = true;
|
|
271
|
+
}
|
|
267
272
|
// Skip sync if external is empty but we have initialized items (first login case)
|
|
268
273
|
// The parent hook starts with [] but we've initialized with defaults
|
|
269
|
-
|
|
274
|
+
// However, once we've received non-empty pinnedItemIds, an empty array means user removed all items
|
|
275
|
+
if (externalPinnedItemIds.length === 0 && state.items.length > 0 && !hasReceivedNonEmptyExternalIds.current)
|
|
270
276
|
return;
|
|
271
277
|
const flatItems = flattenMenuItems(contextMenuItems);
|
|
272
278
|
// Build items from external pinned IDs
|
|
@@ -7,7 +7,10 @@ export declare const StyledMultiViewPanel: import("styled-components/dist/types"
|
|
|
7
7
|
}>> & string;
|
|
8
8
|
export declare const StyledParagraph: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
|
|
9
9
|
export declare const StyledToolbarForm: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
10
|
-
export declare const
|
|
10
|
+
export declare const ReferencesContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
11
|
+
export declare const StyledReferenceButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {
|
|
12
|
+
$bgColor?: string;
|
|
13
|
+
}>> & string;
|
|
11
14
|
export declare const StyledPanelPage: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
12
15
|
$isOpen?: boolean;
|
|
13
16
|
$padding?: string;
|
|
@@ -36,17 +36,25 @@ export const StyledToolbarForm = styled.div `
|
|
|
36
36
|
gap: 2px;
|
|
37
37
|
background-color: ${TMColors.toolbar_background};
|
|
38
38
|
`;
|
|
39
|
+
export const ReferencesContainer = styled.div `
|
|
40
|
+
display: flex;
|
|
41
|
+
justify-content: center;
|
|
42
|
+
gap: 12px;
|
|
43
|
+
flex-wrap: wrap;
|
|
44
|
+
width: 100%;
|
|
45
|
+
height: 100%;
|
|
46
|
+
`;
|
|
39
47
|
export const StyledReferenceButton = styled.button `
|
|
40
48
|
display: flex;
|
|
41
49
|
flex-direction: column;
|
|
42
50
|
align-items: center;
|
|
43
51
|
justify-content: center;
|
|
44
|
-
padding: 10px
|
|
52
|
+
padding: 10px 25px;
|
|
45
53
|
border-radius: 20px;
|
|
46
54
|
border: none;
|
|
47
|
-
background-color: ${TMColors.button_floating_background};
|
|
55
|
+
background-color: ${({ $bgColor }) => $bgColor || TMColors.button_floating_background};
|
|
48
56
|
color: white;
|
|
49
|
-
font-size: 0.
|
|
57
|
+
font-size: 0.95rem;
|
|
50
58
|
font-weight: 500;
|
|
51
59
|
cursor: pointer;
|
|
52
60
|
transition: all 0.2s ease;
|
|
@@ -5,9 +5,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
*/
|
|
6
6
|
import { useCallback, useRef, useState, forwardRef, useImperativeHandle } from 'react';
|
|
7
7
|
import styled from 'styled-components';
|
|
8
|
-
import { IconArrowLeft, IconClearButton, IconWindowMaximize, IconWindowMinimize, isPositiveNumber, SDKUI_Localizator } from '../../helper';
|
|
8
|
+
import { getAppModuleGradient, IconArrowLeft, IconClearButton, IconWindowMaximize, IconWindowMinimize, isPositiveNumber, SDKUI_Localizator } from '../../helper';
|
|
9
9
|
import TMButton from './TMButton';
|
|
10
10
|
import { Gutters } from '../../utils/theme';
|
|
11
|
+
import { AppModules, SDK_Globals } from '@topconsultnpm/sdk-ts';
|
|
11
12
|
const StyledPanelContainer = styled.div `
|
|
12
13
|
width: 100%;
|
|
13
14
|
height: 100%;
|
|
@@ -34,8 +35,9 @@ const StyledPanelHeader = styled.div `
|
|
|
34
35
|
align-items: center;
|
|
35
36
|
justify-content: flex-start;
|
|
36
37
|
padding: 4px 10px;
|
|
37
|
-
background: ${({ $isActive, $backgroundColor }) => $isActive
|
|
38
|
-
?
|
|
38
|
+
background: ${({ $isActive, $backgroundColor, $activeGradient }) => $isActive
|
|
39
|
+
? ($activeGradient ??
|
|
40
|
+
'linear-gradient(270deg, #46B5A2 16%, #3BAABC 34%, #3BAABC 34%, #3681AD 54%, #3368A5 72%, #2F549D 88%, #304F99 100%)')
|
|
39
41
|
: ($backgroundColor ?? '#F4F4F4')};
|
|
40
42
|
box-shadow: 3px 3px 5px #D3D3D3BF;
|
|
41
43
|
color: ${({ $isActive, $color }) => $isActive ? '#FFFFFF' : ($color ?? '#2559A5')};
|
|
@@ -141,7 +143,7 @@ onActivate, onBack, onClose, onHeaderDoubleClick, onMaximize, onActiveChanged },
|
|
|
141
143
|
onHeaderDoubleClick();
|
|
142
144
|
else
|
|
143
145
|
allowMaximize && handleMaximize();
|
|
144
|
-
}, children: _jsxs("div", { style: {
|
|
146
|
+
}, "$activeGradient": getAppModuleGradient(SDK_Globals.tmSession?.SessionDescr?.appModuleID ?? AppModules.SURFER), children: _jsxs("div", { style: {
|
|
145
147
|
display: 'flex',
|
|
146
148
|
flexDirection: 'row',
|
|
147
149
|
alignItems: 'center',
|
|
@@ -258,6 +258,10 @@ const TMMessageBox = ({ resizable = false, onButtonClick, title = 'TopMedia', me
|
|
|
258
258
|
const el = document.getElementById('tm-messagebox-wrapper');
|
|
259
259
|
if (el)
|
|
260
260
|
el.style.zIndex = '20000';
|
|
261
|
+
// Blocca traduzione sul titolo
|
|
262
|
+
const titleEl = el?.querySelector('.dx-popup-title');
|
|
263
|
+
if (titleEl)
|
|
264
|
+
titleEl.setAttribute('translate', 'no');
|
|
261
265
|
}, onResizeEnd: handleResizeEnd, wrapperAttr: { id: 'tm-messagebox-wrapper' }, children: _jsx(ResponsiveMessageBody, { message: message, isMobile: isMobile, MessageToolbar: MessageToolbar, showToppy: showToppy }) }));
|
|
262
266
|
};
|
|
263
267
|
const TMExceptionBox = ({ resizable = false, exception, title = `${SDK_Globals.appModule} v. ${SDK_Globals.appVersion}`, onClose }) => {
|
|
@@ -6,8 +6,9 @@ export interface ITMTreeItem {
|
|
|
6
6
|
hidden?: boolean;
|
|
7
7
|
isLoaded?: boolean;
|
|
8
8
|
isContainer: boolean;
|
|
9
|
+
isExpandible?: boolean;
|
|
9
10
|
items?: ITMTreeItem[];
|
|
10
|
-
|
|
11
|
+
currentPage?: number;
|
|
11
12
|
totalItemsCount?: number;
|
|
12
13
|
}
|
|
13
14
|
interface ITMTreeViewProps<T extends ITMTreeItem> {
|
|
@@ -31,3 +32,4 @@ export default TMTreeView;
|
|
|
31
32
|
export declare const StyledTreeNode: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
32
33
|
$isSelected?: boolean;
|
|
33
34
|
}>> & string;
|
|
35
|
+
export declare const StyledStickyPaginator: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useRef } from 'react';
|
|
3
3
|
import styled from 'styled-components';
|
|
4
|
-
import { IconChevronDown, IconChevronRight } from '../../helper';
|
|
4
|
+
import { IconArrowLeft, IconArrowRight, IconChevronDown, IconChevronRight, SDKUI_Localizator } from '../../helper';
|
|
5
5
|
import TMButton from './TMButton';
|
|
6
6
|
const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMultipleSelection, onDataChanged, calculateItemsForNode, itemRender, onNodeUpdate, onFocusedItemChanged, onSelectionChanged, shouldDelayFocusOnEvent, autoSelectChildren = true, itemsPerPage = 100, showLoadMoreButton = true }) => {
|
|
7
7
|
useEffect(() => {
|
|
@@ -85,7 +85,9 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
|
|
|
85
85
|
let newItems = node.items;
|
|
86
86
|
// Solo se calculateItemsForNode è definito E (ctrl è premuto O non è già caricato)
|
|
87
87
|
if (calculateItemsForNode && (ctrlKey || !node.isLoaded)) {
|
|
88
|
-
|
|
88
|
+
// Se ctrl è premuto, passa un nodo con isLoaded resettato per forzare il refresh
|
|
89
|
+
const nodeForCalculation = ctrlKey ? { ...node, isLoaded: false } : node;
|
|
90
|
+
newItems = await calculateItemsForNode(nodeForCalculation);
|
|
89
91
|
const updatedNode = { ...node, expanded: true, items: newItems, isLoaded: true };
|
|
90
92
|
onNodeUpdate?.(updatedNode);
|
|
91
93
|
return updatedNode;
|
|
@@ -274,53 +276,62 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
|
|
|
274
276
|
return childKeys.every(key => selectedChildKeys.includes(key));
|
|
275
277
|
};
|
|
276
278
|
const hasVisibleItems = (node) => {
|
|
279
|
+
// If node has explicit isExpandible value, use that
|
|
280
|
+
if (node.isExpandible !== undefined) {
|
|
281
|
+
return node.isExpandible;
|
|
282
|
+
}
|
|
283
|
+
// Fallback: check if node has visible items
|
|
277
284
|
if (!node.items)
|
|
278
285
|
return false;
|
|
279
286
|
if (node.items.length <= 0)
|
|
280
287
|
return false;
|
|
281
288
|
return node.items.filter(o => !o.hidden).length > 0;
|
|
282
289
|
};
|
|
283
|
-
// Gestisce il
|
|
284
|
-
const
|
|
285
|
-
const
|
|
290
|
+
// Gestisce il cambio di pagina per un nodo
|
|
291
|
+
const handlePageChange = useCallback((nodeKey, newPage) => {
|
|
292
|
+
const updateNodePage = (nodes) => {
|
|
286
293
|
return nodes.map(node => {
|
|
287
294
|
if (node.key === nodeKey) {
|
|
288
|
-
const
|
|
289
|
-
const newVisible = Math.min(currentVisible + itemsPerPage, node.totalItemsCount ?? node.items?.length ?? 0);
|
|
290
|
-
const updatedNode = { ...node, visibleItemsCount: newVisible };
|
|
295
|
+
const updatedNode = { ...node, currentPage: newPage };
|
|
291
296
|
onNodeUpdate?.(updatedNode);
|
|
292
297
|
return updatedNode;
|
|
293
298
|
}
|
|
294
299
|
if (node.items) {
|
|
295
|
-
return { ...node, items:
|
|
300
|
+
return { ...node, items: updateNodePage(node.items) };
|
|
296
301
|
}
|
|
297
302
|
return node;
|
|
298
303
|
});
|
|
299
304
|
};
|
|
300
|
-
const updatedData =
|
|
305
|
+
const updatedData = updateNodePage(dataSource);
|
|
301
306
|
onDataChanged?.(updatedData);
|
|
302
|
-
}, [dataSource,
|
|
307
|
+
}, [dataSource, onDataChanged, onNodeUpdate]);
|
|
303
308
|
// Filtra gli items da mostrare in base alla paginazione
|
|
304
309
|
const getVisibleItems = useCallback((node) => {
|
|
305
310
|
if (!node.items)
|
|
306
311
|
return [];
|
|
307
312
|
const totalItems = node.items.length;
|
|
308
|
-
const visibleCount = node.visibleItemsCount ?? itemsPerPage;
|
|
309
313
|
// Se non c'è paginazione attiva o gli items sono pochi, mostra tutti
|
|
310
314
|
if (totalItems <= itemsPerPage || !showLoadMoreButton) {
|
|
311
315
|
return node.items;
|
|
312
316
|
}
|
|
313
|
-
// Altrimenti mostra solo
|
|
314
|
-
|
|
317
|
+
// Altrimenti mostra solo gli items della pagina corrente
|
|
318
|
+
const currentPage = node.currentPage ?? 0;
|
|
319
|
+
const startIndex = currentPage * itemsPerPage;
|
|
320
|
+
const endIndex = startIndex + itemsPerPage;
|
|
321
|
+
return node.items.slice(startIndex, endIndex);
|
|
315
322
|
}, [itemsPerPage, showLoadMoreButton]);
|
|
316
|
-
// Verifica se c'è bisogno del
|
|
317
|
-
const
|
|
323
|
+
// Verifica se c'è bisogno del paginatore
|
|
324
|
+
const needsPagination = useCallback((node) => {
|
|
318
325
|
if (!showLoadMoreButton || !node.items)
|
|
319
326
|
return false;
|
|
320
|
-
|
|
321
|
-
const visibleCount = node.visibleItemsCount ?? itemsPerPage;
|
|
322
|
-
return totalItems > itemsPerPage && visibleCount < totalItems;
|
|
327
|
+
return node.items.length > itemsPerPage;
|
|
323
328
|
}, [itemsPerPage, showLoadMoreButton]);
|
|
329
|
+
// Calcola il numero totale di pagine per un nodo
|
|
330
|
+
const getTotalPages = useCallback((node) => {
|
|
331
|
+
if (!node.items)
|
|
332
|
+
return 0;
|
|
333
|
+
return Math.ceil(node.items.length / itemsPerPage);
|
|
334
|
+
}, [itemsPerPage]);
|
|
324
335
|
const renderTree = useCallback((nodes) => {
|
|
325
336
|
return nodes.map(node => !node.hidden && (_jsxs("div", { style: { width: '100%', margin: 0, padding: 0 }, children: [_jsxs(StyledTreeNode, { "$isSelected": node.key === focusedItem?.key, children: [_jsx("div", { style: {
|
|
326
337
|
display: 'flex',
|
|
@@ -339,8 +350,8 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
|
|
|
339
350
|
if (input) {
|
|
340
351
|
input.indeterminate = isIndeterminate(node);
|
|
341
352
|
}
|
|
342
|
-
} })), _jsx("div", { style: { display: 'flex', alignItems: 'center', flex: 1, minWidth: 0 }, onClick: (e) => { handleNodeClick(node, e); }, children: itemRender(node) })] }), node.expanded && node.items && (_jsxs("div", { style: { paddingLeft: 20, width: '100%' }, children: [renderTree(getVisibleItems(node)),
|
|
343
|
-
}, [handleNodeClick, handleNodeToggle, handleCheckboxChange, focusedItem, selectedItems, allowMultipleSelection, getVisibleItems,
|
|
353
|
+
} })), _jsx("div", { style: { display: 'flex', alignItems: 'center', flex: 1, minWidth: 0 }, onClick: (e) => { handleNodeClick(node, e); }, children: itemRender(node) })] }), node.expanded && node.items && (_jsxs("div", { style: { paddingLeft: 20, width: '100%' }, children: [renderTree(getVisibleItems(node)), needsPagination(node) && (_jsxs(StyledStickyPaginator, { children: [_jsx(TMButton, { btnStyle: 'icon', onClick: () => handlePageChange(node.key, (node.currentPage ?? 0) - 1), showTooltip: false, caption: "\u25C4", icon: _jsx(IconArrowLeft, { color: 'white' }), disabled: (node.currentPage ?? 0) <= 0 }), _jsx("span", { style: { fontSize: '11px', whiteSpace: 'nowrap', fontWeight: 500, overflow: 'hidden', textOverflow: 'ellipsis', minWidth: 0, color: 'white' }, children: SDKUI_Localizator.PaginationInfo.replaceParams((node.currentPage ?? 0) + 1, getTotalPages(node), node.items?.length ?? 0) }), _jsx(TMButton, { btnStyle: 'icon', onClick: () => handlePageChange(node.key, (node.currentPage ?? 0) + 1), showTooltip: false, caption: "\u25BA", icon: _jsx(IconArrowRight, { color: 'white' }), disabled: (node.currentPage ?? 0) >= getTotalPages(node) - 1 })] }))] }))] }, node.key)));
|
|
354
|
+
}, [handleNodeClick, handleNodeToggle, handleCheckboxChange, focusedItem, selectedItems, allowMultipleSelection, getVisibleItems, needsPagination, handlePageChange, getTotalPages]);
|
|
344
355
|
return (_jsx("div", { style: { height: '100%', width: '100%', overflowY: 'auto', overflowX: 'hidden', padding: '0px 5px 2px 2px' }, children: renderTree(dataSource) }));
|
|
345
356
|
};
|
|
346
357
|
export default TMTreeView;
|
|
@@ -361,3 +372,39 @@ export const StyledTreeNode = styled.div `
|
|
|
361
372
|
background: ${() => `oklch(from var(--dx-color-primary) l c h / .1)`};
|
|
362
373
|
}
|
|
363
374
|
`;
|
|
375
|
+
export const StyledStickyPaginator = styled.div `
|
|
376
|
+
position: sticky;
|
|
377
|
+
bottom: 0;
|
|
378
|
+
display: flex;
|
|
379
|
+
align-items: center;
|
|
380
|
+
justify-content: center;
|
|
381
|
+
width: fit-content;
|
|
382
|
+
margin: 3px auto;
|
|
383
|
+
gap: 15px;
|
|
384
|
+
padding: 4px 10px;
|
|
385
|
+
background: oklch(from var(--dx-color-primary) l c h / .85);
|
|
386
|
+
border: 1px solid oklch(from var(--dx-color-primary) l c h / .9);
|
|
387
|
+
border-radius: 3px;
|
|
388
|
+
box-shadow: 0 -1px 4px oklch(from var(--dx-color-primary) l c h / .15);
|
|
389
|
+
transition: all 0.2s ease;
|
|
390
|
+
min-width: 0;
|
|
391
|
+
z-index: 10;
|
|
392
|
+
|
|
393
|
+
& > button {
|
|
394
|
+
flex-shrink: 0;
|
|
395
|
+
min-width: 24px !important;
|
|
396
|
+
min-height: 20px !important;
|
|
397
|
+
padding: 2px 6px !important;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
& > span {
|
|
401
|
+
flex: 1 1 auto;
|
|
402
|
+
min-width: 0;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
&:hover {
|
|
406
|
+
background: oklch(from var(--dx-color-primary) l c h / .95);
|
|
407
|
+
border-color: oklch(from var(--dx-color-primary) l c h / 1);
|
|
408
|
+
box-shadow: 0 -1px 6px oklch(from var(--dx-color-primary) l c h / .2);
|
|
409
|
+
}
|
|
410
|
+
`;
|
|
@@ -33,17 +33,18 @@ const StyledProgressText = styled.p ` font-weight: bold; color: #333; margin: 0;
|
|
|
33
33
|
const StyledMessage = styled.p ` color: #666; font-size: 0.9em; margin-top: 10px; `;
|
|
34
34
|
const StyledAbortButton = styled.button ` background: #ff4d4d; color: white; border: none; border-radius: 5px; padding: 10px 20px; font-size: 1em; cursor: pointer; margin-top: 20px; &:hover { background: #ff6666; } `;
|
|
35
35
|
export const TMWaitPanel = (props) => {
|
|
36
|
+
const { title, showPrimary, textPrimary, valuePrimary, maxValuePrimary, showSecondary, textSecondary, valueSecondary, maxValueSecondary, isCancelable, abortController, onAbortClick } = props;
|
|
36
37
|
const calculateProgress = (value = 0, maxValue = 0) => {
|
|
37
38
|
if (maxValue === 0)
|
|
38
39
|
return 0;
|
|
39
40
|
const progress = (value / maxValue) * 100;
|
|
40
41
|
return Number.isFinite(progress) ? progress : 0;
|
|
41
42
|
};
|
|
42
|
-
let progressValue1 = calculateProgress(
|
|
43
|
-
let progressValue2 = calculateProgress(
|
|
44
|
-
return (_jsx(StyledWaitPanelOverlay, { children: _jsxs(StyledWaitPanel, { "$height": (
|
|
45
|
-
_jsxs("div", { style: { width: '100%', height: '100px' }, children: [_jsx(StyledProgressBarContainer, { children: _jsx(StyledProgressBar, { style: { width: `${progressValue1.toFixed(2)}%` } }) }), _jsxs(StyledProgressText, { children: [progressValue1.toFixed(2), "%"] }), _jsx(StyledMessage, { children:
|
|
46
|
-
_jsxs("div", { style: { width: '100%', height: '100px' }, children: [_jsx(StyledProgressBarContainer, { children: _jsx(StyledProgressBar, { style: { width: `${progressValue2.toFixed(2)}%` } }) }), _jsxs(StyledProgressText, { children: [progressValue2.toFixed(2), "%"] }), _jsx(StyledMessage, { children:
|
|
43
|
+
let progressValue1 = calculateProgress(valuePrimary, maxValuePrimary);
|
|
44
|
+
let progressValue2 = calculateProgress(valueSecondary, maxValueSecondary);
|
|
45
|
+
return (_jsx(StyledWaitPanelOverlay, { children: _jsxs(StyledWaitPanel, { "$height": (showPrimary && showSecondary) ? '350px' : '250px', children: [_jsx(StyledTitle, { children: title }), showPrimary &&
|
|
46
|
+
_jsxs("div", { style: { width: '100%', height: '100px' }, children: [_jsx(StyledProgressBarContainer, { children: _jsx(StyledProgressBar, { style: { width: `${progressValue1.toFixed(2)}%` } }) }), _jsxs(StyledProgressText, { children: [progressValue1.toFixed(2), "%"] }), _jsx(StyledMessage, { children: textPrimary })] }), showSecondary &&
|
|
47
|
+
_jsxs("div", { style: { width: '100%', height: '100px' }, children: [_jsx(StyledProgressBarContainer, { children: _jsx(StyledProgressBar, { style: { width: `${progressValue2.toFixed(2)}%` } }) }), _jsxs(StyledProgressText, { children: [progressValue2.toFixed(2), "%"] }), _jsx(StyledMessage, { children: textSecondary })] }), isCancelable && _jsx(StyledAbortButton, { onClick: () => onAbortClick?.(abortController), children: SDKUI_Localizator.Abort })] }) }));
|
|
47
48
|
};
|
|
48
49
|
export const TMLayoutWaitingContainer = ({ showWaitPanel, showWaitPanelPrimary, showWaitPanelSecondary, waitPanelTitle, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, isCancelable, abortController, gap = 3, onClick, justifyContent = 'flex-start', alignItems = 'flex-start', children, direction = 'vertical' }) => {
|
|
49
50
|
return (_jsxs(TMLayoutContainer, { gap: gap, justifyContent: justifyContent, alignItems: alignItems, direction: direction, children: [children, showWaitPanel && (_jsx(TMWaitPanel, { title: waitPanelTitle, showPrimary: showWaitPanelPrimary, textPrimary: waitPanelTextPrimary, valuePrimary: waitPanelValuePrimary, maxValuePrimary: waitPanelMaxValuePrimary, showSecondary: showWaitPanelSecondary, textSecondary: waitPanelTextSecondary, valueSecondary: waitPanelValueSecondary, maxValueSecondary: waitPanelMaxValueSecondary, isCancelable: isCancelable, abortController: abortController, onAbortClick: (abortController) => { setTimeout(() => { abortController?.abort(); }, 1000); } }))] }));
|
|
@@ -31,7 +31,7 @@ const cellRenderIcon = (data) => _jsx(TMImageLibrary, { imageID: data.data?.imag
|
|
|
31
31
|
export const TMDataListItemChooserForm = (props) => {
|
|
32
32
|
const dataColumns = useMemo(() => {
|
|
33
33
|
return [
|
|
34
|
-
{ dataField: 'value', caption: SDKUI_Localizator.Value },
|
|
34
|
+
{ dataField: 'value', caption: SDKUI_Localizator.Value, visible: false },
|
|
35
35
|
{ dataField: 'name', caption: SDKUI_Localizator.Description }
|
|
36
36
|
];
|
|
37
37
|
}, []);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DataListItemDescriptor } from '@topconsultnpm/sdk-ts';
|
|
3
|
+
interface TMDataListItemEditorProps {
|
|
4
|
+
isOpen: boolean;
|
|
5
|
+
item?: DataListItemDescriptor;
|
|
6
|
+
isCreating: boolean;
|
|
7
|
+
onClose: () => void;
|
|
8
|
+
onSave: (item: DataListItemDescriptor) => void;
|
|
9
|
+
}
|
|
10
|
+
declare const TMDataListItemEditor: React.FC<TMDataListItemEditorProps>;
|
|
11
|
+
export default TMDataListItemEditor;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
import { DataListItemDescriptor, NamesLoc3, PlatformObjectValidator } from '@topconsultnpm/sdk-ts';
|
|
5
|
+
import { IconCloseOutline, IconSave, IconUndo, SDKUI_Localizator } from '../../helper';
|
|
6
|
+
import TMButton from '../base/TMButton';
|
|
7
|
+
import TMModal from '../base/TMModal';
|
|
8
|
+
import TMDataListItemFields from './TMDataListItemFields';
|
|
9
|
+
import { TMColors } from '../../utils/theme';
|
|
10
|
+
const FormContainer = styled.div `
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
gap: 15px;
|
|
14
|
+
padding: 20px;
|
|
15
|
+
`;
|
|
16
|
+
const ButtonsContainer = styled.div `
|
|
17
|
+
display: flex;
|
|
18
|
+
justify-content: flex-end;
|
|
19
|
+
gap: 10px;
|
|
20
|
+
margin-top: 10px;
|
|
21
|
+
`;
|
|
22
|
+
const TMDataListItemEditor = ({ isOpen, item, isCreating, onClose, onSave }) => {
|
|
23
|
+
const [editedItem, setEditedItem] = useState(null);
|
|
24
|
+
const [editedItemOrig, setEditedItemOrig] = useState(null);
|
|
25
|
+
const [validationItems, setValidationItems] = useState([]);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!editedItem)
|
|
28
|
+
return;
|
|
29
|
+
let vil = [];
|
|
30
|
+
PlatformObjectValidator.DataListItemValidator(editedItem, vil);
|
|
31
|
+
setValidationItems(vil);
|
|
32
|
+
}, [editedItem]);
|
|
33
|
+
// Funzione helper per clonare un DataListItemDescriptor
|
|
34
|
+
const cloneItem = (source) => {
|
|
35
|
+
const clone = new DataListItemDescriptor();
|
|
36
|
+
Object.assign(clone, source);
|
|
37
|
+
if (source.namesLoc) {
|
|
38
|
+
const namesLocClone = new NamesLoc3();
|
|
39
|
+
namesLocClone.init(source.namesLoc);
|
|
40
|
+
clone.namesLoc = namesLocClone;
|
|
41
|
+
}
|
|
42
|
+
return clone;
|
|
43
|
+
};
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (isOpen) {
|
|
46
|
+
if (item) {
|
|
47
|
+
// Crea una copia dell'item per editarlo
|
|
48
|
+
const clone = cloneItem(item);
|
|
49
|
+
setEditedItem(clone);
|
|
50
|
+
// Salva anche l'originale per il confronto e l'undo
|
|
51
|
+
const original = cloneItem(item);
|
|
52
|
+
setEditedItemOrig(original);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Nuovo item vuoto
|
|
56
|
+
const newItem = new DataListItemDescriptor();
|
|
57
|
+
newItem.value = '';
|
|
58
|
+
newItem.name = '';
|
|
59
|
+
setEditedItem(newItem);
|
|
60
|
+
setEditedItemOrig(cloneItem(newItem));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}, [isOpen, item]);
|
|
64
|
+
// Funzione per verificare se ci sono modifiche rispetto all'originale
|
|
65
|
+
const hasChanges = () => {
|
|
66
|
+
if (!editedItem || !editedItemOrig)
|
|
67
|
+
return false;
|
|
68
|
+
// Confronta i campi principali
|
|
69
|
+
if (editedItem.value !== editedItemOrig.value)
|
|
70
|
+
return true;
|
|
71
|
+
if (editedItem.name !== editedItemOrig.name)
|
|
72
|
+
return true;
|
|
73
|
+
if (editedItem.imageID !== editedItemOrig.imageID)
|
|
74
|
+
return true;
|
|
75
|
+
// Confronta namesLoc
|
|
76
|
+
const namesLoc1 = editedItem.namesLoc;
|
|
77
|
+
const namesLoc2 = editedItemOrig.namesLoc;
|
|
78
|
+
if (!namesLoc1 && !namesLoc2)
|
|
79
|
+
return false;
|
|
80
|
+
if (!namesLoc1 || !namesLoc2)
|
|
81
|
+
return true;
|
|
82
|
+
if (namesLoc1.it_IT !== namesLoc2.it_IT)
|
|
83
|
+
return true;
|
|
84
|
+
if (namesLoc1.en_US !== namesLoc2.en_US)
|
|
85
|
+
return true;
|
|
86
|
+
if (namesLoc1.fr_FR !== namesLoc2.fr_FR)
|
|
87
|
+
return true;
|
|
88
|
+
if (namesLoc1.pt_PT !== namesLoc2.pt_PT)
|
|
89
|
+
return true;
|
|
90
|
+
if (namesLoc1.es_ES !== namesLoc2.es_ES)
|
|
91
|
+
return true;
|
|
92
|
+
if (namesLoc1.de_DE !== namesLoc2.de_DE)
|
|
93
|
+
return true;
|
|
94
|
+
return false;
|
|
95
|
+
};
|
|
96
|
+
const handleUndo = () => {
|
|
97
|
+
if (!editedItemOrig)
|
|
98
|
+
return;
|
|
99
|
+
// Ripristina l'item originale clonandolo
|
|
100
|
+
const restored = cloneItem(editedItemOrig);
|
|
101
|
+
setEditedItem(restored);
|
|
102
|
+
};
|
|
103
|
+
const handleSave = () => {
|
|
104
|
+
if (!editedItem)
|
|
105
|
+
return;
|
|
106
|
+
// Pulisci namesLoc rimuovendo valori undefined o vuoti, mantenendo l'istanza della classe
|
|
107
|
+
if (editedItem.namesLoc) {
|
|
108
|
+
const cleanedData = {};
|
|
109
|
+
Object.entries(editedItem.namesLoc).forEach(([key, value]) => {
|
|
110
|
+
if (value !== undefined && value !== '') {
|
|
111
|
+
cleanedData[key] = value;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
// Crea una nuova istanza di NamesLoc3 con i dati puliti
|
|
115
|
+
if (Object.keys(cleanedData).length > 0) {
|
|
116
|
+
const cleanedNamesLoc = new NamesLoc3();
|
|
117
|
+
cleanedNamesLoc.init(cleanedData);
|
|
118
|
+
editedItem.namesLoc = cleanedNamesLoc;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
editedItem.namesLoc = undefined;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
onSave(editedItem);
|
|
125
|
+
};
|
|
126
|
+
if (!isOpen || !editedItem)
|
|
127
|
+
return null;
|
|
128
|
+
return (_jsx(TMModal, { title: isCreating ? SDKUI_Localizator.NewMale : SDKUI_Localizator.Update, width: "400px", height: "auto", isModal: true, onClose: onClose, children: _jsxs(FormContainer, { children: [_jsx(TMDataListItemFields, { item: editedItem, originalItem: editedItemOrig || undefined, onItemChanged: setEditedItem, validationItems: validationItems }), _jsxs(ButtonsContainer, { children: [_jsx(TMButton, { caption: SDKUI_Localizator.Save, btnStyle: 'advanced', advancedColor: TMColors.primary, icon: _jsx(IconSave, {}), showTooltip: false, onClick: handleSave }), _jsx(TMButton, { caption: SDKUI_Localizator.Undo, btnStyle: 'toolbar', color: 'primary', icon: _jsx(IconUndo, {}), showTooltip: false, disabled: !hasChanges(), onClick: handleUndo }), _jsx(TMButton, { caption: SDKUI_Localizator.Cancel, btnStyle: 'advanced', advancedColor: TMColors.primary, icon: _jsx(IconCloseOutline, {}), showTooltip: false, onClick: onClose })] })] }) }));
|
|
129
|
+
};
|
|
130
|
+
export default TMDataListItemEditor;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DataListItemDescriptor, ValidationItem } from '@topconsultnpm/sdk-ts';
|
|
3
|
+
interface TMDataListItemFieldsProps {
|
|
4
|
+
item: DataListItemDescriptor;
|
|
5
|
+
originalItem?: DataListItemDescriptor;
|
|
6
|
+
onItemChanged: (item: DataListItemDescriptor) => void;
|
|
7
|
+
validationItems?: ValidationItem[];
|
|
8
|
+
readOnly?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare const TMDataListItemFields: React.FC<TMDataListItemFieldsProps>;
|
|
11
|
+
export default TMDataListItemFields;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
import { DataListItemDescriptor, CultureIDs, NamesLoc3 } from '@topconsultnpm/sdk-ts';
|
|
4
|
+
import { SDKUI_Localizator } from '../../helper';
|
|
5
|
+
import TMTextBox from '../editors/TMTextBox';
|
|
6
|
+
import TMLocalizedTextBox from '../editors/TMLocalizedTextBox';
|
|
7
|
+
import TMImageIDChooser from './TMImageIDChooser';
|
|
8
|
+
const FieldsContainer = styled.div `
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
gap: 15px;
|
|
12
|
+
`;
|
|
13
|
+
const TMDataListItemFields = ({ item, originalItem, onItemChanged, validationItems = [], readOnly = false }) => {
|
|
14
|
+
const handleLocalizedNameChange = (lang, newValue) => {
|
|
15
|
+
if (!item.namesLoc) {
|
|
16
|
+
item.namesLoc = new NamesLoc3();
|
|
17
|
+
}
|
|
18
|
+
const namesLoc = item.namesLoc; // Non-null assertion
|
|
19
|
+
switch (lang) {
|
|
20
|
+
case CultureIDs.It_IT:
|
|
21
|
+
namesLoc.it_IT = newValue;
|
|
22
|
+
break;
|
|
23
|
+
case CultureIDs.En_US:
|
|
24
|
+
namesLoc.en_US = newValue;
|
|
25
|
+
break;
|
|
26
|
+
case CultureIDs.Fr_FR:
|
|
27
|
+
namesLoc.fr_FR = newValue;
|
|
28
|
+
break;
|
|
29
|
+
case CultureIDs.Pt_PT:
|
|
30
|
+
namesLoc.pt_PT = newValue;
|
|
31
|
+
break;
|
|
32
|
+
case CultureIDs.Es_ES:
|
|
33
|
+
namesLoc.es_ES = newValue;
|
|
34
|
+
break;
|
|
35
|
+
case CultureIDs.De_DE:
|
|
36
|
+
namesLoc.de_DE = newValue;
|
|
37
|
+
break;
|
|
38
|
+
default:
|
|
39
|
+
item.name = newValue;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
// Forza il re-render clonando l'oggetto
|
|
43
|
+
const clone = new DataListItemDescriptor();
|
|
44
|
+
Object.assign(clone, item);
|
|
45
|
+
onItemChanged(clone);
|
|
46
|
+
};
|
|
47
|
+
const handleValueChange = (e) => {
|
|
48
|
+
item.value = e.target.value || '';
|
|
49
|
+
const clone = new DataListItemDescriptor();
|
|
50
|
+
Object.assign(clone, item);
|
|
51
|
+
onItemChanged(clone);
|
|
52
|
+
};
|
|
53
|
+
const handleImageIDChange = (imageID) => {
|
|
54
|
+
item.imageID = imageID;
|
|
55
|
+
const clone = new DataListItemDescriptor();
|
|
56
|
+
Object.assign(clone, item);
|
|
57
|
+
onItemChanged(clone);
|
|
58
|
+
};
|
|
59
|
+
return (_jsxs(FieldsContainer, { children: [_jsx(TMTextBox, { label: SDKUI_Localizator.Value, value: item.value, isModifiedWhen: (item.value || '') != (originalItem?.value || ''), validationItems: validationItems.filter(o => o.PropertyName === "value"), readOnly: readOnly, autoFocus: true, onValueChanged: handleValueChange }), _jsx(TMLocalizedTextBox, { label: SDKUI_Localizator.Description, value: item.name, isModifiedWhen: (item.name || '') != (originalItem?.name || ''), validationItems: validationItems.filter(o => o.PropertyName === "itemName"), readOnly: readOnly, value_IT: item.namesLoc?.it_IT, value_EN: item.namesLoc?.en_US, value_FR: item.namesLoc?.fr_FR, value_PT: item.namesLoc?.pt_PT, value_ES: item.namesLoc?.es_ES, value_DE: item.namesLoc?.de_DE, onValueChanged: handleLocalizedNameChange }), _jsx(TMImageIDChooser, { elementStyle: { marginBottom: '10px' }, label: "Immagine", value: item.imageID, isModifiedWhen: (item.imageID || '') != (originalItem?.imageID || ''), validationItems: validationItems.filter(o => o.PropertyName === "imageID"), readOnly: readOnly, onValueChanged: handleImageIDChange })] }));
|
|
60
|
+
};
|
|
61
|
+
export default TMDataListItemFields;
|
|
@@ -4,6 +4,8 @@ interface TMDataListItemPickerProps {
|
|
|
4
4
|
dataListID: number | undefined;
|
|
5
5
|
selectedValue: string | undefined;
|
|
6
6
|
onItemSelect: (item: DataListItemDescriptor) => void;
|
|
7
|
+
onItemEdited?: (originalItem: DataListItemDescriptor, editedItem: DataListItemDescriptor) => void;
|
|
8
|
+
allowEdit?: boolean;
|
|
7
9
|
}
|
|
8
10
|
declare const TMDataListItemPicker: React.FC<TMDataListItemPickerProps>;
|
|
9
11
|
export default TMDataListItemPicker;
|