@topconsultnpm/sdkui-react-beta 6.13.34 → 6.13.35
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/base/Styled.d.ts +0 -1
- package/lib/components/base/Styled.js +11 -19
- package/lib/components/base/TMPanel.js +4 -4
- package/lib/components/base/TMPanelManager.d.ts +9 -0
- package/lib/components/base/TMPanelManager.js +465 -0
- package/lib/components/base/TMPanelManagerToolbar.d.ts +16 -0
- package/lib/components/base/TMPanelManagerToolbar.js +100 -0
- package/lib/components/base/TMPanelManagerUtils.d.ts +36 -0
- package/lib/components/base/TMPanelManagerUtils.js +27 -0
- package/lib/components/features/documents/TMDcmtForm.js +7 -5
- package/lib/components/features/documents/TMDcmtPreview.js +1 -1
- package/lib/components/features/search/TMSearchQueryPanel.js +1 -0
- package/lib/components/features/search/TMSearchResult.js +5 -3
- package/lib/components/index.d.ts +3 -2
- package/lib/components/index.js +3 -2
- package/lib/components/sidebar/TMCommandsPanel.js +1 -1
- package/package.json +1 -1
- package/lib/components/base/TMPanelManagerMatrix.d.ts +0 -9
- package/lib/components/base/TMPanelManagerMatrix.js +0 -262
- package/lib/components/base/TMPanelManagerMatrixUtils.d.ts +0 -69
- package/lib/components/base/TMPanelManagerMatrixUtils.js +0 -155
@@ -0,0 +1,100 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
import { useEffect, useMemo, useState } from 'react';
|
3
|
+
import { useDeviceType, DeviceType } from './TMDeviceProvider';
|
4
|
+
import TMTooltip from './TMTooltip';
|
5
|
+
const TMPanelManagerToolbar = (props) => {
|
6
|
+
const { allPanels, activeButtons, handleTogglePanel, updatedDisabledButton, updatedVisibleButton } = props;
|
7
|
+
const deviceType = useDeviceType();
|
8
|
+
let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
|
9
|
+
const [filteredPanels, setFilteredPanels] = useState([]);
|
10
|
+
const [disabledButtons, setDisabledButtons] = useState({});
|
11
|
+
const [visibleButtons, setVisibleButtons] = useState({});
|
12
|
+
// Initialize visibility and disabled states
|
13
|
+
useEffect(() => {
|
14
|
+
const visible = {};
|
15
|
+
const disabled = {};
|
16
|
+
const filtered = allPanels
|
17
|
+
.filter((p) => {
|
18
|
+
const vis = !!p.config.toolbarOptions?.visible;
|
19
|
+
visible[p.fullId] = vis;
|
20
|
+
disabled[p.fullId] = !!p.config.toolbarOptions?.disabled;
|
21
|
+
return vis;
|
22
|
+
})
|
23
|
+
.sort((a, b) => (a.config.toolbarOptions?.orderNumber ?? 0) - (b.config.toolbarOptions?.orderNumber ?? 0));
|
24
|
+
setVisibleButtons(visible);
|
25
|
+
setDisabledButtons(disabled);
|
26
|
+
setFilteredPanels(filtered);
|
27
|
+
}, [allPanels]);
|
28
|
+
// Update disabled button
|
29
|
+
useEffect(() => {
|
30
|
+
if (updatedDisabledButton) {
|
31
|
+
setDisabledButtons((prev) => ({
|
32
|
+
...prev,
|
33
|
+
[updatedDisabledButton.id]: updatedDisabledButton.value,
|
34
|
+
}));
|
35
|
+
}
|
36
|
+
}, [updatedDisabledButton]);
|
37
|
+
// Update visible button
|
38
|
+
useEffect(() => {
|
39
|
+
if (updatedVisibleButton) {
|
40
|
+
const { id, value } = updatedVisibleButton;
|
41
|
+
setVisibleButtons((prev) => ({ ...prev, [id]: value }));
|
42
|
+
setFilteredPanels((prev) => {
|
43
|
+
if (value) {
|
44
|
+
const newPanel = allPanels.find((p) => p.fullId === id);
|
45
|
+
if (newPanel && !prev.some((p) => p.fullId === id)) {
|
46
|
+
return [...prev, newPanel].sort((a, b) => (a.config.toolbarOptions?.orderNumber ?? 0) - (b.config.toolbarOptions?.orderNumber ?? 0));
|
47
|
+
}
|
48
|
+
return prev;
|
49
|
+
}
|
50
|
+
else {
|
51
|
+
return prev.filter((p) => p.fullId !== id);
|
52
|
+
}
|
53
|
+
});
|
54
|
+
}
|
55
|
+
}, [updatedVisibleButton, allPanels]);
|
56
|
+
return (_jsx("div", { style: {
|
57
|
+
display: 'flex',
|
58
|
+
flexDirection: isMobile ? 'row' : 'column',
|
59
|
+
gap: '6px',
|
60
|
+
alignItems: isMobile ? 'center' : 'flex-start',
|
61
|
+
justifyContent: isMobile ? 'center' : 'flex-start',
|
62
|
+
width: '100%',
|
63
|
+
height: '100%',
|
64
|
+
}, children: filteredPanels.map((p, idx) => {
|
65
|
+
const isActive = activeButtons[p.fullId];
|
66
|
+
const handleClick = p.config.buttonOptions?.onClick;
|
67
|
+
const isToolbarDisabled = disabledButtons[p.fullId];
|
68
|
+
// Separator JSX if beginGroup is true and NOT first button (otherwise no separator before first button)
|
69
|
+
const separator = (p.config.toolbarOptions?.beginGroup && idx > 0) ? (_jsx("div", { style: {
|
70
|
+
width: isMobile ? '1px' : '80%',
|
71
|
+
height: isMobile ? '80%' : '1px',
|
72
|
+
backgroundColor: '#ccc',
|
73
|
+
margin: isMobile ? '0 6px' : '6px 0',
|
74
|
+
alignSelf: 'center',
|
75
|
+
} }, `sep-${p.fullId}`)) : null;
|
76
|
+
// Button JSX
|
77
|
+
const button = (_jsx(TMTooltip, { content: p.config.name, position: 'left', children: _jsx("button", { disabled: isToolbarDisabled, onClick: () => { handleTogglePanel(p.fullId); if (handleClick)
|
78
|
+
handleClick(); }, style: {
|
79
|
+
display: 'flex',
|
80
|
+
alignItems: 'center',
|
81
|
+
justifyContent: 'center',
|
82
|
+
height: '40px',
|
83
|
+
width: '40px',
|
84
|
+
border: 'none',
|
85
|
+
borderRadius: '10px',
|
86
|
+
fontSize: '18px',
|
87
|
+
padding: '8px 10px',
|
88
|
+
color: '#fff',
|
89
|
+
transition: 'transform 0.2s ease, box-shadow 0.2s ease',
|
90
|
+
cursor: isToolbarDisabled ? 'not-allowed' : 'pointer',
|
91
|
+
opacity: isToolbarDisabled ? 0.6 : 1,
|
92
|
+
backgroundColor: isActive ? '#81c784' : '#e57373',
|
93
|
+
}, onMouseEnter: (e) => { if (!isToolbarDisabled) {
|
94
|
+
e.currentTarget.style.transform = 'scale(1.1)';
|
95
|
+
} }, onMouseLeave: (e) => { e.currentTarget.style.transform = 'scale(1)'; }, children: typeof p.config.toolbarOptions?.icon === 'string' ? (_jsx("i", { className: `dx-icon dx-icon-${p.config.toolbarOptions?.icon}` })) : (p.config.toolbarOptions?.icon) }) }, p.fullId));
|
96
|
+
// Return separator first, then button
|
97
|
+
return [separator, button];
|
98
|
+
}) }));
|
99
|
+
};
|
100
|
+
export default TMPanelManagerToolbar;
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { ITMPanelProps } from "./TMPanel";
|
2
|
+
export type TMPanelItemConfig = {
|
3
|
+
id: string;
|
4
|
+
name: string;
|
5
|
+
type: 'content' | 'button';
|
6
|
+
alternativePanelIds?: Array<string>;
|
7
|
+
buttonOptions?: {
|
8
|
+
onClick: () => void;
|
9
|
+
};
|
10
|
+
contentOptions?: {
|
11
|
+
height: string;
|
12
|
+
width: string;
|
13
|
+
visible?: boolean;
|
14
|
+
content?: JSX.Element | ((handleTogglePanel: (id: string) => void, handleToggleMaximize: (fullId: string) => void, handleVisibilityButton: (id: string, value: boolean) => void, handleDisableButton: (id: string, value: boolean) => void) => JSX.Element) | Array<TMPanelItemConfig>;
|
15
|
+
panelContainer?: ITMPanelProps;
|
16
|
+
};
|
17
|
+
toolbarOptions?: {
|
18
|
+
icon: string | JSX.Element;
|
19
|
+
isActive: boolean;
|
20
|
+
visible: boolean;
|
21
|
+
disabled?: boolean;
|
22
|
+
orderNumber?: number;
|
23
|
+
beginGroup?: boolean;
|
24
|
+
};
|
25
|
+
};
|
26
|
+
export type TMPanelEntry = {
|
27
|
+
fullId: string;
|
28
|
+
config: TMPanelItemConfig;
|
29
|
+
parentId: string | null;
|
30
|
+
childrenIds: Array<string>;
|
31
|
+
alternativePanelIds: Array<string>;
|
32
|
+
};
|
33
|
+
export declare const isPanelArray: (content: unknown) => content is Array<TMPanelItemConfig>;
|
34
|
+
export declare const flattenPanels: (panels: Array<TMPanelItemConfig>, parentId?: string | null, parentPath?: string) => Array<TMPanelEntry>;
|
35
|
+
export declare const isAtLeastOnePanelVisible: (activeButtons: Record<string, boolean>) => boolean;
|
36
|
+
export declare const isExactlyOnePanelVisible: (activeButtons: Record<string, boolean>) => boolean;
|
@@ -0,0 +1,27 @@
|
|
1
|
+
// Type guard to check if a value is an array of TMPanelItemConfig objects.
|
2
|
+
// Ensures that every item in the array is a non-null object with 'id' and 'contentOptions' properties.
|
3
|
+
export const isPanelArray = (content) => Array.isArray(content) && content.every(p => typeof p === 'object' && p !== null && 'id' in p && 'contentOptions' in p);
|
4
|
+
// Recursively flattens a nested array of panel configurations into a flat array of TMPanelEntry objects.
|
5
|
+
// - panels: the input array of TMPanelItemConfig.
|
6
|
+
// - parentId: optional ID of the parent panel (used for hierarchical relationships).
|
7
|
+
// - parentPath: string path of ancestor IDs, used to build a full, unique identifier for each panel.
|
8
|
+
export const flattenPanels = (panels, parentId = null, parentPath = '') => {
|
9
|
+
return panels.flatMap(panel => {
|
10
|
+
// Construct the full ID by appending the current panel ID to the parent path.
|
11
|
+
const fullId = parentPath ? `${parentPath}.${panel.id}` : panel.id;
|
12
|
+
let children = [];
|
13
|
+
// If the panel has nested content that is also a valid panel array, recursively flatten them.
|
14
|
+
if (isPanelArray(panel.contentOptions?.content)) {
|
15
|
+
children = flattenPanels(panel.contentOptions.content, fullId, fullId);
|
16
|
+
}
|
17
|
+
// Extract full IDs of all child entries.
|
18
|
+
const childrenIds = children.map(c => c.fullId);
|
19
|
+
const alternativePanelIds = panel.alternativePanelIds ?? [];
|
20
|
+
// Return the current panel as a TMPanelEntry followed by its flattened children.
|
21
|
+
return [{ fullId, config: panel, parentId, childrenIds, alternativePanelIds }, ...children];
|
22
|
+
});
|
23
|
+
};
|
24
|
+
// Checks if at least one panel is currently visible (i.e., at least one active button is true)
|
25
|
+
export const isAtLeastOnePanelVisible = (activeButtons) => Object.values(activeButtons).some(Boolean);
|
26
|
+
// Checks if exactly one panel is currently visible (i.e., only one active button is true)
|
27
|
+
export const isExactlyOnePanelVisible = (activeButtons) => Object.values(activeButtons).filter(Boolean).length === 1;
|
@@ -210,7 +210,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
210
210
|
{ icon: svgToString(_jsx(IconDownload, {})), operationType: 'singleRow', disabled: fromDTD?.perm?.canRetrieveFile !== AccessLevels.Yes, text: "Download file", onClick: async () => await downloadDcmtsAsync(getDcmts(), DownloadTypes.Dcmt) },
|
211
211
|
{ icon: svgToString(_jsx(IconDownload, {})), operationType: 'singleRow', disabled: !isXMLFileExt(currentDcmt?.fileExt), text: "Download allegati XML", onClick: async () => await downloadDcmtsAsync(getDcmts(), DownloadTypes.Attachment, openConfirmAttachmentsDialog) },
|
212
212
|
];
|
213
|
-
const formToolbar = _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [canPrev != undefined && _jsx("p", { style: { textAlign: 'center', padding: '1px 4px', display: 'flex' }, children: `${itemIndex}/${count}` }), canPrev != undefined && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', iconColor: 'white', isModified: calcIsModified(formData, formDataOrig), formMode: formMode, canPrev: canPrev, onPrev: onPrev }), canNext != undefined && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', iconColor: 'white', isModified: calcIsModified(formData, formDataOrig), formMode: formMode, canNext: canNext, onNext: onNext }), layoutMode === LayoutModes.Update && _jsx(IconMenuVertical, { id: `commands-detail-${id}`, color: 'white', cursor: 'pointer' }), layoutMode === LayoutModes.Update && _jsx(ContextMenu, { showEvent: 'click', dataSource: commandsMenuItems, target: `#commands-detail-${id}` })] });
|
213
|
+
const formToolbar = _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [canPrev != undefined && _jsx("p", { style: { backgroundColor: `white`, color: TMColors.primaryColor, textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${itemIndex}/${count}` }), canPrev != undefined && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', iconColor: 'white', isModified: calcIsModified(formData, formDataOrig), formMode: formMode, canPrev: canPrev, onPrev: onPrev }), canNext != undefined && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', iconColor: 'white', isModified: calcIsModified(formData, formDataOrig), formMode: formMode, canNext: canNext, onNext: onNext }), layoutMode === LayoutModes.Update && _jsx(IconMenuVertical, { id: `commands-detail-${id}`, color: 'white', cursor: 'pointer' }), layoutMode === LayoutModes.Update && _jsx(ContextMenu, { showEvent: 'click', dataSource: commandsMenuItems, target: `#commands-detail-${id}` })] });
|
214
214
|
function createChange(mid, metadataType, modifiedValue) {
|
215
215
|
return { mid, metadataType, modifiedValue };
|
216
216
|
}
|
@@ -453,7 +453,9 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
453
453
|
gap: SDKUI_Globals.userSettings.themeSettings.gutters,
|
454
454
|
width: '100%',
|
455
455
|
height: '100%',
|
456
|
-
}, children: [_jsx("div", { style: { flex: 1, minWidth: 0, height: '100%' }, children: _jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: useWaitPanelLocalState ? showWaitPanelLocal : showWaitPanel, showWaitPanelPrimary: useWaitPanelLocalState ? showPrimaryLocal : showPrimary, showWaitPanelSecondary: useWaitPanelLocalState ? showSecondaryLocal : showSecondary, waitPanelTitle: useWaitPanelLocalState ? waitPanelTitleLocal : waitPanelTitle, waitPanelTextPrimary: useWaitPanelLocalState ? waitPanelTextPrimaryLocal : waitPanelTextPrimary, waitPanelValuePrimary: useWaitPanelLocalState ? waitPanelValuePrimaryLocal : waitPanelValuePrimary, waitPanelMaxValuePrimary: useWaitPanelLocalState ? waitPanelMaxValuePrimaryLocal : waitPanelMaxValuePrimary, waitPanelTextSecondary: useWaitPanelLocalState ? waitPanelTextSecondaryLocal : waitPanelTextSecondary, waitPanelValueSecondary: useWaitPanelLocalState ? waitPanelValueSecondaryLocal : waitPanelValueSecondary, waitPanelMaxValueSecondary: useWaitPanelLocalState ? waitPanelMaxValueSecondaryLocal : waitPanelMaxValueSecondary, isCancelable: useWaitPanelLocalState ? dcmtFile ? dcmtFile.size >= 1000000 : false : true, abortController: useWaitPanelLocalState ? abortControllerLocal : abortController, children: [_jsxs(TMSplitterLayout, { direction: 'horizontal', overflow: 'visible', separatorSize: SDKUI_Globals.userSettings.themeSettings.gutters, separatorColor: 'transparent', showSeparator: (isOpenPreview || isOpenMiddlePanel()) && deviceType !== DeviceType.MOBILE && isOpenDcmtForm, start: getPrimarySplitterStartLayout(), min: deviceType !== DeviceType.MOBILE && isOpenDcmtForm ? ['150px', '0'] : ['0', '0'], children: [_jsx(TMLayoutItem, { children: _jsx(TMPanel, { showHeader: showHeader, title: fromDTD?.nameLoc, toolbar: allowNavigation ? formToolbar : _jsx(_Fragment, {}),
|
456
|
+
}, children: [_jsx("div", { style: { flex: 1, minWidth: 0, height: '100%' }, children: _jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: useWaitPanelLocalState ? showWaitPanelLocal : showWaitPanel, showWaitPanelPrimary: useWaitPanelLocalState ? showPrimaryLocal : showPrimary, showWaitPanelSecondary: useWaitPanelLocalState ? showSecondaryLocal : showSecondary, waitPanelTitle: useWaitPanelLocalState ? waitPanelTitleLocal : waitPanelTitle, waitPanelTextPrimary: useWaitPanelLocalState ? waitPanelTextPrimaryLocal : waitPanelTextPrimary, waitPanelValuePrimary: useWaitPanelLocalState ? waitPanelValuePrimaryLocal : waitPanelValuePrimary, waitPanelMaxValuePrimary: useWaitPanelLocalState ? waitPanelMaxValuePrimaryLocal : waitPanelMaxValuePrimary, waitPanelTextSecondary: useWaitPanelLocalState ? waitPanelTextSecondaryLocal : waitPanelTextSecondary, waitPanelValueSecondary: useWaitPanelLocalState ? waitPanelValueSecondaryLocal : waitPanelValueSecondary, waitPanelMaxValueSecondary: useWaitPanelLocalState ? waitPanelMaxValueSecondaryLocal : waitPanelMaxValueSecondary, isCancelable: useWaitPanelLocalState ? dcmtFile ? dcmtFile.size >= 1000000 : false : true, abortController: useWaitPanelLocalState ? abortControllerLocal : abortController, children: [_jsxs(TMSplitterLayout, { direction: 'horizontal', overflow: 'visible', separatorSize: SDKUI_Globals.userSettings.themeSettings.gutters, separatorColor: 'transparent', showSeparator: (isOpenPreview || isOpenMiddlePanel()) && deviceType !== DeviceType.MOBILE && isOpenDcmtForm, start: getPrimarySplitterStartLayout(), min: deviceType !== DeviceType.MOBILE && isOpenDcmtForm ? ['150px', '0'] : ['0', '0'], children: [_jsx(TMLayoutItem, { children: _jsx(TMPanel, { showHeader: showHeader, title: fromDTD?.nameLoc, toolbar: allowNavigation ? formToolbar : _jsx(_Fragment, {}),
|
457
|
+
// onBack={isClosable ? undefined : handleClose}
|
458
|
+
onClose: isClosable ? handleClose : undefined, children: metadataValuesSource.length > 0 && _jsxs(StyledToolbarCardContainer, { children: [_jsx(TMMetadataValues, { TID: TID, metadataValues: metadataValuesSource, metadataValuesOrig: metadataValuesSourceOrig, isExpertMode: isExpertMode, isOpenDistinctValues: isOpenDistinctValues, openChooserBySingleClick: !isOpenDistinctValues, selectedMID: focusedMetadataValue?.mid, layoutMode: layoutMode, deviceType: deviceType, validationItems: validationItems, onFocusedItemChanged: (item) => { (item?.mid !== focusedMetadataValue?.mid) && setFocusedMetadataValue(item); }, onValueChanged: (newItems) => {
|
457
459
|
setFormData((prevItems) => prevItems.map((item) => {
|
458
460
|
const newItem = newItems.find((newItem) => newItem.tid === item.tid && newItem.mid === item.mid);
|
459
461
|
return newItem ? { ...item, ...newItem } : item;
|
@@ -470,7 +472,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
470
472
|
} }), _jsxs(StyledFormButtonsContainer, { children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10 }, children: [fromDTD?.templateTID === TemplateTIDs.WF_WIApprView && _jsx(WorkFlowOperationButtons, { onApprove: () => setShowApprovePopup(true), onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), isInDcmtForm: true }), _jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '8px' }, children: layoutMode === LayoutModes.Update ? _jsxs(_Fragment, { children: [_jsx(TMSaveFormButtonSave, { showTooltip: false, btnStyle: 'advanced', advancedColor: '#f09c0a', isModified: isModified, formMode: formMode, errorsCount: validationItems.filter(o => o.ResultType == ResultTypes.ERROR).length, onSaveAsync: confirmActionPopup }), _jsx(TMSaveFormButtonUndo, { btnStyle: 'toolbar', showTooltip: true, color: 'primary', isModified: isModified, formMode: formMode, onUndo: onUndoHandler })] }) :
|
471
473
|
_jsxs(_Fragment, { children: [_jsx(TMButton, { disabled: archiveBtnDisabled, btnStyle: 'advanced', icon: _jsx(IconBoxArchiveIn, {}), showTooltip: false, caption: 'Archivia', advancedColor: TMColors.success, onClick: confirmActionPopup }), _jsx(TMButton, { disabled: !clearFormBtnDisabled, btnStyle: 'advanced', icon: _jsx(IconClear, {}), showTooltip: false, caption: 'Pulisci', advancedColor: TMColors.tertiary, onClick: clearFormHandler }), DID && _jsx(TMButton, { disabled: undoBtnDisabled, btnStyle: 'advanced', icon: _jsx(IconUndo, {}), width: '150px', showTooltip: false, caption: 'Annulla modifiche', advancedColor: TMColors.tertiary, onClick: onUndoHandler })] }) })] }), totalItems > listMaxItems && _jsx(TMShowAllOrMaxItemsButton, { showAll: showAll, dataSourceLength: totalItems, onClick: () => { setShowAll(!showAll); } })] }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, TID: TID, DID: DID, op: 0, onClose: () => setShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, TID: TID, DID: DID, op: 1, onClose: () => setShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, TID: TID, DID: DID, onClose: () => setShowReAssignPopup(false) }), _jsx(ConfirmAttachmentsDialog, {})] }) }) }), isOpenPreview || isOpenMiddlePanel() ?
|
472
474
|
_jsx(TMLayoutItem, { children: _jsxs(TMSplitterLayout, { direction: 'horizontal', overflow: 'visible', separatorSize: SDKUI_Globals.userSettings.themeSettings.gutters, showSeparator: deviceType !== DeviceType.MOBILE && (isOpenPreview && isOpenMiddlePanel()), start: getSecondarySplitterStartLayout(), min: ['0', '0'], separatorColor: 'transparent', children: [isOpenMiddlePanel()
|
473
|
-
? _jsx(TMLayoutItem, { children: _jsxs(TMPanel, { showHeader: !(isOpenDetails && layoutMode === LayoutModes.Update), title: titleText(), onClose: () => { closeMiddlePanel(); }, children: [isOpenBoard && layoutMode === LayoutModes.Update &&
|
475
|
+
? _jsx(TMLayoutItem, { children: _jsxs(TMPanel, { showHeader: !(isOpenDetails && layoutMode === LayoutModes.Update), title: titleText(), toolbar: middlePanelToolbar, onClose: () => { closeMiddlePanel(); }, children: [isOpenBoard && layoutMode === LayoutModes.Update &&
|
474
476
|
_jsx(TMDcmtBlog, { tid: TID, did: DID }), isOpenSysMetadata && layoutMode === LayoutModes.Update &&
|
475
477
|
_jsx(TMMetadataValues, { layoutMode: layoutMode, openChooserBySingleClick: !isOpenDistinctValues, TID: TID, isReadOnly: true, deviceType: deviceType, metadataValues: formData.filter(o => (o.mid != undefined && o.mid <= 100)), metadataValuesOrig: formData.filter(o => (o.mid != undefined && o.mid <= 100)), validationItems: [] }), isOpenFormulaEditor &&
|
476
478
|
_jsx(TMFormulaEditor, { isModal: false, formMode: FormModes.Update, inputData: getFormula(), showBack: false, onClose: () => setIsOpenFormulaEditor(false), onApplied: (newFormula) => {
|
@@ -484,7 +486,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
484
486
|
} })] }) })
|
485
487
|
: _jsx(_Fragment, {}), isOpenPreview
|
486
488
|
? _jsxs(TMLayoutItem, { children: [layoutMode === LayoutModes.Update ?
|
487
|
-
_jsx(TMDcmtPreview, { onClose: () => { setIsOpenPreview(false); onClosePreviewPanel?.(); }, dcmtData: currentDcmt }) :
|
489
|
+
_jsx(TMDcmtPreview, { onClose: () => { setIsOpenPreview(false); onClosePreviewPanel?.(); }, dcmtData: currentDcmt, canNext: canNext, canPrev: canPrev, onNext: onNext, onPrev: onPrev }) :
|
488
490
|
_jsx(TMFileUploader, { onFileUpload: (file) => setDcmtFile(file), onClose: () => setIsOpenPreview(false), isRequired: fromDTD?.archiveConstraint === ArchiveConstraints.ContentCompulsory && dcmtFile === null, defaultBlob: dcmtFile, deviceType: deviceType }), " "] })
|
489
491
|
: _jsx(_Fragment, {})] }) }) : _jsx(_Fragment, {})] }), isOpenDistinctValues &&
|
490
492
|
_jsx(TMDistinctValues, { tid: TID, mid: focusedMetadataValue?.mid, isModal: true, showHeader: false, layoutMode: layoutMode, onSelectionChanged: (e) => {
|
@@ -497,7 +499,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
497
499
|
setIsOpenPreview(!isOpenPreview); } }
|
498
500
|
] : []),
|
499
501
|
...(layoutMode !== LayoutModes.Ark ? [
|
500
|
-
|
502
|
+
{ icon: _jsx(IconArrowLeft, {}), onClick: isClosable ? undefined : handleClose },
|
501
503
|
{ icon: _jsx(IconShow, {}), selected: isOpenPreview, disabled: isPreviewDisabled, onClick: () => { if (!isPreviewDisabled)
|
502
504
|
setIsOpenPreview(!isOpenPreview); } },
|
503
505
|
{ icon: _jsx(IconBoard, {}), selected: isOpenBoard, disabled: isBoardDisabled, onClick: () => { if (!isBoardDisabled) {
|
@@ -85,7 +85,7 @@ const TMDcmtPreview = ({ dcmtData, onClose, canNext, canPrev, onNext, onPrev })
|
|
85
85
|
}
|
86
86
|
return title;
|
87
87
|
};
|
88
|
-
return (_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx(TMPanel, { padding: '0', title: titleHandler(), toolbar: _jsxs("div", { style: { width: 'max-content', display: 'flex', alignItems: 'center', gap: '10px' }, children: [
|
88
|
+
return (_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx(TMPanel, { padding: '0', title: titleHandler(), toolbar: _jsxs("div", { style: { width: 'max-content', display: 'flex', alignItems: 'center', gap: '10px' }, children: [_jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(StyledHeaderIcon, { "$color": TMColors.primaryColor, children: _jsx(TMDropDownMenu, { backgroundColor: 'white', borderRadius: '3px', content: _jsx(TMButton, { btnStyle: 'icon', caption: 'Altro', icon: _jsx(IconMenuVertical, {}), showTooltip: false }), items: [
|
89
89
|
{ icon: _jsx(IconCloseCircle, {}), text: "Rimuovi elemento dalla cache", onClick: () => { removeDcmtsFileCache(cacheKey); setIsFromCache(false); } },
|
90
90
|
{ icon: _jsx(IconClear, {}), text: "Cancella la cache", onClick: () => { clearDcmtsFileCache(); setIsFromCache(false); } },
|
91
91
|
] }, "btn13") }), _jsx(StyledHeaderIcon, { onClick: onClose, "$color": TMColors.primaryColor, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Close, children: _jsx(IconCloseOutline, {}) }) })] }), children: error
|
@@ -222,6 +222,7 @@ const searchByQdAsync = async (qdInput, searchParams) => {
|
|
222
222
|
let qdSearch;
|
223
223
|
try {
|
224
224
|
qdSearch = await prepareQdForSearchAsync(qdInput);
|
225
|
+
let fromTID = qdSearch?.from?.tid;
|
225
226
|
// In modalità easy rimuovi filtri non valorizzati
|
226
227
|
if (!searchParams.isAdvancedSearch) {
|
227
228
|
qdSearch.where = qdSearch?.where?.filter(o => PlatformObjectValidator.WhereItemHasValues(o));
|
@@ -436,7 +436,9 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
|
|
436
436
|
width: '100%',
|
437
437
|
height: '100%',
|
438
438
|
}, children: [_jsx("div", { style: { flex: 1, minWidth: 0, height: '100%', overflow: 'hidden' }, children: _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsxs(TMSplitterLayout, { direction: 'horizontal', overflow: 'visible', separatorSize: SDKUI_Globals.userSettings.themeSettings.gutters, separatorActiveColor: 'transparent', separatorColor: 'transparent', showSeparator: (isOpenPreview || isOpenMiddlePanel() || isOpenBatchUpdate) && deviceType !== DeviceType.MOBILE, start: getPrimarySplitterStartLayout(), min: deviceType !== DeviceType.MOBILE && isOpenDcmtForm ? ['150px', '0'] : ['0', '0'], children: [_jsx(TMLayoutItem, { children: _jsxs(TMPanel, { toolbar: _jsxs(_Fragment, { children: [context !== SearchResultContext.METADATA_SEARCH && fromDTD?.templateTID === TemplateTIDs.WF_WIApprView && _jsx(WorkFlowOperationButtons, { deviceType: deviceType, onApprove: () => setShowApprovePopup(true), onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), approveDisable: disable, rejectDisable: disable, reassignDisable: disable, infoDisable: getSelectedDcmtsOrFocused(selectedItems, focusedItem).length !== 1 }), (dcmtsReturned != dcmtsFound) && _jsx("p", { style: { backgroundColor: `white`, color: TMColors.primaryColor, textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${dcmtsReturned}/${dcmtsFound} restituiti` }), context === SearchResultContext.FAVORITES_AND_RECENTS &&
|
439
|
-
_jsx("div", { style: { display: 'flex', alignItems: 'center', gap: '5px' }, children: _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconDelete, { color: 'white' }), caption: "Rimuovi da " + (selectedSearchResult?.category === "Favorites" ? '"Preferiti"' : '"Recenti"'), disabled: getSelectedDcmtsOrFocused(selectedItems, focusedItem).length <= 0, onClick: removeDcmtFromFavsOrRecents }) }), _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconRefresh, { color: 'white' }), caption: SDKUI_Localizator.Refresh, onClick: onRefreshSearchAsync }), _jsx(IconMenuVertical, { id: `commands-header-${id}`, color: 'white', cursor: 'pointer' }), _jsx(CommandsContextMenu, { target: `#commands-header-${id}`, menuItems: getCommandsMenuItems(fromDTD, selectedItems, focusedItem, context, showFloatingBar, setShowFloatingBar, openFormHandler, downloadDcmtsAsync, runOperationAsync, onRefreshSearchAsync, refreshSelectionDataRowsAsync, onRefreshAfterAddDcmtToFavs, confirmFormat, openConfirmAttachmentsDialog, openTaskFormHandler, openDetailDcmtsFormHandler, openMasterDcmtsFormHandler, openBatchUpdateFormHandler) })] }),
|
439
|
+
_jsx("div", { style: { display: 'flex', alignItems: 'center', gap: '5px' }, children: _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconDelete, { color: 'white' }), caption: "Rimuovi da " + (selectedSearchResult?.category === "Favorites" ? '"Preferiti"' : '"Recenti"'), disabled: getSelectedDcmtsOrFocused(selectedItems, focusedItem).length <= 0, onClick: removeDcmtFromFavsOrRecents }) }), _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconRefresh, { color: 'white' }), caption: SDKUI_Localizator.Refresh, onClick: onRefreshSearchAsync }), _jsx(IconMenuVertical, { id: `commands-header-${id}`, color: 'white', cursor: 'pointer' }), _jsx(CommandsContextMenu, { target: `#commands-header-${id}`, menuItems: getCommandsMenuItems(fromDTD, selectedItems, focusedItem, context, showFloatingBar, setShowFloatingBar, openFormHandler, downloadDcmtsAsync, runOperationAsync, onRefreshSearchAsync, refreshSelectionDataRowsAsync, onRefreshAfterAddDcmtToFavs, confirmFormat, openConfirmAttachmentsDialog, openTaskFormHandler, openDetailDcmtsFormHandler, openMasterDcmtsFormHandler, openBatchUpdateFormHandler) })] }),
|
440
|
+
// onBack={!isClosable && allowBackButton() ? onBack : undefined}
|
441
|
+
onClose: isClosable && allowBackButton() ? onBack : undefined, title: getTitleHeader(), showHeader: showToolbarHeader, children: [_jsxs(TMLayoutItem, { height: '100%', children: [_jsxs(TMSplitterLayout, { direction: 'horizontal', overflow: 'visible', separatorSize: SDKUI_Globals.userSettings.themeSettings.gutters, separatorActiveColor: 'transparent', separatorColor: 'transparent', min: ['0', '0'], showSeparator: showSelector && deviceType !== DeviceType.MOBILE, start: showSelector ? deviceType !== DeviceType.MOBILE ? ['25%', '75%'] : splitterSize : ['0%', '100%'], children: [showSelector ?
|
440
442
|
_jsx(TMLayoutItem, { children: _jsx(TMSearchResultSelector, { searchResults: currentSearchResults, onSelectionChanged: onSearchResultSelectionChanged }) })
|
441
443
|
:
|
442
444
|
_jsx(_Fragment, {}), _jsxs(TMLayoutItem, { children: [_jsx(TMSearchResultGrid
|
@@ -463,10 +465,10 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
|
|
463
465
|
_jsxs(StyledContainer, { children: [isOpenBoard && _jsx(TMDcmtBlog, { tid: focusedItem?.TID, did: focusedItem?.DID }), isOpenSysMetadata &&
|
464
466
|
_jsx(TMMetadataValues, { layoutMode: LayoutModes.Update, openChooserBySingleClick: !isOpenDistinctValues, TID: focusedItem?.TID, isReadOnly: true, deviceType: deviceType, metadataValues: currentMetadataValues.filter(o => (o.mid != undefined && o.mid <= 100)), metadataValuesOrig: currentMetadataValues.filter(o => (o.mid != undefined && o.mid <= 100)), validationItems: [] })] }) }) })
|
465
467
|
: _jsx(_Fragment, {}), isOpenPreview
|
466
|
-
? _jsx(TMLayoutItem, { children: _jsx(TMDcmtPreview, { onClose: () => { setIsOpenPreview(false); onClosePreviewPanel?.(); }, dcmtData: currentDcmt }) })
|
468
|
+
? _jsx(TMLayoutItem, { children: _jsx(TMDcmtPreview, { onClose: () => { setIsOpenPreview(false); onClosePreviewPanel?.(); }, dcmtData: currentDcmt, canNext: canNavigateHandler('next'), canPrev: canNavigateHandler('prev'), onNext: () => onNavigateHandler('next'), onPrev: () => onNavigateHandler('prev') }) })
|
467
469
|
: _jsx(_Fragment, {})] }) })
|
468
470
|
: _jsx(_Fragment, {})] }) }) }), showSearchResultSidebar && _jsx(TMCommandsPanel, { isMobile: deviceType === DeviceType.MOBILE, items: [
|
469
|
-
|
471
|
+
{ icon: _jsx(IconArrowLeft, {}), onClick: !isClosable && allowBackButton() ? onBack : undefined },
|
470
472
|
{ icon: _jsx(IconShow, {}), selected: isOpenPreview, disabled: isPreviewDisabled, onClick: () => { if (!isPreviewDisabled)
|
471
473
|
setIsOpenPreview(!isOpenPreview); } },
|
472
474
|
{ icon: _jsx(IconBoard, {}), selected: isOpenBoard, disabled: isBoardDisabled, onClick: () => { if (!isBoardDisabled) {
|
@@ -14,8 +14,9 @@ export * from './base/TMToolbarCard';
|
|
14
14
|
export * from './base/TMRightSidebar';
|
15
15
|
export * from './base/TMTreeView';
|
16
16
|
export * from './base/TMPanel';
|
17
|
-
export { default as
|
18
|
-
export
|
17
|
+
export { default as TMPanelManager } from './base/TMPanelManager';
|
18
|
+
export { default as TMPanelManagerToolbar } from './base/TMPanelManagerToolbar';
|
19
|
+
export * from './base/TMPanelManagerUtils';
|
19
20
|
export { default as CounterBar } from './base/TMCounterBar';
|
20
21
|
export { default as TMProgressBar } from './base/TMProgressBar';
|
21
22
|
export { default as TMSpinner } from './base/TMSpinner';
|
package/lib/components/index.js
CHANGED
@@ -15,8 +15,9 @@ export * from './base/TMToolbarCard';
|
|
15
15
|
export * from './base/TMRightSidebar';
|
16
16
|
export * from './base/TMTreeView';
|
17
17
|
export * from './base/TMPanel';
|
18
|
-
export { default as
|
19
|
-
export
|
18
|
+
export { default as TMPanelManager } from './base/TMPanelManager';
|
19
|
+
export { default as TMPanelManagerToolbar } from './base/TMPanelManagerToolbar';
|
20
|
+
export * from './base/TMPanelManagerUtils';
|
20
21
|
export { default as CounterBar } from './base/TMCounterBar';
|
21
22
|
export { default as TMProgressBar } from './base/TMProgressBar';
|
22
23
|
export { default as TMSpinner } from './base/TMSpinner';
|
@@ -7,7 +7,7 @@ export const StyledCommandsPanel = styled.div `
|
|
7
7
|
width: ${({ $isMobile }) => ($isMobile ? '100%' : '50px')};
|
8
8
|
height: ${({ $isMobile }) => ($isMobile ? '50px' : 'max-content')};
|
9
9
|
background: transparent linear-gradient(90deg, #CCE0F4 0%, #7EC1E7 14%, #39A6DB 28%, #1E9CD7 35%, #0075BE 78%, #005B97 99%) 0% 0% no-repeat padding-box;
|
10
|
-
border-radius:
|
10
|
+
border-radius: 10px;
|
11
11
|
padding: 10px;
|
12
12
|
gap: 10px;
|
13
13
|
`;
|
package/package.json
CHANGED
@@ -1,9 +0,0 @@
|
|
1
|
-
import { TMPanelManagerMatrixColumn, TMPanelManagerToolbar } from './TMPanelManagerMatrixUtils';
|
2
|
-
export interface TMPanelManagerMatrixProps {
|
3
|
-
panelMatrixMap: Map<string, TMPanelManagerMatrixColumn>;
|
4
|
-
toolbar?: TMPanelManagerToolbar;
|
5
|
-
initialMobilePanelID?: string;
|
6
|
-
gutters?: number;
|
7
|
-
}
|
8
|
-
declare const TMPanelManagerMatrix: (props: TMPanelManagerMatrixProps) => import("react/jsx-runtime").JSX.Element;
|
9
|
-
export default TMPanelManagerMatrix;
|
@@ -1,262 +0,0 @@
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
-
import React, { useEffect, useMemo, useState } from 'react';
|
3
|
-
import { SDKUI_Globals, SDKUI_Localizator, IconInfo } from '../../helper';
|
4
|
-
import { useDeviceType, DeviceType } from './TMDeviceProvider';
|
5
|
-
import TMPanel from './TMPanel';
|
6
|
-
import { calculatePanelSizes, DesktopToolbar, getDynamicColumnWidth, getInitialMobilePanelID, MobileToolbar } from './TMPanelManagerMatrixUtils';
|
7
|
-
const TMPanelManagerMatrix = (props) => {
|
8
|
-
// Destructure props
|
9
|
-
const { panelMatrixMap, toolbar, initialMobilePanelID, gutters = SDKUI_Globals.userSettings.themeSettings.gutters } = props;
|
10
|
-
// Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
|
11
|
-
const deviceType = useDeviceType();
|
12
|
-
// This avoids unnecessary re-renders by only recalculating when deviceType changes.
|
13
|
-
let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
|
14
|
-
// State for toolbar items
|
15
|
-
const [toolbarState, setToolbarState] = useState(toolbar);
|
16
|
-
// State to track which panel IDs are currently hidden
|
17
|
-
const [hiddenPanelIds, setHiddenPanelIds] = useState(() => {
|
18
|
-
const initialHidden = new Set();
|
19
|
-
if (isMobile) {
|
20
|
-
// Mobile: mostra solo il primo pannello
|
21
|
-
let firstMobilePanelID = initialMobilePanelID ?? getInitialMobilePanelID(panelMatrixMap);
|
22
|
-
panelMatrixMap.forEach(col => {
|
23
|
-
col.rows.forEach(row => {
|
24
|
-
if (row.id !== firstMobilePanelID)
|
25
|
-
initialHidden.add(row.id);
|
26
|
-
});
|
27
|
-
});
|
28
|
-
}
|
29
|
-
else {
|
30
|
-
// Desktop: nascondi quelli con hidden true
|
31
|
-
panelMatrixMap.forEach(col => {
|
32
|
-
col.rows.forEach(row => {
|
33
|
-
if (row.hidden)
|
34
|
-
initialHidden.add(row.id);
|
35
|
-
});
|
36
|
-
});
|
37
|
-
}
|
38
|
-
return initialHidden;
|
39
|
-
});
|
40
|
-
// State to store the current widths of all column, represented as a Map
|
41
|
-
const [columnWidths, setColumnWidths] = useState(new Map());
|
42
|
-
// State to store the current heights of all panels, represented as a Map
|
43
|
-
const [panelHeights, setPanelHeights] = useState(new Map());
|
44
|
-
// State to track maximized panel
|
45
|
-
const [maximizedPanelId, setMaximizedPanelId] = useState(null);
|
46
|
-
// Memoized computation of visible columns and the total number of visible panels
|
47
|
-
const { visibleColumns, totalVisiblePanels } = useMemo(() => {
|
48
|
-
let totalVisiblePanels = 0;
|
49
|
-
const visibleColumns = [];
|
50
|
-
for (const [columnKey, column] of panelMatrixMap.entries()) {
|
51
|
-
// Filter visible rows in the current column
|
52
|
-
const visibleRows = column.rows.filter(row => !hiddenPanelIds.has(row.id));
|
53
|
-
// If any visible rows exist, include the column and count them
|
54
|
-
if (visibleRows.length > 0) {
|
55
|
-
visibleColumns.push(columnKey);
|
56
|
-
totalVisiblePanels += visibleRows.length;
|
57
|
-
}
|
58
|
-
}
|
59
|
-
return { visibleColumns, totalVisiblePanels };
|
60
|
-
}, [panelMatrixMap, hiddenPanelIds]);
|
61
|
-
// Effect hook to update column widths
|
62
|
-
useEffect(() => {
|
63
|
-
const newColumnWidths = new Map();
|
64
|
-
Array.from(panelMatrixMap.entries()).forEach(([columnKey, col]) => {
|
65
|
-
if (!maximizedPanelId) {
|
66
|
-
const width = getDynamicColumnWidth(col, hiddenPanelIds, Array.from(panelMatrixMap.values()));
|
67
|
-
newColumnWidths.set(columnKey, { width });
|
68
|
-
}
|
69
|
-
});
|
70
|
-
setColumnWidths(newColumnWidths);
|
71
|
-
}, [panelMatrixMap, hiddenPanelIds, maximizedPanelId]);
|
72
|
-
// Effect hook to set initial hidden panels and their heights
|
73
|
-
useEffect(() => {
|
74
|
-
const initialHidden = new Set();
|
75
|
-
if (isMobile) {
|
76
|
-
// On mobile, only show the first selected mobile panel; hide the rest
|
77
|
-
let firstMobilePanelID = initialMobilePanelID ?? getInitialMobilePanelID(panelMatrixMap);
|
78
|
-
panelMatrixMap.forEach(col => {
|
79
|
-
col.rows.forEach(row => {
|
80
|
-
if (row.id !== firstMobilePanelID)
|
81
|
-
initialHidden.add(row.id);
|
82
|
-
});
|
83
|
-
});
|
84
|
-
}
|
85
|
-
else {
|
86
|
-
// On non-mobile devices, hide panels that are marked as `hidden`
|
87
|
-
panelMatrixMap.forEach(col => {
|
88
|
-
col.rows.forEach(row => {
|
89
|
-
if (row.hidden)
|
90
|
-
initialHidden.add(row.id);
|
91
|
-
});
|
92
|
-
});
|
93
|
-
}
|
94
|
-
// Update state with the calculated hidden panels and panel sizes
|
95
|
-
setHiddenPanelIds(initialHidden);
|
96
|
-
setPanelHeights(calculatePanelSizes(panelMatrixMap, initialHidden));
|
97
|
-
}, [panelMatrixMap, isMobile]);
|
98
|
-
// Function to toggle the disabled of a toolbar given its item
|
99
|
-
const toggleToolbarItemDisabled = (toolbarItem) => {
|
100
|
-
if (!toolbarItem)
|
101
|
-
return;
|
102
|
-
setToolbarState(prevToolbar => {
|
103
|
-
if (!prevToolbar)
|
104
|
-
return prevToolbar;
|
105
|
-
return {
|
106
|
-
...prevToolbar,
|
107
|
-
items: prevToolbar.items.map(item => item.id === toolbarItem.id ? { ...item, disabled: !item.disabled } : item)
|
108
|
-
};
|
109
|
-
});
|
110
|
-
};
|
111
|
-
// Function to toggle the visibility of a toolbar given its item
|
112
|
-
const toggleToolbarItemVisibility = (toolbarItem) => {
|
113
|
-
if (!toolbarItem)
|
114
|
-
return;
|
115
|
-
setToolbarState(prevToolbar => {
|
116
|
-
if (!prevToolbar)
|
117
|
-
return prevToolbar;
|
118
|
-
return {
|
119
|
-
...prevToolbar,
|
120
|
-
items: prevToolbar.items.map(item => item.id === toolbarItem.id ? { ...item, visible: !(item.visible ?? true) } : item)
|
121
|
-
};
|
122
|
-
});
|
123
|
-
};
|
124
|
-
// Function to toggle the visibility of a panel given its item
|
125
|
-
const togglePanelVisibility = (toolbarItem) => {
|
126
|
-
if (!toolbarItem)
|
127
|
-
return;
|
128
|
-
setHiddenPanelIds(prevHidden => {
|
129
|
-
let newHidden;
|
130
|
-
if (isMobile) {
|
131
|
-
// On mobile, make only the selected panel visible; hide all others
|
132
|
-
newHidden = new Set();
|
133
|
-
panelMatrixMap.forEach(col => {
|
134
|
-
col.rows.forEach(row => {
|
135
|
-
if (row.id !== toolbarItem.panelManagerMatrixRowId) {
|
136
|
-
newHidden.add(row.id);
|
137
|
-
}
|
138
|
-
});
|
139
|
-
});
|
140
|
-
}
|
141
|
-
else {
|
142
|
-
// On non-mobile devices, toggle visibility normally
|
143
|
-
newHidden = new Set(prevHidden);
|
144
|
-
// Hide alternative panels if any
|
145
|
-
if (toolbarItem.alternativePanelManagerMatrixRowId?.length) {
|
146
|
-
toolbarItem.alternativePanelManagerMatrixRowId.forEach(altId => newHidden.add(altId));
|
147
|
-
}
|
148
|
-
// Toggle clicked panel visibility
|
149
|
-
if (newHidden.has(toolbarItem.panelManagerMatrixRowId)) {
|
150
|
-
newHidden.delete(toolbarItem.panelManagerMatrixRowId);
|
151
|
-
}
|
152
|
-
else {
|
153
|
-
// If the panel is maximized, call maximizeMinimizePanelCallback to minimize it
|
154
|
-
if (maximizedPanelId === toolbarItem.panelManagerMatrixRowId) {
|
155
|
-
toogleMaximizeMinimizePanelCallback(toolbarItem.panelManagerMatrixRowId);
|
156
|
-
}
|
157
|
-
newHidden.add(toolbarItem.panelManagerMatrixRowId);
|
158
|
-
}
|
159
|
-
}
|
160
|
-
setPanelHeights(calculatePanelSizes(panelMatrixMap, newHidden));
|
161
|
-
return newHidden;
|
162
|
-
});
|
163
|
-
};
|
164
|
-
const toogleMaximizeMinimizePanelCallback = (id) => {
|
165
|
-
setMaximizedPanelId(prevId => (prevId === id ? null : id));
|
166
|
-
};
|
167
|
-
return (_jsx("div", { style: { width: '100%', height: '100%' }, children: _jsxs("div", { style: {
|
168
|
-
display: isMobile ? 'block' : 'flex',
|
169
|
-
flexDirection: 'row',
|
170
|
-
width: "100%",
|
171
|
-
height: '100%',
|
172
|
-
overflow: 'hidden',
|
173
|
-
position: 'relative',
|
174
|
-
}, children: [_jsx("div", { style: {
|
175
|
-
display: 'flex',
|
176
|
-
flexDirection: 'row',
|
177
|
-
width: (toolbarState && toolbarState.items.length > 0) ? `calc(100% - ${isMobile ? "0px" : "60px"})` : '100%',
|
178
|
-
height: `calc(100% - ${isMobile ? "60px" : "0px"})`,
|
179
|
-
overflow: 'hidden',
|
180
|
-
// transition: 'width 0.3s',
|
181
|
-
}, children: visibleColumns.length > 0 ? visibleColumns.map((column, colIndex) => {
|
182
|
-
// Retrieve the column data from the panelMatrixMap using the current column key
|
183
|
-
const col = panelMatrixMap.get(column);
|
184
|
-
// Check if the current column contains the maximized panel
|
185
|
-
const hasMaximized = !!col?.rows?.some(row => row.id === maximizedPanelId);
|
186
|
-
const isLastColumn = colIndex === visibleColumns.length - 1;
|
187
|
-
// Define the base style for all columns with flex layout, full height, smooth width transition, and no minimum width
|
188
|
-
const columnBaseStyle = {
|
189
|
-
display: 'flex',
|
190
|
-
flexDirection: 'column',
|
191
|
-
height: '100%',
|
192
|
-
// transition: isMobile ? 'none' : 'width 0.3s',
|
193
|
-
paddingRight: (!maximizedPanelId && !isLastColumn) ? `${gutters}px` : '0px'
|
194
|
-
};
|
195
|
-
// Declare a variable to hold the final computed style for the column
|
196
|
-
let columnStyle;
|
197
|
-
if (maximizedPanelId) {
|
198
|
-
// If a panel is maximized, if it does, give the column full width
|
199
|
-
columnStyle = hasMaximized ? { ...columnBaseStyle, width: '100%' } : { ...columnBaseStyle, width: '0px', overflow: 'hidden' };
|
200
|
-
}
|
201
|
-
else {
|
202
|
-
// Otherwise, hide this column by setting width to 0 and hiding overflow
|
203
|
-
const savedWidth = columnWidths.get(column)?.width ?? getDynamicColumnWidth(col, hiddenPanelIds, Array.from(panelMatrixMap.values()));
|
204
|
-
columnStyle = { ...columnBaseStyle, width: savedWidth };
|
205
|
-
}
|
206
|
-
return (_jsx(React.Fragment, { children: _jsx("div", { style: columnStyle, children: col?.rows?.map((row) => {
|
207
|
-
const isHiddenPanel = hiddenPanelIds.has(row.id);
|
208
|
-
const visibleRows = col.rows?.filter(r => !hiddenPanelIds.has(r.id));
|
209
|
-
const isLastVisible = visibleRows.length > 0 && visibleRows[visibleRows.length - 1].id === row.id;
|
210
|
-
const isMaximized = maximizedPanelId === row.id;
|
211
|
-
const baseStyle = {
|
212
|
-
borderRadius: '8px',
|
213
|
-
display: 'block',
|
214
|
-
// transition: isMobile ? 'none' : 'all 0.3s ease',
|
215
|
-
paddingBottom: (isHiddenPanel || isLastVisible || isMaximized) ? '0px' : `${gutters}px`,
|
216
|
-
};
|
217
|
-
const hiddenStyle = {
|
218
|
-
minWidth: '0px',
|
219
|
-
width: '0px',
|
220
|
-
height: '0px',
|
221
|
-
visibility: 'hidden',
|
222
|
-
opacity: 0,
|
223
|
-
};
|
224
|
-
const maximizedStyle = {
|
225
|
-
minWidth: '50px',
|
226
|
-
width: '100%',
|
227
|
-
height: '100%',
|
228
|
-
visibility: 'visible',
|
229
|
-
opacity: 1,
|
230
|
-
};
|
231
|
-
const defaultStyle = {
|
232
|
-
minWidth: isHiddenPanel ? '0px' : '50px',
|
233
|
-
width: '100%',
|
234
|
-
height: isHiddenPanel ? '0px' : panelHeights.get(row.id)?.height ?? '100%',
|
235
|
-
visibility: isHiddenPanel ? 'hidden' : 'visible',
|
236
|
-
opacity: isHiddenPanel ? 0 : 1,
|
237
|
-
};
|
238
|
-
const panelStyle = maximizedPanelId ? (isMaximized ? { ...baseStyle, ...maximizedStyle } : hiddenStyle) : { ...baseStyle, ...defaultStyle };
|
239
|
-
return _jsx("div", { style: panelStyle, children: row.panel ? _jsx(TMPanel, { title: row.panel.title, totalItems: row.panel.totalItems ?? undefined, displayedItemsCount: row.panel.displayedItemsCount ?? undefined, showHeader: row.panel.showHeader ?? true, allowMaximize: !isMobile, onClose: (!isMobile && toolbarState) ? () => togglePanelVisibility(toolbarState.items.find(item => item.panelManagerMatrixRowId === row.id)) : undefined, onMaximize: () => toogleMaximizeMinimizePanelCallback(row.id), onHeaderDoubleClick: () => toogleMaximizeMinimizePanelCallback(row.id), children: _jsx("div", { style: { width: '100%', height: '100%' }, children: typeof row.content === "function" ? row.content(togglePanelVisibility, toogleMaximizeMinimizePanelCallback, toggleToolbarItemDisabled, toggleToolbarItemVisibility) : row.content }) })
|
240
|
-
: _jsx("div", { style: { width: '100%', height: '100%' }, children: typeof row.content === "function" ? row.content(togglePanelVisibility, toogleMaximizeMinimizePanelCallback, toggleToolbarItemDisabled, toggleToolbarItemVisibility) : row.content }) }, "TMPanelManagerMatrix-r-" + row.id);
|
241
|
-
}) }) }, "TMPanelManagerMatrix-c-" + column));
|
242
|
-
}) : _jsxs("div", { style: {
|
243
|
-
width: '100%',
|
244
|
-
height: '100%',
|
245
|
-
display: 'flex',
|
246
|
-
flexDirection: 'column',
|
247
|
-
alignItems: 'center',
|
248
|
-
justifyContent: 'center',
|
249
|
-
backgroundColor: '#fff',
|
250
|
-
border: '1px solid #ddd',
|
251
|
-
borderRadius: '12px',
|
252
|
-
boxShadow: '0 4px 10px rgba(0, 0, 0, 0.05)',
|
253
|
-
padding: '40px',
|
254
|
-
textAlign: 'center',
|
255
|
-
color: '#555',
|
256
|
-
fontSize: '18px',
|
257
|
-
gap: '16px'
|
258
|
-
}, children: [_jsx(IconInfo, { style: { fontSize: 50 } }), _jsx("div", { children: SDKUI_Localizator.NoPanelSelected })] }) }), toolbarState && toolbarState.items.length > 0 && (!isMobile
|
259
|
-
? DesktopToolbar(toolbarState, hiddenPanelIds, togglePanelVisibility)
|
260
|
-
: MobileToolbar(toolbarState, hiddenPanelIds, togglePanelVisibility))] }) }));
|
261
|
-
};
|
262
|
-
export default TMPanelManagerMatrix;
|