diff --git a/public/apps/configuration/app-router.tsx b/public/apps/configuration/app-router.tsx index 4bc3ab7c1..a97d728ef 100644 --- a/public/apps/configuration/app-router.tsx +++ b/public/apps/configuration/app-router.tsx @@ -41,7 +41,7 @@ import { Action, RouteItem, SubAction } from './types'; import { ResourceType } from '../../../common'; import { buildHashUrl, buildUrl } from './utils/url-builder'; import { CrossPageToast } from './cross-page-toast'; -import { getDataSourceFromUrl } from '../../utils/datasource-utils'; +import { getDataSourceFromUrl, LocalCluster } from '../../utils/datasource-utils'; const LANDING_PAGE_URL = '/getstarted'; @@ -151,8 +151,6 @@ export interface DataSourceContextType { setDataSource: React.Dispatch>; } -export const LocalCluster = { label: 'Local cluster', id: '' }; - export const DataSourceContext = createContext(null); export function AppRouter(props: AppDependencies) { diff --git a/public/apps/configuration/top-nav-menu.tsx b/public/apps/configuration/top-nav-menu.tsx index 5e5e51893..ee71c71c4 100644 --- a/public/apps/configuration/top-nav-menu.tsx +++ b/public/apps/configuration/top-nav-menu.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { DataSourceSelectableConfig } from 'src/plugins/data_source_management/public'; import { DataSourceOption } from 'src/plugins/data_source_management/public/components/data_source_menu/types'; import { AppDependencies } from '../types'; -import { setDataSourceInUrl } from '../../utils/datasource-utils'; +import { setDataSourceInUrl, setDataSource as setDataSourceInSubscription } from '../../utils/datasource-utils'; export interface TopNavMenuProps extends AppDependencies { dataSourcePickerReadOnly: boolean; @@ -44,6 +44,7 @@ export const SecurityPluginTopNavMenu = React.memo( const wrapSetDataSourceWithUpdateUrl = (dataSources: DataSourceOption[]) => { setDataSourceInUrl(dataSources[0]); setDataSource(dataSources[0]); + setDataSourceInSubscription(dataSources[0]); }; return dataSourceEnabled ? ( diff --git a/public/plugin.ts b/public/plugin.ts index 4c669757b..e5995aa48 100644 --- a/public/plugin.ts +++ b/public/plugin.ts @@ -53,6 +53,7 @@ import { addTenantToShareURL } from './services/shared-link'; import { interceptError } from './utils/logout-utils'; import { tenantColumn, getNamespacesToRegister } from './apps/configuration/utils/tenant-utils'; import { getDashboardsInfoSafe } from './utils/dashboards-info-utils'; +import { dataSource$, getDataSourceEnabledUrl, getDataSourceFromUrl, setDataSourceInUrl } from './utils/datasource-utils'; async function hasApiPermission(core: CoreSetup): Promise { try { @@ -90,6 +91,15 @@ export class SecurityPlugin // @ts-ignore : initializerContext not used constructor(private readonly initializerContext: PluginInitializerContext) {} + private updateDefaultRouteOfSecurityApplications: AppUpdater = () => { + const url = getDataSourceEnabledUrl(getDataSourceFromUrl()); + return { + defaultPath: `?${url.searchParams.toString()}` + }; + } + + private appStateUpdater = new BehaviorSubject(this.updateDefaultRouteOfSecurityApplications); + public async setup( core: CoreSetup, deps: SecurityPluginSetupDependencies @@ -161,6 +171,7 @@ export class SecurityPlugin title: 'Get Started', order: 8040, workspaceAvailability: WorkspaceAvailability.outsideWorkspace, + updater$: this.appStateUpdater, mount: async (params: AppMountParameters) => { return mountWrapper(params, '/getstarted'); }, @@ -170,6 +181,7 @@ export class SecurityPlugin title: 'Authentication', order: 8040, workspaceAvailability: WorkspaceAvailability.outsideWorkspace, + updater$: this.appStateUpdater, mount: async (params: AppMountParameters) => { return mountWrapper(params, '/auth'); }, @@ -179,6 +191,7 @@ export class SecurityPlugin title: 'Roles', order: 8040, workspaceAvailability: WorkspaceAvailability.outsideWorkspace, + updater$: this.appStateUpdater, mount: async (params: AppMountParameters) => { return mountWrapper(params, '/roles'); }, @@ -188,6 +201,7 @@ export class SecurityPlugin title: 'Internal users', order: 8040, workspaceAvailability: WorkspaceAvailability.outsideWorkspace, + updater$: this.appStateUpdater, mount: async (params: AppMountParameters) => { return mountWrapper(params, '/users'); }, @@ -197,6 +211,7 @@ export class SecurityPlugin title: 'Permissions', order: 8040, workspaceAvailability: WorkspaceAvailability.outsideWorkspace, + updater$: this.appStateUpdater, mount: async (params: AppMountParameters) => { return mountWrapper(params, '/permissions'); }, @@ -206,6 +221,7 @@ export class SecurityPlugin title: 'Tenants', order: 8040, workspaceAvailability: WorkspaceAvailability.outsideWorkspace, + updater$: this.appStateUpdater, mount: async (params: AppMountParameters) => { return mountWrapper(params, '/tenants'); }, @@ -215,6 +231,7 @@ export class SecurityPlugin title: 'Audit logs', order: 8040, workspaceAvailability: WorkspaceAvailability.outsideWorkspace, + updater$: this.appStateUpdater, mount: async (params: AppMountParameters) => { return mountWrapper(params, '/auditLogging'); }, @@ -263,6 +280,12 @@ export class SecurityPlugin }), }); } + + dataSource$.subscribe((dataSourceOption) => { + if (dataSourceOption) { + this.appStateUpdater.next(this.updateDefaultRouteOfSecurityApplications); + } + }); } core.application.register({ diff --git a/public/utils/datasource-utils.ts b/public/utils/datasource-utils.ts index 638c515eb..45eef9a56 100644 --- a/public/utils/datasource-utils.ts +++ b/public/utils/datasource-utils.ts @@ -13,6 +13,7 @@ * permissions and limitations under the License. */ +import { BehaviorSubject } from 'rxjs'; import { DataSourceOption } from 'src/plugins/data_source_management/public/components/data_source_menu/types'; const DATASOURCEURLKEY = 'dataSource'; @@ -35,8 +36,20 @@ export function getDataSourceFromUrl(): DataSourceOption { } } -export function setDataSourceInUrl(dataSource: DataSourceOption) { +export function getDataSourceEnabledUrl(dataSource: DataSourceOption) { const url = new URL(window.location.href); url.searchParams.set(DATASOURCEURLKEY, JSON.stringify(dataSource)); - window.history.replaceState({}, '', url.toString()); + return url; +} + +export function setDataSourceInUrl(dataSource: DataSourceOption) { + window.history.replaceState({}, '', getDataSourceEnabledUrl(dataSource).toString()); +} + +export const LocalCluster = { label: 'Local cluster', id: '' }; + +export const dataSource$ = new BehaviorSubject(getDataSourceFromUrl() || LocalCluster); + +export function setDataSource(dataSource: DataSourceOption) { + dataSource$.next(dataSource); }