Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion apps/web/public/config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,34 @@
],
"CONTACT_LINK": "",
"SMTP_ENABLED": false,
"ADVANCED_SERVICE": {}
"SERVICES": {
"DASHBOARDS": {
"ENABLED": true,
"VERSION": "V1"
},
"PROJECT": {
"ENABLED": true,
"VERSION": "V1"
},
"SERVICE_ACCOUNT": {
"ENABLED": true,
"VERSION": "V1"
},
"ASSET_INVENTORY": {
"ENABLED": true,
"VERSION": "V1"
},
"COST_ANALYSIS": {
"ENABLED": true,
"VERSION": "V1"
},
"OPS_FLOW": {
"ENABLED": true,
"VERSION": "V1"
},
"ALERT_MANAGER": {
"ENABLED": true,
"VERSION": "V1"
}
}
}
21 changes: 5 additions & 16 deletions apps/web/src/api-clients/api-client-manager.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,22 @@
import { SpaceConnector } from '@cloudforet/core-lib/space-connector';

import config from '@/lib/config';
import type { ApiClientsSchemaType } from '@/lib/config/global-config/api-client-schema';
import { ApiClientEndpoint } from '@/lib/config/global-config/api-client-schema';
import type { GlobalServiceConfig } from '@/lib/config/global-config/type';

interface ServiceConfig {
ENABLED: boolean;
VERSION: string;
}

interface GlobalConfig {
SERVICES: {
[key: string]: ServiceConfig;
};
}

