@antscorp/antsomi-ui 1.3.5-beta.209 → 1.3.5-beta.210

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.
Files changed (32) hide show
  1. package/es/components/organism/LeftMenu/components/HomeMenu/constants.js +2 -2
  2. package/es/components/organism/LeftMenu/components/HomeMenu/useHomeMenu.js +2 -2
  3. package/es/components/organism/LeftMenu/components/common/ChildMenu/index.js +8 -8
  4. package/es/components/organism/LeftMenu/components/common/ChildMenu/styled.js +5 -0
  5. package/es/components/organism/LeftMenu/components/common/ChildMenu/utils.d.ts +12 -0
  6. package/es/components/organism/LeftMenu/components/common/ChildMenu/utils.js +13 -4
  7. package/es/components/organism/LeftMenu/hooks/useLeftMenu.d.ts +0 -1
  8. package/es/components/organism/LeftMenu/hooks/useLeftMenu.js +26 -6
  9. package/es/components/organism/LeftMenu/hooks/useNavigatePath.d.ts +5 -0
  10. package/es/components/organism/LeftMenu/hooks/useNavigatePath.js +43 -0
  11. package/es/components/organism/LeftMenu/index.d.ts +2 -0
  12. package/es/components/organism/LeftMenu/index.js +4 -6
  13. package/es/components/organism/LeftMenu/styled.js +1 -1
  14. package/es/components/organism/LeftMenu/utils/index.d.ts +6 -1
  15. package/es/components/organism/LeftMenu/utils/index.js +39 -12
  16. package/es/components/template/Layout/Layout.d.ts +3 -1
  17. package/es/components/template/Layout/Layout.js +22 -7
  18. package/es/components/template/Layout/constants/index.d.ts +2 -0
  19. package/es/components/template/Layout/constants/index.js +2 -0
  20. package/es/components/template/Layout/constants/menuCode.d.ts +29 -0
  21. package/es/components/template/Layout/constants/menuCode.js +30 -0
  22. package/es/components/template/Layout/constants/permission.d.ts +6 -0
  23. package/es/components/template/Layout/constants/permission.js +6 -0
  24. package/es/components/template/Layout/stores/index.d.ts +5 -0
  25. package/es/components/template/Layout/stores/index.js +4 -0
  26. package/es/components/template/Layout/utils/index.d.ts +1 -0
  27. package/es/components/template/Layout/utils/index.js +1 -0
  28. package/es/components/template/Layout/utils/permission.d.ts +16 -0
  29. package/es/components/template/Layout/utils/permission.js +48 -0
  30. package/package.json +1 -1
  31. package/es/services/LeftMenu/utils.d.ts +0 -9
  32. package/es/services/LeftMenu/utils.js +0 -135
@@ -1,6 +1,6 @@
1
1
  export const HOME_REPORT_ROUTES = {
2
- DETAIL: ':reportId',
3
- CONFIGURE: ':reportId/configure',
2
+ DETAIL: 'detail/:dashboardId',
3
+ CONFIGURE: 'detail/:dashboardId/configure',
4
4
  CREATE: 'create',
5
5
  };
6
6
  export const CONFIG_OPTIONS = {
@@ -33,7 +33,7 @@ export const useHomeMenu = () => {
33
33
  const { optionKey, menuItemKey } = args;
34
34
  switch (optionKey) {
35
35
  case CONFIG_OPTIONS.CONFIGURE.key: {
36
- const newPathName = getGeneratePath(getHomePath(HOME_REPORT_ROUTES.CONFIGURE), Object.assign(Object.assign({}, auth), { reportId: menuItemKey }));
36
+ const newPathName = getGeneratePath(getHomePath(HOME_REPORT_ROUTES.CONFIGURE), Object.assign(Object.assign({}, auth), { dashboardId: menuItemKey }));
37
37
  if (newPathName !== pathname) {
38
38
  history.push(newPathName);
39
39
  }
@@ -54,7 +54,7 @@ export const useHomeMenu = () => {
54
54
  history.push(getGeneratePath(getHomePath(HOME_REPORT_ROUTES.CREATE), auth));
55
55
  }, [auth, history, getHomePath]);
56
56
  const onMenuClick = useCallback((key, _) => {
57
- const newPathName = getGeneratePath(getHomePath(HOME_REPORT_ROUTES.DETAIL), Object.assign(Object.assign({}, auth), { reportId: key }));
57
+ const newPathName = getGeneratePath(getHomePath(HOME_REPORT_ROUTES.DETAIL), Object.assign(Object.assign({}, auth), { dashboardId: key }));
58
58
  if (newPathName !== pathname) {
59
59
  history.push(newPathName);
60
60
  }
@@ -12,19 +12,19 @@ import { MenuItemImage } from './components';
12
12
  import { LabelCustom, MenuWrapper } from './styled';
13
13
  // Constants
14
14
  import { ICON_SIZE } from '../../../constants';
15
- import { ENV } from '@antscorp/antsomi-ui/es/config';
16
15
  // Contexts
17
16
  import { AppConfigContext } from '@antscorp/antsomi-ui/es/providers';
18
17
  // Utils
19
- import { findActiveAppCodeByUrl, getGeneratePath } from '../../../utils';
20
- import { findActiveMenuItemByUrl, recursiveFindParentOfActiveItem } from './utils';
18
+ import { findActiveAppCodeByUrl, findLastMatchedCodeByUrl } from '../../../utils';
19
+ import { recursiveFindParentOfActiveItem } from './utils';
21
20
  import { random } from '@antscorp/antsomi-ui/es/utils';
21
+ // Hooks
22
22
  import { useLeftMenuStore } from '../../../stores';
23
+ import { useNavigatePath } from '../../../hooks/useNavigatePath';
23
24
  export const ChildMenu = memo(props => {
24
25
  const { items = [], parentKey, onMenuClick } = props;
25
26
  // Contexts
26
27
  const auth = useContextSelector(AppConfigContext, state => state === null || state === void 0 ? void 0 : state.auth);
27
- const env = useContextSelector(AppConfigContext, state => state === null || state === void 0 ? void 0 : state.env);
28
28
  // Stores
29
29
  const activeAppCode = useLeftMenuStore(store => store.state.activeAppCode);
30
30
  const menuItems = useLeftMenuStore(store => store.state.menuItems);
@@ -36,11 +36,12 @@ export const ChildMenu = memo(props => {
36
36
  const randomMenuWrapperId = random(10);
37
37
  // Hooks
38
38
  const { pathname, hash, search } = useLocation();
39
+ const { isPushDifferentDomain, getPath, navigatePath } = useNavigatePath();
39
40
  // Side Effects
40
41
  useEffect(() => {
41
42
  const url = `${pathname}${hash}${search}`;
42
43
  /** Active menu item by current url */
43
- const activeMenuItem = findActiveMenuItemByUrl({ url, menuItems, auth });
44
+ const activeMenuItem = findLastMatchedCodeByUrl({ url, menuItems, auth });
44
45
  if (activeMenuItem && activeMenuItem !== currentActiveItem) {
45
46
  setCurrentActiveItem(activeMenuItem);
46
47
  /** Find parent key of active menu item to open it */
@@ -75,8 +76,7 @@ export const ChildMenu = memo(props => {
75
76
  var _a;
76
77
  return (_a = args === null || args === void 0 ? void 0 : args.items) === null || _a === void 0 ? void 0 : _a.map(item => {
77
78
  var _a;
78
- const { key, label, children, icon, logo_url, menu_item_path, menu_item_domain, options, optionCallback, } = item;
79
- const domain = !isNil(menu_item_domain) && env === ENV.DEV ? menu_item_domain : '';
79
+ const { key, label, children, icon, logo_url, menu_item_path = null, menu_item_domain = null, options, optionCallback, } = item;
80
80
  const labelComponent = () => (!children || isEmpty(children)) && !isEmpty(options) ? (React.createElement(Flex, { gap: 10, align: "center", justify: "space-between", style: { width: '100%' }, className: "child-menu-label" },
81
81
  React.createElement(LabelCustom, { ellipsis: { tooltip: label } }, label),
82
82
  React.createElement(Dropdown, { menu: {
@@ -90,7 +90,7 @@ export const ChildMenu = memo(props => {
90
90
  React.createElement(Icon, { className: "child-menu-item-icon", type: "icon-ants-three-dot-vertical", style: { marginTop: '2px', zIndex: 1000 } })))) : (React.createElement(LabelCustom, { ellipsis: { tooltip: label } }, label));
91
91
  return {
92
92
  key,
93
- label: isString(menu_item_path) ? (React.createElement(Link, { to: getGeneratePath(`${domain}${menu_item_path}`, auth), className: "menu-link" }, labelComponent())) : (labelComponent()),
93
+ label: isString(menu_item_path) ? (isPushDifferentDomain(menu_item_domain, menu_item_path) ? (React.createElement("div", { onClick: () => navigatePath(menu_item_domain, menu_item_path), className: "menu-link" }, labelComponent())) : (React.createElement(Link, { to: getPath(menu_item_domain, menu_item_path), className: "menu-link" }, labelComponent()))) : (labelComponent()),
94
94
  icon: !isNil(icon) ? (React.createElement(Icon, { type: icon, style: { fontSize: ICON_SIZE } })) : !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 })) : null,
95
95
  children: customMenuItems({ parent: item, items: children }),
96
96
  };
@@ -21,6 +21,11 @@ export const MenuWrapper = styled.div `
21
21
  margin: 0 !important;
22
22
  width: 100% !important;
23
23
 
24
+ div {
25
+ width: ${ICON_SIZE}px;
26
+ height: ${ICON_SIZE}px;
27
+ }
28
+
24
29
  [role='icon'] {
25
30
  font-size: ${ICON_SIZE}px !important;
26
31
  }
@@ -1,5 +1,17 @@
1
1
  import { TFeatureMenu } from '@antscorp/antsomi-ui/es/models/LeftMenu';
2
2
  import { PayloadInfo } from '@antscorp/antsomi-ui/es/types';
3
+ /**
4
+ * Finds the active menu item code based on the provided URL within the given menu items.
5
+ * ATTENTION: Start finding from level 2 because level 1 contains apps
6
+ *
7
+ * @param {Object} args - The arguments object.
8
+ * @param {string} args.url - The URL to match against menu item paths.
9
+ * @param {TFeatureMenu[]} args.menuItems - The array of menu items to search within.
10
+ * @param {Partial<PayloadInfo>} [args.auth] - Additional authentication information (optional).
11
+ * @returns {string | undefined} The menu item code of the active menu item or undefined if not found.
12
+ *
13
+ * @throws Will throw an error if any issue occurs during the process.
14
+ */
3
15
  export declare const findActiveMenuItemByUrl: (args: {
4
16
  url: string;
5
17
  menuItems: TFeatureMenu[];
@@ -1,9 +1,19 @@
1
- // Libraries
2
- import { isNil } from 'lodash';
3
1
  // Utils
4
2
  import { getGeneratePath } from '../../../utils';
5
3
  import { handleError } from '@antscorp/antsomi-ui/es/utils';
6
4
  const PATH = 'src/components/organism/LeftMenu/components/common/ChildMenu/utils.ts';
5
+ /**
6
+ * Finds the active menu item code based on the provided URL within the given menu items.
7
+ * ATTENTION: Start finding from level 2 because level 1 contains apps
8
+ *
9
+ * @param {Object} args - The arguments object.
10
+ * @param {string} args.url - The URL to match against menu item paths.
11
+ * @param {TFeatureMenu[]} args.menuItems - The array of menu items to search within.
12
+ * @param {Partial<PayloadInfo>} [args.auth] - Additional authentication information (optional).
13
+ * @returns {string | undefined} The menu item code of the active menu item or undefined if not found.
14
+ *
15
+ * @throws Will throw an error if any issue occurs during the process.
16
+ */
7
17
  export const findActiveMenuItemByUrl = (args) => {
8
18
  try {
9
19
  const { url, menuItems, auth } = args;
@@ -12,8 +22,7 @@ export const findActiveMenuItemByUrl = (args) => {
12
22
  const recursiveFindActiveItem = (items) => {
13
23
  let activeItem;
14
24
  for (const item of items) {
15
- if (!isNil(item === null || item === void 0 ? void 0 : item.menu_item_path) &&
16
- url.includes(getGeneratePath(item.menu_item_path, auth))) {
25
+ if (!!(item === null || item === void 0 ? void 0 : item.menu_item_path) && url.includes(getGeneratePath(item.menu_item_path, auth))) {
17
26
  activeItem = item === null || item === void 0 ? void 0 : item.menu_item_code;
18
27
  break;
19
28
  }
@@ -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
- appConfig: import("@antscorp/antsomi-ui/es/providers").AppConfigProviderProps;
11
10
  onToggleChildMenu: () => void;
12
11
  onMouseEnter: (key: string) => void;
13
12
  onMouseLeave: () => void;
@@ -8,7 +8,7 @@ import { AppConfigContext } from '@antscorp/antsomi-ui/es/providers';
8
8
  // Queries
9
9
  import { useGetDashboard, useGetDestinationChannel, useGetListMenu, useGetListMenuPermission, } from '@antscorp/antsomi-ui/es/queries/LeftMenu';
10
10
  // Utils
11
- import { findActiveAppCodeByUrl, flattenMenuArray, getMappingAppChildren, recursivePermissionMenu, } from '../utils';
11
+ import { findActiveAppCodeByUrl, findLastMatchedCodeByUrl, flattenMenuArray, getMappingAppChildren, recursivePermissionMenu, } from '../utils';
12
12
  // Store
13
13
  import { useLeftMenuStore } from '../stores';
14
14
  const initialState = {
@@ -17,7 +17,7 @@ const initialState = {
17
17
  };
18
18
  export const useLeftMenu = (props) => {
19
19
  // Props
20
- const { objectType = 'OVERVIEW', objectId = 1, isGrouped = true } = props;
20
+ const { objectType = 'OVERVIEW', objectId = 1, isGrouped = true, onActiveMenuCodeChange } = props;
21
21
  // Hooks
22
22
  const { pathname, hash, search } = useLocation();
23
23
  // Contexts
@@ -93,9 +93,7 @@ export const useLeftMenu = (props) => {
93
93
  // Variables
94
94
  const flattenMenuPermission = flattenMenuArray(menuListPermission || [], 'childs');
95
95
  // Memos
96
- const permissionMenu = useMemo(() => sortBy(recursivePermissionMenu((menuList === null || menuList === void 0 ? void 0 : menuList.rows) || [], flattenMenuPermission), [
97
- 'level_position',
98
- ]), [menuList === null || menuList === void 0 ? void 0 : menuList.rows, flattenMenuPermission]);
96
+ 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]);
99
97
  const mappingChildrenMenu = useMemo(() => getMappingAppChildren({
100
98
  menuList: permissionMenu,
101
99
  auth,
@@ -103,6 +101,9 @@ export const useLeftMenu = (props) => {
103
101
  destinationChannelEntries: destinationChannel === null || destinationChannel === void 0 ? void 0 : destinationChannel.entries,
104
102
  }), [auth, dashboardData, destinationChannel === null || destinationChannel === void 0 ? void 0 : destinationChannel.entries, permissionMenu]);
105
103
  // Side Effects
104
+ /**
105
+ * Change list menu children when hovering or activating items, giving priority to hovering items
106
+ */
106
107
  useEffect(() => {
107
108
  var _a;
108
109
  const appCode = state.hoverItem ? state.hoverItem : activeAppCode;
@@ -133,6 +134,26 @@ export const useLeftMenu = (props) => {
133
134
  search,
134
135
  setLeftMenuState,
135
136
  ]);
137
+ /**
138
+ * Callback function when url change
139
+ */
140
+ useEffect(() => {
141
+ const url = `${pathname}${hash}${search}`;
142
+ const matchedCode = findLastMatchedCodeByUrl({
143
+ url,
144
+ menuItems: mappingChildrenMenu,
145
+ auth,
146
+ });
147
+ onActiveMenuCodeChange === null || onActiveMenuCodeChange === void 0 ? void 0 : onActiveMenuCodeChange(matchedCode, flattenMenuPermission);
148
+ }, [
149
+ auth,
150
+ flattenMenuPermission,
151
+ hash,
152
+ mappingChildrenMenu,
153
+ onActiveMenuCodeChange,
154
+ pathname,
155
+ search,
156
+ ]);
136
157
  /* Callbacks */
137
158
  const onToggleChildMenu = useCallback(() => {
138
159
  setState(prev => (Object.assign(Object.assign({}, prev), { isExpandMenu: !prev.isExpandMenu })));
@@ -154,7 +175,6 @@ export const useLeftMenu = (props) => {
154
175
  activeAppCode,
155
176
  /* Data Queries */
156
177
  permissionMenu,
157
- appConfig,
158
178
  /* Callbacks */
159
179
  onToggleChildMenu,
160
180
  onMouseEnter,
@@ -0,0 +1,5 @@
1
+ export declare const useNavigatePath: () => {
2
+ isPushDifferentDomain: (domain: string | null, path: string | null) => boolean;
3
+ getPath: (domain: string | null, path: string | null) => string;
4
+ navigatePath: (domain: string | null, path: string | null) => void;
5
+ };
@@ -0,0 +1,43 @@
1
+ // Libraries
2
+ import { useContextSelector } from 'use-context-selector';
3
+ import { useCallback } from 'react';
4
+ import { isNil } from 'lodash';
5
+ // Contexts
6
+ import { AppConfigContext } from '@antscorp/antsomi-ui/es/providers';
7
+ // Utils
8
+ import { getGeneratePath } from '../utils';
9
+ // Constants
10
+ import { ENV } from '@antscorp/antsomi-ui/es/config';
11
+ export const useNavigatePath = () => {
12
+ // Contexts
13
+ const { auth, env } = useContextSelector(AppConfigContext, state => state);
14
+ // Callbacks
15
+ const isPushDifferentDomain = useCallback((domain, path) => {
16
+ var _a, _b, _c, _d, _e, _f;
17
+ if (env === ENV.DEV)
18
+ return false;
19
+ const customDomain = domain !== null && domain !== void 0 ? domain : '';
20
+ const splitNextPath = (path === null || path === void 0 ? void 0 : path.split('#')) || ['', ''];
21
+ const isCurrentPathIncludeHash = (_b = (_a = window.location) === null || _a === void 0 ? void 0 : _a.href) === null || _b === void 0 ? void 0 : _b.includes('#');
22
+ const isNextPathIncludeHash = path === null || path === void 0 ? void 0 : path.includes('#');
23
+ if (isCurrentPathIncludeHash && isNextPathIncludeHash) {
24
+ const currentRoute = ((_e = (_d = (_c = window.location.href) === null || _c === void 0 ? void 0 : _c.split) === null || _d === void 0 ? void 0 : _d['#']) === null || _e === void 0 ? void 0 : _e[0]) || '';
25
+ const nextRoute = `${customDomain}${splitNextPath[0]}`;
26
+ return currentRoute !== nextRoute;
27
+ }
28
+ return !!customDomain && customDomain !== ((_f = window.location) === null || _f === void 0 ? void 0 : _f.origin);
29
+ }, [env]);
30
+ const getPath = useCallback((domain, path) => {
31
+ var _a;
32
+ if ((path === null || path === void 0 ? void 0 : path.includes('#')) && isPushDifferentDomain(domain, path)) {
33
+ const customPath = ((_a = path === null || path === void 0 ? void 0 : path.split('#')) === null || _a === void 0 ? void 0 : _a[1]) || '';
34
+ return getGeneratePath(customPath, auth);
35
+ }
36
+ return getGeneratePath(`${path !== null && path !== void 0 ? path : ''}`, auth);
37
+ }, [auth, isPushDifferentDomain]);
38
+ const navigatePath = useCallback((domain, path) => {
39
+ const newDomain = isNil(domain) || env === ENV.DEV ? '' : domain;
40
+ window.location.assign(getGeneratePath(`${newDomain}${path}`, auth));
41
+ }, [auth, env]);
42
+ return { isPushDifferentDomain, getPath, navigatePath };
43
+ };
@@ -1,9 +1,11 @@
1
1
  import React from 'react';
2
+ import { FeatureMenuPermission } from '@antscorp/antsomi-ui/es/models/LeftMenu';
2
3
  export interface LeftMenuProps {
3
4
  objectType?: string;
4
5
  objectId?: number;
5
6
  isGrouped?: boolean;
6
7
  style?: React.CSSProperties;
7
8
  className?: string;
9
+ onActiveMenuCodeChange?: (activeMenuCode?: string, flattenPermissionList?: FeatureMenuPermission[]) => void;
8
10
  }
9
11
  export declare const LeftMenu: React.FC<LeftMenuProps>;
@@ -10,14 +10,12 @@ import SubLogoAntsomi from '@antscorp/antsomi-ui/es/assets/images/logo/sub-logo-
10
10
  // Styled
11
11
  import { ChildMenuWrapper, ExpandWrapper, FeatureMenu, FeatureMenuItem, LeftMenuNav, LeftMenuNavWrapper, PopoverWrapper, NavLogoWrapper, FeatureMenuWrapper, } from './styled';
12
12
  // Constants
13
- import { ENV } from '@antscorp/antsomi-ui/es/config';
14
13
  import { APP_KEYS, ICON_SIZE } from './constants';
15
14
  // Components
16
15
  import { ProfilesMenu, ContentMenu, DataMenu, MarketingMenu, HomeMenu, InsightsMenu, SettingsMenu, TemplatesMenu, } from './components';
17
16
  // Hooks
18
17
  import { useLeftMenu } from './hooks';
19
- // Utils
20
- import { getGeneratePath } from './utils';
18
+ import { useNavigatePath } from './hooks/useNavigatePath';
21
19
  export const LeftMenu = memo(props => {
22
20
  var _a;
23
21
  const { style, className } = props;
@@ -28,9 +26,10 @@ export const LeftMenu = memo(props => {
28
26
  /* Store */
29
27
  activeAppCode,
30
28
  /* Data Queries */
31
- permissionMenu, appConfig,
29
+ permissionMenu,
32
30
  /* Callbacks */
33
31
  onToggleChildMenu, onMouseEnter, onMouseLeave, } = useLeftMenu(props);
32
+ const { isPushDifferentDomain, getPath, navigatePath } = useNavigatePath();
34
33
  // Memo
35
34
  const childMenu = useMemo(() => {
36
35
  const selectedFeatureKey = state.hoverItem ? state.hoverItem : activeAppCode;
@@ -66,14 +65,13 @@ export const LeftMenu = memo(props => {
66
65
  // Render components
67
66
  const renderFeatureMenuItems = (item) => {
68
67
  const { menu_item_name, menu_item, icon_name, menu_item_code, menu_item_path, menu_item_domain, } = item;
69
- const domain = !isNil(menu_item_domain) && (appConfig === null || appConfig === void 0 ? void 0 : appConfig.env) === ENV.DEV ? menu_item_domain : '';
70
68
  const isActive = activeAppCode === menu_item_code;
71
69
  const isHover = state.hoverItem === menu_item_code;
72
70
  const labelComponent = () => (React.createElement("li", { role: "menuitem", className: classNames({ isActive, isHover }) },
73
71
  React.createElement("div", { className: "icon-wrapper" }, isNil(icon_name) ? null : React.createElement(Icon, { type: icon_name, style: { fontSize: ICON_SIZE } })),
74
72
  React.createElement(Typography.Text, null, menu_item_name),
75
73
  React.createElement("div", { className: "popup-triangle" })));
76
- return (React.createElement(FeatureMenuItem, { key: menu_item, onMouseEnter: () => onMouseEnter(menu_item_code) }, isString(menu_item_path) ? (React.createElement(Link, { to: getGeneratePath(`${domain}${menu_item_path}`, appConfig === null || appConfig === void 0 ? void 0 : appConfig.auth), className: "menu-link" }, labelComponent())) : (labelComponent())));
74
+ 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) }, labelComponent())) : (React.createElement(Link, { to: getPath(menu_item_domain, menu_item_path), className: "menu-link" }, labelComponent()))) : (labelComponent())));
77
75
  };
78
76
  return (React.createElement(LeftMenuNavWrapper, { style: style, className: className },
79
77
  React.createElement(LeftMenuNav, null,
@@ -11,7 +11,7 @@ export const PopoverWrapper = styled.div `
11
11
  visibility: hidden;
12
12
  position: absolute;
13
13
  background-color: white;
14
- left: 70px;
14
+ left: 69px;
15
15
  border-radius: ${(_a = THEME === null || THEME === void 0 ? void 0 : THEME.token) === null || _a === void 0 ? void 0 : _a.borderRadiusXL}px;
16
16
  bottom: 15px;
17
17
  width: 230px;
@@ -25,7 +25,7 @@ export declare const recursivePermissionMenu: (menuItems: TFeatureMenu[], MenuPe
25
25
  * @returns {string} The generated path with replaced parameters.
26
26
  */
27
27
  export declare const getGeneratePath: (path: string, params?: Partial<PayloadInfo> & {
28
- reportId?: string;
28
+ dashboardId?: string;
29
29
  channelId?: number;
30
30
  }) => string;
31
31
  /**
@@ -54,3 +54,8 @@ export declare const findActiveAppCodeByUrl: (args: {
54
54
  menuItems: TFeatureMenu[];
55
55
  auth?: Partial<PayloadInfo>;
56
56
  }) => string | undefined;
57
+ export declare const findLastMatchedCodeByUrl: (args: {
58
+ url: string;
59
+ menuItems: TFeatureMenu[];
60
+ auth?: Partial<PayloadInfo>;
61
+ }) => string | undefined;
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  // Libraries
13
- import { isArray, isEmpty, isNil } from 'lodash';
13
+ import { isArray, isEmpty, sortBy } from 'lodash';
14
14
  import { generatePath } from 'react-router-dom';
15
15
  // Constants
16
16
  import { APP_KEYS, MARKETING_CHANNEL_KEY, HOME_MENU_ITEMS, MARKETING_ROUTES, MENU_ITEM_TYPE, MARKETING_CHANNEL_CODE, RENDER_OPTION, } from '../constants';
@@ -54,9 +54,11 @@ export const recursivePermissionMenu = (menuItems, MenuPermissions) => {
54
54
  if (menu_item_type !== MENU_ITEM_TYPE.MENU) {
55
55
  return true;
56
56
  }
57
- return MenuPermissions === null || MenuPermissions === void 0 ? void 0 : MenuPermissions.find(({ app_code = '', menu_code = '' }) => !isNil(permission_code) && [app_code, menu_code].includes(permission_code));
57
+ return MenuPermissions === null || MenuPermissions === void 0 ? void 0 : MenuPermissions.find(({ app_code = '', menu_code = '' }) => !!permission_code && [app_code, menu_code].includes(permission_code));
58
58
  })) === null || _a === void 0 ? void 0 : _a.map(item => (Object.assign(Object.assign({}, item), (isArray(item.children)
59
- ? { children: recursivePermissionMenu(item.children, MenuPermissions) }
59
+ ? {
60
+ children: recursivePermissionMenu(sortBy(item.children || [], ['level_position']), MenuPermissions),
61
+ }
60
62
  : {}))))) === null || _b === void 0 ? void 0 : _b.filter(item => !(isArray(item.children) && isEmpty(item.children)));
61
63
  return menu;
62
64
  };
@@ -66,12 +68,13 @@ export const recursivePermissionMenu = (menuItems, MenuPermissions) => {
66
68
  */
67
69
  export const getGeneratePath = (path, params) => {
68
70
  try {
69
- return generatePath(path.replace('#', `/${params === null || params === void 0 ? void 0 : params.portalId}#`), {
70
- user_id: (params === null || params === void 0 ? void 0 : params.userId) || '-1',
71
- networkId: !isNil(params === null || params === void 0 ? void 0 : params.portalId) ? params === null || params === void 0 ? void 0 : params.portalId : -1,
72
- portalId: !isNil(params === null || params === void 0 ? void 0 : params.portalId) ? params === null || params === void 0 ? void 0 : params.portalId : -1,
73
- reportId: (params === null || params === void 0 ? void 0 : params.reportId) || '-1',
74
- channelId: !isNil(params === null || params === void 0 ? void 0 : params.channelId) ? params === null || params === void 0 ? void 0 : params.channelId : -1,
71
+ const { portalId, userId, dashboardId, channelId } = params || {};
72
+ return generatePath(path, {
73
+ user_id: userId !== null && userId !== void 0 ? userId : '-1',
74
+ networkId: portalId !== null && portalId !== void 0 ? portalId : -1,
75
+ portalId: portalId !== null && portalId !== void 0 ? portalId : -1,
76
+ dashboardId: dashboardId !== null && dashboardId !== void 0 ? dashboardId : '-1',
77
+ channelId: channelId !== null && channelId !== void 0 ? channelId : -1,
75
78
  });
76
79
  }
77
80
  catch (error) {
@@ -162,8 +165,7 @@ export const findActiveAppCodeByUrl = (args) => {
162
165
  const recursiveCheckHasActiveChild = (items) => {
163
166
  let matchAppCode = false;
164
167
  for (const item of items) {
165
- if (!isNil(item === null || item === void 0 ? void 0 : item.menu_item_path) &&
166
- url.includes(getGeneratePath(item.menu_item_path, auth))) {
168
+ if (!!(item === null || item === void 0 ? void 0 : item.menu_item_path) && url.includes(getGeneratePath(item.menu_item_path, auth))) {
167
169
  matchAppCode = true;
168
170
  break;
169
171
  }
@@ -177,7 +179,7 @@ export const findActiveAppCodeByUrl = (args) => {
177
179
  return matchAppCode;
178
180
  };
179
181
  for (const menuItem of menuItems) {
180
- if (!isNil(menuItem === null || menuItem === void 0 ? void 0 : menuItem.menu_item_path) &&
182
+ if (!!(menuItem === null || menuItem === void 0 ? void 0 : menuItem.menu_item_path) &&
181
183
  url.includes(getGeneratePath(menuItem.menu_item_path, auth))) {
182
184
  matchAppCode = menuItem.menu_item_code;
183
185
  break;
@@ -198,3 +200,28 @@ export const findActiveAppCodeByUrl = (args) => {
198
200
  });
199
201
  }
200
202
  };
203
+ export const findLastMatchedCodeByUrl = (args) => {
204
+ try {
205
+ const { url, menuItems, auth } = args;
206
+ const matchedItemCodes = [];
207
+ const recursiveFindActiveItem = (items) => {
208
+ for (const item of items) {
209
+ if (!!(item === null || item === void 0 ? void 0 : item.menu_item_path) && url.includes(getGeneratePath(item.menu_item_path, auth))) {
210
+ matchedItemCodes.push(item.menu_item_code);
211
+ }
212
+ if ((item === null || item === void 0 ? void 0 : item.children) && item.children.length) {
213
+ recursiveFindActiveItem(item.children);
214
+ }
215
+ }
216
+ };
217
+ recursiveFindActiveItem(menuItems || []);
218
+ return matchedItemCodes === null || matchedItemCodes === void 0 ? void 0 : matchedItemCodes.pop();
219
+ }
220
+ catch (error) {
221
+ handleError(error, {
222
+ path: PATH,
223
+ name: findLastMatchedCodeByUrl.name,
224
+ args,
225
+ });
226
+ }
227
+ };
@@ -7,7 +7,9 @@ interface LayoutProps {
7
7
  headerProps?: Partial<HeaderV2Props>;
8
8
  leftMenuProps?: LeftMenuProps;
9
9
  processingNotificationProps?: Partial<ProcessingNotificationProps>;
10
- workspaceProps?: React.HTMLAttributes<HTMLDivElement>;
10
+ workspaceProps?: React.HTMLAttributes<HTMLDivElement> & {
11
+ workspaceContentProps?: React.HTMLAttributes<HTMLDivElement>;
12
+ };
11
13
  }
12
14
  export declare const Layout: React.FC<PropsWithChildren<LayoutProps>>;
13
15
  declare global {
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  // Libraries
13
- import React, { memo, useMemo } from 'react';
13
+ import React, { memo, useCallback, useMemo, useState } from 'react';
14
14
  import { useContextSelector } from 'use-context-selector';
15
15
  import AntsProcessingNotification from '@antscorp/processing-notification';
16
16
  import { merge } from 'lodash';
@@ -27,16 +27,19 @@ import { PERMISSION_API, SOCKET_API } from '../../../constants';
27
27
  // Css
28
28
  import '@antscorp/processing-notification/dist/index.css';
29
29
  import { useLayoutStore } from './stores';
30
+ import { checkingRoleScope } from './utils';
30
31
  export const Layout = memo(props => {
31
32
  const { leftMenuProps, headerProps = {}, workspaceProps, processingNotificationProps, children, } = props;
32
33
  const _a = leftMenuProps || {}, { className = '' } = _a, restOfLeftMenuProps = __rest(_a, ["className"]);
34
+ const _b = workspaceProps || {}, { workspaceContentProps } = _b, restOfWorkspaceProps = __rest(_b, ["workspaceContentProps"]);
33
35
  // Selectors
34
36
  const { auth, languageCode } = useContextSelector(AppConfigContext, state => state);
35
37
  const { token, userId, portalId } = auth || {};
36
38
  const headerStore = useLayoutStore(store => store.state.header);
39
+ const [showAccountSelection, setShowAccountSelection] = useState(false);
37
40
  // Memo
38
41
  const initialHeaderProps = useMemo(() => {
39
- var _a;
42
+ var _a, _b;
40
43
  return (Object.assign(Object.assign({ className: 'layout-header' }, headerProps), { helpConfig: {
41
44
  configs: Object.assign(Object.assign({}, (_a = headerProps === null || headerProps === void 0 ? void 0 : headerProps.helpConfig) === null || _a === void 0 ? void 0 : _a.configs), { appCode: 'SANDBOX_MARKETING', avatar: '//c0-platform.ants.tech/avatar/2021/09/17/0xgbkurioo.png', config: {
42
45
  p_timezone: 'Asia/Singapore',
@@ -45,18 +48,30 @@ export const Layout = memo(props => {
45
48
  embeddedData: {},
46
49
  INSIGHT_U_OGS: 'uogs',
47
50
  } }),
48
- }, accountSharingConfig: Object.assign(Object.assign({}, headerProps === null || headerProps === void 0 ? void 0 : headerProps.accountSharingConfig), { u_ogs: 'uogs', appCode: 'APP_CUSTOMER_360' }) }));
49
- }, [headerProps]);
51
+ }, accountSharingConfig: Object.assign(Object.assign({}, headerProps === null || headerProps === void 0 ? void 0 : headerProps.accountSharingConfig), { u_ogs: 'uogs', appCode: 'APP_CUSTOMER_360' }), accountSelection: Object.assign(Object.assign({}, headerProps === null || headerProps === void 0 ? void 0 : headerProps.accountSelection), { show: ((_b = headerProps === null || headerProps === void 0 ? void 0 : headerProps.accountSelection) === null || _b === void 0 ? void 0 : _b.show) && showAccountSelection }) }));
52
+ }, [headerProps, showAccountSelection]);
50
53
  const mergeHeaderProps = useMemo(() => merge(initialHeaderProps, headerStore), [initialHeaderProps, headerStore]);
51
54
  const antsProcessingNotificationConfig = useMemo(() => (Object.assign({ permissionDomain: PERMISSION_API, socketDomain: SOCKET_API, token, accountId: userId, userId, lang: languageCode, networkId: portalId }, processingNotificationProps)), [languageCode, portalId, token, userId, processingNotificationProps]);
55
+ // const showAccountSelection = useMemo(() => HIDE_MODAL_ACCOUNT.includes(menuCodeActive), []);
56
+ // const showAccountSelection =
57
+ // !state.hasRoleBreadcrumb ||
58
+ // HIDE_MODAL_ACCOUNT.includes(menuCodeActive) ||
59
+ // isHiddenAccountJourney;
60
+ const onActiveMenuCodeChange = useCallback((activeMenuCode, flattenPermissionList) => {
61
+ const menuPermission = flattenPermissionList === null || flattenPermissionList === void 0 ? void 0 : flattenPermissionList.find(item => activeMenuCode === item.app_code || activeMenuCode === item.menu_code);
62
+ const roleScope = activeMenuCode && menuPermission
63
+ ? checkingRoleScope({ menuCode: activeMenuCode, menuPermission })
64
+ : false;
65
+ setShowAccountSelection(roleScope);
66
+ }, []);
52
67
  return (React.createElement(LayoutWrapper, null,
53
68
  React.createElement(HeaderV2, Object.assign({}, mergeHeaderProps)),
54
69
  React.createElement(Flex, { className: "layout-body" },
55
- React.createElement(LeftMenu, Object.assign({ className: `layout-body__menu ${className}` }, restOfLeftMenuProps)),
70
+ React.createElement(LeftMenu, Object.assign({ className: `layout-body__menu ${className}` }, restOfLeftMenuProps, { onActiveMenuCodeChange: onActiveMenuCodeChange })),
56
71
  React.createElement(ContentWrapper, null,
57
- React.createElement("div", Object.assign({}, workspaceProps, { className: `layout-body__content ${(workspaceProps === null || workspaceProps === void 0 ? void 0 : workspaceProps.className) || ''}` }),
72
+ React.createElement("div", Object.assign({}, restOfWorkspaceProps, { className: `layout-body__content ${(workspaceProps === null || workspaceProps === void 0 ? void 0 : workspaceProps.className) || ''}` }),
58
73
  React.createElement(NotificationWrapper, null,
59
74
  React.createElement(AntsProcessingNotification, Object.assign({}, antsProcessingNotificationConfig))),
60
- React.createElement(ChildrenWrapper, null,
75
+ React.createElement(ChildrenWrapper, Object.assign({}, workspaceContentProps),
61
76
  React.createElement("div", null, children)))))));
62
77
  });
@@ -0,0 +1,2 @@
1
+ export * from './menuCode';
2
+ export * from './permission';
@@ -0,0 +1,2 @@
1
+ export * from './menuCode';
2
+ export * from './permission';
@@ -0,0 +1,29 @@
1
+ export declare const MENU_CODE: {
2
+ VISITOR: string;
3
+ PLANNINGS: string;
4
+ CUSTOMER: string;
5
+ SEGMENT: string;
6
+ EVENT_SOURCES: string;
7
+ ANALYTICS_MODELS: string;
8
+ JOURNEY: string;
9
+ DESTINATIONS_HUB: string;
10
+ ACCOUNT: string;
11
+ DATA_ENCRYPT: string;
12
+ PORTAL_PREFERENCES: string;
13
+ BUSINESS_OBJECT: string;
14
+ PROMOTION_CENTER: string;
15
+ LABELS: string;
16
+ DASHBOARD_OVERVIEW: string;
17
+ MEDIA_TEMPLATE: string;
18
+ JSON_TEMPLATE: string;
19
+ EMAIL_TEMPLATE: string;
20
+ DIAGRAM: string;
21
+ RFM: string;
22
+ LINK_MANAGEMENT: string;
23
+ CONVERSION: string;
24
+ OVERVIEW: string;
25
+ DASHBOARD: string;
26
+ DATA_VIEW: string;
27
+ DATA_OBJECT: string;
28
+ JOURNEY_TACTIC: string;
29
+ };
@@ -0,0 +1,30 @@
1
+ export const MENU_CODE = {
2
+ VISITOR: `VISITOR`,
3
+ PLANNINGS: 'PLANNINGS',
4
+ CUSTOMER: `CUSTOMER`,
5
+ SEGMENT: `SEGMENT`,
6
+ EVENT_SOURCES: `EVENT_SOURCES`,
7
+ ANALYTICS_MODELS: `ANALYTICS_MODELS`,
8
+ JOURNEY: `JOURNEY`,
9
+ DESTINATIONS_HUB: `DESTINATIONS_HUB`,
10
+ ACCOUNT: `ACCOUNT`,
11
+ DATA_ENCRYPT: `DATA_ENCRYPT`,
12
+ PORTAL_PREFERENCES: 'PORTAL_PREFERENCES',
13
+ // PORTAL_PREFERENCES: 'ACCOUNT',
14
+ BUSINESS_OBJECT: 'BUSINESS_OBJECT',
15
+ PROMOTION_CENTER: 'PROMOTION_CENTER',
16
+ LABELS: 'LABELS',
17
+ DASHBOARD_OVERVIEW: 'DASHBOARD_OVERVIEW',
18
+ MEDIA_TEMPLATE: 'MEDIA_TEMPLATE',
19
+ JSON_TEMPLATE: 'JSON_TEMPLATE',
20
+ EMAIL_TEMPLATE: 'EMAIL_TEMPLATE',
21
+ DIAGRAM: 'DATA_SCHEMA',
22
+ RFM: 'RFM',
23
+ LINK_MANAGEMENT: 'LINK_MANAGEMENT',
24
+ CONVERSION: 'CONVERSION',
25
+ OVERVIEW: 'JOURNEY_OVERVIEW',
26
+ DASHBOARD: 'DASHBOARD',
27
+ DATA_VIEW: 'DATA_VIEW',
28
+ DATA_OBJECT: 'DATA_OBJECT',
29
+ JOURNEY_TACTIC: 'JOURNEY_TACTIC',
30
+ };
@@ -0,0 +1,6 @@
1
+ export declare const APP_ROLE_SCOPE: {
2
+ NONE: number;
3
+ CREATED_BY_USER: number;
4
+ MANAGEMENT_BY_USER: number;
5
+ EVERYTHING: number;
6
+ };
@@ -0,0 +1,6 @@
1
+ export const APP_ROLE_SCOPE = {
2
+ NONE: 1,
3
+ CREATED_BY_USER: 2,
4
+ MANAGEMENT_BY_USER: 3,
5
+ EVERYTHING: 4,
6
+ };
@@ -2,15 +2,20 @@ import { HeaderV2Props } from '../../../molecules';
2
2
  import { DeepPartial } from '@antscorp/antsomi-ui/es/types';
3
3
  export interface HeaderStore extends Partial<HeaderV2Props> {
4
4
  }
5
+ export interface LeftMenuStore {
6
+ menuCodeActive?: string;
7
+ }
5
8
  export interface WorkspaceStore {
6
9
  }
7
10
  export interface LayoutStoreState {
8
11
  header: HeaderStore;
12
+ leftMenu: LeftMenuStore;
9
13
  workspace: WorkspaceStore;
10
14
  }
11
15
  interface LayoutStore {
12
16
  state: LayoutStoreState;
13
17
  setHeaderState: (state: DeepPartial<HeaderStore>) => void;
18
+ setLeftMenuState: (state: DeepPartial<LeftMenuStore>) => void;
14
19
  setWorkspaceState: (state: Partial<WorkspaceStore>) => void;
15
20
  setLayoutState: (state: DeepPartial<LayoutStoreState>) => void;
16
21
  }
@@ -3,6 +3,7 @@ import { create } from 'zustand';
3
3
  import { merge } from 'lodash';
4
4
  const initialState = {
5
5
  header: {},
6
+ leftMenu: {},
6
7
  workspace: {},
7
8
  };
8
9
  export const useLayoutStore = create(set => ({
@@ -11,6 +12,9 @@ export const useLayoutStore = create(set => ({
11
12
  setHeaderState: newState => set(store => ({
12
13
  state: Object.assign(Object.assign({}, store.state), { header: Object.assign(Object.assign({}, store.state.header), newState) }),
13
14
  })),
15
+ setLeftMenuState: newState => set(store => ({
16
+ state: Object.assign(Object.assign({}, store.state), { leftMenu: Object.assign(Object.assign({}, store.state.leftMenu), newState) }),
17
+ })),
14
18
  setWorkspaceState: newState => set(store => ({
15
19
  state: Object.assign(Object.assign({}, store.state), { workspace: Object.assign(Object.assign({}, store.state.workspace), newState) }),
16
20
  })),
@@ -0,0 +1 @@
1
+ export * from './permission';
@@ -0,0 +1 @@
1
+ export * from './permission';
@@ -0,0 +1,16 @@
1
+ import { FeatureMenuPermission } from '@antscorp/antsomi-ui/es/models/LeftMenu';
2
+ /**
3
+ *
4
+ * @param {*} menuCode MENU_CODE
5
+ * @param {*} action APP_ACTION
6
+ * @param {*} scope APP_ROLE_SCOPE
7
+ * @param {*} isExactly
8
+ * @returns
9
+ */
10
+ export declare const checkingRoleScope: (args: {
11
+ menuCode: string;
12
+ menuPermission: FeatureMenuPermission;
13
+ action?: string;
14
+ scope?: string;
15
+ isExactly?: boolean;
16
+ }) => boolean;
@@ -0,0 +1,48 @@
1
+ import { MENU_CODE, APP_ROLE_SCOPE } from '../constants';
2
+ const EDIT_ROLE = new Set(['CREATE', 'UPDATE', 'DELETE']);
3
+ /**
4
+ *
5
+ * @param {*} menuCode MENU_CODE
6
+ * @param {*} action APP_ACTION
7
+ * @param {*} scope APP_ROLE_SCOPE
8
+ * @param {*} isExactly
9
+ * @returns
10
+ */
11
+ export const checkingRoleScope = (args) => {
12
+ const { menuCode, menuPermission, scope = APP_ROLE_SCOPE.NONE, action = 'NONE', isExactly = false, } = args;
13
+ if (![
14
+ MENU_CODE.JOURNEY,
15
+ MENU_CODE.LABELS,
16
+ MENU_CODE.DASHBOARD_OVERVIEW,
17
+ MENU_CODE.MEDIA_TEMPLATE,
18
+ MENU_CODE.EMAIL_TEMPLATE,
19
+ MENU_CODE.SEGMENT,
20
+ MENU_CODE.DESTINATIONS_HUB,
21
+ MENU_CODE.BUSINESS_OBJECT,
22
+ MENU_CODE.DATA_OBJECT,
23
+ MENU_CODE.DATA_VIEW,
24
+ ].includes(menuCode))
25
+ return false;
26
+ const menuRole = menuPermission;
27
+ let isOK = false;
28
+ // role Create/Update/Delete is similar current define, only has view and edit(create/delete)
29
+ const { selected_view = 1, selected_edit = 1 } = menuRole;
30
+ if (isExactly) {
31
+ if (EDIT_ROLE.has(action)) {
32
+ isOK = Number(selected_edit) === Number(scope);
33
+ }
34
+ else {
35
+ isOK = Number(selected_view) === Number(scope);
36
+ }
37
+ }
38
+ else {
39
+ // eslint-disable-next-line no-lonely-if
40
+ if (EDIT_ROLE.has(action)) {
41
+ isOK = Number(selected_edit) >= Number(scope);
42
+ }
43
+ else {
44
+ isOK = Number(selected_view) >= Number(scope);
45
+ }
46
+ }
47
+ return isOK;
48
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antscorp/antsomi-ui",
3
- "version": "1.3.5-beta.209",
3
+ "version": "1.3.5-beta.210",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",
@@ -1,9 +0,0 @@
1
- export declare function getCurrentUserId(): string;
2
- export declare const convertShareAccessToFE: (shareAccess?: any) => {
3
- accessInfo: {
4
- general: any;
5
- listAccess: any[];
6
- };
7
- isAllowEdit: boolean;
8
- isPublic: any;
9
- };
@@ -1,135 +0,0 @@
1
- import { generateKey } from '../../utils';
2
- const getAccessType = public_role => {
3
- switch (public_role) {
4
- case 2: // editor
5
- return {
6
- label: 'Editor',
7
- value: 'editor',
8
- type: 'TYPE_ACCESS',
9
- };
10
- case 3: // viewer
11
- return {
12
- label: 'Viewer',
13
- value: 'viewer',
14
- type: 'TYPE_ACCESS',
15
- };
16
- default:
17
- return {};
18
- }
19
- };
20
- export function getCurrentUserId() {
21
- return '';
22
- // const userId = safeParse(getAppSession('user_id'), 0);
23
- // if (userId === 0) {
24
- // // if user_id not set, read 3rd cookie
25
- // try {
26
- // const tempt = getCookie(`${PORTAL_CONFIG.INSIGHT_U_OGS}_${getPortalId()}`);
27
- // // console.log(tempt);
28
- // if (tempt) {
29
- // const data = JSON.parse(tempt);
30
- // return parseInt(window.decodeURIComponent(data.user_id));
31
- // }
32
- // } catch (err) {
33
- // console.error(err);
34
- // }
35
- // }
36
- // return userId;
37
- }
38
- const checkAllowEdit = (listAccess = [], isPublic, publicRole) => {
39
- let isAllowEdit = false;
40
- const userId = getCurrentUserId();
41
- const listUserIdAllowEdit = listAccess.map(access => {
42
- if (+access.role === 1 || +access.role === 2) {
43
- return +access.user_id;
44
- }
45
- return undefined;
46
- });
47
- if (isPublic && +publicRole === 2) {
48
- // dashboard set permission public-edit
49
- isAllowEdit = true;
50
- }
51
- else {
52
- isAllowEdit = listUserIdAllowEdit.includes(+userId);
53
- }
54
- return isAllowEdit;
55
- };
56
- export const convertShareAccessToFE = (shareAccess = {}) => {
57
- const dataConvert = {
58
- general: {},
59
- listAccess: [],
60
- };
61
- const { is_public, list_access = [], public_role } = shareAccess || {};
62
- let newGeneral = {};
63
- let newListAccess = [];
64
- switch (is_public) {
65
- case 1: // public
66
- newGeneral = {
67
- label: 'Public',
68
- value: 'public',
69
- description: 'Anyone on the portal can view this item',
70
- icon: 'icon-xlab-padlock-open',
71
- type: 'GENERAL_ACCESS',
72
- isPublic: 1,
73
- };
74
- if (public_role) {
75
- newGeneral.accessType = getAccessType(+public_role);
76
- }
77
- break;
78
- case 0:
79
- newGeneral = {
80
- label: 'Restricted',
81
- value: 'restricted',
82
- description: 'Only people with access can open this item',
83
- icon: 'icon-xlab-padlock-filled',
84
- type: 'GENERAL_ACCESS',
85
- isPublic: 0,
86
- };
87
- break;
88
- default:
89
- break;
90
- }
91
- newListAccess = list_access.map(access => {
92
- const { user_id, full_name, email, role, avatar } = access;
93
- const data = {
94
- id: generateKey(),
95
- userId: +user_id,
96
- name: full_name,
97
- email,
98
- role: +role,
99
- avatar,
100
- };
101
- if (+role === 1) {
102
- data.accessType = {
103
- value: 'owner',
104
- label: 'Owner',
105
- };
106
- data.allow_view = 1;
107
- data.allow_edit = 1;
108
- }
109
- else if (+role === 2) {
110
- data.accessType = {
111
- value: 'editor',
112
- label: 'Editor',
113
- };
114
- data.allow_view = 1;
115
- data.allow_edit = 1;
116
- }
117
- else {
118
- data.accessType = {
119
- value: 'viewer',
120
- label: 'Viewer',
121
- };
122
- data.allow_view = 1;
123
- data.allow_edit = 0;
124
- }
125
- return data;
126
- });
127
- const isAllowEdit = checkAllowEdit(list_access, is_public, public_role);
128
- dataConvert.general = newGeneral;
129
- dataConvert.listAccess = newListAccess;
130
- return {
131
- accessInfo: dataConvert,
132
- isAllowEdit,
133
- isPublic: is_public,
134
- };
135
- };