@topconsultnpm/sdkui-react 6.22.0-dev2.3 → 6.22.0-dev2.31
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/TMContextMenu.js +1 -1
- package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +1 -1
- package/lib/components/base/TMButton.d.ts +13 -0
- package/lib/components/base/TMButton.js +137 -5
- package/lib/components/base/TMDataGrid.d.ts +2 -0
- package/lib/components/base/TMDataGrid.js +81 -8
- package/lib/components/base/TMEditorBase.d.ts +2 -0
- package/lib/components/base/TMFileManager.js +5 -3
- package/lib/components/base/TMFileManagerUtils.d.ts +1 -0
- package/lib/components/base/TMFileManagerUtils.js +16 -0
- package/lib/components/base/TMModal.d.ts +4 -0
- package/lib/components/base/TMModal.js +42 -11
- package/lib/components/base/TMPanel.d.ts +1 -0
- package/lib/components/base/TMPanel.js +79 -20
- package/lib/components/base/TMPopUp.js +3 -0
- package/lib/components/base/TMTooltip.d.ts +2 -1
- package/lib/components/base/TMTooltip.js +23 -6
- package/lib/components/base/TMTreeView.js +108 -67
- package/lib/components/choosers/TMDcmtTypeChooser.js +4 -3
- package/lib/components/choosers/TMDistinctValues.d.ts +9 -7
- package/lib/components/choosers/TMDistinctValues.js +149 -142
- package/lib/components/choosers/TMMetadataChooser.js +1 -1
- package/lib/components/choosers/TMQuickSearchInfo.d.ts +12 -0
- package/lib/components/choosers/TMQuickSearchInfo.js +279 -0
- package/lib/components/choosers/TMQuickSearchSettingsForm.d.ts +16 -0
- package/lib/components/choosers/TMQuickSearchSettingsForm.js +94 -0
- package/lib/components/choosers/TMSelectedValuesSummary.d.ts +13 -0
- package/lib/components/choosers/TMSelectedValuesSummary.js +91 -0
- package/lib/components/editors/TMDropDown.d.ts +3 -0
- package/lib/components/editors/TMDropDown.js +197 -5
- package/lib/components/editors/TMMetadataEditor.d.ts +5 -1
- package/lib/components/editors/TMMetadataEditor.js +8 -3
- package/lib/components/editors/TMTextBox.js +2 -2
- package/lib/components/features/documents/TMBatchUpdateForm.js +19 -5
- package/lib/components/features/documents/TMDcmtBlog.d.ts +3 -0
- package/lib/components/features/documents/TMDcmtBlog.js +4 -4
- package/lib/components/features/documents/TMDcmtForm.d.ts +7 -0
- package/lib/components/features/documents/TMDcmtForm.js +112 -45
- package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +11 -0
- package/lib/components/features/documents/TMDcmtFormActionButtons.js +74 -7
- package/lib/components/features/documents/TMDcmtPreview.js +10 -6
- package/lib/components/features/documents/TMMasterDetailDcmts.js +95 -33
- package/lib/components/features/documents/TMMasterInfoFields.d.ts +19 -0
- package/lib/components/features/documents/TMMasterInfoFields.js +186 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.d.ts +40 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.js +296 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.d.ts +363 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.js +259 -0
- package/lib/components/features/documents/TMRelationViewer.d.ts +14 -1
- package/lib/components/features/documents/TMRelationViewer.js +69 -20
- package/lib/components/features/search/TMSearch.js +29 -16
- package/lib/components/features/search/TMSearchQueryEditor.js +5 -3
- package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -1
- package/lib/components/features/search/TMSearchQueryPanel.js +28 -7
- package/lib/components/features/search/TMSearchResult.d.ts +9 -0
- package/lib/components/features/search/TMSearchResult.js +419 -108
- package/lib/components/features/search/TMTreeSelector.js +18 -5
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +10 -0
- package/lib/components/features/workflow/TMWorkflowPopup.js +8 -4
- package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +1 -0
- package/lib/components/layout/panelManager/TMPanelManagerContainer.js +24 -14
- package/lib/components/layout/panelManager/TMPanelManagerContext.js +68 -93
- package/lib/components/layout/panelManager/TMPanelWrapper.js +2 -2
- package/lib/components/layout/panelManager/types.d.ts +3 -0
- package/lib/components/layout/panelManager/utils.js +13 -11
- package/lib/components/viewers/TMMidViewer.js +4 -1
- package/lib/components/viewers/TMTidViewer.js +25 -11
- package/lib/helper/SDKUI_Globals.d.ts +90 -0
- package/lib/helper/SDKUI_Globals.js +136 -0
- package/lib/helper/SDKUI_Localizator.d.ts +24 -0
- package/lib/helper/SDKUI_Localizator.js +240 -0
- package/lib/helper/TMIcons.d.ts +1 -0
- package/lib/helper/TMIcons.js +3 -0
- package/lib/helper/dataGridSearchHelper.d.ts +28 -0
- package/lib/helper/dataGridSearchHelper.js +51 -0
- package/lib/helper/dcmtsHelper.d.ts +20 -0
- package/lib/helper/dcmtsHelper.js +58 -1
- package/lib/helper/helpers.d.ts +20 -0
- package/lib/helper/helpers.js +55 -1
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/helper/queryHelper.d.ts +2 -0
- package/lib/helper/queryHelper.js +3 -1
- package/lib/hooks/tmDistinctValuesGridHelper.d.ts +16 -0
- package/lib/hooks/tmDistinctValuesGridHelper.js +31 -0
- package/lib/hooks/useArchiveListForm.d.ts +39 -0
- package/lib/hooks/useArchiveListForm.js +46 -0
- package/lib/hooks/useCaseFlowApprove.d.ts +56 -0
- package/lib/hooks/useCaseFlowApprove.js +157 -0
- package/lib/hooks/useDataUserIdItem.d.ts +1 -0
- package/lib/hooks/useDataUserIdItem.js +1 -0
- package/lib/hooks/useDocumentOperations.d.ts +2 -0
- package/lib/hooks/useDocumentOperations.js +28 -5
- package/lib/hooks/useMultiMasterDetailDcmts.d.ts +100 -0
- package/lib/hooks/useMultiMasterDetailDcmts.js +587 -0
- package/lib/hooks/useRelatedDocuments.js +2 -26
- package/lib/hooks/useShowDossiersV5.d.ts +12 -0
- package/lib/hooks/useShowDossiersV5.js +37 -0
- package/lib/hooks/useTMDistinctValuesMetadataDisplay.d.ts +18 -0
- package/lib/hooks/useTMDistinctValuesMetadataDisplay.js +103 -0
- package/lib/hooks/useTMDistinctValuesQuickSearch.d.ts +49 -0
- package/lib/hooks/useTMDistinctValuesQuickSearch.js +307 -0
- package/lib/hooks/useTMDistinctValuesSelection.d.ts +42 -0
- package/lib/hooks/useTMDistinctValuesSelection.js +103 -0
- package/lib/hooks/useTMDistinctValuesSource.d.ts +29 -0
- package/lib/hooks/useTMDistinctValuesSource.js +105 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/services/caseflow/CaseFlowService.d.ts +236 -0
- package/lib/services/caseflow/CaseFlowService.js +693 -0
- package/lib/services/caseflow/CaseFlowTemplateCacheService.d.ts +28 -0
- package/lib/services/caseflow/CaseFlowTemplateCacheService.js +121 -0
- package/lib/services/caseflow/caseFlowNameCache.d.ts +32 -0
- package/lib/services/caseflow/caseFlowNameCache.js +116 -0
- package/lib/services/caseflow/caseFlowWorkItemUtils.d.ts +61 -0
- package/lib/services/caseflow/caseFlowWorkItemUtils.js +113 -0
- package/lib/services/index.d.ts +4 -0
- package/lib/services/index.js +4 -0
- package/lib/services/platform_services.d.ts +1 -1
- package/package.json +66 -66
|
@@ -126,6 +126,16 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
|
|
|
126
126
|
setSelectedRowKeys(selectedKeys);
|
|
127
127
|
setIsGridBoxOpened(false);
|
|
128
128
|
}, []);
|
|
129
|
+
// Handles click on a tree row in the trees data grid: clicking the already selected tree
|
|
130
|
+
// does not raise onSelectionChanged, so the drop down must be closed here as well
|
|
131
|
+
const onRowClickTrees = useCallback((e) => {
|
|
132
|
+
const tree = e.data;
|
|
133
|
+
if (tree?.id === undefined)
|
|
134
|
+
return;
|
|
135
|
+
setSelectedTreeId(tree.id);
|
|
136
|
+
setSelectedRowKeys([tree.id]);
|
|
137
|
+
setIsGridBoxOpened(false);
|
|
138
|
+
}, []);
|
|
129
139
|
// Handles focus change in the data grid
|
|
130
140
|
const onFocusedRowChanged = useCallback((e) => {
|
|
131
141
|
setFocusedRowKey(e.row?.key);
|
|
@@ -161,6 +171,13 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
|
|
|
161
171
|
}
|
|
162
172
|
}
|
|
163
173
|
}, []);
|
|
174
|
+
// Callback function to handle click events on a tree view row.
|
|
175
|
+
const onRowClickTreeView = useCallback((e) => {
|
|
176
|
+
const treeItem = e.data;
|
|
177
|
+
if (treeItem?.type === TreeItemTypes.DcmtType) {
|
|
178
|
+
onSelectedTIDChanged?.(treeItem.tid, selectedTreeId);
|
|
179
|
+
}
|
|
180
|
+
}, [onSelectedTIDChanged, selectedTreeId]);
|
|
164
181
|
return (_jsx(TMPanel, { title: SDK_Localizator.Trees, isVisible: isVisible, totalItems: trees.length, onClose: onClosePanel, allowMaximize: allowMaximize, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, toolbar: _jsx(TMButton, { btnStyle: 'icon', caption: defaultTreeId == selectedTreeId ? SDKUI_Localizator.TreeRemoveDefault : SDKUI_Localizator.SetAsDefault, icon: defaultTreeId == selectedTreeId ? _jsx(IconStarRemove, { color: 'rgb(243, 114, 92)' }) : _jsx(IconStar, { color: 'rgb(248, 215, 117)' }), onClick: () => {
|
|
165
182
|
if (defaultTreeId == selectedTreeId) {
|
|
166
183
|
if (layoutMode == LayoutModes.Update)
|
|
@@ -193,11 +210,7 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
|
|
|
193
210
|
}, value: selectedTreeId, opened: isGridBoxOpened, valueExpr: "id", displayExpr: "nameLoc", deferRendering: false, dataSource: trees, onValueChanged: syncDataGridSelection, onOptionChanged: onGridBoxOpened, style: { height: 30, padding: '5px' }, children: _jsx(TMDataGrid, { height: "100%", width: "100%", dataSource: trees, dataColumns: [
|
|
194
211
|
{ dataField: 'nameLoc', caption: SDKUI_Localizator.Name, width: 'auto' },
|
|
195
212
|
{ dataField: 'description', caption: SDKUI_Localizator.Description, width: 'auto' },
|
|
196
|
-
], selection: { mode: 'single', showCheckBoxesMode: "none" }, showHeaderFilter: false, selectedRowKeys: selectedRowKeys, onSelectionChanged: onSelectionChanged, focusedRowKey: focusedRowKey, onFocusedRowChanged: onFocusedRowChanged }) }) }), _jsxs(StyledTreeListWrapper, { children: [_jsxs(TreeList, { height: "100%", dataSource: treeItems, showRowLines: false, showColumnLines: false, showBorders: false, columnAutoWidth: false, keyExpr: "id", parentIdExpr: "parentID", dataStructure: "plain", showColumnHeaders: false, onContentReady: (e) => e.component.clearSelection(), onCellDblClick: onCellDblClickTreeView,
|
|
197
|
-
if (e.selectedRowsData[0] && e.selectedRowsData[0].type == TreeItemTypes.DcmtType) {
|
|
198
|
-
onSelectedTIDChanged?.(e.selectedRowsData[0].tid, selectedTreeId);
|
|
199
|
-
}
|
|
200
|
-
}, children: [_jsx(Column, { dataField: "nameLoc", caption: SDKUI_Localizator.Name, cellRender: renderCell, width: "100%" }), _jsx(Scrolling, { mode: "virtual", useNative: Number(SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar) === 1 }), _jsx(Selection, { mode: "single" })] }), _jsxs(StyledOffCanvasPanel, { ref: panelRef, "$isOpen": isMobile && infoDTD !== undefined, children: [_jsxs(StyledDivHorizontal, { style: { gap: 10, padding: '10px 8px', width: '100%', alignItems: 'center' }, children: [_jsx("p", { style: { fontSize: '1.1rem', fontWeight: 'bold' }, children: `${SDKUI_Localizator.DcmtType} - ${SDKUI_Localizator.About}` }), _jsx(IconCloseOutline, { style: { marginLeft: 'auto', cursor: 'pointer' }, onClick: () => setInfoDTD(undefined) })] }), renderDTDTooltipContent(infoDTD)] })] })] })
|
|
213
|
+
], selection: { mode: 'single', showCheckBoxesMode: "none" }, showHeaderFilter: false, selectedRowKeys: selectedRowKeys, onSelectionChanged: onSelectionChanged, onRowClick: onRowClickTrees, focusedRowKey: focusedRowKey, onFocusedRowChanged: onFocusedRowChanged }) }) }), _jsxs(StyledTreeListWrapper, { children: [_jsxs(TreeList, { height: "100%", dataSource: treeItems, showRowLines: false, showColumnLines: false, showBorders: false, columnAutoWidth: false, keyExpr: "id", parentIdExpr: "parentID", dataStructure: "plain", showColumnHeaders: false, onContentReady: (e) => e.component.clearSelection(), onCellDblClick: onCellDblClickTreeView, onRowClick: onRowClickTreeView, children: [_jsx(Column, { dataField: "nameLoc", caption: SDKUI_Localizator.Name, cellRender: renderCell, width: "100%" }), _jsx(Scrolling, { mode: "virtual", useNative: Number(SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar) === 1 }), _jsx(Selection, { mode: "single" })] }), _jsxs(StyledOffCanvasPanel, { ref: panelRef, "$isOpen": isMobile && infoDTD !== undefined, children: [_jsxs(StyledDivHorizontal, { style: { gap: 10, padding: '10px 8px', width: '100%', alignItems: 'center' }, children: [_jsx("p", { style: { fontSize: '1.1rem', fontWeight: 'bold' }, children: `${SDKUI_Localizator.DcmtType} - ${SDKUI_Localizator.About}` }), _jsx(IconCloseOutline, { style: { marginLeft: 'auto', cursor: 'pointer' }, onClick: () => setInfoDTD(undefined) })] }), renderDTDTooltipContent(infoDTD)] })] })] })
|
|
201
214
|
: _jsx("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', fontSize: '1.5rem' }, children: SDKUI_Localizator.TreesNoAvailable }) }));
|
|
202
215
|
};
|
|
203
216
|
export default TMTreeSelector;
|
|
@@ -3,6 +3,16 @@ import { DeviceType } from "../../base/TMDeviceProvider";
|
|
|
3
3
|
import { WorkItemDetail } from "../../../ts";
|
|
4
4
|
interface IWorkflowOperationButtonsProps {
|
|
5
5
|
dtd: DcmtTypeDescriptor | undefined;
|
|
6
|
+
/**
|
|
7
|
+
* Forza la forma dei pulsanti: `true` = flusso di FIRMA (Firma e approva),
|
|
8
|
+
* `false` = flusso di APPROVAZIONE. Se omesso si deduce dal tipo documento
|
|
9
|
+
* (widget Sign4Top), che è il comportamento del workflow.
|
|
10
|
+
*
|
|
11
|
+
* Serve a chi conosce la natura dell'attività meglio del tipo documento: un
|
|
12
|
+
* work item di sola approvazione su un tipo ABILITATO alla firma non deve
|
|
13
|
+
* mostrare "Firma e approva".
|
|
14
|
+
*/
|
|
15
|
+
signFlow?: boolean;
|
|
6
16
|
approveDisable?: boolean;
|
|
7
17
|
signApproveDisable?: boolean;
|
|
8
18
|
rejectDisable?: boolean;
|
|
@@ -53,16 +53,20 @@ const StyledHorizontalContainer = styled.div `
|
|
|
53
53
|
/* align-items: flex-end; */
|
|
54
54
|
`;
|
|
55
55
|
export const WorkFlowOperationButtons = (props) => {
|
|
56
|
-
const { dtd = undefined, deviceType = DeviceType.DESKTOP, approveDisable = false, signApproveDisable = false, rejectDisable = false, reassignDisable = false, infoDisable = false, onApprove, onSignApprove, onReject, onReAssign, onMoreInfo, } = props;
|
|
56
|
+
const { dtd = undefined, signFlow = undefined, deviceType = DeviceType.DESKTOP, approveDisable = false, signApproveDisable = false, rejectDisable = false, reassignDisable = false, infoDisable = false, onApprove, onSignApprove, onReject, onReAssign, onMoreInfo, } = props;
|
|
57
57
|
const isMobile = deviceType === DeviceType.MOBILE;
|
|
58
|
-
// Calcola direttamente se è un workflow di firma per evitare flickering durante il render
|
|
58
|
+
// Calcola direttamente se è un workflow di firma per evitare flickering durante il render.
|
|
59
|
+
// `signFlow`, se fornito, ha la precedenza: chi lo passa conosce la natura
|
|
60
|
+
// dell'attività (es. categoria del work item) meglio del tipo documento.
|
|
59
61
|
const isSignWorkflow = useMemo(() => {
|
|
62
|
+
if (signFlow !== undefined)
|
|
63
|
+
return signFlow;
|
|
60
64
|
if (dtd && dtd.widgets && dtd.widgets.length > 0) {
|
|
61
65
|
return isSign4TopEnabled(dtd.widgets);
|
|
62
66
|
}
|
|
63
67
|
return false;
|
|
64
|
-
}, [dtd]);
|
|
65
|
-
return (_jsx(StyledWorkFlowOperationButtonsContainer, { "$isMobile": isMobile, children: isSignWorkflow ? (_jsxs(_Fragment, { children: [_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconSignaturePencil, {}), caption: SDKUI_Localizator.SignatureAndApprove, width: "160px", disabled: signApproveDisable, onClick: () => !signApproveDisable && onSignApprove?.(), onMouseDown: e => e.stopPropagation(), advancedColor: "#1a9a49", color: "success" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconCloseOutline, {}), caption: SDKUI_Localizator.Reject, disabled: rejectDisable, onClick: () => !rejectDisable && onReject?.(), onMouseDown: e => e.stopPropagation(), advancedColor: TMColors.error, color: "error" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconInfo, { fontSize: 16 }), caption: SDKUI_Localizator.MoreInformation, width: "180px", disabled: infoDisable, onClick: () => !infoDisable && onMoreInfo?.(), onMouseDown: e => e.stopPropagation(), advancedColor: TMColors.info, color: "info" })] })) : (_jsxs(_Fragment, { children: [_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconApply, {}), caption: SDKUI_Localizator.Approve, disabled: approveDisable, onClick: () => !approveDisable && onApprove?.(), advancedColor: "#1a9a49", color: "success" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconCloseOutline, {}), caption: SDKUI_Localizator.Reject, disabled: rejectDisable, onClick: () => !rejectDisable && onReject?.(), advancedColor: TMColors.error, color: "error" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconUser, { fontSize: 16 }), caption: SDKUI_Localizator.Reassign, disabled: reassignDisable, onClick: () => !reassignDisable && onReAssign?.(), advancedColor: TMColors.tertiary, color: "tertiary" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconInfo, { fontSize: 16 }), caption: SDKUI_Localizator.MoreInformation, width: "180px", disabled: infoDisable, onClick: () => !infoDisable && onMoreInfo?.(), advancedColor: TMColors.info, color: "info" })] })) }));
|
|
68
|
+
}, [dtd, signFlow]);
|
|
69
|
+
return (_jsx(StyledWorkFlowOperationButtonsContainer, { "$isMobile": isMobile, children: isSignWorkflow ? (_jsxs(_Fragment, { children: [_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconSignaturePencil, {}), caption: SDKUI_Localizator.SignatureAndApprove, width: "160px", disabled: signApproveDisable, onClick: () => !signApproveDisable && onSignApprove?.(), onMouseDown: e => e.stopPropagation(), advancedColor: "#1a9a49", color: "success" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconCloseOutline, {}), caption: SDKUI_Localizator.Reject, disabled: rejectDisable, onClick: () => !rejectDisable && onReject?.(), onMouseDown: e => e.stopPropagation(), advancedColor: TMColors.error, color: "error" }), onMoreInfo && (_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconInfo, { fontSize: 16 }), caption: SDKUI_Localizator.MoreInformation, width: "180px", disabled: infoDisable, onClick: () => !infoDisable && onMoreInfo?.(), onMouseDown: e => e.stopPropagation(), advancedColor: TMColors.info, color: "info" }))] })) : (_jsxs(_Fragment, { children: [_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconApply, {}), caption: SDKUI_Localizator.Approve, disabled: approveDisable, onClick: () => !approveDisable && onApprove?.(), advancedColor: "#1a9a49", color: "success" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconCloseOutline, {}), caption: SDKUI_Localizator.Reject, disabled: rejectDisable, onClick: () => !rejectDisable && onReject?.(), advancedColor: TMColors.error, color: "error" }), onReAssign && (_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconUser, { fontSize: 16 }), caption: SDKUI_Localizator.Reassign, disabled: reassignDisable, onClick: () => !reassignDisable && onReAssign?.(), advancedColor: TMColors.tertiary, color: "tertiary" })), onMoreInfo && (_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconInfo, { fontSize: 16 }), caption: SDKUI_Localizator.MoreInformation, width: "180px", disabled: infoDisable, onClick: () => !infoDisable && onMoreInfo?.(), advancedColor: TMColors.info, color: "info" }))] })) }));
|
|
66
70
|
};
|
|
67
71
|
export const WorkFlowApproveRejectPopUp = ({ TID = 0, DID = 0, deviceType = DeviceType.DESKTOP, isReject, selectedItems = [], onClose, onCompleted }) => {
|
|
68
72
|
const { refreshWorkflowApprove } = useWorkflowApprove();
|
|
@@ -5,6 +5,7 @@ interface TMPanelManagerContainerProps {
|
|
|
5
5
|
direction: TMPanelDirection;
|
|
6
6
|
parentId?: string;
|
|
7
7
|
minPanelSizePx?: number;
|
|
8
|
+
gutterSizePx?: number;
|
|
8
9
|
}
|
|
9
10
|
declare const TMPanelManagerContainer: (props: TMPanelManagerContainerProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
10
11
|
export default TMPanelManagerContainer;
|
|
@@ -18,20 +18,20 @@ const StyledPanelContainerWrapper = styled.div `
|
|
|
18
18
|
`;
|
|
19
19
|
// Styled Component per il gutter (separatore)
|
|
20
20
|
const StyledResizerGutter = styled.div `
|
|
21
|
-
cursor: ${props => (props.$direction === 'horizontal' ? 'col-resize' : 'row-resize')};
|
|
22
|
-
${props => (props.$direction === 'horizontal' ? `width: ${
|
|
21
|
+
cursor: ${props => (!props.$canResize ? 'default' : props.$direction === 'horizontal' ? 'col-resize' : 'row-resize')};
|
|
22
|
+
${props => (props.$direction === 'horizontal' ? `width: ${props.$size}px;` : `height: ${props.$size}px;`)}
|
|
23
23
|
flex-shrink: 0;
|
|
24
24
|
background-color: "transparent";
|
|
25
25
|
z-index: 10;
|
|
26
26
|
`;
|
|
27
27
|
const TMPanelManagerContainer = (props) => {
|
|
28
|
-
const { panels, showToolbar, direction, parentId, minPanelSizePx = 150 } = props;
|
|
28
|
+
const { panels, showToolbar, direction, parentId, minPanelSizePx = 150, gutterSizePx } = props;
|
|
29
29
|
const { panelVisibility, setPanelDimensionsById, hasVisiblePanels, maximizedPanels, updateIsResizingActive } = useTMPanelManagerContext();
|
|
30
30
|
// Get the current device type (e.g., mobile, tablet, desktop) using a custom hook
|
|
31
31
|
const deviceType = useDeviceType();
|
|
32
32
|
// This avoids unnecessary re-renders by only recalculating when deviceType changes
|
|
33
33
|
let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
|
|
34
|
-
const gutters = Gutters.getGutters();
|
|
34
|
+
const gutters = gutterSizePx ?? Gutters.getGutters();
|
|
35
35
|
// References to store information related to resizing
|
|
36
36
|
// startMousePos: stores the mouse position when resizing starts (x or y coordinate)
|
|
37
37
|
const startMousePos = useRef(0);
|
|
@@ -47,6 +47,19 @@ const TMPanelManagerContainer = (props) => {
|
|
|
47
47
|
const containerRef = useRef(null);
|
|
48
48
|
// Count how many child panels are currently visible (based on panelVisibility)
|
|
49
49
|
const currentlyVisibleChildrenCount = panels.filter(panel => panelVisibility[panel.id]).length;
|
|
50
|
+
/**
|
|
51
|
+
* Pannello ridimensionabile più prossimo a partire da `from` nella direzione `step`:
|
|
52
|
+
* i pannelli non visibili e quelli collassati (che vivono del solo ingombro minimo) si saltano,
|
|
53
|
+
* altrimenti il trascinamento del separatore assegnerebbe spazio a un pannello ridotto
|
|
54
|
+
*/
|
|
55
|
+
const findResizablePanelId = (from, step) => {
|
|
56
|
+
for (let i = from; i >= 0 && i < panels.length; i += step) {
|
|
57
|
+
const candidate = panels[i];
|
|
58
|
+
if (panelVisibility[candidate.id] && candidate.contentOptions?.isCollapsed !== true)
|
|
59
|
+
return candidate.id;
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
};
|
|
50
63
|
// If this component has a parent panel, and the parent panel is visible,
|
|
51
64
|
// but none of the current child panels are visible, return null to avoid rendering empty container
|
|
52
65
|
if (parentId && panelVisibility[parentId] && currentlyVisibleChildrenCount === 0) {
|
|
@@ -156,14 +169,6 @@ const TMPanelManagerContainer = (props) => {
|
|
|
156
169
|
}, children: _jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx(StyledPanelContainerWrapper, { ref: containerRef, "$direction": direction, "$hasVisiblePanels": hasVisiblePanels(), children: panels.map((panel, index) => {
|
|
157
170
|
// Check if current panel is visible according to context state
|
|
158
171
|
const isVisible = panelVisibility[panel.id];
|
|
159
|
-
// Find the closest previous visible panel's ID to place the resizer gutter between
|
|
160
|
-
let prevPanelIdForGutter = null;
|
|
161
|
-
for (let i = index - 1; i >= 0; i--) {
|
|
162
|
-
if (panelVisibility[panels[i].id]) {
|
|
163
|
-
prevPanelIdForGutter = panels[i].id;
|
|
164
|
-
break;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
172
|
/*
|
|
168
173
|
Determine if we should show the gutter (resize handle) before this panel.
|
|
169
174
|
The gutter is shown only if:
|
|
@@ -171,6 +176,11 @@ const TMPanelManagerContainer = (props) => {
|
|
|
171
176
|
- at least one visible panel was encountered before this one
|
|
172
177
|
*/
|
|
173
178
|
const showGutter = isVisible && hasSeenVisiblePanel && maximizedPanels.length === 0;
|
|
179
|
+
// I due pannelli su cui agisce il separatore: i più prossimi fra quelli ridimensionabili.
|
|
180
|
+
// Senza una coppia valida (es. tutti i vicini collassati) il separatore resta solo un divisorio
|
|
181
|
+
const resizeFromId = showGutter ? findResizablePanelId(index - 1, -1) : null;
|
|
182
|
+
const resizeToId = showGutter ? findResizablePanelId(index, 1) : null;
|
|
183
|
+
const canResize = resizeFromId !== null && resizeToId !== null && resizeFromId !== resizeToId;
|
|
174
184
|
// Update the flag once a visible panel is found, so gutters after it are shown correctly
|
|
175
185
|
if (isVisible) {
|
|
176
186
|
hasSeenVisiblePanel = true;
|
|
@@ -178,7 +188,7 @@ const TMPanelManagerContainer = (props) => {
|
|
|
178
188
|
// If the panel has child panels, render a nested TMPanelManagerContainer or a component
|
|
179
189
|
if (panel.children && panel.children.length > 0) {
|
|
180
190
|
const jsxComponent = panel.contentOptions?.component;
|
|
181
|
-
return (_jsxs(React.Fragment, { children: [showGutter && (_jsx(StyledResizerGutter, { "$direction": direction, onMouseDown: (e) => startResizing(e,
|
|
191
|
+
return (_jsxs(React.Fragment, { children: [showGutter && (_jsx(StyledResizerGutter, { "$direction": direction, "$size": gutters, "$canResize": canResize, onMouseDown: canResize ? (e) => startResizing(e, resizeFromId, resizeToId) : undefined })), _jsx(TMPanelWrapper, { panel: panel, children: jsxComponent
|
|
182
192
|
? React.isValidElement(jsxComponent)
|
|
183
193
|
? React.cloneElement(jsxComponent, { groupId: panel.id, mainDirection: panel.childrenGroupDirection || direction })
|
|
184
194
|
: jsxComponent
|
|
@@ -186,7 +196,7 @@ const TMPanelManagerContainer = (props) => {
|
|
|
186
196
|
}
|
|
187
197
|
// If the panel has a component specified, render it with a possible gutter before it
|
|
188
198
|
if (panel.contentOptions && panel.contentOptions.component) {
|
|
189
|
-
return (_jsxs(React.Fragment, { children: [showGutter && (_jsx(StyledResizerGutter, { "$direction": direction, onMouseDown: (e) => startResizing(e,
|
|
199
|
+
return (_jsxs(React.Fragment, { children: [showGutter && (_jsx(StyledResizerGutter, { "$direction": direction, "$size": gutters, "$canResize": canResize, onMouseDown: canResize ? (e) => startResizing(e, resizeFromId, resizeToId) : undefined })), _jsx(TMPanelWrapper, { panel: panel, children: panel.contentOptions.component })] }, panel.id));
|
|
190
200
|
}
|
|
191
201
|
// If no children or components, render nothing for this panel
|
|
192
202
|
return null;
|
|
@@ -14,12 +14,14 @@ export const TMPanelManagerProvider = (props) => {
|
|
|
14
14
|
const defaultPanelDimensionsRef = useRef(defaultDimensions);
|
|
15
15
|
// Memoize the panel hierarchy map to avoid re-generating it on every render unless `panels` change
|
|
16
16
|
const hierarchyMap = useMemo(() => generatePanelHierarchyMap(panels), [panels]);
|
|
17
|
-
// State to track the dimensions (width and height) of each panel, initialized with props
|
|
18
|
-
const [
|
|
17
|
+
// State to track the visibility and the dimensions (width and height) of each panel, initialized with props
|
|
18
|
+
const [panelLayout, setPanelLayout] = useState({ visibility: {}, dimensions: initialDimensions });
|
|
19
|
+
// Visibility of each panel, keyed by panel ID
|
|
20
|
+
const panelVisibility = panelLayout.visibility;
|
|
21
|
+
// Dimensions of each panel, keyed by panel ID
|
|
22
|
+
const panelDimensions = panelLayout.dimensions;
|
|
19
23
|
// IDs of maximized panels, including their parents if present
|
|
20
24
|
const [maximizedPanels, setMaximizedPanels] = useState([]);
|
|
21
|
-
// State to track the visibility of each panel, keyed by panel ID
|
|
22
|
-
const [panelVisibility, setPanelVisibility] = useState({});
|
|
23
25
|
// State to track visibility of toolbar buttons, keyed by panel ID
|
|
24
26
|
const [toolbarButtonsVisibility, setToolbarButtonsVisibility] = useState({});
|
|
25
27
|
// State to track disabled status of toolbar buttons, keyed by panel ID
|
|
@@ -31,94 +33,73 @@ export const TMPanelManagerProvider = (props) => {
|
|
|
31
33
|
setToolbarButtonsVisibility(visibilityMap);
|
|
32
34
|
setToolbarButtonsDisabled(disabledMap);
|
|
33
35
|
}, []);
|
|
34
|
-
// Callback to update the visibility state of a specific panel and its related hierarchy
|
|
35
|
-
const adjustPanelVisibilityAndSize = useCallback((id, isVisible,
|
|
36
|
+
// Callback to update the visibility state of a specific panel and its related hierarchy, redistributing the dimensions accordingly
|
|
37
|
+
const adjustPanelVisibilityAndSize = useCallback((id, isVisible, prevLayout) => {
|
|
36
38
|
// Clone previous visibility state to work with
|
|
37
|
-
let updatedVisibility = { ...
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const parentsToShow = showParentRecursively(id, hierarchyMap);
|
|
44
|
-
parentsToShow.forEach(([pid, visible]) => { updatedVisibility[pid] = visible; });
|
|
45
|
-
// Show the target panel
|
|
46
|
-
updatedVisibility[id] = true;
|
|
47
|
-
// Redistribute dimensions to account for newly shown panel
|
|
48
|
-
setPanelDimensions(prev => redistributeDimensionsOnShow(id, prev, defaultPanelDimensionsRef.current, hierarchyMap, updatedVisibility));
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
// Hide the panel
|
|
52
|
-
updatedVisibility[id] = false;
|
|
53
|
-
// Recursively hide parents
|
|
54
|
-
const parentsToHide = hideParentRecursively(id, hierarchyMap, updatedVisibility);
|
|
55
|
-
parentsToHide.forEach(([pid, visible]) => { updatedVisibility[pid] = visible; });
|
|
56
|
-
4;
|
|
57
|
-
// Redistribute dimensions after hiding
|
|
58
|
-
setPanelDimensions(prev => redistributeDimensionsOnHide(id, prev, hierarchyMap, updatedVisibility));
|
|
39
|
+
let updatedVisibility = { ...prevLayout.visibility };
|
|
40
|
+
let updatedDimensions;
|
|
41
|
+
if (isVisible) {
|
|
42
|
+
// On mobile, showing one panel hides all others first
|
|
43
|
+
if (isMobile) {
|
|
44
|
+
updatedVisibility = Object.keys(prevLayout.visibility).reduce((acc, key) => { acc[key] = false; return acc; }, {});
|
|
59
45
|
}
|
|
46
|
+
// Recursively determine and show parent panels
|
|
47
|
+
const parentsToShow = showParentRecursively(id, hierarchyMap);
|
|
48
|
+
parentsToShow.forEach(([pid, visible]) => { updatedVisibility[pid] = visible; });
|
|
49
|
+
// Show the target panel
|
|
50
|
+
updatedVisibility[id] = true;
|
|
51
|
+
// Redistribute dimensions to account for newly shown panel
|
|
52
|
+
updatedDimensions = redistributeDimensionsOnShow(id, prevLayout.dimensions, defaultPanelDimensionsRef.current, hierarchyMap, updatedVisibility);
|
|
60
53
|
}
|
|
61
54
|
else {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
setPanelDimensions(prev => redistributeDimensionsOnShow(id, prev, defaultPanelDimensionsRef.current, hierarchyMap, updatedVisibility));
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
// Hide the panel
|
|
73
|
-
updatedVisibility[id] = false;
|
|
74
|
-
// Recursively hide parent panels
|
|
75
|
-
const parentsToHide = hideParentRecursively(id, hierarchyMap, updatedVisibility);
|
|
76
|
-
parentsToHide.forEach(([pid, visible]) => { updatedVisibility[pid] = visible; });
|
|
77
|
-
// Adjust dimensions after hiding
|
|
78
|
-
setPanelDimensions(prev => redistributeDimensionsOnHide(id, prev, hierarchyMap, updatedVisibility));
|
|
79
|
-
}
|
|
55
|
+
// Hide the panel
|
|
56
|
+
updatedVisibility[id] = false;
|
|
57
|
+
// Recursively hide parents
|
|
58
|
+
const parentsToHide = hideParentRecursively(id, hierarchyMap, updatedVisibility);
|
|
59
|
+
parentsToHide.forEach(([pid, visible]) => { updatedVisibility[pid] = visible; });
|
|
60
|
+
// Redistribute dimensions after hiding
|
|
61
|
+
updatedDimensions = redistributeDimensionsOnHide(id, prevLayout.dimensions, hierarchyMap, updatedVisibility);
|
|
80
62
|
}
|
|
81
|
-
return updatedVisibility;
|
|
63
|
+
return { visibility: updatedVisibility, dimensions: updatedDimensions };
|
|
82
64
|
}, [hierarchyMap, isMobile]);
|
|
83
65
|
// On initial mount: initialize panel visibility using the provided `initialVisibility` config
|
|
84
66
|
// Each panel's visibility is processed through `updatePanelVisibility` to ensure hierarchy logic is applied
|
|
85
67
|
useEffect(() => {
|
|
86
68
|
if (isPersistenceEnabled) {
|
|
87
69
|
// If persistence is enabled, visibility and dimensions are already synced from persisted state, so just set them directly
|
|
88
|
-
|
|
89
|
-
setPanelDimensions(initialDimensions);
|
|
70
|
+
setPanelLayout({ visibility: initialVisibility, dimensions: initialDimensions });
|
|
90
71
|
}
|
|
91
72
|
else {
|
|
92
73
|
// If persistence is not enabled, recalculate visibility and dimensions based on the initial visibility, applying the hierarchy logic
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
74
|
+
setPanelLayout(prev => {
|
|
75
|
+
let updated = { visibility: { ...initialVisibility }, dimensions: prev.dimensions };
|
|
76
|
+
Object.entries(initialVisibility).forEach(([id, isVisible]) => {
|
|
77
|
+
updated = adjustPanelVisibilityAndSize(id, isVisible, updated);
|
|
78
|
+
});
|
|
79
|
+
return updated;
|
|
96
80
|
});
|
|
97
|
-
// Update panel visibility state with recalculated values
|
|
98
|
-
setPanelVisibility(updated);
|
|
99
81
|
}
|
|
100
82
|
}, []);
|
|
101
83
|
// On mobile devices: automatically show the initial mobile panel when layout switches to mobile
|
|
102
84
|
// This ensures the correct panel is visible by default on smaller screens
|
|
103
85
|
useEffect(() => {
|
|
104
86
|
if (isMobile) {
|
|
105
|
-
|
|
106
|
-
return adjustPanelVisibilityAndSize(initialMobilePanelId, true, prev);
|
|
107
|
-
});
|
|
87
|
+
setPanelLayout(prev => adjustPanelVisibilityAndSize(initialMobilePanelId, true, prev));
|
|
108
88
|
}
|
|
109
89
|
else {
|
|
110
90
|
if (isPersistenceEnabled) {
|
|
111
91
|
// If persistence is enabled, visibility and dimensions are already synced from persisted state, so just set them directly
|
|
112
|
-
|
|
92
|
+
setPanelLayout(prev => ({ ...prev, visibility: initialVisibility }));
|
|
113
93
|
}
|
|
114
94
|
else {
|
|
115
95
|
// If persistence is not enabled, recalculate visibility and dimensions based on the initial visibility, applying the hierarchy logic
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
96
|
+
setPanelLayout(prev => {
|
|
97
|
+
let updated = { visibility: { ...initialVisibility }, dimensions: prev.dimensions };
|
|
98
|
+
Object.entries(initialVisibility).forEach(([id, isVisible]) => {
|
|
99
|
+
updated = adjustPanelVisibilityAndSize(id, isVisible, updated);
|
|
100
|
+
});
|
|
101
|
+
return updated;
|
|
119
102
|
});
|
|
120
|
-
// Update panel visibility state with recalculated values
|
|
121
|
-
setPanelVisibility(updated);
|
|
122
103
|
}
|
|
123
104
|
}
|
|
124
105
|
}, [isMobile]);
|
|
@@ -131,9 +112,9 @@ export const TMPanelManagerProvider = (props) => {
|
|
|
131
112
|
// Update state to track which panels are maximized
|
|
132
113
|
setMaximizedPanels(toMaximize);
|
|
133
114
|
// Update panel dimensions accordingly
|
|
134
|
-
|
|
115
|
+
setPanelLayout(prev => {
|
|
135
116
|
const newDimensions = {};
|
|
136
|
-
Object.keys(prev).forEach(pid => {
|
|
117
|
+
Object.keys(prev.dimensions).forEach(pid => {
|
|
137
118
|
if (toMaximize.includes(pid)) {
|
|
138
119
|
// For maximized panels (target + parents), set width and height to 100%
|
|
139
120
|
newDimensions[pid] = { width: '100%', height: '100%' };
|
|
@@ -143,31 +124,31 @@ export const TMPanelManagerProvider = (props) => {
|
|
|
143
124
|
newDimensions[pid] = { width: '0%', height: '0%' };
|
|
144
125
|
}
|
|
145
126
|
});
|
|
146
|
-
return newDimensions;
|
|
127
|
+
return { ...prev, dimensions: newDimensions };
|
|
147
128
|
});
|
|
148
129
|
}, [hierarchyMap]);
|
|
149
130
|
// Restore all panels to their original dimensions
|
|
150
131
|
const resetMaximization = useCallback(() => {
|
|
151
132
|
// Clear the list of maximized panels to exit maximize mode
|
|
152
133
|
setMaximizedPanels([]);
|
|
153
|
-
// Clone the current visibility state of panels
|
|
154
|
-
let updatedVisibility = { ...panelVisibility };
|
|
155
134
|
// Start with the initial panel dimensions as the base for restoration
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
135
|
+
setPanelLayout(prev => {
|
|
136
|
+
const updatedVisibility = prev.visibility;
|
|
137
|
+
const nextDimensions = Object.entries(updatedVisibility).reduce((acc, [id, isVisible]) => {
|
|
138
|
+
if (isVisible) {
|
|
139
|
+
// If the panel is visible, adjust dimensions to show it properly
|
|
140
|
+
acc = redistributeDimensionsOnShow(id, acc, defaultPanelDimensionsRef.current, hierarchyMap, updatedVisibility);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// If the panel is hidden, adjust dimensions to hide it
|
|
144
|
+
acc = redistributeDimensionsOnHide(id, acc, hierarchyMap, updatedVisibility);
|
|
145
|
+
}
|
|
146
|
+
return acc;
|
|
147
|
+
}, defaultPanelDimensionsRef.current);
|
|
148
|
+
// Apply the recalculated dimensions to the panel state
|
|
149
|
+
return { ...prev, dimensions: nextDimensions };
|
|
150
|
+
});
|
|
151
|
+
}, [hierarchyMap]);
|
|
171
152
|
// Toggle the maximized state of a panel by its ID
|
|
172
153
|
const toggleMaximize = useCallback((id) => {
|
|
173
154
|
if (maximizedPanels.includes(id)) {
|
|
@@ -186,17 +167,11 @@ export const TMPanelManagerProvider = (props) => {
|
|
|
186
167
|
// If it is maximized, first reset all maximized panels to their original state
|
|
187
168
|
resetMaximization();
|
|
188
169
|
// Then update the visibility of the panel, toggling its current state
|
|
189
|
-
|
|
190
|
-
const isCurrentlyVisible = prev[id];
|
|
191
|
-
return adjustPanelVisibilityAndSize(id, !isCurrentlyVisible, prev);
|
|
192
|
-
});
|
|
170
|
+
setPanelLayout(prev => adjustPanelVisibilityAndSize(id, !prev.visibility[id], prev));
|
|
193
171
|
}
|
|
194
172
|
else {
|
|
195
173
|
// If the panel is not maximized, simply toggle its visibility
|
|
196
|
-
|
|
197
|
-
const isCurrentlyVisible = prev[id];
|
|
198
|
-
return adjustPanelVisibilityAndSize(id, !isCurrentlyVisible, prev);
|
|
199
|
-
});
|
|
174
|
+
setPanelLayout(prev => adjustPanelVisibilityAndSize(id, !prev.visibility[id], prev));
|
|
200
175
|
}
|
|
201
176
|
}, [maximizedPanels, resetMaximization, adjustPanelVisibilityAndSize]);
|
|
202
177
|
// Sets the visibility of a panel by its ID to a specific value (true = show, false = hide)
|
|
@@ -206,14 +181,14 @@ export const TMPanelManagerProvider = (props) => {
|
|
|
206
181
|
resetMaximization();
|
|
207
182
|
}
|
|
208
183
|
// Then update the visibility state of the panel to the given value
|
|
209
|
-
|
|
184
|
+
setPanelLayout(prev => adjustPanelVisibilityAndSize(id, isVisible, prev));
|
|
210
185
|
}, [maximizedPanels, resetMaximization, adjustPanelVisibilityAndSize]);
|
|
211
186
|
// Sets the dimensions (width and height) of a specific panel by its ID
|
|
212
187
|
const setPanelDimensionsById = useCallback((id, width, height) => {
|
|
213
188
|
// Update the ref holding the initial dimensions
|
|
214
189
|
defaultPanelDimensionsRef.current = { ...defaultPanelDimensionsRef.current, [id]: { width, height } };
|
|
215
190
|
// Update the panel dimensions state
|
|
216
|
-
|
|
191
|
+
setPanelLayout(prev => ({ ...prev, dimensions: { ...prev.dimensions, [id]: { width, height } } }));
|
|
217
192
|
}, []);
|
|
218
193
|
// Checks if there is at least one panel currently visible
|
|
219
194
|
const hasVisiblePanels = useCallback(() => {
|
|
@@ -34,8 +34,8 @@ const TMPanelWrapper = (props) => {
|
|
|
34
34
|
// Applica 'flex' o 'none' solo se è già stato reso visibile almeno una volta
|
|
35
35
|
display: isCurrentlyVisible ? 'flex' : 'none',
|
|
36
36
|
flexDirection: 'column',
|
|
37
|
-
minWidth: '50px',
|
|
38
|
-
minHeight: '50px',
|
|
37
|
+
minWidth: panel.contentOptions?.minWidth ?? '50px',
|
|
38
|
+
minHeight: panel.contentOptions?.minHeight ?? '50px',
|
|
39
39
|
width: width,
|
|
40
40
|
height: height,
|
|
41
41
|
pointerEvents: 'auto',
|
|
@@ -97,18 +97,20 @@ export const redistributeDimensionsOnHide = (hiddenPanelId, currentDimensions, h
|
|
|
97
97
|
const hiddenWidthNum = parseFloat(hiddenDims.width);
|
|
98
98
|
const hiddenHeightNum = parseFloat(hiddenDims.height);
|
|
99
99
|
const visibleSiblings = siblings.filter(siblingId => panelVisibility[siblingId]);
|
|
100
|
-
const widthIncrement = hiddenWidthNum / visibleSiblings.length;
|
|
101
|
-
const heightIncrement = hiddenHeightNum / visibleSiblings.length;
|
|
102
100
|
let newDimensions = { ...currentDimensions };
|
|
103
|
-
visibleSiblings.
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
101
|
+
if (visibleSiblings.length > 0) {
|
|
102
|
+
const widthIncrement = hiddenWidthNum / visibleSiblings.length;
|
|
103
|
+
const heightIncrement = hiddenHeightNum / visibleSiblings.length;
|
|
104
|
+
visibleSiblings.forEach(siblingId => {
|
|
105
|
+
const siblingDims = newDimensions[siblingId] || { width: '0%', height: '0%' };
|
|
106
|
+
const siblingWidthNum = parseFloat(siblingDims.width) || 0;
|
|
107
|
+
const siblingHeightNum = parseFloat(siblingDims.height) || 0;
|
|
108
|
+
const newWidthNum = Math.min(siblingWidthNum + widthIncrement, 100);
|
|
109
|
+
const newHeightNum = Math.min(siblingHeightNum + heightIncrement, 100);
|
|
110
|
+
newDimensions[siblingId] = { width: `${newWidthNum}%`, height: `${newHeightNum}%` };
|
|
111
|
+
});
|
|
112
|
+
newDimensions[hiddenPanelId] = { width: '0%', height: '0%' };
|
|
113
|
+
}
|
|
112
114
|
// Ora controllo se il parent non ha più figli visibili e chiamo ricorsivamente
|
|
113
115
|
if (parentId) {
|
|
114
116
|
const parentInfo = hierarchyMap.get(parentId);
|
|
@@ -92,8 +92,11 @@ export const TMMetadataIcon = ({ tid, md, color, layoutMode = LayoutModes.Update
|
|
|
92
92
|
break;
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
+
// color='inherit' serve solo all'icona (eredita il colore dell'editor): il tooltip è renderizzato in overlay,
|
|
96
|
+
// dove 'inherit' non risolverebbe al colore dell'editor, quindi lì manteniamo la palette normale
|
|
97
|
+
let tooltipColor = color === 'inherit' ? undefined : color;
|
|
95
98
|
return (_jsx(_Fragment, { children: icon
|
|
96
|
-
? _jsx(TMMetadataTooltip, { tid: tid, md: md, layoutMode: layoutMode, color:
|
|
99
|
+
? _jsx(TMMetadataTooltip, { tid: tid, md: md, layoutMode: layoutMode, color: tooltipColor, children: icon })
|
|
97
100
|
: null }));
|
|
98
101
|
};
|
|
99
102
|
export const TMMetadataTooltip = ({ tid, md, color, children, layoutMode = LayoutModes.Update }) => {
|
|
@@ -259,7 +259,7 @@ export const TMDcmtTypeIcon = ({ dtd }) => {
|
|
|
259
259
|
return (_jsx(TMDcmtTypeTooltip, { dtd: dtd, children: icon }));
|
|
260
260
|
};
|
|
261
261
|
export const TMDcmtTypeTooltip = ({ dtd, children }) => {
|
|
262
|
-
return (_jsx("div", { style: { pointerEvents: 'all' }, children: _jsx(TMTooltip, { content: renderDTDTooltipContent(dtd), children: children }) }));
|
|
262
|
+
return (_jsx("div", { style: { pointerEvents: 'all' }, children: _jsx(TMTooltip, { allowContentInteraction: true, content: renderDTDTooltipContent(dtd), children: children }) }));
|
|
263
263
|
};
|
|
264
264
|
const TMTidViewer = ({ tmSession, tid, did, showIcon = false, color, showId = false, noneSelectionText = `<${SDKUI_Localizator.NoneSelection}>` }) => {
|
|
265
265
|
const [dtd, setDtd] = useState();
|
|
@@ -297,29 +297,43 @@ const TMTidViewer = ({ tmSession, tid, did, showIcon = false, color, showId = fa
|
|
|
297
297
|
textOverflow: 'ellipsis'
|
|
298
298
|
}, children: [showIcon && dtd && _jsx(TMDcmtTypeIcon, { dtd: dtd }), _jsx("p", { title: displayName(), style: {
|
|
299
299
|
textAlign: 'left',
|
|
300
|
+
margin: 0,
|
|
300
301
|
marginLeft: showIcon ? '5px' : '',
|
|
301
|
-
color:
|
|
302
|
+
color: dtd?.isView ? 'red' : (color ?? TMColors.primary),
|
|
302
303
|
whiteSpace: 'nowrap',
|
|
303
304
|
overflow: 'hidden',
|
|
304
305
|
textOverflow: 'ellipsis',
|
|
305
306
|
// paddingRight: '10px'
|
|
306
|
-
}, children: displayName() }), showId && _jsx("p", { style: { padding: '0px 3px' }, children: `(TID: ${tid})` })] }));
|
|
307
|
+
}, children: displayName() }), showId && _jsx("p", { style: { padding: '0px 3px', margin: 0 }, children: `(TID: ${tid})` })] }));
|
|
307
308
|
};
|
|
308
309
|
export default TMTidViewer;
|
|
309
310
|
export const cellRenderTID = (data, noneSelectionText) => {
|
|
310
311
|
return (_jsx(TMTidViewer, { tid: data.value, noneSelectionText: noneSelectionText }));
|
|
311
312
|
};
|
|
312
|
-
/**
|
|
313
|
+
/** Metodi di visualizzazione già richiesti, per non ricaricare i metadati ad ogni riapertura del tooltip */
|
|
314
|
+
const displayNameMethodCache = new Map();
|
|
313
315
|
const TMDisplayNameMethodItem = ({ dtd }) => {
|
|
314
|
-
const [displayNameMethod, setDisplayNameMethod] = useState(
|
|
315
|
-
|
|
316
|
-
|
|
316
|
+
const [displayNameMethod, setDisplayNameMethod] = useState(() => dtd.id ? displayNameMethodCache.get(dtd.id) : undefined);
|
|
317
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
318
|
+
const onShowClick = async (e) => {
|
|
319
|
+
/* Un click qualsiasi chiude il tooltip: senza questo il risultato non sarebbe mai visibile */
|
|
320
|
+
e.stopPropagation();
|
|
321
|
+
if (isLoading || displayNameMethod)
|
|
322
|
+
return;
|
|
323
|
+
setIsLoading(true);
|
|
324
|
+
try {
|
|
317
325
|
const method = await getDTDDisplayNameInfo(dtd);
|
|
326
|
+
if (dtd.id)
|
|
327
|
+
displayNameMethodCache.set(dtd.id, method);
|
|
318
328
|
setDisplayNameMethod(method);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
329
|
+
}
|
|
330
|
+
finally {
|
|
331
|
+
setIsLoading(false);
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
return (_jsxs(StyledTooltipItem, { children: [`${SDKUI_Localizator.DisplayNameMethod}: `, displayNameMethod ?? (isLoading
|
|
335
|
+
? `${SDKUI_Localizator.Loading} ...`
|
|
336
|
+
: _jsx("span", { style: { color: TMColors.primary, cursor: 'pointer', textDecoration: 'underline' }, onClick: onShowClick, children: SDKUI_Localizator.Details }))] }));
|
|
323
337
|
};
|
|
324
338
|
export const renderDTDTooltipContent = (dtd) => {
|
|
325
339
|
const mapAccessLevelToLocalizedString = (level) => {
|