@antscorp/antsomi-ui 1.3.5-beta.291 → 1.3.5-beta.293
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/HeaderV2/HeaderV2.js +1 -3
- package/es/components/organism/LeftMenu/components/HomeMenu/index.js +2 -2
- package/es/components/organism/LeftMenu/components/HomeMenu/styled.js +1 -0
- package/es/components/organism/LeftMenu/components/HomeMenu/useHomeMenu.d.ts +2 -1
- package/es/components/organism/LeftMenu/components/HomeMenu/useHomeMenu.js +13 -24
- package/es/components/organism/LeftMenu/components/common/ChildMenu/index.js +39 -34
- package/es/components/organism/LeftMenu/components/common/ChildMenu/styled.d.ts +3 -1
- package/es/components/organism/LeftMenu/components/common/ChildMenu/styled.js +87 -27
- package/es/components/organism/LeftMenu/hooks/useLeftMenu.d.ts +0 -1
- package/es/components/organism/LeftMenu/hooks/useLeftMenu.js +39 -49
- package/es/components/organism/LeftMenu/index.js +6 -20
- package/es/components/organism/LeftMenu/styled.js +1 -2
- package/es/components/organism/LeftMenu/utils/index.d.ts +1 -1
- package/es/components/organism/LeftMenu/utils/index.js +12 -7
- package/es/components/template/Layout/Layout.js +10 -4
- package/es/components/template/Layout/constants/permission.d.ts +0 -3
- package/es/components/template/Layout/constants/permission.js +0 -3
- package/es/components/template/Layout/stores/index.d.ts +6 -0
- package/es/components/template/Layout/stores/index.js +12 -0
- package/es/components/template/Layout/utils/permission.d.ts +1 -1
- package/es/components/template/TemplateListing/components/CategoryListing/index.js +1 -7
- package/es/components/template/TemplateListing/index.js +0 -4
- package/es/hooks/index.d.ts +3 -0
- package/es/hooks/index.js +3 -0
- package/es/hooks/useEventListener.d.ts +6 -0
- package/es/hooks/useEventListener.js +28 -0
- package/es/hooks/useListingItemResize.js +19 -40
- package/es/hooks/useWindowSize.d.ts +11 -0
- package/es/hooks/useWindowSize.js +35 -0
- package/package.json +1 -1
|
@@ -28,14 +28,13 @@ export const HeaderV2 = memo(props => {
|
|
|
28
28
|
const { auth, env: envContext, languageCode = 'en', appCode: contextAppCode, urlLogout: urlLogoutProvider = '', menuCode: contextMenuCode, } = useContextSelector(AppConfigContext, state => state);
|
|
29
29
|
const { search } = useLocation();
|
|
30
30
|
const history = useHistory();
|
|
31
|
-
|
|
31
|
+
// * Prefer to use Header in AppConfigContext
|
|
32
32
|
const { className, style, breadcrumbs, pageTitle = '', accountSelection = {}, helpConfig, notificationConfig = {}, accountSharingConfig, useURLParam, config, } = props;
|
|
33
33
|
/** General config for children component */
|
|
34
34
|
const { env = envContext, language = languageCode, userId = isNaN(Number(auth === null || auth === void 0 ? void 0 : auth.userId)) ? 0 : Number(auth === null || auth === void 0 ? void 0 : auth.userId), portalId = auth === null || auth === void 0 ? void 0 : auth.portalId, token = auth === null || auth === void 0 ? void 0 : auth.token, permissionDomain = PERMISSION_API, iamDomain = IAM_API, appCode = contextAppCode, menuCode = contextMenuCode, } = config || {};
|
|
35
35
|
const { currentAccount, inputStyle = 'select', onSelectAccount } = accountSelection, accountSelectionProps = __rest(accountSelection, ["currentAccount", "inputStyle", "onSelectAccount"]);
|
|
36
36
|
const urlParams = useMemo(() => new URLSearchParams(search), [search]);
|
|
37
37
|
const oidParam = (_a = urlParams.get('oid')) !== null && _a !== void 0 ? _a : 'all';
|
|
38
|
-
// States
|
|
39
38
|
const [selectedAccount, setSelectedAccount] = useState(`${useURLParam ? oidParam : `${(_b = currentAccount !== null && currentAccount !== void 0 ? currentAccount : userId) !== null && _b !== void 0 ? _b : 'all'}`}`);
|
|
40
39
|
// Memo
|
|
41
40
|
const accountSelectionDomain = useMemo(() => {
|
|
@@ -85,7 +84,6 @@ export const HeaderV2 = memo(props => {
|
|
|
85
84
|
token,
|
|
86
85
|
lang: language,
|
|
87
86
|
};
|
|
88
|
-
// Handlers
|
|
89
87
|
const handleChangeAccount = (userId) => {
|
|
90
88
|
setSelectedAccount(userId);
|
|
91
89
|
if (useURLParam) {
|
|
@@ -10,9 +10,9 @@ import { CreateButton, HomeMenuWrapper } from './styled';
|
|
|
10
10
|
// Hooks
|
|
11
11
|
import { useHomeMenu } from './useHomeMenu';
|
|
12
12
|
export const HomeMenu = memo(() => {
|
|
13
|
-
// Handlers
|
|
14
13
|
const { children, onCreateNewReport, onMenuClick } = useHomeMenu();
|
|
15
|
-
|
|
14
|
+
// console.log({});
|
|
15
|
+
return (React.createElement(HomeMenuWrapper, { gap: 10, vertical: true },
|
|
16
16
|
React.createElement(CreateButton, { type: "primary", onClick: onCreateNewReport },
|
|
17
17
|
React.createElement(Flex, { gap: 10, align: "center" },
|
|
18
18
|
React.createElement(Icon, { type: "icon-ants-plus-slim", style: { fontSize: 14 } }),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
1
2
|
export declare const useHomeMenu: () => {
|
|
2
3
|
children: import("@antscorp/antsomi-ui/es/components/organism/LeftMenu/types").TMenuItem[];
|
|
3
|
-
onCreateNewReport: ()
|
|
4
|
+
onCreateNewReport: import("react").MouseEventHandler<HTMLElement>;
|
|
4
5
|
onOptionCallback: (args: {
|
|
5
6
|
menuItemKey: string;
|
|
6
7
|
optionKey: string;
|
|
@@ -8,29 +8,14 @@ import { HOME_REPORT_ROUTES, HOME_ROUTE } from '../../constants';
|
|
|
8
8
|
import { getGeneratePath, getMenuItem } from '../../utils';
|
|
9
9
|
// Types
|
|
10
10
|
import { useLeftMenuStore } from '../../stores';
|
|
11
|
+
import { useLayoutStore } from '@antscorp/antsomi-ui/es/components/template';
|
|
11
12
|
export const useHomeMenu = () => {
|
|
12
|
-
|
|
13
|
-
const { pathname, hash, search } = window.location;
|
|
13
|
+
const { pathname, search } = window.location;
|
|
14
14
|
const history = useHistory();
|
|
15
|
-
// Stores
|
|
16
15
|
const appMenuChildren = useLeftMenuStore(store => store.state.appMenuChildren);
|
|
17
16
|
const auth = useLeftMenuStore(store => { var _a; return (_a = store.state.appConfig) === null || _a === void 0 ? void 0 : _a.auth; });
|
|
18
|
-
|
|
17
|
+
const onClickCreateDashboard = useLayoutStore(store => store.state.leftMenu.onClickCreateDashboard);
|
|
19
18
|
const urlParams = useMemo(() => new URLSearchParams(search), [search]);
|
|
20
|
-
// Handlers
|
|
21
|
-
const handleSetSearchParams = useCallback((searchParam) => {
|
|
22
|
-
const url = `${pathname}${hash}`;
|
|
23
|
-
if (url.includes(getGeneratePath(HOME_ROUTE, Object.assign({}, auth)))) {
|
|
24
|
-
urlParams.set('type', searchParam);
|
|
25
|
-
history.replace({ search: urlParams.toString() });
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
history.push(getGeneratePath(HOME_ROUTE, Object.assign({}, auth)));
|
|
29
|
-
urlParams.set('type', searchParam);
|
|
30
|
-
history.replace({ search: urlParams.toString() });
|
|
31
|
-
}
|
|
32
|
-
}, [auth, hash, history, pathname, urlParams]);
|
|
33
|
-
// Memos
|
|
34
19
|
const onOptionCallback = useCallback((args) => {
|
|
35
20
|
const { optionKey, menuItemKey } = args;
|
|
36
21
|
switch (optionKey) {
|
|
@@ -51,12 +36,16 @@ export const useHomeMenu = () => {
|
|
|
51
36
|
var _a;
|
|
52
37
|
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 }))) }));
|
|
53
38
|
}), [appMenuChildren, onOptionCallback]);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
39
|
+
const onCreateNewReport = useCallback(e => {
|
|
40
|
+
if (onClickCreateDashboard) {
|
|
41
|
+
onClickCreateDashboard(e);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
history.push(getGeneratePath(HOME_ROUTE, auth));
|
|
45
|
+
urlParams.set('type', HOME_REPORT_ROUTES.CREATE);
|
|
46
|
+
history.replace({ search: urlParams.toString() });
|
|
47
|
+
}
|
|
48
|
+
}, [auth, history, onClickCreateDashboard, urlParams]);
|
|
60
49
|
const onMenuClick = useCallback((key, _) => {
|
|
61
50
|
const newPathName = getGeneratePath(HOME_REPORT_ROUTES.DETAIL, Object.assign(Object.assign({}, auth), { dashboardId: key }));
|
|
62
51
|
if (newPathName !== pathname) {
|
|
@@ -6,10 +6,10 @@ import classNames from 'classnames';
|
|
|
6
6
|
import { Link } from 'react-router-dom';
|
|
7
7
|
// Components
|
|
8
8
|
import { Dropdown, Menu } from 'antd';
|
|
9
|
-
import { Flex } from '../../../../../atoms';
|
|
10
9
|
import { MenuItemImage } from './components';
|
|
10
|
+
import { Flex } from '../../../../../atoms';
|
|
11
11
|
// Styled
|
|
12
|
-
import { LabelCustom, MenuWrapper } from './styled';
|
|
12
|
+
import { LabelCustom, LabelWrapper, MenuWrapper, OptionDropdownWrapper } from './styled';
|
|
13
13
|
import { IconWrapper } from '../../../styled';
|
|
14
14
|
// Constants
|
|
15
15
|
import { ICON_SIZE } from '../../../constants';
|
|
@@ -19,9 +19,17 @@ import { recursiveFindParentOfActiveItem } from './utils';
|
|
|
19
19
|
// Hooks
|
|
20
20
|
import { useLeftMenuStore } from '../../../stores';
|
|
21
21
|
import { useNavigatePath } from '../../../hooks';
|
|
22
|
+
const styles = {
|
|
23
|
+
dropdownMenu: { width: '130px', padding: '8px 0' },
|
|
24
|
+
icon: { marginTop: '2px', zIndex: 1000, flexShrink: 0 },
|
|
25
|
+
expandIcon: {
|
|
26
|
+
fontSize: ICON_SIZE,
|
|
27
|
+
color: 'inherit',
|
|
28
|
+
},
|
|
29
|
+
menuItemTitle: { flex: '1 1 0%', maxWidth: '100%' },
|
|
30
|
+
};
|
|
22
31
|
export const ChildMenu = memo(props => {
|
|
23
32
|
const { items = [], onMenuClick } = props;
|
|
24
|
-
// Stores
|
|
25
33
|
const auth = useLeftMenuStore(store => { var _a; return (_a = store.state.appConfig) === null || _a === void 0 ? void 0 : _a.auth; });
|
|
26
34
|
const activeAppCode = useLeftMenuStore(store => store.state.activeAppCode);
|
|
27
35
|
const menuItems = useLeftMenuStore(store => store.state.menuItems);
|
|
@@ -29,18 +37,15 @@ export const ChildMenu = memo(props => {
|
|
|
29
37
|
const isCustomized = useLeftMenuStore(store => store.state.isCustomized);
|
|
30
38
|
const customActiveCurrentKey = useLeftMenuStore(store => store.state.customActiveCurrentKey);
|
|
31
39
|
const setLeftMenuState = useLeftMenuStore(store => store.setState);
|
|
32
|
-
// States
|
|
33
40
|
const [currentActiveItem, setCurrentActiveItem] = useState('');
|
|
34
41
|
const [openKeys, setOpenKeys] = useState([]);
|
|
35
|
-
// Hooks
|
|
36
42
|
const { pathname, hash } = window.location;
|
|
37
43
|
const { isPushDifferentDomain, getPath, navigatePath } = useNavigatePath();
|
|
38
|
-
// Side Effects
|
|
39
44
|
useEffect(() => {
|
|
40
45
|
var _a;
|
|
41
46
|
if (isCustomized) {
|
|
42
47
|
setCurrentActiveItem(customActiveCurrentKey);
|
|
43
|
-
|
|
48
|
+
// Find parent key of active menu item to open it
|
|
44
49
|
const parentKey = recursiveFindParentOfActiveItem({
|
|
45
50
|
activeMenuItem: customActiveCurrentKey,
|
|
46
51
|
menuItems: customItems,
|
|
@@ -51,11 +56,11 @@ export const ChildMenu = memo(props => {
|
|
|
51
56
|
}
|
|
52
57
|
else {
|
|
53
58
|
const url = `${pathname}${hash}`;
|
|
54
|
-
|
|
59
|
+
// Active menu item by current url
|
|
55
60
|
const activeMenuItem = (_a = findLastMatchedItemByUrl({ url, menuItems, auth })) === null || _a === void 0 ? void 0 : _a.menu_item_code;
|
|
56
61
|
if (activeMenuItem && activeMenuItem !== currentActiveItem) {
|
|
57
62
|
setCurrentActiveItem(activeMenuItem);
|
|
58
|
-
|
|
63
|
+
// Find parent key of active menu item to open it
|
|
59
64
|
const parentKey = recursiveFindParentOfActiveItem({
|
|
60
65
|
activeMenuItem,
|
|
61
66
|
menuItems: menuItems === null || menuItems === void 0 ? void 0 : menuItems.map(item => getMenuItem(item)),
|
|
@@ -63,7 +68,7 @@ export const ChildMenu = memo(props => {
|
|
|
63
68
|
if (parentKey) {
|
|
64
69
|
setOpenKeys(prev => [...prev, parentKey]);
|
|
65
70
|
}
|
|
66
|
-
|
|
71
|
+
// Active App Item having code matching url
|
|
67
72
|
const matchAppCode = findActiveAppCodeByUrl({ menuItems, url, auth });
|
|
68
73
|
if (matchAppCode && matchAppCode !== activeAppCode) {
|
|
69
74
|
setLeftMenuState({ activeAppCode: matchAppCode });
|
|
@@ -83,43 +88,43 @@ export const ChildMenu = memo(props => {
|
|
|
83
88
|
customActiveCurrentKey,
|
|
84
89
|
customItems,
|
|
85
90
|
]);
|
|
86
|
-
// Handlers
|
|
87
91
|
const onClick = e => {
|
|
88
92
|
onMenuClick === null || onMenuClick === void 0 ? void 0 : onMenuClick(e.key, e.keyPath);
|
|
89
93
|
};
|
|
90
|
-
// Render components
|
|
91
94
|
const customMenuItems = (args) => {
|
|
92
95
|
var _a;
|
|
93
96
|
return (_a = args === null || args === void 0 ? void 0 : args.items) === null || _a === void 0 ? void 0 : _a.map(item => {
|
|
94
|
-
var _a;
|
|
95
97
|
const { key, label, children, icon, logo_url, menu_item_path = null, menu_item_domain = null, options, optionCallback, } = item;
|
|
96
|
-
const
|
|
97
|
-
React.createElement(LabelCustom, { ellipsis: { tooltip: label } }, label),
|
|
98
|
-
React.createElement(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
e
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
98
|
+
const renderLabel = () => (!children || isEmpty(children)) && !isEmpty(options) ? (React.createElement(LabelWrapper, null,
|
|
99
|
+
React.createElement(LabelCustom, { ellipsis: { tooltip: label }, style: { flex: '1 1 0%' } }, label),
|
|
100
|
+
React.createElement(OptionDropdownWrapper, null,
|
|
101
|
+
React.createElement(Dropdown, { menu: {
|
|
102
|
+
items: options,
|
|
103
|
+
onClick: e => {
|
|
104
|
+
e.domEvent.stopPropagation();
|
|
105
|
+
e.domEvent.preventDefault();
|
|
106
|
+
optionCallback === null || optionCallback === void 0 ? void 0 : optionCallback({ menuItemKey: key, optionKey: e.key });
|
|
107
|
+
},
|
|
108
|
+
style: styles.dropdownMenu,
|
|
109
|
+
}, trigger: ['click'] },
|
|
110
|
+
React.createElement(Icon, { className: "child-menu-item-icon", type: "icon-ants-three-dot-vertical", style: styles.icon }))))) : (React.createElement(LabelCustom, { ellipsis: { tooltip: label } }, label));
|
|
111
|
+
const renderIcon = () => {
|
|
112
|
+
var _a;
|
|
113
|
+
return !isNil(icon) || !isNil(logo_url) ? (React.createElement(Flex, { style: { flexShrink: 0 }, align: "center" }, !isNil(icon) ? (React.createElement(IconWrapper, null,
|
|
114
|
+
React.createElement(Icon, { type: icon }))) : !isNil(logo_url) ? (React.createElement(MenuItemImage, { imageUrl: logo_url, fallbackIcon: (_a = args === null || args === void 0 ? void 0 : args.parent) === null || _a === void 0 ? void 0 : _a.icon, className: classNames({ isActive: currentActiveItem === key }) })) : null)) : null;
|
|
115
|
+
};
|
|
116
|
+
const renderTitle = () => !menu_item_path ? (renderLabel()) : isPushDifferentDomain(menu_item_domain, menu_item_path) ? (React.createElement("div", { onClick: () => navigatePath(menu_item_domain, menu_item_path), className: "menu-link" }, renderLabel())) : (React.createElement(Link, { to: getPath(menu_item_path), className: "menu-link" }, renderLabel()));
|
|
107
117
|
return {
|
|
108
118
|
key,
|
|
109
|
-
label:
|
|
110
|
-
|
|
111
|
-
React.createElement(
|
|
119
|
+
label: (React.createElement(Flex, { gap: 10, align: "center", justify: "space-between", style: { height: '100%' } },
|
|
120
|
+
renderIcon(),
|
|
121
|
+
React.createElement(Flex, { style: styles.menuItemTitle, align: "center" }, renderTitle()))),
|
|
112
122
|
children: customMenuItems({ parent: item, items: children }),
|
|
113
123
|
};
|
|
114
124
|
});
|
|
115
125
|
};
|
|
116
126
|
return (React.createElement(MenuWrapper, null,
|
|
117
|
-
React.createElement(Menu, { selectedKeys: [currentActiveItem], defaultOpenKeys: [currentActiveItem], openKeys: uniq(openKeys), mode: "inline", items: customMenuItems({ items }), inlineIndent:
|
|
127
|
+
React.createElement(Menu, { selectedKeys: [currentActiveItem], defaultOpenKeys: [currentActiveItem], openKeys: uniq(openKeys), mode: "inline", items: customMenuItems({ items }), inlineIndent: 12, onOpenChange: openKeys => {
|
|
118
128
|
setOpenKeys(openKeys);
|
|
119
|
-
}, expandIcon: ({ isOpen }) => (React.createElement(Icon, { type: "icon-ants-expand-more", style: {
|
|
120
|
-
fontSize: ICON_SIZE,
|
|
121
|
-
color: 'inherit',
|
|
122
|
-
// color: THEME.token?.bw8,
|
|
123
|
-
transform: `rotate(${isOpen ? '180deg' : '0deg'})`,
|
|
124
|
-
} })), onClick: onClick })));
|
|
129
|
+
}, expandIcon: ({ isOpen }) => (React.createElement(Icon, { type: "icon-ants-expand-more", style: Object.assign(Object.assign({}, styles.expandIcon), { transform: `rotate(${isOpen ? '180deg' : '0deg'})` }) })), onClick: onClick })));
|
|
125
130
|
});
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const LabelWrapper: 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>;
|
|
3
3
|
export declare const LabelCustom: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("antd/es/typography/Text").TextProps & import("react").RefAttributes<HTMLSpanElement>>, any, {}, never>;
|
|
4
|
+
export declare const OptionDropdownWrapper: 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
|
+
export declare const MenuWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
@@ -1,11 +1,27 @@
|
|
|
1
|
-
var _a;
|
|
1
|
+
var _a, _b;
|
|
2
2
|
// Libraries
|
|
3
3
|
import styled from 'styled-components';
|
|
4
4
|
// Components
|
|
5
|
-
import { Typography } from '../../../../../atoms';
|
|
5
|
+
import { Flex, Typography } from '../../../../../atoms';
|
|
6
6
|
// Constants
|
|
7
7
|
import { THEME } from '@antscorp/antsomi-ui/es/constants';
|
|
8
8
|
import { ICON_SIZE } from '../../../constants';
|
|
9
|
+
export const LabelWrapper = styled(Flex) `
|
|
10
|
+
width: 100%;
|
|
11
|
+
`;
|
|
12
|
+
LabelWrapper.defaultProps = {
|
|
13
|
+
gap: 10,
|
|
14
|
+
align: 'center',
|
|
15
|
+
justify: 'space-between',
|
|
16
|
+
};
|
|
17
|
+
export const LabelCustom = styled(Typography.Text) `
|
|
18
|
+
font-size: inherit !important;
|
|
19
|
+
color: inherit !important;
|
|
20
|
+
`;
|
|
21
|
+
export const OptionDropdownWrapper = styled(Flex) `
|
|
22
|
+
width: 24px;
|
|
23
|
+
`;
|
|
24
|
+
OptionDropdownWrapper.defaultProps = { align: 'center' };
|
|
9
25
|
export const MenuWrapper = styled.div `
|
|
10
26
|
width: 100%;
|
|
11
27
|
height: 100%;
|
|
@@ -14,15 +30,81 @@ export const MenuWrapper = styled.div `
|
|
|
14
30
|
font-weight: bold !important;
|
|
15
31
|
border-right: none !important;
|
|
16
32
|
|
|
17
|
-
& > ul {
|
|
33
|
+
& > ul.antsomi-menu.antsomi-menu-root {
|
|
18
34
|
height: 100%;
|
|
19
35
|
|
|
20
|
-
li {
|
|
21
|
-
|
|
36
|
+
& > li {
|
|
37
|
+
padding-left: 0px !important;
|
|
38
|
+
|
|
39
|
+
&.antsomi-menu-submenu > [role='menuitem'] {
|
|
40
|
+
margin: 0;
|
|
41
|
+
padding-left: 0px !important;
|
|
42
|
+
width: 100%;
|
|
43
|
+
border-radius: ${(_a = THEME === null || THEME === void 0 ? void 0 : THEME.token) === null || _a === void 0 ? void 0 : _a.borderRadiusXL}px;
|
|
44
|
+
padding-right: 4px !important;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
& li {
|
|
49
|
+
width: 100%;
|
|
50
|
+
margin: 0;
|
|
51
|
+
padding-right: 0px;
|
|
52
|
+
background-color: transparent !important;
|
|
53
|
+
|
|
54
|
+
& .antsomi-menu-title-content {
|
|
55
|
+
width: 100%;
|
|
56
|
+
height: 100%;
|
|
57
|
+
border-radius: ${(_b = THEME === null || THEME === void 0 ? void 0 : THEME.token) === null || _b === void 0 ? void 0 : _b.borderRadiusXL}px;
|
|
58
|
+
padding: 0 8px;
|
|
59
|
+
|
|
60
|
+
&:hover {
|
|
61
|
+
background-color: #f2f9ff !important;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
&.antsomi-menu-item-selected {
|
|
66
|
+
& > .antsomi-menu-title-content {
|
|
67
|
+
background-color: #deeffe !important;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
22
70
|
|
|
23
71
|
[role='icon'] {
|
|
24
72
|
font-size: ${ICON_SIZE}px !important;
|
|
25
73
|
}
|
|
74
|
+
|
|
75
|
+
& a.menu-link {
|
|
76
|
+
width: 100%;
|
|
77
|
+
height: 100%;
|
|
78
|
+
display: flex;
|
|
79
|
+
align-items: center;
|
|
80
|
+
color: inherit;
|
|
81
|
+
text-decoration: none;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
&.antsomi-menu-submenu {
|
|
85
|
+
& > [role='menuitem'] {
|
|
86
|
+
padding-right: 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
& > ul.antsomi-menu.antsomi-menu-sub {
|
|
90
|
+
& > [role='menuitem'] {
|
|
91
|
+
width: 100%;
|
|
92
|
+
padding-right: 0px;
|
|
93
|
+
|
|
94
|
+
& > .antsomi-menu-title-content {
|
|
95
|
+
& ${OptionDropdownWrapper} {
|
|
96
|
+
display: none;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
&:hover {
|
|
100
|
+
& ${OptionDropdownWrapper} {
|
|
101
|
+
display: flex;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
26
108
|
}
|
|
27
109
|
}
|
|
28
110
|
|
|
@@ -31,30 +113,8 @@ export const MenuWrapper = styled.div `
|
|
|
31
113
|
border: none !important;
|
|
32
114
|
}
|
|
33
115
|
|
|
34
|
-
[role='menuitem'] {
|
|
35
|
-
margin: 0 !important;
|
|
36
|
-
border-radius: ${(_a = THEME === null || THEME === void 0 ? void 0 : THEME.token) === null || _a === void 0 ? void 0 : _a.borderRadiusXL}px !important;
|
|
37
|
-
padding-right: 10px !important;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
[role='menuitem'].antsomi-menu-item-selected {
|
|
41
|
-
background-color: #deeffe !important;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
116
|
.antsomi-menu-item-active,
|
|
45
117
|
.antsomi-menu-submenu-title:hover {
|
|
46
118
|
background-color: #f2f9ff !important;
|
|
47
119
|
}
|
|
48
|
-
|
|
49
|
-
.menu-link {
|
|
50
|
-
width: 100% !important;
|
|
51
|
-
height: 100% !important;
|
|
52
|
-
display: flex !important;
|
|
53
|
-
color: inherit !important;
|
|
54
|
-
text-decoration: none !important;
|
|
55
|
-
}
|
|
56
|
-
`;
|
|
57
|
-
export const LabelCustom = styled(Typography.Text) `
|
|
58
|
-
font-size: inherit !important;
|
|
59
|
-
color: inherit !important;
|
|
60
120
|
`;
|
|
@@ -7,7 +7,6 @@ export declare const useLeftMenu: (props: LeftMenuProps) => {
|
|
|
7
7
|
state: TState;
|
|
8
8
|
activeAppCode: string;
|
|
9
9
|
permissionMenu: import("@antscorp/antsomi-ui/es/models/LeftMenu").TFeatureMenu[];
|
|
10
|
-
/** Variables */
|
|
11
10
|
customActiveAppKey: string;
|
|
12
11
|
onToggleChildMenu: () => void;
|
|
13
12
|
onMouseEnter: (key: string) => void;
|
|
@@ -9,7 +9,7 @@ import { findActiveAppCodeByChild, findActiveAppCodeByUrl, findLastMatchedItemBy
|
|
|
9
9
|
import { useLeftMenuStore } from '../stores';
|
|
10
10
|
import { POST_MESSAGE_TYPES } from '@antscorp/antsomi-ui/es/constants/postMessage';
|
|
11
11
|
// Constants
|
|
12
|
-
import { CDP_API, PERMISSION_API
|
|
12
|
+
import { CDP_API, PERMISSION_API } from '@antscorp/antsomi-ui/es/constants';
|
|
13
13
|
const initialState = {
|
|
14
14
|
hoverItem: '',
|
|
15
15
|
isExpandMenu: true,
|
|
@@ -18,23 +18,31 @@ export const useLeftMenu = (props) => {
|
|
|
18
18
|
// Props
|
|
19
19
|
const { objectType = 'OVERVIEW', objectId = 1, isGrouped = true, appConfig, customization, onActiveMenuCodeChange, } = props;
|
|
20
20
|
const { isExpandable = true, isCustomized = false, items, activeKey } = customization || {};
|
|
21
|
-
|
|
22
|
-
const { pathname, hash, search } = window.location;
|
|
23
|
-
const urlParams = useMemo(() => new URLSearchParams(search), [search]);
|
|
24
|
-
// Stores
|
|
21
|
+
const { pathname, hash } = window.location;
|
|
25
22
|
const activeAppCode = useLeftMenuStore(store => store.state.activeAppCode);
|
|
26
23
|
const customActiveAppKey = useLeftMenuStore(store => store.state.customActiveAppKey);
|
|
27
24
|
const setLeftMenuState = useLeftMenuStore(store => store.setState);
|
|
28
|
-
|
|
29
|
-
const { auth, languageCode, env } = appConfig || {};
|
|
30
|
-
// State
|
|
25
|
+
const { auth, languageCode = 'en', env = 'development' } = appConfig || {};
|
|
31
26
|
const [state, setState] = useState(initialState);
|
|
32
|
-
//
|
|
27
|
+
// const { data: menuList } = useGetListMenu({
|
|
28
|
+
// args: {
|
|
29
|
+
// auth: {
|
|
30
|
+
// token: env === 'production' ? auth?.token : '5474r2x214z284d4w2b4y444d464b444q4y274u4t5x5',
|
|
31
|
+
// url: 'https://permission.antsomi.com',
|
|
32
|
+
// portalId: env === 'production' ? auth?.portalId : 561236459,
|
|
33
|
+
// userId: env === 'production' ? auth?.userId : '1600083836',
|
|
34
|
+
// accountId: env === 'production' ? auth?.accountId : '1600083836',
|
|
35
|
+
// },
|
|
36
|
+
// params: {
|
|
37
|
+
// type: 'menu-item-permission',
|
|
38
|
+
// },
|
|
39
|
+
// },
|
|
40
|
+
// });
|
|
33
41
|
const { data: menuList } = useGetListMenu({
|
|
34
42
|
args: {
|
|
35
43
|
auth: {
|
|
36
|
-
token:
|
|
37
|
-
url:
|
|
44
|
+
token: '5474r2x214r2b4b4v2d4y444u2v5q2p5o4d4c4f424e4' || (auth === null || auth === void 0 ? void 0 : auth.token),
|
|
45
|
+
url: 'https://sandbox-permission.ants.vn',
|
|
38
46
|
portalId: auth === null || auth === void 0 ? void 0 : auth.portalId,
|
|
39
47
|
userId: auth === null || auth === void 0 ? void 0 : auth.userId,
|
|
40
48
|
accountId: auth === null || auth === void 0 ? void 0 : auth.accountId,
|
|
@@ -63,10 +71,10 @@ export const useLeftMenu = (props) => {
|
|
|
63
71
|
const { data: dashboardData, refetch: refetchDashboard } = useGetDashboard({
|
|
64
72
|
args: {
|
|
65
73
|
auth: {
|
|
66
|
-
token: auth === null || auth === void 0 ? void 0 : auth.token,
|
|
67
|
-
url: env ? `${CDP_API.production}/hub` :
|
|
68
|
-
portalId: auth === null || auth === void 0 ? void 0 : auth.portalId,
|
|
69
|
-
userId: auth === null || auth === void 0 ? void 0 : auth.userId,
|
|
74
|
+
token: env === 'development' ? '5474r2x214z284d4w2b4y494d43464k5a4v2j464m5a4' : auth === null || auth === void 0 ? void 0 : auth.token,
|
|
75
|
+
url: env === 'development' ? `${CDP_API.production}/hub` : `${CDP_API === null || CDP_API === void 0 ? void 0 : CDP_API[env]}/hub`,
|
|
76
|
+
portalId: env === 'development' ? 561236459 : auth === null || auth === void 0 ? void 0 : auth.portalId,
|
|
77
|
+
userId: env === 'development' ? '1600083836' : auth === null || auth === void 0 ? void 0 : auth.userId,
|
|
70
78
|
},
|
|
71
79
|
params: {
|
|
72
80
|
objectType,
|
|
@@ -90,9 +98,7 @@ export const useLeftMenu = (props) => {
|
|
|
90
98
|
},
|
|
91
99
|
},
|
|
92
100
|
});
|
|
93
|
-
// Variables
|
|
94
101
|
const flattenMenuPermission = flattenMenuArray(menuListPermission || [], 'childs');
|
|
95
|
-
// Memos
|
|
96
102
|
const permissionMenu = useMemo(() => recursivePermissionMenu(sortBy((menuList === null || menuList === void 0 ? void 0 : menuList.rows) || [], ['level_position']), flattenMenuPermission), [menuList === null || menuList === void 0 ? void 0 : menuList.rows, flattenMenuPermission]);
|
|
97
103
|
const mappingChildrenMenu = useMemo(() => getMappingAppChildren({
|
|
98
104
|
menuList: permissionMenu,
|
|
@@ -100,7 +106,6 @@ export const useLeftMenu = (props) => {
|
|
|
100
106
|
dashboardData,
|
|
101
107
|
destinationChannelEntries: destinationChannel === null || destinationChannel === void 0 ? void 0 : destinationChannel.entries,
|
|
102
108
|
}), [auth, dashboardData, destinationChannel === null || destinationChannel === void 0 ? void 0 : destinationChannel.entries, permissionMenu]);
|
|
103
|
-
/* Handlers */
|
|
104
109
|
const receivePostMessage = (event) => {
|
|
105
110
|
const { data } = event;
|
|
106
111
|
const { type } = data || {};
|
|
@@ -113,7 +118,6 @@ export const useLeftMenu = (props) => {
|
|
|
113
118
|
break;
|
|
114
119
|
}
|
|
115
120
|
};
|
|
116
|
-
// Side Effects
|
|
117
121
|
// Receive Post Message
|
|
118
122
|
useEffect(() => {
|
|
119
123
|
if (!isCustomized) {
|
|
@@ -125,9 +129,7 @@ export const useLeftMenu = (props) => {
|
|
|
125
129
|
useEffect(() => {
|
|
126
130
|
setLeftMenuState({ appConfig, isCustomized });
|
|
127
131
|
}, [appConfig, isCustomized, setLeftMenuState]);
|
|
128
|
-
|
|
129
|
-
* Active Custom App Key when active key is changed
|
|
130
|
-
*/
|
|
132
|
+
// Active Custom App Key when active key is changed
|
|
131
133
|
useEffect(() => {
|
|
132
134
|
if (activeKey && items)
|
|
133
135
|
setLeftMenuState({
|
|
@@ -138,9 +140,7 @@ export const useLeftMenu = (props) => {
|
|
|
138
140
|
customActiveCurrentKey: activeKey,
|
|
139
141
|
});
|
|
140
142
|
}, [activeKey, appConfig, isCustomized, items, setLeftMenuState]);
|
|
141
|
-
|
|
142
|
-
* Change list menu children when hovering or activating items, giving priority to hovering items
|
|
143
|
-
*/
|
|
143
|
+
// Change list menu children when hovering or activating items, giving priority to hovering items
|
|
144
144
|
useEffect(() => {
|
|
145
145
|
var _a, _b;
|
|
146
146
|
if (isCustomized) {
|
|
@@ -160,33 +160,33 @@ export const useLeftMenu = (props) => {
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
}, [
|
|
163
|
-
isCustomized,
|
|
164
163
|
activeAppCode,
|
|
164
|
+
customActiveAppKey,
|
|
165
|
+
isCustomized,
|
|
166
|
+
items,
|
|
165
167
|
mappingChildrenMenu,
|
|
166
168
|
state.hoverItem,
|
|
167
169
|
setLeftMenuState,
|
|
168
|
-
items,
|
|
169
|
-
customActiveAppKey,
|
|
170
170
|
]);
|
|
171
171
|
useEffect(() => {
|
|
172
|
-
var _a;
|
|
173
172
|
if (!isCustomized) {
|
|
174
173
|
const url = `${pathname}${hash}`;
|
|
175
|
-
|
|
176
|
-
* Active App Item having code matching url
|
|
177
|
-
*/
|
|
174
|
+
// Active App Item having code matching url
|
|
178
175
|
const matchAppCode = findActiveAppCodeByUrl({ url, menuItems: mappingChildrenMenu, auth });
|
|
179
176
|
if (matchAppCode && matchAppCode !== activeAppCode) {
|
|
180
177
|
setLeftMenuState({ activeAppCode: matchAppCode });
|
|
181
178
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
179
|
+
}
|
|
180
|
+
}, [activeAppCode, auth, hash, isCustomized, mappingChildrenMenu, pathname, setLeftMenuState]);
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
if (!isCustomized) {
|
|
183
|
+
const url = `${pathname}${hash}`;
|
|
184
|
+
// Callback function using at Layout when url change
|
|
185
|
+
const matchedCode = findLastMatchedItemByUrl({
|
|
186
186
|
url,
|
|
187
187
|
menuItems: mappingChildrenMenu,
|
|
188
188
|
auth,
|
|
189
|
-
})
|
|
189
|
+
});
|
|
190
190
|
const activeItemPath = matchedCode
|
|
191
191
|
? findPathOfActiveItem({
|
|
192
192
|
activeMenuItem: matchedCode,
|
|
@@ -196,19 +196,14 @@ export const useLeftMenu = (props) => {
|
|
|
196
196
|
onActiveMenuCodeChange === null || onActiveMenuCodeChange === void 0 ? void 0 : onActiveMenuCodeChange(activeItemPath, flattenMenuPermission);
|
|
197
197
|
}
|
|
198
198
|
}, [
|
|
199
|
-
isCustomized,
|
|
200
|
-
activeAppCode,
|
|
201
199
|
auth,
|
|
200
|
+
flattenMenuPermission,
|
|
202
201
|
hash,
|
|
202
|
+
isCustomized,
|
|
203
203
|
mappingChildrenMenu,
|
|
204
204
|
pathname,
|
|
205
|
-
permissionMenu,
|
|
206
|
-
setLeftMenuState,
|
|
207
205
|
onActiveMenuCodeChange,
|
|
208
|
-
flattenMenuPermission,
|
|
209
|
-
urlParams,
|
|
210
206
|
]);
|
|
211
|
-
/* Callbacks */
|
|
212
207
|
const onToggleChildMenu = useCallback(() => {
|
|
213
208
|
setState(prev => (Object.assign(Object.assign({}, prev), { isExpandMenu: !prev.isExpandMenu })));
|
|
214
209
|
}, []);
|
|
@@ -226,15 +221,10 @@ export const useLeftMenu = (props) => {
|
|
|
226
221
|
onMouseEnter(isCustomized ? customActiveAppKey : activeAppCode);
|
|
227
222
|
};
|
|
228
223
|
return {
|
|
229
|
-
/* State */
|
|
230
224
|
state,
|
|
231
|
-
/* Zustand */
|
|
232
225
|
activeAppCode,
|
|
233
|
-
/* Data Queries */
|
|
234
226
|
permissionMenu,
|
|
235
|
-
/** Variables */
|
|
236
227
|
customActiveAppKey,
|
|
237
|
-
/* Callbacks */
|
|
238
228
|
onToggleChildMenu,
|
|
239
229
|
onMouseEnter,
|
|
240
230
|
onMouseLeave,
|
|
@@ -18,42 +18,28 @@ import { useLeftMenu, useNavigatePath } from './hooks';
|
|
|
18
18
|
export const LeftMenu = memo(props => {
|
|
19
19
|
const { style, className, customization } = props;
|
|
20
20
|
const { isExpandable = true, isCustomized = false, items = [], onMenuItemClick, } = customization || {};
|
|
21
|
-
|
|
22
|
-
const {
|
|
23
|
-
/* State */
|
|
24
|
-
state,
|
|
25
|
-
/* Store */
|
|
26
|
-
activeAppCode,
|
|
27
|
-
/* Data Queries */
|
|
28
|
-
permissionMenu,
|
|
29
|
-
/** Variables */
|
|
30
|
-
customActiveAppKey,
|
|
31
|
-
/* Callbacks */
|
|
32
|
-
onToggleChildMenu, onMouseEnter, onMouseLeave, onHoverMenuBar, } = useLeftMenu(props);
|
|
21
|
+
const { state, activeAppCode, permissionMenu, customActiveAppKey, onToggleChildMenu, onMouseEnter, onMouseLeave, onHoverMenuBar, } = useLeftMenu(props);
|
|
33
22
|
const { isPushDifferentDomain, getPath, navigatePath } = useNavigatePath();
|
|
34
|
-
// Memo
|
|
35
23
|
const childMenu = useMemo(() => {
|
|
36
24
|
const selectedFeatureKey = state.hoverItem ? state.hoverItem : activeAppCode;
|
|
37
25
|
if (isCustomized)
|
|
38
26
|
return React.createElement(CustomMenu, { onMenuItemClick: onMenuItemClick });
|
|
39
27
|
switch (selectedFeatureKey) {
|
|
40
|
-
case APP_KEYS.HOME:
|
|
28
|
+
case APP_KEYS.HOME:
|
|
41
29
|
return React.createElement(HomeMenu, null);
|
|
42
|
-
}
|
|
43
30
|
default:
|
|
44
31
|
return React.createElement(CommonMenu, null);
|
|
45
32
|
}
|
|
46
33
|
}, [activeAppCode, isCustomized, state.hoverItem, onMenuItemClick]);
|
|
47
|
-
// Render components
|
|
48
34
|
const renderFeatureMenuItems = useCallback((item) => {
|
|
49
35
|
const { menu_item_name, menu_item, icon_name, menu_item_code, menu_item_path, menu_item_domain, } = item;
|
|
50
36
|
const isActive = activeAppCode === menu_item_code;
|
|
51
37
|
const isHover = state.hoverItem === menu_item_code;
|
|
52
|
-
const
|
|
38
|
+
const renderLabel = () => (React.createElement("li", { role: "menuitem", className: classNames({ isActive, isHover }) },
|
|
53
39
|
React.createElement(IconWrapper, null, isNil(icon_name) ? null : React.createElement(Icon, { type: icon_name })),
|
|
54
40
|
React.createElement(Typography.Text, null, menu_item_name),
|
|
55
41
|
React.createElement("div", { className: "popup-triangle" })));
|
|
56
|
-
return (React.createElement(FeatureMenuItem, { key: menu_item, onMouseEnter: () => onMouseEnter(menu_item_code) }, isString(menu_item_path) ? (isPushDifferentDomain(menu_item_domain, menu_item_path) ? (React.createElement("div", { onClick: () => navigatePath(menu_item_domain, menu_item_path) },
|
|
42
|
+
return (React.createElement(FeatureMenuItem, { key: menu_item, onMouseEnter: () => onMouseEnter(menu_item_code) }, isString(menu_item_path) ? (isPushDifferentDomain(menu_item_domain, menu_item_path) ? (React.createElement("div", { onClick: () => navigatePath(menu_item_domain, menu_item_path) }, renderLabel())) : (React.createElement(Link, { to: getPath(menu_item_path), className: "menu-link" }, renderLabel()))) : (renderLabel())));
|
|
57
43
|
}, [activeAppCode, getPath, isPushDifferentDomain, navigatePath, onMouseEnter, state.hoverItem]);
|
|
58
44
|
const renderCustomizedMenuItems = useCallback((items) => items === null || items === void 0 ? void 0 : items.map(item => {
|
|
59
45
|
const { key, icon, label } = item;
|
|
@@ -89,7 +75,7 @@ export const LeftMenu = memo(props => {
|
|
|
89
75
|
React.createElement("div", { className: "menu-content scroll-content" }, renderAppMenuItems()),
|
|
90
76
|
React.createElement("div", { className: "nav-blank", onMouseEnter: onHoverMenuBar }),
|
|
91
77
|
React.createElement(PopoverWrapper, { className: "antsomi-scroll-box antsomi-child-menu-popover", onMouseLeave: onMouseLeave },
|
|
92
|
-
React.createElement("div", { className: "scroll-content" }, childMenu))),
|
|
78
|
+
React.createElement("div", { className: "scroll-content", style: { width: '200px', maxHeight: '100%' } }, childMenu))),
|
|
93
79
|
React.createElement("div", { style: { flexShrink: 0 } }, renderSettings())),
|
|
94
80
|
isExpandable && (React.createElement(ExpandWrapper, { onMouseEnter: onMouseLeave },
|
|
95
81
|
React.createElement(Icon, { type: "icon-ants-expand-more", style: {
|
|
@@ -98,5 +84,5 @@ export const LeftMenu = memo(props => {
|
|
|
98
84
|
transform: `rotate(${state.isExpandMenu ? '90deg' : '270deg'})`,
|
|
99
85
|
}, onClick: onToggleChildMenu })))),
|
|
100
86
|
React.createElement(ChildMenuWrapper, { isExpand: state.isExpandMenu && isExpandable, className: "antsomi-scroll-box" },
|
|
101
|
-
React.createElement("div", { className: "scroll-content" }, childMenu))));
|
|
87
|
+
React.createElement("div", { className: "scroll-content", style: { width: '200px', maxHeight: '100%' } }, childMenu))));
|
|
102
88
|
});
|
|
@@ -26,12 +26,11 @@ export const PopoverWrapper = styled.div `
|
|
|
26
26
|
left: 65px;
|
|
27
27
|
border-radius: ${(_a = THEME === null || THEME === void 0 ? void 0 : THEME.token) === null || _a === void 0 ? void 0 : _a.borderRadiusXL}px;
|
|
28
28
|
bottom: 15px;
|
|
29
|
-
width: 230px;
|
|
30
29
|
box-shadow: 0px 3px 20px 0px #002e5933;
|
|
31
30
|
height: calc(100% - ${HEADER_HEIGHT + 15}px);
|
|
32
31
|
transition: visibility 0s, opacity 0.2s ease-out;
|
|
33
32
|
z-index: 10;
|
|
34
|
-
padding:
|
|
33
|
+
padding: 20px;
|
|
35
34
|
box-sizing: border-box;
|
|
36
35
|
`;
|
|
37
36
|
export const FeatureMenuWrapper = styled(Flex) `
|
|
@@ -84,7 +84,7 @@ export declare const findLastMatchedItemByUrl: (args: {
|
|
|
84
84
|
auth?: Partial<PayloadInfo>;
|
|
85
85
|
}) => TFeatureMenu | undefined;
|
|
86
86
|
export declare const findPathOfActiveItem: (args: {
|
|
87
|
-
activeMenuItem:
|
|
87
|
+
activeMenuItem: TFeatureMenu;
|
|
88
88
|
menuItems: TFeatureMenu[];
|
|
89
89
|
}) => TFeatureMenu[];
|
|
90
90
|
/**
|
|
@@ -129,6 +129,7 @@ export const getMappingAppChildren = (args) => {
|
|
|
129
129
|
menu_item_code: item.channelCode,
|
|
130
130
|
menu_item_name: item.translateLabel,
|
|
131
131
|
logo_url: item.logoUrl,
|
|
132
|
+
menu_item_parent: menuItem.menu_item,
|
|
132
133
|
menu_item_path: getGeneratePath(path, Object.assign(Object.assign({}, auth), { channelId: item.channelId })),
|
|
133
134
|
}))))) || [];
|
|
134
135
|
break;
|
|
@@ -156,10 +157,12 @@ export const getMappingAppChildren = (args) => {
|
|
|
156
157
|
menu_item: childMenuItem.menu_item_code,
|
|
157
158
|
menu_item_code: childMenuItem.menu_item_code,
|
|
158
159
|
menu_item_name: childMenuItem.menu_item_name,
|
|
160
|
+
menu_item_parent: appItem.menu_item,
|
|
159
161
|
})), { children: (_a = (((dashboardObject === null || dashboardObject === void 0 ? void 0 : dashboardObject[childMenuItem.menu_item_code]) || []))) === null || _a === void 0 ? void 0 : _a.map(item => (Object.assign({}, getInitialFeatureMenuItem({
|
|
160
162
|
menu_item: String(item.dashboardId),
|
|
161
163
|
menu_item_code: String(item.dashboardId),
|
|
162
164
|
menu_item_name: item.dashboardName,
|
|
165
|
+
menu_item_parent: childMenuItem.menu_item_code,
|
|
163
166
|
menu_item_path: getGeneratePath(HOME_REPORT_ROUTES.DETAIL, Object.assign(Object.assign({}, auth), { dashboardId: String(item.dashboardId) })),
|
|
164
167
|
})))) }));
|
|
165
168
|
});
|
|
@@ -243,14 +246,15 @@ export const findLastMatchedItemByUrl = (args) => {
|
|
|
243
246
|
try {
|
|
244
247
|
const { url, menuItems, auth } = args;
|
|
245
248
|
const matchedItems = [];
|
|
246
|
-
const recursiveFindActiveItem = (items) => {
|
|
249
|
+
const recursiveFindActiveItem = (items, parentId) => {
|
|
247
250
|
for (const item of items) {
|
|
248
|
-
if (
|
|
249
|
-
url.includes(getComparePath(getGeneratePath(item.menu_item_path, auth)))
|
|
251
|
+
if ((item === null || item === void 0 ? void 0 : item.menu_item_path) &&
|
|
252
|
+
url.includes(getComparePath(getGeneratePath(item.menu_item_path, auth))) &&
|
|
253
|
+
(!parentId || item.menu_item_parent === parentId)) {
|
|
250
254
|
matchedItems.push(item);
|
|
251
255
|
}
|
|
252
256
|
if ((item === null || item === void 0 ? void 0 : item.children) && item.children.length) {
|
|
253
|
-
recursiveFindActiveItem(item.children);
|
|
257
|
+
recursiveFindActiveItem(item.children, String(item.menu_item));
|
|
254
258
|
}
|
|
255
259
|
}
|
|
256
260
|
};
|
|
@@ -268,14 +272,15 @@ export const findLastMatchedItemByUrl = (args) => {
|
|
|
268
272
|
export const findPathOfActiveItem = (args) => {
|
|
269
273
|
try {
|
|
270
274
|
const { activeMenuItem, menuItems } = args;
|
|
271
|
-
const recursiveFindPathOfActiveItem = (menuItems) => {
|
|
275
|
+
const recursiveFindPathOfActiveItem = (menuItems, parentId) => {
|
|
272
276
|
let path = [];
|
|
273
277
|
for (const item of menuItems) {
|
|
274
|
-
if (item.menu_item_code === activeMenuItem)
|
|
278
|
+
if (item.menu_item_code === (activeMenuItem === null || activeMenuItem === void 0 ? void 0 : activeMenuItem.menu_item_code) &&
|
|
279
|
+
(!parentId || (activeMenuItem === null || activeMenuItem === void 0 ? void 0 : activeMenuItem.menu_item_parent) === parentId)) {
|
|
275
280
|
path.push(item);
|
|
276
281
|
break;
|
|
277
282
|
}
|
|
278
|
-
const childPath = recursiveFindPathOfActiveItem((item === null || item === void 0 ? void 0 : item.children) || []);
|
|
283
|
+
const childPath = recursiveFindPathOfActiveItem((item === null || item === void 0 ? void 0 : item.children) || [], String(item.menu_item));
|
|
279
284
|
if (childPath.length) {
|
|
280
285
|
path = [item, ...childPath];
|
|
281
286
|
break;
|
|
@@ -23,7 +23,7 @@ import { HeaderV2 } from '../../molecules';
|
|
|
23
23
|
// Contexts
|
|
24
24
|
import { AppConfigContext } from '../../..';
|
|
25
25
|
// Constants
|
|
26
|
-
import { MENU_PERMISSIONS } from './constants';
|
|
26
|
+
import { APP_ROLE_SCOPE, MENU_PERMISSIONS } from './constants';
|
|
27
27
|
import { APP_CODES, APP_IAM_DOMAIN, APP_PERMISSION_DOMAIN, IAM_API, PERMISSION_API, PORTALS_IDS, SOCKET_API, } from '../../../constants';
|
|
28
28
|
// Css
|
|
29
29
|
import '@antscorp/processing-notification/dist/index.css';
|
|
@@ -35,7 +35,6 @@ export const Layout = memo(props => {
|
|
|
35
35
|
const { leftMenuProps, headerProps = {}, workspaceProps, processingNotificationProps, children, onActiveMenuChange, } = props;
|
|
36
36
|
const _a = leftMenuProps || {}, { className = '' } = _a, restOfLeftMenuProps = __rest(_a, ["className"]);
|
|
37
37
|
const _b = workspaceProps || {}, { workspaceContentProps } = _b, restOfWorkspaceProps = __rest(_b, ["workspaceContentProps"]);
|
|
38
|
-
// Selectors
|
|
39
38
|
const appConfig = useContextSelector(AppConfigContext, state => state);
|
|
40
39
|
const { auth, languageCode, appCode, env } = appConfig;
|
|
41
40
|
const { token, userId, portalId } = auth || {};
|
|
@@ -114,14 +113,21 @@ export const Layout = memo(props => {
|
|
|
114
113
|
const menuPermission = flattenPermissionList === null || flattenPermissionList === void 0 ? void 0 : flattenPermissionList.find(item => permissionCode === item.menu_code);
|
|
115
114
|
if (menuPermission) {
|
|
116
115
|
const checkRoleScope = menuPermission
|
|
117
|
-
? checkingRoleScope({
|
|
116
|
+
? checkingRoleScope({
|
|
117
|
+
menuCode: menuPermission.menu_code || '',
|
|
118
|
+
menuPermission,
|
|
119
|
+
scope: APP_ROLE_SCOPE.EVERYTHING,
|
|
120
|
+
})
|
|
118
121
|
: false;
|
|
119
122
|
if (checkRoleScope) {
|
|
120
123
|
roleScope = true;
|
|
121
124
|
break;
|
|
122
125
|
}
|
|
123
126
|
}
|
|
124
|
-
/**
|
|
127
|
+
/**
|
|
128
|
+
* Nếu trong Api Permission không có những có trong @constant MENU_PERMISSIONS
|
|
129
|
+
* thì vẫn trả về True vì có những MENU_CODE mà BA chưa define permission
|
|
130
|
+
* */
|
|
125
131
|
if (isExternalPermissionCode) {
|
|
126
132
|
roleScope = true;
|
|
127
133
|
break;
|
|
@@ -14,9 +14,6 @@ export declare const MARKETING_CHANNEL_CODE: {
|
|
|
14
14
|
* Nếu PERMISSION_CODE không được tìm thấy trong api get permissions và trong @constant MENU_PERMISSIONS thì sẽ ẩn account selection
|
|
15
15
|
*/
|
|
16
16
|
export declare const MENU_PERMISSIONS: {
|
|
17
|
-
ALL_CHANNEL: string;
|
|
18
|
-
ORCHESTRATION: string;
|
|
19
|
-
CAMPAIGN: string;
|
|
20
17
|
BATCH_STREAM: string;
|
|
21
18
|
REALTIME_STREAM: string;
|
|
22
19
|
DF_DATA_SOURCE: string;
|
|
@@ -14,9 +14,6 @@ export const MARKETING_CHANNEL_CODE = {
|
|
|
14
14
|
* Nếu PERMISSION_CODE không được tìm thấy trong api get permissions và trong @constant MENU_PERMISSIONS thì sẽ ẩn account selection
|
|
15
15
|
*/
|
|
16
16
|
export const MENU_PERMISSIONS = {
|
|
17
|
-
[MARKETING_CHANNEL_CODE.ALL_CHANNEL]: 'JOURNEY',
|
|
18
|
-
[MARKETING_CHANNEL_CODE.ORCHESTRATION]: 'JOURNEY',
|
|
19
|
-
[MARKETING_CHANNEL_CODE.CAMPAIGN]: 'JOURNEY',
|
|
20
17
|
BATCH_STREAM: 'BATCH_STREAM',
|
|
21
18
|
REALTIME_STREAM: 'REALTIME_STREAM',
|
|
22
19
|
DF_DATA_SOURCE: 'DF_DATA_SOURCE',
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
1
2
|
import { HeaderV2Props } from '../../../molecules';
|
|
2
3
|
import { DeepPartial } from '@antscorp/antsomi-ui/es/types';
|
|
3
4
|
export interface HeaderStore extends Partial<HeaderV2Props> {
|
|
4
5
|
}
|
|
5
6
|
export interface LeftMenuStore {
|
|
7
|
+
onClickCreateDashboard?: React.MouseEventHandler<HTMLElement>;
|
|
6
8
|
}
|
|
7
9
|
export interface WorkspaceStore {
|
|
8
10
|
}
|
|
@@ -17,6 +19,10 @@ interface LayoutStore {
|
|
|
17
19
|
setLeftMenuState: (state: DeepPartial<LeftMenuStore>) => void;
|
|
18
20
|
setWorkspaceState: (state: Partial<WorkspaceStore>) => void;
|
|
19
21
|
setLayoutState: (state: DeepPartial<LayoutStoreState>) => void;
|
|
22
|
+
resetHeaderState: () => void;
|
|
23
|
+
resetLeftMenuState: () => void;
|
|
24
|
+
resetWorkspaceState: () => void;
|
|
25
|
+
resetLayoutState: () => void;
|
|
20
26
|
}
|
|
21
27
|
export declare const useLayoutStore: import("zustand").UseBoundStore<import("zustand").StoreApi<LayoutStore>>;
|
|
22
28
|
export {};
|
|
@@ -18,4 +18,16 @@ export const useLayoutStore = create(set => ({
|
|
|
18
18
|
setWorkspaceState: newState => set(store => ({
|
|
19
19
|
state: Object.assign(Object.assign({}, store.state), { workspace: Object.assign(Object.assign({}, store.state.workspace), newState) }),
|
|
20
20
|
})),
|
|
21
|
+
resetHeaderState: () => set(store => ({
|
|
22
|
+
state: Object.assign(Object.assign({}, store.state), { header: initialState.header }),
|
|
23
|
+
})),
|
|
24
|
+
resetLeftMenuState: () => set(store => ({
|
|
25
|
+
state: Object.assign(Object.assign({}, store.state), { leftMenu: initialState.leftMenu }),
|
|
26
|
+
})),
|
|
27
|
+
resetWorkspaceState: () => set(store => ({
|
|
28
|
+
state: Object.assign(Object.assign({}, store.state), { workspace: initialState.workspace }),
|
|
29
|
+
})),
|
|
30
|
+
resetLayoutState: () => set(store => ({
|
|
31
|
+
state: Object.assign(Object.assign({}, store.state), initialState),
|
|
32
|
+
})),
|
|
21
33
|
}));
|
|
@@ -29,15 +29,11 @@ const PATH = 'src/components/template/TemplateListing/components/CategoryListing
|
|
|
29
29
|
export const CategoryListing = memo(props => {
|
|
30
30
|
var _a;
|
|
31
31
|
const { width = CATEGORY_LISTING_WITH, items = [], loading = false, show = true, checkedCategories = {}, emptyProps, debounceChangeMenu = CATEGORY_DEBOUNCE, header, footer, onMenuChange } = props, restOfProps = __rest(props, ["width", "items", "loading", "show", "checkedCategories", "emptyProps", "debounceChangeMenu", "header", "footer", "onMenuChange"]);
|
|
32
|
-
// States
|
|
33
32
|
const [checkedState, setCheckedState] = useState({});
|
|
34
|
-
// Side Effects
|
|
35
33
|
useEffect(() => {
|
|
36
34
|
setCheckedState(prev => (isEqual(prev, checkedCategories) ? prev : checkedCategories));
|
|
37
35
|
}, [checkedCategories]);
|
|
38
|
-
// Ref
|
|
39
36
|
const timeoutAfterChange = useRef(null);
|
|
40
|
-
// Handlers
|
|
41
37
|
const handleClickMenu = e => {
|
|
42
38
|
var _a;
|
|
43
39
|
try {
|
|
@@ -63,7 +59,6 @@ export const CategoryListing = memo(props => {
|
|
|
63
59
|
});
|
|
64
60
|
}
|
|
65
61
|
};
|
|
66
|
-
// Render components
|
|
67
62
|
const renderCustomLabel = useCallback((args) => {
|
|
68
63
|
var _a;
|
|
69
64
|
try {
|
|
@@ -108,10 +103,9 @@ export const CategoryListing = memo(props => {
|
|
|
108
103
|
return undefined;
|
|
109
104
|
}
|
|
110
105
|
}, [renderCustomLabel]);
|
|
111
|
-
// Memo
|
|
112
106
|
const menuItems = useMemo(() => {
|
|
113
107
|
const menuItems = [];
|
|
114
|
-
items === null || items === void 0 ? void 0 : items.forEach((item,
|
|
108
|
+
items === null || items === void 0 ? void 0 : items.forEach((item, _) => {
|
|
115
109
|
// if (index > 0) menuItems.push({ type: 'divider' });
|
|
116
110
|
const menuItem = getItem(Object.assign(Object.assign({}, item), { parentId: null }), true);
|
|
117
111
|
if (menuItem)
|
|
@@ -25,11 +25,8 @@ import { LoadMoreBlock, TemplateListingWrapper, TemplateWrapper } from './styled
|
|
|
25
25
|
// Hooks
|
|
26
26
|
import { useIntersectionObserver, useListingItemResize } from '@antscorp/antsomi-ui/es/hooks';
|
|
27
27
|
export const TemplateListing = memo(props => {
|
|
28
|
-
// Props
|
|
29
28
|
const { templatesProps = TEMPLATES_DEFAULT, templateItemProps = TEMPLATE_ITEM_DEFAULT, blankTemplateProps = BLANK_TEMPLATE_DEFAULT, categoryListingProps = CATEGORY_LISTING_DEFAULT, emptyProps = EMPTY_DEFAULT, previewModalProps, } = props;
|
|
30
|
-
// States
|
|
31
29
|
const [openPreviewModal, setOpenPreviewModal] = useState(false);
|
|
32
|
-
// Variables
|
|
33
30
|
const { header, footer, items = [], gap = LISTING_GAP_DEFAULT, loading = false, wrapperClassName, wrapperStyle, onLoadMoreTemplates = () => { }, } = templatesProps || {};
|
|
34
31
|
const _a = previewModalProps || {}, { onOk, onCancel } = _a, restOfPreviewModalProps = __rest(_a, ["onOk", "onCancel"]);
|
|
35
32
|
const _b = templateItemProps || {}, { width = THUMBNAIL_CARD_DEFAULT_WIDTH, height = THUMBNAIL_CARD_DEFAULT_HEIGHT, previewBtnProps } = _b, restOfTemplateItemProps = __rest(_b, ["width", "height", "previewBtnProps"]);
|
|
@@ -51,7 +48,6 @@ export const TemplateListing = memo(props => {
|
|
|
51
48
|
}
|
|
52
49
|
},
|
|
53
50
|
});
|
|
54
|
-
// Handlers
|
|
55
51
|
const handleClickThumbnailPreview = (id) => {
|
|
56
52
|
onClickPreview === null || onClickPreview === void 0 ? void 0 : onClickPreview(id);
|
|
57
53
|
setOpenPreviewModal(true);
|
package/es/hooks/index.d.ts
CHANGED
package/es/hooks/index.js
CHANGED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
2
|
+
declare function useEventListener<K extends keyof MediaQueryListEventMap>(eventName: K, handler: (event: MediaQueryListEventMap[K]) => void, element: RefObject<MediaQueryList>, options?: boolean | AddEventListenerOptions): void;
|
|
3
|
+
declare function useEventListener<K extends keyof WindowEventMap>(eventName: K, handler: (event: WindowEventMap[K]) => void, element?: undefined, options?: boolean | AddEventListenerOptions): void;
|
|
4
|
+
declare function useEventListener<K extends keyof HTMLElementEventMap & keyof SVGElementEventMap, T extends Element = K extends keyof HTMLElementEventMap ? HTMLDivElement : SVGElement>(eventName: K, handler: ((event: HTMLElementEventMap[K]) => void) | ((event: SVGElementEventMap[K]) => void), element: RefObject<T>, options?: boolean | AddEventListenerOptions): void;
|
|
5
|
+
declare function useEventListener<K extends keyof DocumentEventMap>(eventName: K, handler: (event: DocumentEventMap[K]) => void, element: RefObject<Document>, options?: boolean | AddEventListenerOptions): void;
|
|
6
|
+
export { useEventListener };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Libraries
|
|
2
|
+
import { useEffect, useRef } from 'react';
|
|
3
|
+
// Hooks
|
|
4
|
+
import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';
|
|
5
|
+
function useEventListener(eventName, handler, element, options) {
|
|
6
|
+
// Create a ref that stores handler
|
|
7
|
+
const savedHandler = useRef(handler);
|
|
8
|
+
useIsomorphicLayoutEffect(() => {
|
|
9
|
+
savedHandler.current = handler;
|
|
10
|
+
}, [handler]);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
var _a;
|
|
13
|
+
// Define the listening target
|
|
14
|
+
const targetElement = (_a = element === null || element === void 0 ? void 0 : element.current) !== null && _a !== void 0 ? _a : window;
|
|
15
|
+
if (!(targetElement && targetElement.addEventListener))
|
|
16
|
+
return;
|
|
17
|
+
// Create event listener that calls handler function stored in ref
|
|
18
|
+
const listener = event => {
|
|
19
|
+
savedHandler.current(event);
|
|
20
|
+
};
|
|
21
|
+
targetElement.addEventListener(eventName, listener, options);
|
|
22
|
+
// Remove event listener on cleanup
|
|
23
|
+
return () => {
|
|
24
|
+
targetElement.removeEventListener(eventName, listener, options);
|
|
25
|
+
};
|
|
26
|
+
}, [eventName, element, options]);
|
|
27
|
+
}
|
|
28
|
+
export { useEventListener };
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
// Libraries
|
|
2
|
-
import { useMemo, useRef } from 'react';
|
|
2
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
3
3
|
import { useForceUpdate } from '@antscorp/antsomi-ui/es/hooks';
|
|
4
4
|
import { isNumber } from 'lodash';
|
|
5
5
|
const DEFAULT_RATIO = 1;
|
|
6
6
|
export const useListingItemResize = (props) => {
|
|
7
7
|
var _a;
|
|
8
8
|
const { initialWidth, gap } = props;
|
|
9
|
-
// Ref
|
|
10
9
|
const ref = useRef(null);
|
|
11
|
-
const timeoutAfterChange = useRef(null);
|
|
12
|
-
// Hooks
|
|
13
10
|
const forceUpdate = useForceUpdate();
|
|
14
|
-
/* Variables */
|
|
15
11
|
const containerWidth = (_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.offsetWidth;
|
|
16
|
-
/* Memo */
|
|
17
12
|
/**
|
|
18
13
|
* The number of items per row to display in the container
|
|
19
14
|
*/
|
|
@@ -45,39 +40,23 @@ export const useListingItemResize = (props) => {
|
|
|
45
40
|
}
|
|
46
41
|
return DEFAULT_RATIO;
|
|
47
42
|
}, [containerWidth, gap, initialWidth, itemPerRow]);
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// childList: true,
|
|
67
|
-
// subtree: true,
|
|
68
|
-
// characterData: true,
|
|
69
|
-
// attributeOldValue: true,
|
|
70
|
-
// characterDataOldValue: true,
|
|
71
|
-
// },
|
|
72
|
-
// );
|
|
73
|
-
/* Events */
|
|
74
|
-
window.addEventListener('resize', () => {
|
|
75
|
-
if (timeoutAfterChange) {
|
|
76
|
-
clearTimeout(timeoutAfterChange.current);
|
|
77
|
-
}
|
|
78
|
-
timeoutAfterChange.current = setTimeout(() => {
|
|
79
|
-
forceUpdate();
|
|
80
|
-
}, 200);
|
|
81
|
-
});
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
let timeoutAfterChange = null;
|
|
45
|
+
const handleResize = () => {
|
|
46
|
+
if (timeoutAfterChange) {
|
|
47
|
+
clearTimeout(timeoutAfterChange);
|
|
48
|
+
}
|
|
49
|
+
timeoutAfterChange = setTimeout(() => {
|
|
50
|
+
forceUpdate();
|
|
51
|
+
}, 500);
|
|
52
|
+
};
|
|
53
|
+
window.addEventListener('resize', handleResize);
|
|
54
|
+
return () => {
|
|
55
|
+
window.removeEventListener('resize', handleResize);
|
|
56
|
+
if (timeoutAfterChange) {
|
|
57
|
+
clearTimeout(timeoutAfterChange);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}, [forceUpdate]);
|
|
82
61
|
return { ref, itemPerRow, ratio, gap };
|
|
83
62
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type WindowSize<T extends number | undefined = number | undefined> = {
|
|
2
|
+
width: T;
|
|
3
|
+
height: T;
|
|
4
|
+
};
|
|
5
|
+
type UseWindowSizeOptions<InitializeWithValue extends boolean | undefined> = {
|
|
6
|
+
initializeWithValue: InitializeWithValue;
|
|
7
|
+
debounceDelay?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function useWindowSize(options: UseWindowSizeOptions<false>): WindowSize;
|
|
10
|
+
export declare function useWindowSize(options?: Partial<UseWindowSizeOptions<true>>): WindowSize<number>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { useDebounceCallback, useEventListener, useIsomorphicLayoutEffect } from '.';
|
|
3
|
+
const IS_SERVER = typeof window === 'undefined';
|
|
4
|
+
export function useWindowSize(options = {}) {
|
|
5
|
+
let { initializeWithValue = true } = options;
|
|
6
|
+
if (IS_SERVER) {
|
|
7
|
+
initializeWithValue = false;
|
|
8
|
+
}
|
|
9
|
+
const [windowSize, setWindowSize] = useState(() => {
|
|
10
|
+
if (initializeWithValue) {
|
|
11
|
+
return {
|
|
12
|
+
width: window.innerWidth,
|
|
13
|
+
height: window.innerHeight,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
width: undefined,
|
|
18
|
+
height: undefined,
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
const debouncedSetWindowSize = useDebounceCallback(setWindowSize, options.debounceDelay);
|
|
22
|
+
function handleSize() {
|
|
23
|
+
const setSize = options.debounceDelay ? debouncedSetWindowSize : setWindowSize;
|
|
24
|
+
setSize({
|
|
25
|
+
width: window.innerWidth,
|
|
26
|
+
height: window.innerHeight,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
useEventListener('resize', handleSize);
|
|
30
|
+
// Set size at the first client-side load
|
|
31
|
+
useIsomorphicLayoutEffect(() => {
|
|
32
|
+
handleSize();
|
|
33
|
+
}, []);
|
|
34
|
+
return windowSize;
|
|
35
|
+
}
|