class APIClientManager {
// eslint-disable-next-line no-undef
[key: string]: any;

private config: GlobalConfig['SERVICES'] | null = null;
private config: GlobalServiceConfig = {} as GlobalServiceConfig;

private apiClientsSchema: ApiClientsSchemaType = {} as ApiClientsSchemaType;

async initialize() {
await config.init();
this.config = config.get('SERVICES') || {};
this.apiClientsSchema = JSON.parse(JSON.stringify(ApiClientEndpoint));
async initialize(mergedConfig) {
this.config = mergedConfig;

this.apiClientsSchema = JSON.parse(JSON.stringify(ApiClientEndpoint));
this.defineDynamicServices();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const PUBLIC_CONFIG_NAMES = {
TASK_LANDING: 'console:task-management:landing',
TASK_TEMPLATE: 'console:task-management:template',
OVERRIDE_SERVICE_SETTING: 'console:override-service-setting',
EXTRA_MENU: 'console:ext-menu', // NOTE: Not used yet. Will be used after migration from domain-config to public-config
SETTINGS: 'settings', // NOTE: Not used yet. Will be used after migration from domain-config to public-config
} as const;
2 changes: 0 additions & 2 deletions apps/web/src/lib/site-initializer/api-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { SpaceConnector } from '@cloudforet/core-lib/space-connector';
import TokenAPI from '@cloudforet/core-lib/space-connector/token-api';
import type { DevConfig, MockConfig, AuthConfig } from '@cloudforet/core-lib/space-connector/type';

import APIClientManager from '@/api-clients/api-client-manager';
import type { TokenGrantParameters } from '@/api-clients/identity/token/schema/api-verbs/grant';
import type { TokenGrantModel } from '@/api-clients/identity/token/schema/model';

Expand Down Expand Up @@ -434,7 +433,6 @@ export const initApiClient = async (config) => {
getAfterCallApiMap(),
serviceConfig,
);
await APIClientManager.initialize();
const existingRefreshToken = SpaceConnector.getRefreshToken();

if (!existingRefreshToken) return;
Expand Down
6 changes: 5 additions & 1 deletion apps/web/src/lib/site-initializer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { computed, watch } from 'vue';

import { QueryHelper } from '@cloudforet/core-lib/query';

import APIClientManager from '@/api-clients/api-client-manager';
import { SpaceRouter } from '@/router';
import { setI18nLocale } from '@/translations';

Expand All @@ -25,6 +26,7 @@ import { initDomainSettings } from '@/lib/site-initializer/domain-settings';
import { initEcharts } from '@/lib/site-initializer/echarts';
import { initErrorHandler } from '@/lib/site-initializer/error-handler';
import { initTaskManagementTemplate } from '@/lib/site-initializer/initTaskManagementTemplate';
import { mergeConfig } from '@/lib/site-initializer/merge-config';
import { initModeSetting } from '@/lib/site-initializer/mode-setting';
import { checkSsoAccessToken } from '@/lib/site-initializer/sso';
import { initUserAndAuth } from '@/lib/site-initializer/user-auth';
Expand Down Expand Up @@ -83,10 +85,12 @@ const init = async () => {
/* Init SpaceONE Console */
try {
await config.init();
await ServiceConfigurator.initialize();
await initApiClient(config);
const domainId = await initDomain(config);
const userId = await initUserAndAuth(config);
const mergedConfig = await mergeConfig(config, domainId);
await ServiceConfigurator.initialize(mergedConfig);
await APIClientManager.initialize(mergedConfig);
initDomainSettings();
initModeSetting();
await initWorkspace(userId);
Expand Down
28 changes: 28 additions & 0 deletions apps/web/src/lib/site-initializer/merge-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { SpaceConnector } from '@cloudforet/core-lib/space-connector';

import type { PublicConfigGetParameters } from '@/api-clients/config/public-config/schema/api-verbs/get';
import { PUBLIC_CONFIG_NAMES } from '@/api-clients/config/public-config/schema/constant';
import type { PublicConfigModel } from '@/api-clients/config/public-config/schema/model';

import type { GlobalServiceConfig } from '@/lib/config/global-config/type';

export const mergeConfig = async (config, domainId: string): Promise<GlobalServiceConfig> => {
const baseConfig = config.get('SERVICES') || {};

const { data: overrideConfigData } = await SpaceConnector.clientV2.config.publicConfig.get<PublicConfigGetParameters, PublicConfigModel>({
name: PUBLIC_CONFIG_NAMES.OVERRIDE_SERVICE_SETTING,
domain_id: domainId,
});
const overrideConfig = overrideConfigData.SERVICES || {};

Object.keys(overrideConfig).forEach((serviceName) => {
if (baseConfig[serviceName]) {
baseConfig[serviceName] = {
...baseConfig[serviceName],
...overrideConfig[serviceName],
};
}
});

return baseConfig;
};
8 changes: 4 additions & 4 deletions apps/web/src/services/configurator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { isEmpty } from 'lodash';

import { useMenuStore } from '@/store/menu/menu-store';

import config from '@/lib/config';
import { FeatureSchemaManager } from '@/lib/config/global-config/feature-schema-manager';
import type { FeatureSchemaType, GlobalServiceConfig } from '@/lib/config/global-config/type';
import type { Menu } from '@/lib/menu/config';
Expand All @@ -24,14 +23,15 @@ import ServiceAccountConfigurator from '@/services/service-account/configurator'
import adminWorkspaceHomeRoutes from '@/services/workspace-home/routes/admin/routes';
import workspaceHomeRoute from '@/services/workspace-home/routes/routes';


class ServiceConfigurator {
private config: GlobalServiceConfig = {} as GlobalServiceConfig;

private featureSchema: FeatureSchemaType = {} as FeatureSchemaType;

async initialize() {
await config.init();
this.config = config.get('SERVICES') || {};
async initialize(mergedConfig) {
this.config = mergedConfig;

const featureSchemaManager = new FeatureSchemaManager(this.config);
const featureSchema = await featureSchemaManager.applyGlobalConfig();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import type { DisplayMenu } from '@/store/display/type';

import type { MenuId } from '@/lib/menu/config';
import { MENU_ID } from '@/lib/menu/config';

import { useContentsAccessibility } from '@/common/composables/contents-accessibility';

import {
useTaskManagementTemplateStore,
} from '@/services/ops-flow/task-management-templates/stores/use-task-management-template-store';

const ADVANCED_SERVICE_NAMES: MenuId[] = [MENU_ID.OPS_FLOW];
export const useAdvancedMenuDisplay = () => {
const taskManagementTemplateStore = useTaskManagementTemplateStore();

const isMenuDisplayable = (menuId: MenuId): boolean => {
if (!ADVANCED_SERVICE_NAMES.includes(menuId)) return true;
const { visibleContents } = useContentsAccessibility(menuId);
return !!visibleContents;
};

const refineOpsflowSubMenu = (menu: DisplayMenu): DisplayMenu[]|undefined => {
const sub = menu.subMenuList;
if (!sub) return undefined;
const refined: DisplayMenu[] = sub.map((s) => {
if (s.id === MENU_ID.OPS_FLOW_LANDING) {
const label = taskManagementTemplateStore.templates.TemplateName;
const hideOnGNB = taskManagementTemplateStore.state.templateId === 'default' || !taskManagementTemplateStore.state.enableLanding;
const hideOnSiteMap = taskManagementTemplateStore.state.templateId === 'default' || !taskManagementTemplateStore.state.enableLanding;
return {
...s,
label,
hideOnGNB,
hideOnSiteMap,
};
}
if (s.id === MENU_ID.TASK_BOARD) {
const label = taskManagementTemplateStore.templates.TaskBoard;
return { ...s, label };
}
return s;
});

return refined;
};

const refineGNBMenuList = (allGNBMenuList: DisplayMenu[]): DisplayMenu[] => allGNBMenuList.filter((menu) => isMenuDisplayable(menu.id)).map((menu) => {
if (menu.id === MENU_ID.OPS_FLOW) {
return {
...menu,
subMenuList: refineOpsflowSubMenu(menu),
};
}
return menu;
});
return {
refineGNBMenuList,
};
};
4 changes: 4 additions & 0 deletions apps/web/src/store/display/display-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { makeAdminRouteName } from '@/router/helpers/route-helper';

import { useAppContextStore } from '@/store/app-context/app-context-store';
import { useUserWorkspaceStore } from '@/store/app-context/workspace/user-workspace-store';
import { useAdvancedMenuDisplay } from '@/store/display/composables/use-advanced-menu-display';
import { SIDEBAR_TYPE } from '@/store/display/constant';
import type {
DisplayMenu, DisplayStoreState, SidebarProps, SidebarType,
Expand Down Expand Up @@ -107,6 +108,7 @@ export const useDisplayStore = defineStore('display-store', () => {
gnbNotificationLastReadTime: '',
});

const advancedMenuDisplay = useAdvancedMenuDisplay();
const getters = reactive<DisplayStoreGetters>({
hasUncheckedNotifications: computed<boolean>(() => !!(state.uncheckedNotificationCount && state.uncheckedNotificationCount > 0)),
isHandbookVisible: computed<boolean>(() => state.visibleSidebar && (state.sidebarType === SIDEBAR_TYPE.handbook)),
Expand Down Expand Up @@ -328,6 +330,8 @@ export const useDisplayStore = defineStore('display-store', () => {
});
}

// advanced service menu display
_allGnbMenuList = advancedMenuDisplay.refineGNBMenuList(_allGnbMenuList);
return _allGnbMenuList;
};

Expand Down
Loading