diff --git a/packages/web-app-admin-settings/src/index.ts b/packages/web-app-admin-settings/src/index.ts index 320661a192c..818e1054c43 100644 --- a/packages/web-app-admin-settings/src/index.ts +++ b/packages/web-app-admin-settings/src/index.ts @@ -15,14 +15,11 @@ const appInfo = { isFileEditor: false } -// FIXME: a better way to access this is needed -const permissionManager = () => (window as any).__$permissionManager - -const routes = [ +const routes = ({ $permissionManager }) => [ { path: '/', redirect: () => { - if (permissionManager().hasSystemManagement()) { + if ($permissionManager.hasSystemManagement()) { return { name: 'admin-settings-general' } } return { name: 'admin-settings-spaces' } @@ -66,7 +63,7 @@ const routes = [ } ] -const navItems = [ +const navItems = ({ $permissionManager }) => [ { name: $gettext('General'), icon: 'settings-4', @@ -74,7 +71,7 @@ const navItems = [ path: `/${appInfo.id}/general?` }, enabled: () => { - return permissionManager().hasSystemManagement() + return $permissionManager.hasSystemManagement() } }, { @@ -84,7 +81,7 @@ const navItems = [ path: `/${appInfo.id}/users?` }, enabled: () => { - return permissionManager().hasUserManagement() + return $permissionManager.hasUserManagement() } }, { @@ -94,7 +91,7 @@ const navItems = [ path: `/${appInfo.id}/groups?` }, enabled: () => { - return permissionManager().hasUserManagement() + return $permissionManager.hasUserManagement() } }, { @@ -104,7 +101,7 @@ const navItems = [ path: `/${appInfo.id}/spaces?` }, enabled: () => { - return permissionManager().hasSpaceManagement() + return $permissionManager.hasSpaceManagement() } } ] diff --git a/packages/web-app-admin-settings/tests/unit/index.spec.ts b/packages/web-app-admin-settings/tests/unit/index.spec.ts index 3ad3c184b64..5bf3d461d70 100644 --- a/packages/web-app-admin-settings/tests/unit/index.spec.ts +++ b/packages/web-app-admin-settings/tests/unit/index.spec.ts @@ -4,54 +4,68 @@ describe('admin settings index', () => { describe('navItems', () => { describe('general', () => { it.each([true, false])('should be enabled according to the permissions', (enabled) => { - ;(window as any).__$permissionManager = { - hasSystemManagement: () => enabled - } - expect(index.navItems.find((n) => n.name === 'General').enabled()).toBe(enabled) + const $permissionManager = { hasSystemManagement: () => enabled } + expect( + index + .navItems({ $permissionManager }) + .find((n) => n.name === 'General') + .enabled() + ).toBe(enabled) }) }) describe('user management', () => { it.each([true, false])('should be enabled according to the permissions', (enabled) => { - ;(window as any).__$permissionManager = { - hasUserManagement: () => enabled - } - expect(index.navItems.find((n) => n.name === 'Users').enabled()).toBe(enabled) + const $permissionManager = { hasUserManagement: () => enabled } + expect( + index + .navItems({ $permissionManager }) + .find((n) => n.name === 'Users') + .enabled() + ).toBe(enabled) }) }) describe('group management', () => { it.each([true, false])('should be enabled according to the permissions', (enabled) => { - ;(window as any).__$permissionManager = { - hasUserManagement: () => enabled - } - expect(index.navItems.find((n) => n.name === 'Groups').enabled()).toBe(enabled) + const $permissionManager = { hasUserManagement: () => enabled } + expect( + index + .navItems({ $permissionManager }) + .find((n) => n.name === 'Groups') + .enabled() + ).toBe(enabled) }) }) describe('space management', () => { it.each([true, false])('should be enabled according to the permissions', (enabled) => { - ;(window as any).__$permissionManager = { - hasSpaceManagement: () => enabled - } - expect(index.navItems.find((n) => n.name === 'Spaces').enabled()).toBe(enabled) + const $permissionManager = { hasSpaceManagement: () => enabled } + expect( + index + .navItems({ $permissionManager }) + .find((n) => n.name === 'Spaces') + .enabled() + ).toBe(enabled) }) }) }) describe('routes', () => { describe('default-route "/"', () => { it('should redirect to general if permission given', () => { - ;(window as any).__$permissionManager = { - hasSystemManagement: () => true - } - expect(index.routes.find((n) => n.path === '/').redirect().name).toEqual( - 'admin-settings-general' - ) + const $permissionManager = { hasSystemManagement: () => true } + expect( + index + .routes({ $permissionManager }) + .find((n) => n.path === '/') + .redirect().name + ).toEqual('admin-settings-general') }) it('should redirect to space management if no system management permission given', () => { - ;(window as any).__$permissionManager = { - hasSystemManagement: () => false - } - expect(index.routes.find((n) => n.path === '/').redirect().name).toEqual( - 'admin-settings-spaces' - ) + const $permissionManager = { hasSystemManagement: () => false } + expect( + index + .routes({ $permissionManager }) + .find((n) => n.path === '/') + .redirect().name + ).toEqual('admin-settings-spaces') }) }) }) diff --git a/packages/web-runtime/src/container/application/classic.ts b/packages/web-runtime/src/container/application/classic.ts index 2909edae38f..a861b918186 100644 --- a/packages/web-runtime/src/container/application/classic.ts +++ b/packages/web-runtime/src/container/application/classic.ts @@ -13,17 +13,22 @@ import { RuntimeError } from '../error' */ class ClassicApplication extends NextApplication { private readonly applicationScript: ClassicApplicationScript + private readonly app: App - constructor(runtimeApi: RuntimeApi, applicationScript: ClassicApplicationScript) { + constructor(runtimeApi: RuntimeApi, applicationScript: ClassicApplicationScript, app: App) { super(runtimeApi) this.applicationScript = applicationScript + this.app = app } initialize(): Promise { const { routes, navItems, translations, quickActions, store } = this.applicationScript + const { globalProperties } = this.app.config + const _routes = typeof routes === 'function' ? routes(globalProperties) : routes + const _navItems = typeof navItems === 'function' ? navItems(globalProperties) : navItems - routes && this.runtimeApi.announceRoutes(routes) - navItems && this.runtimeApi.announceNavigationItems(navItems) + routes && this.runtimeApi.announceRoutes(_routes) + navItems && this.runtimeApi.announceNavigationItems(_navItems) translations && this.runtimeApi.announceTranslations(translations) quickActions && this.runtimeApi.announceQuickActions(quickActions) store && this.runtimeApi.announceStore(store) @@ -61,6 +66,7 @@ class ClassicApplication extends NextApplication { /** * + * @param app * @param applicationPath * @param store * @param router @@ -68,12 +74,14 @@ class ClassicApplication extends NextApplication { * @param supportedLanguages */ export const convertClassicApplication = async ({ + app, applicationScript, store, router, translations, supportedLanguages }: { + app: App applicationScript: ClassicApplicationScript store: Store router: Router @@ -107,5 +115,5 @@ export const convertClassicApplication = async ({ await store.dispatch('registerApp', applicationScript.appInfo) - return new ClassicApplication(runtimeApi, applicationScript) + return new ClassicApplication(runtimeApi, applicationScript, app) } diff --git a/packages/web-runtime/src/container/application/index.ts b/packages/web-runtime/src/container/application/index.ts index 6ae6206e77b..a2f98c6a98b 100644 --- a/packages/web-runtime/src/container/application/index.ts +++ b/packages/web-runtime/src/container/application/index.ts @@ -15,6 +15,7 @@ import * as vueGettext from 'vue3-gettext' // eslint-disable-line import { urlJoin } from 'web-client/src/utils' import { ConfigurationManager } from 'web-pkg' +import { App } from 'vue' export { NextApplication } from './next' @@ -52,6 +53,7 @@ const loadScriptRequireJS = (moduleUri: string) => { * @param args */ export const buildApplication = async ({ + app, applicationPath, store, router, @@ -59,6 +61,7 @@ export const buildApplication = async ({ supportedLanguages, configurationManager }: { + app: App applicationPath: string store: Store router: Router @@ -111,6 +114,7 @@ export const buildApplication = async ({ throw new RuntimeError('next applications not implemented yet, stay tuned') } else { application = await convertClassicApplication({ + app, applicationScript, store, router, diff --git a/packages/web-runtime/src/container/bootstrap.ts b/packages/web-runtime/src/container/bootstrap.ts index 57069b20fd2..b66b5b74947 100644 --- a/packages/web-runtime/src/container/bootstrap.ts +++ b/packages/web-runtime/src/container/bootstrap.ts @@ -97,6 +97,7 @@ export const announceClient = async (runtimeConfiguration: RuntimeConfiguration) * - bulk build all applications * - bulk register all applications, no other application is guaranteed to be registered here, don't request one * + * @param app * @param runtimeConfiguration * @param store * @param router @@ -104,6 +105,7 @@ export const announceClient = async (runtimeConfiguration: RuntimeConfiguration) * @param supportedLanguages */ export const initializeApplications = async ({ + app, runtimeConfiguration, configurationManager, store, @@ -111,6 +113,7 @@ export const initializeApplications = async ({ translations, supportedLanguages }: { + app: App runtimeConfiguration: RuntimeConfiguration configurationManager: ConfigurationManager store: Store @@ -129,6 +132,7 @@ export const initializeApplications = async ({ const applicationResults = await Promise.allSettled( applicationPaths.map((applicationPath) => buildApplication({ + app, applicationPath, store, supportedLanguages, diff --git a/packages/web-runtime/src/container/types.ts b/packages/web-runtime/src/container/types.ts index 5ab5c360fc4..f95ba1614c4 100644 --- a/packages/web-runtime/src/container/types.ts +++ b/packages/web-runtime/src/container/types.ts @@ -65,8 +65,8 @@ export interface ApplicationTranslations { export interface ClassicApplicationScript { appInfo?: ApplicationInformation store?: Store - routes?: RouteRecordRaw[] - navItems?: ApplicationNavigationItem[] + routes?: ((...args) => RouteRecordRaw[]) | RouteRecordRaw[] + navItems?: ((...args) => ApplicationNavigationItem[]) | ApplicationNavigationItem[] quickActions?: ApplicationQuickActions translations?: ApplicationTranslations initialize?: () => void diff --git a/packages/web-runtime/src/index.ts b/packages/web-runtime/src/index.ts index eb894223907..df21e0ccfe0 100644 --- a/packages/web-runtime/src/index.ts +++ b/packages/web-runtime/src/index.ts @@ -48,6 +48,7 @@ export const bootstrapApp = async (configurationPath: string): Promise => announcePermissionManager({ app, store }) const applicationsPromise = await initializeApplications({ + app, runtimeConfiguration, configurationManager, store, diff --git a/packages/web-runtime/tests/unit/container/bootstrap.spec.ts b/packages/web-runtime/tests/unit/container/bootstrap.spec.ts index 0e776cb7e71..82faa968cea 100644 --- a/packages/web-runtime/tests/unit/container/bootstrap.spec.ts +++ b/packages/web-runtime/tests/unit/container/bootstrap.spec.ts @@ -31,6 +31,7 @@ describe('initialize applications', () => { jest.mocked(buildApplication).mockImplementation(buildApplicationMock) const applications = await initializeApplications({ + app: createApp(defineComponent({})), configurationManager: mockDeep(), runtimeConfiguration: { apps: ['internalFishy', 'internalValid'],