@antscorp/antsomi-ui 1.3.5-beta.407 → 1.3.5-beta.408
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/es/components/molecules/ModalSelect/ModalSelect.js +3 -2
- package/es/components/molecules/ModalSelect/styled.js +4 -3
- package/es/components/molecules/ModalSelect/types.d.ts +1 -0
- package/es/components/organism/LeftMenu/LeftMenu.js +22 -14
- package/es/components/organism/LeftMenu/components/CommonMenu/index.d.ts +5 -1
- package/es/components/organism/LeftMenu/components/CommonMenu/index.js +4 -2
- package/es/components/organism/LeftMenu/components/CustomMenu/index.d.ts +1 -0
- package/es/components/organism/LeftMenu/components/CustomMenu/index.js +3 -2
- package/es/components/organism/LeftMenu/components/HomeMenu/index.d.ts +4 -1
- package/es/components/organism/LeftMenu/components/HomeMenu/index.js +2 -38
- package/es/components/organism/LeftMenu/components/HomeMenu/useHomeMenu.d.ts +2 -1
- package/es/components/organism/LeftMenu/components/HomeMenu/useHomeMenu.js +8 -2
- package/es/components/organism/LeftMenu/components/common/ChildMenu/index.js +16 -11
- package/es/components/organism/LeftMenu/hooks/useLeftMenu.d.ts +2 -0
- package/es/components/organism/LeftMenu/hooks/useLeftMenu.js +44 -22
- package/es/components/organism/LeftMenu/hooks/useNavigatePath.js +5 -4
- package/es/components/organism/LeftMenu/stores/index.d.ts +2 -0
- package/es/components/organism/LeftMenu/stores/index.js +2 -0
- package/es/components/organism/LeftMenu/styled.d.ts +3 -1
- package/es/components/organism/LeftMenu/styled.js +10 -9
- package/package.json +1 -1
|
@@ -13,8 +13,9 @@ import React, { useCallback, useEffect, useState } from 'react';
|
|
|
13
13
|
import { Menu } from 'antd';
|
|
14
14
|
import { StyledModal } from './styled';
|
|
15
15
|
import { isFunction } from 'lodash';
|
|
16
|
+
import clsx from 'clsx';
|
|
16
17
|
export const ModalSelect = (props) => {
|
|
17
|
-
const { value, content, options = [], okButtonProps = {}, cancelButtonProps = {}, title, open: openProp, menuRef: menuRefProp, onChange, onOk } = props, rest = __rest(props, ["value", "content", "options", "okButtonProps", "cancelButtonProps", "title", "open", "menuRef", "onChange", "onOk"]);
|
|
18
|
+
const { value, content, options = [], okButtonProps = {}, cancelButtonProps = {}, title, open: openProp, menuRef: menuRefProp, onChange, onOk, contentWrapperProps = {} } = props, rest = __rest(props, ["value", "content", "options", "okButtonProps", "cancelButtonProps", "title", "open", "menuRef", "onChange", "onOk", "contentWrapperProps"]);
|
|
18
19
|
const [selected, setSelected] = useState(null);
|
|
19
20
|
const [open, setOpen] = useState(false);
|
|
20
21
|
const handleSetMenuRef = useCallback((ref) => {
|
|
@@ -51,5 +52,5 @@ export const ModalSelect = (props) => {
|
|
|
51
52
|
};
|
|
52
53
|
return (React.createElement(StyledModal, Object.assign({}, rest, { open: open, onOk: handleOk, okButtonProps: Object.assign(Object.assign({}, okButtonProps), { className: `${okButtonProps.className} ok-btn` }), cancelButtonProps: Object.assign(Object.assign({}, cancelButtonProps), { className: `${cancelButtonProps.className} cancel-btn` }), title: title || 'Select' }),
|
|
53
54
|
React.createElement(Menu, { ref: handleSetMenuRef, items: options, selectedKeys: [selected || ''], onClick: info => handleClickItem(info.key) }),
|
|
54
|
-
React.createElement("div", { className:
|
|
55
|
+
React.createElement("div", Object.assign({}, contentWrapperProps, { className: clsx(contentWrapperProps === null || contentWrapperProps === void 0 ? void 0 : contentWrapperProps.className, 'ModalSelect-content') }), renderContent())));
|
|
55
56
|
};
|
|
@@ -63,12 +63,14 @@ export const StyledModal = styled(Modal) `
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
> .content {
|
|
67
|
-
overflow: hidden;
|
|
66
|
+
> .ModalSelect-content {
|
|
68
67
|
margin-left: 80px;
|
|
68
|
+
border-radius: 10px;
|
|
69
|
+
overflow: hidden;
|
|
69
70
|
|
|
70
71
|
&:hover {
|
|
71
72
|
overflow: auto;
|
|
73
|
+
scrollbar-width: none;
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
76
|
}
|
|
@@ -143,7 +145,6 @@ export const CardRecommendedContainer = styled.div `
|
|
|
143
145
|
line-height: 14px;
|
|
144
146
|
font-size: 12px;
|
|
145
147
|
padding: 5px 10px;
|
|
146
|
-
border-radius: 24px;
|
|
147
148
|
|
|
148
149
|
&.antsomi-tag-borderless {
|
|
149
150
|
border-width: 0;
|
|
@@ -6,6 +6,7 @@ export type ModalSelectProps = {
|
|
|
6
6
|
value?: string;
|
|
7
7
|
options?: MenuProps['items'];
|
|
8
8
|
content?: (active: string | null) => React.ReactNode;
|
|
9
|
+
contentWrapperProps?: React.ComponentProps<'div'>;
|
|
9
10
|
onChange?: (active: string) => void;
|
|
10
11
|
menuRef?: RefCallback<HTMLUListElement>;
|
|
11
12
|
onOk?: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>, active: string | null) => void;
|
|
@@ -5,6 +5,7 @@ import { Typography } from 'antd';
|
|
|
5
5
|
import classNames from 'classnames';
|
|
6
6
|
import { isNil, isString } from 'lodash';
|
|
7
7
|
import { Link } from 'react-router-dom';
|
|
8
|
+
import isEqual from 'react-fast-compare';
|
|
8
9
|
// Styled
|
|
9
10
|
import { ChildMenuWrapper, ExpandWrapper, FeatureMenu, FeatureMenuItem, LeftMenuNav, LeftMenuNavWrapper, PopoverWrapper, NavLogoWrapper, FeatureMenuWrapper, IconWrapper, } from './styled';
|
|
10
11
|
// Constants
|
|
@@ -17,14 +18,10 @@ const SubLogoAntsomi = 'https://st-media-template.antsomi.com/icons/antsomi/ants
|
|
|
17
18
|
export const LeftMenuComponent = memo(props => {
|
|
18
19
|
const { style, className, customization, showLogo = true } = props;
|
|
19
20
|
const { isExpandable = true, isCustomized, isRecommendation, items = [], onMenuItemClick, } = customization || {};
|
|
20
|
-
const { state, activeAppCode, permissionMenu, customActiveAppKey, onToggleChildMenu, onMouseEnter, onMouseLeave, onHoverMenuBar, } = useLeftMenu(props);
|
|
21
|
+
const { state, activeAppCode, permissionMenu, customActiveAppKey, onToggleChildMenu, onMouseEnter, onMouseLeave, onHoverMenuBar, onShowPopover, } = useLeftMenu(props);
|
|
21
22
|
const { isPushDifferentDomain, getPath, navigatePath } = useNavigatePath();
|
|
22
|
-
const
|
|
23
|
-
const appActiveKey =
|
|
24
|
-
? state.hoverItem
|
|
25
|
-
: isCustomized || isRecommendation
|
|
26
|
-
? customActiveAppKey
|
|
27
|
-
: activeAppCode;
|
|
23
|
+
const childActiveMenu = useMemo(() => {
|
|
24
|
+
const appActiveKey = isCustomized || isRecommendation ? customActiveAppKey : activeAppCode;
|
|
28
25
|
if (isCustomized)
|
|
29
26
|
return React.createElement(CustomMenu, null);
|
|
30
27
|
switch (appActiveKey) {
|
|
@@ -33,7 +30,18 @@ export const LeftMenuComponent = memo(props => {
|
|
|
33
30
|
default:
|
|
34
31
|
return React.createElement(CommonMenu, null);
|
|
35
32
|
}
|
|
36
|
-
}, [activeAppCode, customActiveAppKey, isCustomized, isRecommendation
|
|
33
|
+
}, [activeAppCode, customActiveAppKey, isCustomized, isRecommendation]);
|
|
34
|
+
const childHoverMenu = useMemo(() => {
|
|
35
|
+
const appActiveKey = state.hoverItem;
|
|
36
|
+
if (isCustomized)
|
|
37
|
+
return React.createElement(CustomMenu, { isHover: true });
|
|
38
|
+
switch (appActiveKey) {
|
|
39
|
+
case isRecommendation ? 'DASHBOARD' : APP_KEYS.HOME:
|
|
40
|
+
return React.createElement(HomeMenu, { isHover: true });
|
|
41
|
+
default:
|
|
42
|
+
return React.createElement(CommonMenu, { isHover: true });
|
|
43
|
+
}
|
|
44
|
+
}, [isCustomized, isRecommendation, state.hoverItem]);
|
|
37
45
|
const renderFeatureMenuItem = useCallback((item) => {
|
|
38
46
|
const { menu_item_name, menu_item, icon_name, menu_item_code, menu_item_path, menu_item_domain, } = item;
|
|
39
47
|
const isActive = activeAppCode === menu_item_code;
|
|
@@ -90,15 +98,15 @@ export const LeftMenuComponent = memo(props => {
|
|
|
90
98
|
};
|
|
91
99
|
return (React.createElement(LeftMenuNavWrapper, { style: style, "$isExpandMenu": state.isExpandMenu, className: className },
|
|
92
100
|
React.createElement(LeftMenuNav, { className: "left-menu-nav" },
|
|
93
|
-
React.createElement(FeatureMenuWrapper, { vertical: true },
|
|
101
|
+
React.createElement(FeatureMenuWrapper, { vertical: true, onMouseEnter: () => onShowPopover(), onMouseLeave: onMouseLeave },
|
|
94
102
|
showLogo && (React.createElement(NavLogoWrapper, { align: "center", justify: "center", onMouseEnter: onHoverMenuBar },
|
|
95
103
|
React.createElement("div", { className: "image-wrapper" },
|
|
96
104
|
React.createElement("img", { src: SubLogoAntsomi, alt: "Antsomi sub logo" })))),
|
|
97
|
-
React.createElement(FeatureMenu, { role: "menu", className: "antsomi-scroll-box"
|
|
105
|
+
React.createElement(FeatureMenu, { role: "menu", className: "antsomi-scroll-box" },
|
|
98
106
|
React.createElement("div", { className: "menu-content scroll-content" }, renderAppMenuItems()),
|
|
99
107
|
React.createElement("div", { className: "nav-blank", onMouseEnter: onHoverMenuBar }),
|
|
100
|
-
React.createElement(PopoverWrapper, { className: "antsomi-scroll-box antsomi-child-menu-popover"
|
|
101
|
-
React.createElement("div", { className: "scroll-content", style: { width: '200px', maxHeight: '100%' } },
|
|
108
|
+
React.createElement(PopoverWrapper, { show: state.isShowPopover && isExpandable, className: "antsomi-scroll-box antsomi-child-menu-popover" },
|
|
109
|
+
React.createElement("div", { className: "scroll-content", style: { width: '200px', maxHeight: '100%' } }, childHoverMenu))),
|
|
102
110
|
React.createElement("div", { style: { flexShrink: 0 } }, renderSettings())),
|
|
103
111
|
isExpandable && !isRecommendation && (React.createElement(ExpandWrapper, { onMouseEnter: onMouseLeave },
|
|
104
112
|
React.createElement(Icon, { type: "icon-ants-expand-more", style: {
|
|
@@ -107,5 +115,5 @@ export const LeftMenuComponent = memo(props => {
|
|
|
107
115
|
transform: `rotate(${state.isExpandMenu ? '90deg' : '270deg'})`,
|
|
108
116
|
}, onClick: onToggleChildMenu })))),
|
|
109
117
|
React.createElement(ChildMenuWrapper, { isExpand: state.isExpandMenu && isExpandable, isMarginTop: showLogo, className: "antsomi-scroll-box" },
|
|
110
|
-
React.createElement("div", { className: "scroll-content", style: { width: '200px', maxHeight: '100%' } },
|
|
111
|
-
});
|
|
118
|
+
React.createElement("div", { className: "scroll-content", style: { width: '200px', maxHeight: '100%' } }, childActiveMenu))));
|
|
119
|
+
}, (prevProps, nextProps) => isEqual(prevProps, nextProps));
|
|
@@ -6,9 +6,11 @@ import { ChildMenu } from '../common';
|
|
|
6
6
|
import { useLeftMenuContext } from '../../contexts';
|
|
7
7
|
// Utils
|
|
8
8
|
import { getMenuItem } from '../../utils';
|
|
9
|
-
export const CommonMenu = memo(() => {
|
|
9
|
+
export const CommonMenu = memo(({ isHover }) => {
|
|
10
10
|
const appMenuChildren = useLeftMenuContext(store => store.appMenuChildren);
|
|
11
|
+
const appHoverMenuChildren = useLeftMenuContext(store => store.appHoverMenuChildren);
|
|
11
12
|
const onMenuClick = useLeftMenuContext(store => store.onMenuClick);
|
|
12
13
|
const customChildren = useMemo(() => appMenuChildren === null || appMenuChildren === void 0 ? void 0 : appMenuChildren.map(item => getMenuItem(item)), [appMenuChildren]);
|
|
13
|
-
|
|
14
|
+
const customHoverChildren = useMemo(() => appHoverMenuChildren === null || appHoverMenuChildren === void 0 ? void 0 : appHoverMenuChildren.map(item => getMenuItem(item)), [appHoverMenuChildren]);
|
|
15
|
+
return (React.createElement(ChildMenu, { items: isHover ? customHoverChildren : customChildren, onMenuClick: onMenuClick }));
|
|
14
16
|
});
|
|
@@ -4,8 +4,9 @@ import React, { memo } from 'react';
|
|
|
4
4
|
import { ChildMenu } from '../common';
|
|
5
5
|
// Hooks
|
|
6
6
|
import { useLeftMenuContext } from '../../contexts';
|
|
7
|
-
export const CustomMenu = memo(() => {
|
|
7
|
+
export const CustomMenu = memo(({ isHover }) => {
|
|
8
8
|
const appCustomMenuChildren = useLeftMenuContext(store => store.customMenuChildren);
|
|
9
|
+
const appCustomHoverMenuChildren = useLeftMenuContext(store => store.customHoverMenuChildren);
|
|
9
10
|
const onMenuClick = useLeftMenuContext(store => store.onMenuClick);
|
|
10
|
-
return React.createElement(ChildMenu, { items: appCustomMenuChildren, onMenuClick: onMenuClick });
|
|
11
|
+
return (React.createElement(ChildMenu, { items: isHover ? appCustomHoverMenuChildren : appCustomMenuChildren, onMenuClick: onMenuClick }));
|
|
11
12
|
});
|
|
@@ -9,44 +9,8 @@ import Icon from '@antscorp/icons';
|
|
|
9
9
|
import { CreateButton, HomeMenuWrapper, ModalWrapper } from './styled';
|
|
10
10
|
// Hooks
|
|
11
11
|
import { useHomeMenu } from './useHomeMenu';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// HEADING: getTranslateMessage(TRANSLATE_KEY._TITL_REMOV_ACCESS_TAB, 'Remove access to this tab'),
|
|
15
|
-
// BODY: getTranslateMessage(
|
|
16
|
-
// TRANSLATE_KEY.REMOV_ACCESS_TAB,
|
|
17
|
-
// 'This action will remove your access to this tab. You will not see it anymore. Are you sure you want to continue?',
|
|
18
|
-
// ),
|
|
19
|
-
// HEADING_DASHBOARD: getTranslateMessage(
|
|
20
|
-
// TRANSLATE_KEY._TITL_REMOV_ACCESS_DB,
|
|
21
|
-
// 'Remove access to this dashboard',
|
|
22
|
-
// ),
|
|
23
|
-
// BODY_DASHBOARD: getTranslateMessage(
|
|
24
|
-
// TRANSLATE_KEY.REMOV_ACCESS_DB,
|
|
25
|
-
// 'This action will remove your access to selected dashboard. You will not see it anymore. Are you sure you want to continue?',
|
|
26
|
-
// ),
|
|
27
|
-
// },
|
|
28
|
-
// DELETE_TAB: {
|
|
29
|
-
// HEADING: getTranslateMessage(TRANSLATE_KEY._TITL_DELETE_TAB, 'Remove this tab'),
|
|
30
|
-
// BODY: getTranslateMessage(
|
|
31
|
-
// TRANSLATE_KEY.DELETE_TAB_MESS,
|
|
32
|
-
// 'Removing this tab will delete it permanently. Are you sure you want to perform this action?',
|
|
33
|
-
// ),
|
|
34
|
-
// HEADING_DASHBOARD: getTranslateMessage(TRANSLATE_KEY._TITL_DELETE_DB, 'Remove this dashboard'),
|
|
35
|
-
// BODY_DASHBOARD: getTranslateMessage(
|
|
36
|
-
// TRANSLATE_KEY.DELETE_DB_MESS,
|
|
37
|
-
// 'Removing this dashboard will delete it permanently. Are you sure you want to perform this action?',
|
|
38
|
-
// ),
|
|
39
|
-
// },
|
|
40
|
-
// 'my-report-template': {
|
|
41
|
-
// HEADING: getTranslateMessage(TRANSLATE_KEY._TITL_SHARE_RP, 'Share Report'),
|
|
42
|
-
// BODY: getTranslateMessage(
|
|
43
|
-
// TRANSLATE_KEY._SHARE_RP_MESS,
|
|
44
|
-
// 'Sharing this tab with Public access will make your report public for everyone on the portal.',
|
|
45
|
-
// ),
|
|
46
|
-
// },
|
|
47
|
-
// };
|
|
48
|
-
export const HomeMenu = memo(() => {
|
|
49
|
-
const { children, removedDashboardId, isDashboardRemoving, isRecommendation, setRemovedDashboardId, onCreateNewReport, onMenuClick, onRemoveDashboard, } = useHomeMenu();
|
|
12
|
+
export const HomeMenu = memo(props => {
|
|
13
|
+
const { children, removedDashboardId, isDashboardRemoving, isRecommendation, setRemovedDashboardId, onCreateNewReport, onMenuClick, onRemoveDashboard, } = useHomeMenu(props);
|
|
50
14
|
return (React.createElement(React.Fragment, null,
|
|
51
15
|
React.createElement(HomeMenuWrapper, { gap: 10, vertical: true },
|
|
52
16
|
!isRecommendation && (React.createElement(CreateButton, { type: "primary", onClick: onCreateNewReport },
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
|
|
2
|
+
import { HomeMenuProps } from '.';
|
|
3
|
+
export declare const useHomeMenu: (props: HomeMenuProps) => {
|
|
3
4
|
children: import("../../types").TMenuItem[];
|
|
4
5
|
removedDashboardId: string;
|
|
5
6
|
isDashboardRemoving: boolean;
|
|
@@ -21,10 +21,12 @@ import { useLayoutStore } from '@antscorp/antsomi-ui/es/components/template';
|
|
|
21
21
|
import { useCustomRouter } from '@antscorp/antsomi-ui/es/hooks';
|
|
22
22
|
// Queries
|
|
23
23
|
import { useRemoveDashboard } from '@antscorp/antsomi-ui/es/queries/LeftMenu';
|
|
24
|
-
export const useHomeMenu = () => {
|
|
24
|
+
export const useHomeMenu = (props) => {
|
|
25
|
+
const { isHover } = props;
|
|
25
26
|
const { pathname, search } = window.location;
|
|
26
27
|
const { navigate, replace } = useCustomRouter();
|
|
27
28
|
const appMenuChildren = useLeftMenuContext(store => store.appMenuChildren);
|
|
29
|
+
const appHoverMenuChildren = useLeftMenuContext(store => store.appHoverMenuChildren);
|
|
28
30
|
const isRecommendation = useLeftMenuContext(store => store.isRecommendation);
|
|
29
31
|
const auth = useLeftMenuContext(store => { var _a; return (_a = store.appConfig) === null || _a === void 0 ? void 0 : _a.auth; });
|
|
30
32
|
const env = useLeftMenuContext(store => { var _a; return (_a = store.appConfig) === null || _a === void 0 ? void 0 : _a.env; });
|
|
@@ -55,6 +57,10 @@ export const useHomeMenu = () => {
|
|
|
55
57
|
var _a;
|
|
56
58
|
return getMenuItem(Object.assign(Object.assign({}, appMenuItem), { children: (_a = appMenuItem === null || appMenuItem === void 0 ? void 0 : appMenuItem.children) === null || _a === void 0 ? void 0 : _a.map(item => (Object.assign(Object.assign({}, item), { options: Object.values(CONFIG_OPTIONS), optionCallback: onOptionCallback }))) }));
|
|
57
59
|
}), [appMenuChildren, onOptionCallback]);
|
|
60
|
+
const customHoverChildren = useMemo(() => appHoverMenuChildren === null || appHoverMenuChildren === void 0 ? void 0 : appHoverMenuChildren.map(appMenuItem => {
|
|
61
|
+
var _a;
|
|
62
|
+
return getMenuItem(Object.assign(Object.assign({}, appMenuItem), { children: (_a = appMenuItem === null || appMenuItem === void 0 ? void 0 : appMenuItem.children) === null || _a === void 0 ? void 0 : _a.map(item => (Object.assign(Object.assign({}, item), { options: Object.values(CONFIG_OPTIONS), optionCallback: onOptionCallback }))) }));
|
|
63
|
+
}), [appHoverMenuChildren, onOptionCallback]);
|
|
58
64
|
const onCreateNewReport = useCallback(e => {
|
|
59
65
|
if (onClickCreateDashboard) {
|
|
60
66
|
onClickCreateDashboard(e);
|
|
@@ -110,7 +116,7 @@ export const useHomeMenu = () => {
|
|
|
110
116
|
navigate,
|
|
111
117
|
]);
|
|
112
118
|
return {
|
|
113
|
-
children: customChildren,
|
|
119
|
+
children: isHover ? customHoverChildren : customChildren,
|
|
114
120
|
removedDashboardId,
|
|
115
121
|
isDashboardRemoving,
|
|
116
122
|
isRecommendation,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Libraries
|
|
2
|
-
import React, { memo, useLayoutEffect, useState } from 'react';
|
|
2
|
+
import React, { memo, useLayoutEffect, useMemo, useState } from 'react';
|
|
3
3
|
import Icon from '@antscorp/icons';
|
|
4
4
|
import { isEmpty, isNil, uniq } from 'lodash';
|
|
5
5
|
import classNames from 'classnames';
|
|
6
6
|
import { Link } from 'react-router-dom';
|
|
7
|
+
import { Cookies } from 'react-cookie';
|
|
7
8
|
// Components
|
|
8
9
|
import { Dropdown, Menu } from 'antd';
|
|
9
10
|
import { MenuItemImage } from './components';
|
|
@@ -18,10 +19,10 @@ import { findActiveAppCodeByUrl, findLastMatchedItemByUrl, getMenuItem } from '.
|
|
|
18
19
|
import { findItemByPermissionCode, recursiveFindItemByKey, recursiveFindParentOfActiveItem, } from './utils';
|
|
19
20
|
// Hooks
|
|
20
21
|
import { useNavigatePath } from '../../../hooks';
|
|
22
|
+
import { useDeepCompareEffect } from '@antscorp/antsomi-ui/es/hooks';
|
|
21
23
|
// Contexts
|
|
22
24
|
import { useLeftMenuContext } from '../../../contexts';
|
|
23
25
|
import { MARKETING_CHANNEL_CODE } from '@antscorp/antsomi-ui/es/components/template/Layout/constants';
|
|
24
|
-
import { useDeepCompareEffect } from '@antscorp/antsomi-ui/es/hooks';
|
|
25
26
|
const noDashboardItem = {
|
|
26
27
|
key: 'no_dashboard',
|
|
27
28
|
label: 'No dashboard available',
|
|
@@ -38,8 +39,9 @@ const styles = {
|
|
|
38
39
|
menuItemTitle: { flex: '1 1 0%', maxWidth: '100%', overflow: 'hidden' },
|
|
39
40
|
};
|
|
40
41
|
export const ChildMenu = memo(props => {
|
|
41
|
-
var _a;
|
|
42
|
+
var _a, _b;
|
|
42
43
|
const { items = [], onMenuClick } = props;
|
|
44
|
+
const cookies = useMemo(() => new Cookies(), []);
|
|
43
45
|
const auth = useLeftMenuContext(store => { var _a; return (_a = store.appConfig) === null || _a === void 0 ? void 0 : _a.auth; });
|
|
44
46
|
const env = useLeftMenuContext(store => { var _a; return (_a = store.appConfig) === null || _a === void 0 ? void 0 : _a.env; });
|
|
45
47
|
const activeAppCode = useLeftMenuContext(store => store.activeAppCode);
|
|
@@ -47,17 +49,20 @@ export const ChildMenu = memo(props => {
|
|
|
47
49
|
const customItems = useLeftMenuContext(store => store.customItems);
|
|
48
50
|
const isCustomized = useLeftMenuContext(store => store.isCustomized);
|
|
49
51
|
const isRecommendation = useLeftMenuContext(store => store.isRecommendation);
|
|
52
|
+
const customActiveAppKey = useLeftMenuContext(store => store.customActiveAppKey);
|
|
50
53
|
const customActiveCurrentKey = useLeftMenuContext(store => store.customActiveCurrentKey);
|
|
51
54
|
const setLeftMenuState = useLeftMenuContext(store => store.setState);
|
|
52
|
-
const
|
|
53
|
-
const
|
|
55
|
+
const activeApp = useMemo(() => (isCustomized ? customActiveAppKey : activeAppCode), [activeAppCode, customActiveAppKey, isCustomized]);
|
|
56
|
+
const leftMenuCookies = cookies.get('_leftmenu_state');
|
|
57
|
+
const openMenuKeys = ((_b = (_a = cookies.get('_leftmenu_state')) === null || _a === void 0 ? void 0 : _a.openMenuKeys) === null || _b === void 0 ? void 0 : _b[activeApp]) || [];
|
|
54
58
|
const [currentActiveItem, setCurrentActiveItem] = useState('');
|
|
55
59
|
const [openKeys, setOpenKeys] = useState(openMenuKeys);
|
|
56
60
|
const { pathname, hash } = window.location;
|
|
57
61
|
const { isPushDifferentDomain, getPath, navigatePath } = useNavigatePath();
|
|
58
62
|
useLayoutEffect(() => {
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
if (activeApp)
|
|
64
|
+
cookies.set('_leftmenu_state', Object.assign(Object.assign({}, leftMenuCookies), { openMenuKeys: Object.assign(Object.assign({}, leftMenuCookies === null || leftMenuCookies === void 0 ? void 0 : leftMenuCookies.openMenuKeys), { [activeApp]: uniq(openKeys === null || openKeys === void 0 ? void 0 : openKeys.filter(item => item !== activeApp)) }) }));
|
|
65
|
+
}, [activeApp, cookies, leftMenuCookies, openKeys]);
|
|
61
66
|
useDeepCompareEffect(() => {
|
|
62
67
|
var _a;
|
|
63
68
|
switch (true) {
|
|
@@ -69,7 +74,7 @@ export const ChildMenu = memo(props => {
|
|
|
69
74
|
menuItems: customItems,
|
|
70
75
|
});
|
|
71
76
|
if (parentKey) {
|
|
72
|
-
setOpenKeys(prev => [...prev, parentKey]);
|
|
77
|
+
setOpenKeys(prev => uniq([...prev, parentKey]));
|
|
73
78
|
}
|
|
74
79
|
break;
|
|
75
80
|
}
|
|
@@ -129,7 +134,7 @@ export const ChildMenu = memo(props => {
|
|
|
129
134
|
menuItems: menuItems === null || menuItems === void 0 ? void 0 : menuItems.map(item => (Object.assign(Object.assign({}, getMenuItem(item)), { key: (item === null || item === void 0 ? void 0 : item.permission_code) || '' }))),
|
|
130
135
|
});
|
|
131
136
|
if (parentKey) {
|
|
132
|
-
setOpenKeys(prev => [...prev, parentKey]);
|
|
137
|
+
setOpenKeys(prev => uniq([...prev, parentKey]));
|
|
133
138
|
}
|
|
134
139
|
}
|
|
135
140
|
break;
|
|
@@ -151,7 +156,7 @@ export const ChildMenu = memo(props => {
|
|
|
151
156
|
menuItems: menuItems === null || menuItems === void 0 ? void 0 : menuItems.map(item => getMenuItem(item)),
|
|
152
157
|
});
|
|
153
158
|
if (parentKey) {
|
|
154
|
-
setOpenKeys(prev => [...prev, parentKey]);
|
|
159
|
+
setOpenKeys(prev => uniq([...prev, parentKey]));
|
|
155
160
|
}
|
|
156
161
|
// Active App Item having code matching url
|
|
157
162
|
const matchAppCode = findActiveAppCodeByUrl({ menuItems, url, auth });
|
|
@@ -247,6 +252,6 @@ export const ChildMenu = memo(props => {
|
|
|
247
252
|
};
|
|
248
253
|
return (React.createElement(MenuWrapper, null,
|
|
249
254
|
React.createElement(Menu, { selectedKeys: [currentActiveItem], defaultOpenKeys: [currentActiveItem], openKeys: uniq(openKeys), mode: "inline", items: customMenuItems({ items }), inlineIndent: 12, onOpenChange: openKeys => {
|
|
250
|
-
setOpenKeys(openKeys);
|
|
255
|
+
setOpenKeys(uniq(openKeys));
|
|
251
256
|
}, expandIcon: ({ isOpen }) => (React.createElement(Icon, { type: "icon-ants-expand-more", style: Object.assign(Object.assign({}, styles.expandIcon), { transform: `rotate(${isOpen ? '180deg' : '0deg'})` }) })), onClick: onClick })));
|
|
252
257
|
});
|
|
@@ -2,6 +2,7 @@ import { LeftMenuProps } from '..';
|
|
|
2
2
|
interface TState {
|
|
3
3
|
hoverItem: string;
|
|
4
4
|
isExpandMenu: boolean;
|
|
5
|
+
isShowPopover: boolean;
|
|
5
6
|
}
|
|
6
7
|
export declare const useLeftMenu: (props: LeftMenuProps) => {
|
|
7
8
|
state: TState;
|
|
@@ -12,5 +13,6 @@ export declare const useLeftMenu: (props: LeftMenuProps) => {
|
|
|
12
13
|
onMouseEnter: (key: string) => void;
|
|
13
14
|
onMouseLeave: () => void;
|
|
14
15
|
onHoverMenuBar: () => void;
|
|
16
|
+
onShowPopover: (hoverItem?: string) => void;
|
|
15
17
|
};
|
|
16
18
|
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Libraries
|
|
2
|
-
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { isArray, isNil } from 'lodash';
|
|
4
|
+
import { Cookies } from 'react-cookie';
|
|
4
5
|
// Utils
|
|
5
6
|
import { findActiveAppCodeByChild, findActiveAppCodeByUrl, recursiveGetMenuItemByPermission, } from '../utils';
|
|
6
7
|
// Store
|
|
@@ -9,12 +10,11 @@ import { useLeftMenuContext } from '../contexts';
|
|
|
9
10
|
import { DASHBOARD_MODULE_CONFIG } from '../../../template/Layout/constants';
|
|
10
11
|
// Hooks
|
|
11
12
|
import { usePermission } from './usePermission';
|
|
12
|
-
import { Cookies } from 'react-cookie';
|
|
13
13
|
import { useDeepCompareEffect } from '@antscorp/antsomi-ui/es/hooks';
|
|
14
14
|
export const useLeftMenu = (props) => {
|
|
15
15
|
// Props
|
|
16
16
|
const { objectType = DASHBOARD_MODULE_CONFIG.objectType, objectId = DASHBOARD_MODULE_CONFIG.objectId, isGrouped = DASHBOARD_MODULE_CONFIG.isGrouped, appConfig, customization, onActiveMenuCodeChange, } = props;
|
|
17
|
-
const {
|
|
17
|
+
const { expandMenu = false, isCustomized = false, isRecommendation = false, items, activeKey, onMenuItemClick, } = customization || {};
|
|
18
18
|
const mappedActiveKey = useMemo(() => {
|
|
19
19
|
if (!isRecommendation)
|
|
20
20
|
return activeKey;
|
|
@@ -32,16 +32,18 @@ export const useLeftMenu = (props) => {
|
|
|
32
32
|
return activeKey;
|
|
33
33
|
}
|
|
34
34
|
}, [activeKey, isRecommendation]);
|
|
35
|
-
const
|
|
35
|
+
const cookies = new Cookies();
|
|
36
36
|
const { pathname, hash, origin } = window.location;
|
|
37
37
|
const activeAppCode = useLeftMenuContext(store => store.activeAppCode);
|
|
38
38
|
const customActiveAppKey = useLeftMenuContext(store => store.customActiveAppKey);
|
|
39
39
|
const setLeftMenuContextState = useLeftMenuContext(store => store.setState);
|
|
40
40
|
const { auth, env } = appConfig || {};
|
|
41
|
-
const
|
|
41
|
+
const timeoutPopover = useRef(null);
|
|
42
|
+
const leftMenuCookies = cookies.get('_leftmenu_state');
|
|
42
43
|
const isOpenMenu = !isNil(leftMenuCookies === null || leftMenuCookies === void 0 ? void 0 : leftMenuCookies.expand) ? leftMenuCookies === null || leftMenuCookies === void 0 ? void 0 : leftMenuCookies.expand : true;
|
|
43
44
|
const [state, setState] = useState({
|
|
44
45
|
hoverItem: '',
|
|
46
|
+
isShowPopover: false,
|
|
45
47
|
isExpandMenu: expandMenu || isOpenMenu,
|
|
46
48
|
});
|
|
47
49
|
const { mappingChildrenMenu, flattenMenuPermission, permissionMenu, activeItemPath } = usePermission();
|
|
@@ -53,7 +55,7 @@ export const useLeftMenu = (props) => {
|
|
|
53
55
|
}, [customActiveAppKey, isRecommendation, onMenuItemClick, setLeftMenuContextState]);
|
|
54
56
|
useDeepCompareEffect(() => {
|
|
55
57
|
if (!expandMenu) {
|
|
56
|
-
|
|
58
|
+
cookies.set('_leftmenu_state', Object.assign(Object.assign({}, leftMenuCookies), { expand: state.isExpandMenu }));
|
|
57
59
|
// const domain = '.antsomi.com';
|
|
58
60
|
// const cookieValue = {
|
|
59
61
|
// ...leftMenuCookies,
|
|
@@ -119,25 +121,27 @@ export const useLeftMenu = (props) => {
|
|
|
119
121
|
]);
|
|
120
122
|
// Change list menu children when hovering or activating items, giving priority to hovering items
|
|
121
123
|
useDeepCompareEffect(() => {
|
|
122
|
-
var _a, _b, _c;
|
|
123
|
-
const appActiveKey =
|
|
124
|
-
? state.hoverItem
|
|
125
|
-
: isCustomized || isRecommendation
|
|
126
|
-
? customActiveAppKey
|
|
127
|
-
: activeAppCode;
|
|
124
|
+
var _a, _b, _c, _d, _e, _f;
|
|
125
|
+
const appActiveKey = isCustomized || isRecommendation ? customActiveAppKey : activeAppCode;
|
|
128
126
|
switch (true) {
|
|
129
127
|
case isCustomized: {
|
|
130
128
|
setLeftMenuContextState({
|
|
131
129
|
customItems: items,
|
|
132
130
|
customMenuChildren: ((_a = items === null || items === void 0 ? void 0 : items.find(item => item.key === appActiveKey)) === null || _a === void 0 ? void 0 : _a.children) || [],
|
|
131
|
+
customHoverMenuChildren: state.hoverItem
|
|
132
|
+
? ((_b = items === null || items === void 0 ? void 0 : items.find(item => item.key === state.hoverItem)) === null || _b === void 0 ? void 0 : _b.children) || []
|
|
133
|
+
: [],
|
|
133
134
|
});
|
|
134
135
|
break;
|
|
135
136
|
}
|
|
136
137
|
case isRecommendation: {
|
|
137
138
|
setLeftMenuContextState({
|
|
138
139
|
menuItems: mappingChildrenMenu,
|
|
139
|
-
appMenuChildren: ((
|
|
140
|
+
appMenuChildren: ((_c = mappingChildrenMenu === null || mappingChildrenMenu === void 0 ? void 0 : mappingChildrenMenu.find(item => item.permission_code === appActiveKey)) === null || _c === void 0 ? void 0 : _c.children) ||
|
|
140
141
|
[],
|
|
142
|
+
appHoverMenuChildren: state.hoverItem
|
|
143
|
+
? ((_d = mappingChildrenMenu === null || mappingChildrenMenu === void 0 ? void 0 : mappingChildrenMenu.find(item => item.permission_code === state.hoverItem)) === null || _d === void 0 ? void 0 : _d.children) || []
|
|
144
|
+
: [],
|
|
141
145
|
});
|
|
142
146
|
break;
|
|
143
147
|
}
|
|
@@ -145,8 +149,11 @@ export const useLeftMenu = (props) => {
|
|
|
145
149
|
if (isArray(mappingChildrenMenu)) {
|
|
146
150
|
setLeftMenuContextState({
|
|
147
151
|
menuItems: mappingChildrenMenu,
|
|
148
|
-
appMenuChildren: ((
|
|
152
|
+
appMenuChildren: ((_e = mappingChildrenMenu === null || mappingChildrenMenu === void 0 ? void 0 : mappingChildrenMenu.find(item => item.menu_item_code === appActiveKey)) === null || _e === void 0 ? void 0 : _e.children) ||
|
|
149
153
|
[],
|
|
154
|
+
appHoverMenuChildren: state.hoverItem
|
|
155
|
+
? ((_f = mappingChildrenMenu === null || mappingChildrenMenu === void 0 ? void 0 : mappingChildrenMenu.find(item => item.menu_item_code === state.hoverItem)) === null || _f === void 0 ? void 0 : _f.children) || []
|
|
156
|
+
: [],
|
|
150
157
|
});
|
|
151
158
|
}
|
|
152
159
|
break;
|
|
@@ -204,24 +211,38 @@ export const useLeftMenu = (props) => {
|
|
|
204
211
|
isRecommendation,
|
|
205
212
|
onActiveMenuCodeChange,
|
|
206
213
|
]);
|
|
214
|
+
useEffect(() => clearTimeout(timeoutPopover === null || timeoutPopover === void 0 ? void 0 : timeoutPopover.current), [timeoutPopover]);
|
|
215
|
+
const onShowPopover = useCallback((hoverItem) => {
|
|
216
|
+
if (timeoutPopover)
|
|
217
|
+
clearTimeout(timeoutPopover === null || timeoutPopover === void 0 ? void 0 : timeoutPopover.current);
|
|
218
|
+
if (!state.isShowPopover)
|
|
219
|
+
setState(prev => (Object.assign(Object.assign({}, prev), { isShowPopover: true })));
|
|
220
|
+
if (hoverItem)
|
|
221
|
+
setState(prev => (Object.assign(Object.assign({}, prev), { hoverItem })));
|
|
222
|
+
}, [state.isShowPopover]);
|
|
207
223
|
const onToggleChildMenu = useCallback(() => {
|
|
208
224
|
setState(prev => (Object.assign(Object.assign({}, prev), { isExpandMenu: !prev.isExpandMenu })));
|
|
209
225
|
}, []);
|
|
210
226
|
const onMouseEnter = useCallback((key) => {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
227
|
+
if (state.hoverItem !== key) {
|
|
228
|
+
onShowPopover(key);
|
|
229
|
+
// if (!state.isExpandMenu || !isExpandable) {
|
|
230
|
+
// setState(prev => ({ ...prev, hoverItem: key }));
|
|
231
|
+
// }
|
|
232
|
+
}
|
|
233
|
+
}, [state.hoverItem, onShowPopover]);
|
|
216
234
|
const onMouseLeave = useCallback(() => {
|
|
217
|
-
|
|
235
|
+
timeoutPopover.current = setTimeout(() => {
|
|
236
|
+
setState(prev => (Object.assign(Object.assign({}, prev), { hoverItem: '' })));
|
|
237
|
+
setState(prev => (Object.assign(Object.assign({}, prev), { isShowPopover: false })));
|
|
238
|
+
}, 500);
|
|
218
239
|
// if (!state.isExpandMenu || !isExpandable) {
|
|
219
240
|
// setState(prev => ({ ...prev, hoverItem: '' }));
|
|
220
241
|
// }
|
|
221
242
|
}, []);
|
|
222
|
-
const onHoverMenuBar = () => {
|
|
243
|
+
const onHoverMenuBar = useCallback(() => {
|
|
223
244
|
onMouseEnter(isCustomized ? customActiveAppKey : activeAppCode);
|
|
224
|
-
};
|
|
245
|
+
}, [activeAppCode, customActiveAppKey, isCustomized, onMouseEnter]);
|
|
225
246
|
return {
|
|
226
247
|
state,
|
|
227
248
|
activeAppCode,
|
|
@@ -231,5 +252,6 @@ export const useLeftMenu = (props) => {
|
|
|
231
252
|
onMouseEnter,
|
|
232
253
|
onMouseLeave,
|
|
233
254
|
onHoverMenuBar,
|
|
255
|
+
onShowPopover,
|
|
234
256
|
};
|
|
235
257
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// Libraries
|
|
2
|
-
import { useContextSelector } from 'use-context-selector';
|
|
3
2
|
import { useCallback, useMemo } from 'react';
|
|
4
3
|
import { isNil } from 'lodash';
|
|
5
4
|
import { useLocation } from 'react-router-dom';
|
|
5
|
+
import { useDeepCompareMemo } from '@antscorp/antsomi-ui/es/hooks';
|
|
6
6
|
// Contexts
|
|
7
|
-
import {
|
|
7
|
+
import { useLeftMenuContext } from '../contexts';
|
|
8
8
|
// Utils
|
|
9
9
|
import { getGeneratePath } from '../utils';
|
|
10
10
|
import { hasSelectAccountPermission } from '../../../template/Layout/utils';
|
|
@@ -13,11 +13,12 @@ import { ENV } from '@antscorp/antsomi-ui/es/config';
|
|
|
13
13
|
// Hooks
|
|
14
14
|
import { usePermission } from './usePermission';
|
|
15
15
|
export const useNavigatePath = () => {
|
|
16
|
-
const
|
|
16
|
+
const appConfig = useLeftMenuContext(store => store.appConfig);
|
|
17
|
+
const { auth, env } = appConfig || {};
|
|
17
18
|
const { search } = useLocation();
|
|
18
19
|
const isDev = env === ENV.DEV;
|
|
19
20
|
const { activeItemPath, flattenMenuPermission } = usePermission();
|
|
20
|
-
const hasRole =
|
|
21
|
+
const hasRole = useDeepCompareMemo(() => hasSelectAccountPermission(activeItemPath, flattenMenuPermission), [activeItemPath, flattenMenuPermission]);
|
|
21
22
|
const urlParams = useMemo(() => new URLSearchParams(search), [search]);
|
|
22
23
|
const oidParam = hasRole ? urlParams.get('oid') : null;
|
|
23
24
|
const searchParams = oidParam ? `?oid=${oidParam}` : '';
|
|
@@ -8,7 +8,9 @@ export interface LeftMenuStoreProps {
|
|
|
8
8
|
menuItems: TFeatureMenu[];
|
|
9
9
|
customItems: TMenuItem[];
|
|
10
10
|
customMenuChildren: TMenuItem[];
|
|
11
|
+
customHoverMenuChildren: TMenuItem[];
|
|
11
12
|
appMenuChildren: TFeatureMenu[];
|
|
13
|
+
appHoverMenuChildren: TFeatureMenu[];
|
|
12
14
|
appConfig?: AppConfigProviderProps;
|
|
13
15
|
isCustomized?: boolean;
|
|
14
16
|
isRecommendation?: boolean;
|
|
@@ -6,8 +6,10 @@ const DEFAULT_PROPS = {
|
|
|
6
6
|
customActiveCurrentKey: '',
|
|
7
7
|
menuItems: [],
|
|
8
8
|
appMenuChildren: [],
|
|
9
|
+
appHoverMenuChildren: [],
|
|
9
10
|
customItems: [],
|
|
10
11
|
customMenuChildren: [],
|
|
12
|
+
customHoverMenuChildren: [],
|
|
11
13
|
isCustomized: false,
|
|
12
14
|
isRecommendation: false,
|
|
13
15
|
dashboardParams: {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
export declare const IconWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
3
|
-
export declare const PopoverWrapper: import("styled-components").StyledComponent<"div", any, {
|
|
3
|
+
export declare const PopoverWrapper: import("styled-components").StyledComponent<"div", any, {
|
|
4
|
+
show: boolean;
|
|
5
|
+
}, never>;
|
|
4
6
|
export declare const FeatureMenuWrapper: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("antd/es/flex/interface").FlexProps<import("antd/es/_util/type").AnyObject> & import("react").RefAttributes<HTMLElement>>, any, {}, never>;
|
|
5
7
|
export declare const ExpandWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
6
8
|
export declare const LeftMenuNavWrapper: import("styled-components").StyledComponent<"div", any, {
|
|
@@ -19,8 +19,16 @@ export const IconWrapper = styled.div `
|
|
|
19
19
|
}
|
|
20
20
|
`;
|
|
21
21
|
export const PopoverWrapper = styled.div `
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
${({ show }) => show
|
|
23
|
+
? `
|
|
24
|
+
opacity: 1;
|
|
25
|
+
visibility: visible;
|
|
26
|
+
`
|
|
27
|
+
: `
|
|
28
|
+
opacity: 0;
|
|
29
|
+
visibility: hidden;
|
|
30
|
+
`}
|
|
31
|
+
|
|
24
32
|
position: absolute;
|
|
25
33
|
background-color: white;
|
|
26
34
|
left: 65px;
|
|
@@ -36,13 +44,6 @@ export const PopoverWrapper = styled.div `
|
|
|
36
44
|
export const FeatureMenuWrapper = styled(Flex) `
|
|
37
45
|
flex: 1 1 0%;
|
|
38
46
|
overflow: hidden;
|
|
39
|
-
|
|
40
|
-
&:hover {
|
|
41
|
-
${PopoverWrapper} {
|
|
42
|
-
visibility: visible;
|
|
43
|
-
opacity: 1;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
47
|
`;
|
|
47
48
|
export const ExpandWrapper = styled.div `
|
|
48
49
|
height: 35px;
|