mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Remove kibana.defaultAppId setting (#109798)
* Remove kibana.defaultAppId setting * Fix typings * Remove plugin dependency * Use proper navigation method to get to home * Default route for home * Address discover new routing code * Make non existing /kibana URLs working * Fix space awareness * Remove documentation * Remove the setting from docker file * Make defaultRoute forward work properly * Add forward_url tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
634ce7f83b
commit
b6ab15e9f4
18 changed files with 70 additions and 210 deletions
|
@ -295,12 +295,6 @@ is an alternative to `elasticsearch.username` and `elasticsearch.password`.
|
|||
| `interpreter.enableInVisualize`
|
||||
| Enables use of interpreter in Visualize. *Default: `true`*
|
||||
|
||||
| `kibana.defaultAppId:`
|
||||
| deprecated:[7.9.0,This setting will be removed in Kibana 8.0.]
|
||||
Instead, use the <<defaultroute,`defaultRoute` advanced setting>>.
|
||||
+
|
||||
The default application to load. *Default: `"home"`*
|
||||
|
||||
|[[kibana-index]] `kibana.index:`
|
||||
| deprecated:[7.11.0,This setting will be removed in 8.0.] Multitenancy by
|
||||
changing `kibana.index` will not be supported starting in 8.0. See
|
||||
|
|
|
@ -76,7 +76,6 @@ kibana_vars=(
|
|||
interpreter.enableInVisualize
|
||||
kibana.autocompleteTerminateAfter
|
||||
kibana.autocompleteTimeout
|
||||
kibana.defaultAppId
|
||||
kibana.index
|
||||
logging.appenders
|
||||
logging.appenders.console
|
||||
|
|
|
@ -28,10 +28,7 @@ export function NotFoundRoute(props: NotFoundRouteProps) {
|
|||
useEffect(() => {
|
||||
const path = window.location.hash.substr(1);
|
||||
getUrlTracker().restorePreviousUrl();
|
||||
const { navigated } = urlForwarding.navigateToLegacyKibanaUrl(path);
|
||||
if (!navigated) {
|
||||
urlForwarding.navigateToDefaultApp();
|
||||
}
|
||||
urlForwarding.navigateToLegacyKibanaUrl(path);
|
||||
|
||||
const bannerMessage = i18n.translate('discover.noMatchRoute.bannerTitleText', {
|
||||
defaultMessage: 'Page not found',
|
||||
|
|
|
@ -12,19 +12,10 @@ import PropTypes from 'prop-types';
|
|||
import { Home } from './home';
|
||||
import { TutorialDirectory } from './tutorial_directory';
|
||||
import { Tutorial } from './tutorial/tutorial';
|
||||
import { HashRouter as Router, Switch, Route } from 'react-router-dom';
|
||||
import { HashRouter as Router, Switch, Route, Redirect } from 'react-router-dom';
|
||||
import { getTutorial } from '../load_tutorials';
|
||||
import { replaceTemplateStrings } from './tutorial/replace_template_strings';
|
||||
import { getServices } from '../kibana_services';
|
||||
import useMount from 'react-use/lib/useMount';
|
||||
|
||||
const RedirectToDefaultApp = () => {
|
||||
useMount(() => {
|
||||
const { urlForwarding } = getServices();
|
||||
urlForwarding.navigateToDefaultApp();
|
||||
});
|
||||
return null;
|
||||
};
|
||||
|
||||
export function HomeApp({ directories, solutions }) {
|
||||
const {
|
||||
|
@ -78,7 +69,7 @@ export function HomeApp({ directories, solutions }) {
|
|||
hasUserIndexPattern={() => indexPatternService.hasUserIndexPattern()}
|
||||
/>
|
||||
</Route>
|
||||
<Route path="*" exact={true} component={RedirectToDefaultApp} />
|
||||
<Redirect to="/" />
|
||||
</Switch>
|
||||
</Router>
|
||||
</I18nProvider>
|
||||
|
|
|
@ -14,7 +14,6 @@ import {
|
|||
PluginInitializerContext,
|
||||
} from 'kibana/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { first } from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
EnvironmentService,
|
||||
|
@ -137,27 +136,9 @@ export class HomePublicPlugin
|
|||
};
|
||||
}
|
||||
|
||||
public start(
|
||||
{ application: { capabilities, currentAppId$ }, http }: CoreStart,
|
||||
{ urlForwarding }: HomePluginStartDependencies
|
||||
) {
|
||||
public start({ application: { capabilities } }: CoreStart) {
|
||||
this.featuresCatalogueRegistry.start({ capabilities });
|
||||
|
||||
// If the home app is the initial location when loading Kibana...
|
||||
if (
|
||||
window.location.pathname === http.basePath.prepend(HOME_APP_BASE_PATH) &&
|
||||
window.location.hash === ''
|
||||
) {
|
||||
// ...wait for the app to mount initially and then...
|
||||
currentAppId$.pipe(first()).subscribe((appId) => {
|
||||
if (appId === 'home') {
|
||||
// ...navigate to default app set by `kibana.defaultAppId`.
|
||||
// This doesn't do anything as along as the default settings are kept.
|
||||
urlForwarding.navigateToDefaultApp({ overwriteHash: false });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return { featureCatalogue: this.featuresCatalogueRegistry };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
|
||||
export const configSchema = schema.object({
|
||||
defaultAppId: schema.string({ defaultValue: 'home' }),
|
||||
});
|
||||
|
||||
export type ConfigSchema = TypeOf<typeof configSchema>;
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "kibanaLegacy",
|
||||
"version": "kibana",
|
||||
"server": true,
|
||||
"server": false,
|
||||
"ui": true,
|
||||
"owner": {
|
||||
"name": "Vis Editors",
|
||||
|
|
|
@ -9,11 +9,9 @@
|
|||
// TODO: https://github.com/elastic/kibana/issues/110891
|
||||
/* eslint-disable @kbn/eslint/no_export_all */
|
||||
|
||||
import { PluginInitializerContext } from 'kibana/public';
|
||||
import { KibanaLegacyPlugin } from './plugin';
|
||||
|
||||
export const plugin = (initializerContext: PluginInitializerContext) =>
|
||||
new KibanaLegacyPlugin(initializerContext);
|
||||
export const plugin = () => new KibanaLegacyPlugin();
|
||||
|
||||
export * from './plugin';
|
||||
|
||||
|
|
|
@ -14,9 +14,6 @@ export type Start = jest.Mocked<ReturnType<KibanaLegacyPlugin['start']>>;
|
|||
const createSetupContract = (): Setup => ({});
|
||||
|
||||
const createStartContract = (): Start => ({
|
||||
config: {
|
||||
defaultAppId: 'home',
|
||||
},
|
||||
loadFontAwesome: jest.fn(),
|
||||
loadAngularBootstrap: jest.fn(),
|
||||
});
|
||||
|
|
|
@ -6,18 +6,15 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { PluginInitializerContext, CoreStart, CoreSetup } from 'kibana/public';
|
||||
import { ConfigSchema } from '../config';
|
||||
import { CoreStart, CoreSetup } from 'kibana/public';
|
||||
import { injectHeaderStyle } from './utils/inject_header_style';
|
||||
|
||||
export class KibanaLegacyPlugin {
|
||||
constructor(private readonly initializerContext: PluginInitializerContext<ConfigSchema>) {}
|
||||
|
||||
public setup(core: CoreSetup<{}, KibanaLegacyStart>) {
|
||||
return {};
|
||||
}
|
||||
|
||||
public start({ application, http: { basePath }, uiSettings }: CoreStart) {
|
||||
public start({ uiSettings }: CoreStart) {
|
||||
injectHeaderStyle(uiSettings);
|
||||
return {
|
||||
/**
|
||||
|
@ -35,11 +32,6 @@ export class KibanaLegacyPlugin {
|
|||
const { initAngularBootstrap } = await import('./angular_bootstrap');
|
||||
initAngularBootstrap();
|
||||
},
|
||||
/**
|
||||
* @deprecated
|
||||
* Just exported for wiring up with dashboard mode, should not be used.
|
||||
*/
|
||||
config: this.initializerContext.config.get(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { CoreSetup, CoreStart, PluginConfigDescriptor } from 'kibana/server';
|
||||
import { get } from 'lodash';
|
||||
|
||||
import { configSchema, ConfigSchema } from '../config';
|
||||
|
||||
export const config: PluginConfigDescriptor<ConfigSchema> = {
|
||||
exposeToBrowser: {
|
||||
defaultAppId: true,
|
||||
},
|
||||
schema: configSchema,
|
||||
deprecations: ({ renameFromRoot }) => [
|
||||
// TODO: Remove deprecation once defaultAppId is deleted
|
||||
renameFromRoot('kibana.defaultAppId', 'kibana_legacy.defaultAppId', { silent: true }),
|
||||
(completeConfig, rootPath, addDeprecation) => {
|
||||
if (
|
||||
get(completeConfig, 'kibana.defaultAppId') === undefined &&
|
||||
get(completeConfig, 'kibana_legacy.defaultAppId') === undefined
|
||||
) {
|
||||
return;
|
||||
}
|
||||
addDeprecation({
|
||||
message: `kibana.defaultAppId is deprecated and will be removed in 8.0. Please use the \`defaultRoute\` advanced setting instead`,
|
||||
correctiveActions: {
|
||||
manualSteps: [
|
||||
'Go to Stack Management > Advanced Settings',
|
||||
'Update the "defaultRoute" setting under the General section',
|
||||
'Remove "kibana.defaultAppId" from the kibana.yml config file',
|
||||
],
|
||||
},
|
||||
});
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
class Plugin {
|
||||
public setup(core: CoreSetup) {}
|
||||
|
||||
public start(core: CoreStart) {}
|
||||
}
|
||||
|
||||
export const plugin = () => new Plugin();
|
|
@ -6,6 +6,5 @@
|
|||
"owner": {
|
||||
"name": "Vis Editors",
|
||||
"githubTeam": "kibana-vis-editors"
|
||||
},
|
||||
"requiredPlugins": ["kibanaLegacy"]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
import type { Location } from 'history';
|
||||
import type { AppMountParameters, CoreSetup, ScopedHistory } from 'kibana/public';
|
||||
import { coreMock } from '../../../../core/public/mocks';
|
||||
import type { UrlForwardingStart } from '../plugin';
|
||||
import { createLegacyUrlForwardApp } from './forward_app';
|
||||
|
||||
function createAppMountParams(hash: string): AppMountParameters {
|
||||
return {
|
||||
history: {
|
||||
location: {
|
||||
hash,
|
||||
} as Location<unknown>,
|
||||
} as ScopedHistory,
|
||||
} as AppMountParameters;
|
||||
}
|
||||
|
||||
describe('forward_app', () => {
|
||||
let coreSetup: CoreSetup<{}, UrlForwardingStart>;
|
||||
let coreStart: ReturnType<typeof coreMock['createStart']>;
|
||||
|
||||
beforeEach(() => {
|
||||
coreSetup = coreMock.createSetup({ basePath: '/base/path' });
|
||||
coreStart = coreMock.createStart({ basePath: '/base/path' });
|
||||
coreSetup.getStartServices = () => Promise.resolve([coreStart, {}, {} as any]);
|
||||
});
|
||||
|
||||
it('should forward to defaultRoute if hash is not a known redirect', async () => {
|
||||
coreStart.uiSettings.get.mockImplementation((key) => {
|
||||
if (key === 'defaultRoute') return '/app/defaultApp';
|
||||
throw new Error('Mock implementation missing');
|
||||
});
|
||||
|
||||
const app = createLegacyUrlForwardApp(coreSetup, [
|
||||
{ legacyAppId: 'discover', newAppId: 'discover', rewritePath: (p) => p },
|
||||
]);
|
||||
await app.mount(createAppMountParams('#/foobar'));
|
||||
expect(coreStart.application.navigateToUrl).toHaveBeenCalledWith('/base/path/app/defaultApp');
|
||||
});
|
||||
|
||||
it('should not forward to defaultRoute if hash path is a known redirect', async () => {
|
||||
const app = createLegacyUrlForwardApp(coreSetup, [
|
||||
{ legacyAppId: 'discover', newAppId: 'discover', rewritePath: (p) => p },
|
||||
]);
|
||||
await app.mount(createAppMountParams('#/discover'));
|
||||
expect(coreStart.application.navigateToUrl).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
|
@ -23,23 +23,18 @@ export const createLegacyUrlForwardApp = (
|
|||
async mount(params: AppMountParameters) {
|
||||
const hash = params.history.location.hash.substr(1);
|
||||
|
||||
if (!hash) {
|
||||
const [, , kibanaLegacyStart] = await core.getStartServices();
|
||||
kibanaLegacyStart.navigateToDefaultApp();
|
||||
}
|
||||
|
||||
const [
|
||||
{
|
||||
application,
|
||||
uiSettings,
|
||||
http: { basePath },
|
||||
},
|
||||
] = await core.getStartServices();
|
||||
|
||||
const result = await navigateToLegacyKibanaUrl(hash, forwards, basePath, application);
|
||||
|
||||
if (!result.navigated) {
|
||||
const [, , kibanaLegacyStart] = await core.getStartServices();
|
||||
kibanaLegacyStart.navigateToDefaultApp();
|
||||
const { navigated } = navigateToLegacyKibanaUrl(hash, forwards, basePath, application);
|
||||
if (!navigated) {
|
||||
const defaultRoute = uiSettings.get<string>('defaultRoute');
|
||||
application.navigateToUrl(basePath.prepend(defaultRoute));
|
||||
}
|
||||
|
||||
return () => {};
|
||||
|
|
|
@ -17,7 +17,6 @@ const createSetupContract = (): Setup => ({
|
|||
|
||||
const createStartContract = (): Start => ({
|
||||
getForwards: jest.fn(),
|
||||
navigateToDefaultApp: jest.fn(),
|
||||
navigateToLegacyKibanaUrl: jest.fn(),
|
||||
});
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { ApplicationStart, IBasePath } from 'kibana/public';
|
||||
import { ForwardDefinition } from './plugin';
|
||||
|
||||
export function navigateToDefaultApp(
|
||||
defaultAppId: string,
|
||||
forwards: ForwardDefinition[],
|
||||
application: ApplicationStart,
|
||||
basePath: IBasePath,
|
||||
currentAppId: string | undefined,
|
||||
overwriteHash: boolean
|
||||
) {
|
||||
// navigate to the respective path in the legacy kibana plugin by default (for unmigrated plugins)
|
||||
let targetAppId = 'kibana';
|
||||
let targetAppPath = `#/${defaultAppId}`;
|
||||
|
||||
// try to find an existing redirect for the target path if possible
|
||||
// this avoids having to load the legacy app just to get redirected to a core application again afterwards
|
||||
const relevantForward = forwards.find((forward) => defaultAppId.startsWith(forward.legacyAppId));
|
||||
if (relevantForward) {
|
||||
targetAppPath = relevantForward.rewritePath(`/${defaultAppId}`);
|
||||
targetAppId = relevantForward.newAppId;
|
||||
}
|
||||
|
||||
// when the correct app is already loaded, just set the hash to the right value
|
||||
// otherwise use navigateToApp (or setting href in case of kibana app)
|
||||
if (currentAppId !== targetAppId) {
|
||||
application.navigateToApp(targetAppId, { path: targetAppPath, replace: true });
|
||||
} else if (overwriteHash) {
|
||||
window.location.hash = targetAppPath;
|
||||
}
|
||||
}
|
|
@ -7,9 +7,6 @@
|
|||
*/
|
||||
|
||||
import { CoreStart, CoreSetup } from 'kibana/public';
|
||||
import { KibanaLegacyStart } from 'src/plugins/kibana_legacy/public';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { navigateToDefaultApp } from './navigate_to_default_app';
|
||||
import { createLegacyUrlForwardApp } from './forward_app';
|
||||
import { navigateToLegacyKibanaUrl } from './forward_app/navigate_to_legacy_kibana_url';
|
||||
|
||||
|
@ -21,8 +18,6 @@ export interface ForwardDefinition {
|
|||
|
||||
export class UrlForwardingPlugin {
|
||||
private forwardDefinitions: ForwardDefinition[] = [];
|
||||
private currentAppId: string | undefined;
|
||||
private currentAppIdSubscription: Subscription | undefined;
|
||||
|
||||
public setup(core: CoreSetup<{}, UrlForwardingStart>) {
|
||||
core.application.register(createLegacyUrlForwardApp(core, this.forwardDefinitions));
|
||||
|
@ -71,30 +66,8 @@ export class UrlForwardingPlugin {
|
|||
};
|
||||
}
|
||||
|
||||
public start(
|
||||
{ application, http: { basePath }, uiSettings }: CoreStart,
|
||||
{ kibanaLegacy }: { kibanaLegacy: KibanaLegacyStart }
|
||||
) {
|
||||
this.currentAppIdSubscription = application.currentAppId$.subscribe((currentAppId) => {
|
||||
this.currentAppId = currentAppId;
|
||||
});
|
||||
public start({ application, http: { basePath } }: CoreStart) {
|
||||
return {
|
||||
/**
|
||||
* Navigates to the app defined as kibana.defaultAppId.
|
||||
* This takes redirects into account and uses the right mechanism to navigate.
|
||||
*/
|
||||
navigateToDefaultApp: (
|
||||
{ overwriteHash }: { overwriteHash: boolean } = { overwriteHash: true }
|
||||
) => {
|
||||
navigateToDefaultApp(
|
||||
kibanaLegacy.config.defaultAppId,
|
||||
this.forwardDefinitions,
|
||||
application,
|
||||
basePath,
|
||||
this.currentAppId,
|
||||
overwriteHash
|
||||
);
|
||||
},
|
||||
/**
|
||||
* Resolves the provided hash using the registered forwards and navigates to the target app.
|
||||
* If a navigation happened, `{ navigated: true }` will be returned.
|
||||
|
@ -111,12 +84,6 @@ export class UrlForwardingPlugin {
|
|||
getForwards: () => this.forwardDefinitions,
|
||||
};
|
||||
}
|
||||
|
||||
public stop() {
|
||||
if (this.currentAppIdSubscription) {
|
||||
this.currentAppIdSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type UrlForwardingSetup = ReturnType<UrlForwardingPlugin['setup']>;
|
||||
|
|
|
@ -26,7 +26,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
it('clicking on console on homepage should take you to console app', async () => {
|
||||
await PageObjects.common.navigateToUrl('home');
|
||||
await PageObjects.common.navigateToApp('home');
|
||||
await testSubjects.click('homeDevTools');
|
||||
const url = await browser.getCurrentUrl();
|
||||
expect(url.includes('/app/dev_tools#/console')).to.be(true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue