diff --git a/apps/web/src/lib/access-control/page-access-helper.ts b/apps/web/src/lib/access-control/page-access-helper.ts index 063ed6b5c6..8d3b56691c 100644 --- a/apps/web/src/lib/access-control/page-access-helper.ts +++ b/apps/web/src/lib/access-control/page-access-helper.ts @@ -13,10 +13,18 @@ import { WORKSPACE_OWNER_DEFAULT_PERMISSIONS, WORKSPACE_USER_MINIMAL_PERMISSIONS, } from '@/lib/access-control/config'; +import config from '@/lib/config'; +import type { GlobalServiceConfig } from '@/lib/config/global-config/type'; import type { Menu, MenuId } from '@/lib/menu/config'; import type { LSBItem, LSBMenu } from '@/common/modules/navigations/lsb/type'; +import { + ALERT_V1_WORKSPACE_PAGE_ACCESS_MENU_LIST, + ALERT_V2_WORKSPACE_PAGE_ACCESS_MENU_LIST, DEFAULT_WORKSPACE_PAGE_ACCESS_MENU_LIST, +} from '@/services/iam/constants/role-constant'; +import type { PageAccessMenuByConfig } from '@/services/iam/types/role-type'; + export const getDefaultPageAccessPermissionList = (roleType?: RoleType): MenuId[] => { if (roleType === 'SYSTEM_ADMIN') return SYSTEM_USER_DEFAULT_PERMISSIONS; if (roleType === 'DOMAIN_ADMIN') return DOMAIN_ADMIN_DEFAULT_PERMISSIONS; @@ -38,10 +46,11 @@ export const flattenMenu = (menuList: Menu[]): Menu[] => menuList.flatMap((menu) ...(menu.subMenuList ? flattenMenu(menu.subMenuList) : []), ]); -export const getPageAccessMapFromRawData = (pageAccessPermissions?: string[]): PageAccessMap => { +export const getPageAccessMapFromRawData = (pageAccessPermissions?: string[], isRolePage?: boolean): PageAccessMap => { + const globalConfig = config.get('SERVICES') || {}; const menuStore = useMenuStore(); const result: PageAccessMap = {}; - const menuListByVersion = menuStore.state.menuList; + const menuListByVersion = !isRolePage ? menuStore.state.menuList : getEnabledMenus(globalConfig); const flattenedMenuList = flattenMenu(menuListByVersion); const setPermissions = (id: string, read = true, write = true, access = true) => { result[id] = { read, write, access }; @@ -113,3 +122,29 @@ export const checkAllMenuReadonly = (permissions: string[]) => permissions.every const accessType = item.split('.*')[0].split(':')[1]; return accessType === PAGE_ACCESS.READONLY; }); + +export const getEnabledMenus = (globalServiceConfig: GlobalServiceConfig): Menu[] => { + const versionMenuMap = { + V1: ALERT_V1_WORKSPACE_PAGE_ACCESS_MENU_LIST, + V2: ALERT_V2_WORKSPACE_PAGE_ACCESS_MENU_LIST, + }; + + const getAllMenus = (version: string): PageAccessMenuByConfig[] => [ + ...DEFAULT_WORKSPACE_PAGE_ACCESS_MENU_LIST, + ...versionMenuMap[version], + ]; + + return Object.entries(globalServiceConfig) + // eslint-disable-next-line @typescript-eslint/no-unused-vars + .filter(([_, cfg]) => cfg.ENABLED) + .flatMap(([configKey, cfg]) => { + const targetMenus = getAllMenus(cfg.VERSION); + const matchedMenu = targetMenus + .filter((menuItem) => menuItem.key === configKey); + + return matchedMenu.map((i) => ({ + id: i.id, + subMenuList: (i.subMenuList || [{ id: i.id }]) as Menu[], + })); + }); +}; diff --git a/apps/web/src/lib/config/global-config/type.ts b/apps/web/src/lib/config/global-config/type.ts index ab3a3db37f..a3a2f769be 100644 --- a/apps/web/src/lib/config/global-config/type.ts +++ b/apps/web/src/lib/config/global-config/type.ts @@ -3,7 +3,7 @@ import type { MenuId } from '@/lib/menu/config'; export type GlobalServiceConfig = Record; -type FeatureKeyType = typeof FEATURES[keyof typeof FEATURES]; +export type FeatureKeyType = typeof FEATURES[keyof typeof FEATURES]; type MenuConfig = Partial>; export type FeatureVersionSettingsType = { diff --git a/apps/web/src/services/iam/components/RoleManagementTabDetail.vue b/apps/web/src/services/iam/components/RoleManagementTabDetail.vue index ab9e71a44b..45b53be57b 100644 --- a/apps/web/src/services/iam/components/RoleManagementTabDetail.vue +++ b/apps/web/src/services/iam/components/RoleManagementTabDetail.vue @@ -141,7 +141,7 @@ watch(() => state.selectedRole.role_id, async (roleId) => { await getRoleDetailData(selectedRoleId); state.pageAccessDataList = getPageAccessMenuListByRoleType(state.data.role_type); - const pageAccessPermissionMap = getPageAccessMapFromRawData(state.pageAccess); + const pageAccessPermissionMap = getPageAccessMapFromRawData(state.pageAccess, true); Object.entries(pageAccessPermissionMap).forEach(([itemId, accessible]) => { if (!itemId) return; diff --git a/apps/web/src/services/iam/components/RoleUpdateFormPermissionForm.vue b/apps/web/src/services/iam/components/RoleUpdateFormPermissionForm.vue index 3f6d4d07f2..441a9a65c3 100644 --- a/apps/web/src/services/iam/components/RoleUpdateFormPermissionForm.vue +++ b/apps/web/src/services/iam/components/RoleUpdateFormPermissionForm.vue @@ -91,7 +91,7 @@ const handleUpdateEditor = (value: string) => { }; const setPageAccessPermissionsData = () => { if (!props.initialPageAccess) return; - const pageAccessPermissionMap = getPageAccessMapFromRawData(props.initialPageAccess); + const pageAccessPermissionMap = getPageAccessMapFromRawData(props.initialPageAccess, true); // eslint-disable-next-line no-restricted-syntax for (const [itemId, accessible] of Object.entries(pageAccessPermissionMap)) { if (!itemId) return; diff --git a/apps/web/src/services/iam/constants/role-constant.ts b/apps/web/src/services/iam/constants/role-constant.ts index 7889a969fb..cfc3071b5b 100644 --- a/apps/web/src/services/iam/constants/role-constant.ts +++ b/apps/web/src/services/iam/constants/role-constant.ts @@ -3,7 +3,11 @@ import type { KeyItemSet } from '@cloudforet/mirinae/types/controls/search/query import { ROLE_TYPE } from '@/api-clients/identity/role/constant'; +import { FEATURES } from '@/lib/config/global-config/constants'; import type { ExcelDataField } from '@/lib/helper/file-download-helper/type'; +import { MENU_ID } from '@/lib/menu/config'; + +import type { PageAccessMenuByConfig } from '@/services/iam/types/role-type'; export const ROLE_TYPE_BADGE_OPTION = { [ROLE_TYPE.DOMAIN_ADMIN]: { label: 'Admin' }, @@ -86,3 +90,76 @@ export const ROLE_TAB_TABLE_FIELDS = [ export const MANAGED_PAGE_ACCESS = [ '*', ] as const; + +export const DEFAULT_WORKSPACE_PAGE_ACCESS_MENU_LIST: PageAccessMenuByConfig[] = [ + { id: MENU_ID.DASHBOARDS, key: FEATURES.DASHBOARDS }, + { id: MENU_ID.SERVICE_ACCOUNT, key: FEATURES.SERVICE_ACCOUNT }, + { id: MENU_ID.PROJECT, key: FEATURES.PROJECT }, + { + id: MENU_ID.ASSET_INVENTORY, + key: FEATURES.ASSET_INVENTORY, + subMenuList: [ + { id: MENU_ID.CLOUD_SERVICE }, + { id: MENU_ID.SERVER }, + { id: MENU_ID.SECURITY }, + { id: MENU_ID.METRIC_EXPLORER }, + { id: MENU_ID.COLLECTOR }, + ], + }, + { + id: MENU_ID.COST_EXPLORER, + key: FEATURES.COST_EXPLORER, + subMenuList: [ + { id: MENU_ID.COST_ANALYSIS }, + { id: MENU_ID.BUDGET }, + { id: MENU_ID.COST_REPORT }, + ], + }, + { + id: MENU_ID.OPS_FLOW, + key: FEATURES.OPS_FLOW, + subMenuList: [ + { id: MENU_ID.OPS_FLOW_LANDING }, + { id: MENU_ID.TASK_BOARD }, + ], + }, +]; +export const ALERT_V2_WORKSPACE_PAGE_ACCESS_MENU_LIST: PageAccessMenuByConfig[] = [ + { + id: MENU_ID.ALERT_MANAGER, + key: FEATURES.ALERT_MANAGER, + subMenuList: [ + { id: MENU_ID.SERVICE }, + { id: MENU_ID.ALERTS }, + ], + }, + { + id: MENU_ID.IAM, + key: FEATURES.IAM, + subMenuList: [ + { id: MENU_ID.USER }, + { id: MENU_ID.USER_GROUP }, + { id: MENU_ID.APP }, + ], + }, +]; + +export const ALERT_V1_WORKSPACE_PAGE_ACCESS_MENU_LIST: PageAccessMenuByConfig[] = [ + { + id: MENU_ID.ALERT_MANAGER, + key: FEATURES.ALERT_MANAGER, + subMenuList: [ + { id: MENU_ID.ALERT_MANAGER_DASHBOARD }, + { id: MENU_ID.ALERTS }, + { id: MENU_ID.ESCALATION_POLICY }, + ], + }, + { + id: MENU_ID.IAM, + key: FEATURES.IAM, + subMenuList: [ + { id: MENU_ID.USER }, + { id: MENU_ID.APP }, + ], + }, +]; diff --git a/apps/web/src/services/iam/helpers/role-page-access-menu-list.ts b/apps/web/src/services/iam/helpers/role-page-access-menu-list.ts index ddb687000a..3d2e88caa4 100644 --- a/apps/web/src/services/iam/helpers/role-page-access-menu-list.ts +++ b/apps/web/src/services/iam/helpers/role-page-access-menu-list.ts @@ -1,9 +1,8 @@ import type { RoleType } from '@/api-clients/identity/role/type'; -import { useMenuStore } from '@/store/menu/menu-store'; - import { PAGE_ACCESS } from '@/lib/access-control/config'; -import { getDefaultPageAccessPermissionList } from '@/lib/access-control/page-access-helper'; +import { getDefaultPageAccessPermissionList, getEnabledMenus } from '@/lib/access-control/page-access-helper'; +import config from '@/lib/config'; import type { Menu, MenuId } from '@/lib/menu/config'; import { MENU_ID } from '@/lib/menu/config'; import { MENU_INFO_MAP } from '@/lib/menu/menu-info'; @@ -14,7 +13,7 @@ const flattenSubMenuList = (subMenuList: Menu[], defaultMenuIds: MenuId[], trans if (!subMenuList) return []; let results: PageAccessMenuItem[] = []; subMenuList.forEach((subMenu) => { - if (!subMenu.needPermissionByRole || !defaultMenuIds.includes(subMenu.id)) return; + if (!defaultMenuIds.includes(subMenu.id)) return; const menuInfo = MENU_INFO_MAP[subMenu.id]; if (subMenu.subMenuList?.length) { @@ -31,12 +30,12 @@ const flattenSubMenuList = (subMenuList: Menu[], defaultMenuIds: MenuId[], trans }; export const getPageAccessMenuListByRoleType = (roleType: RoleType): PageAccessMenuItem[] => { - const menuStore = useMenuStore(); + const globalConfig = config.get('SERVICES') || {}; const results: PageAccessMenuItem[] = []; const defaultMenuIdsByRoleType = getDefaultPageAccessPermissionList(roleType); - const menuListByVersion = menuStore.state.menuList; + const menuListByVersion = getEnabledMenus(globalConfig); menuListByVersion.forEach((menu) => { - if (menu.needPermissionByRole && defaultMenuIdsByRoleType.includes(menu.id)) { + if (defaultMenuIdsByRoleType.includes(menu.id)) { if (menu.id === MENU_ID.WORKSPACE_HOME) return; const menuInfo = MENU_INFO_MAP[menu.id]; results.push({ diff --git a/apps/web/src/services/iam/types/role-type.ts b/apps/web/src/services/iam/types/role-type.ts index 1d94eb281d..8352c2aae4 100644 --- a/apps/web/src/services/iam/types/role-type.ts +++ b/apps/web/src/services/iam/types/role-type.ts @@ -2,6 +2,9 @@ import type { TranslateResult } from 'vue-i18n'; import type { RoleType } from '@/api-clients/identity/role/type'; +import type { FeatureKeyType } from '@/lib/config/global-config/type'; +import type { MenuId } from '@/lib/menu/config'; + export interface RoleFormData { name?: string; role_type?: RoleType; @@ -18,6 +21,11 @@ export interface TableItem { accessible_menu_list?: PageAccessMenuItem[]; isInValid?: boolean } +export interface PageAccessMenuByConfig { + id: MenuId, + key?: FeatureKeyType, + subMenuList?: PageAccessMenuItem[]; +} export interface PageAccessMenuItem { id: string; translationIds?: string[];