mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Properly redirect legacy URLs (#68284)
This commit is contained in:
parent
fc9df7244b
commit
d1a6fa26b8
96 changed files with 473 additions and 642 deletions
|
@ -73,7 +73,6 @@ module.exports = {
|
|||
'rxjs',
|
||||
'sinon',
|
||||
'tinycolor2',
|
||||
'./src/legacy/ui/public/styles/font_awesome.less',
|
||||
'./src/legacy/ui/public/styles/bootstrap/bootstrap_light.less',
|
||||
],
|
||||
plugins: [
|
||||
|
|
|
@ -23,9 +23,6 @@ import { promisify } from 'util';
|
|||
|
||||
import { getUiSettingDefaults } from './server/ui_setting_defaults';
|
||||
import { registerCspCollector } from './server/lib/csp_usage_collector';
|
||||
import { injectVars } from './inject_vars';
|
||||
|
||||
import { kbnBaseUrl } from '../../../plugins/kibana_legacy/server';
|
||||
|
||||
const mkdirAsync = promisify(Fs.mkdir);
|
||||
|
||||
|
@ -43,35 +40,7 @@ export default function (kibana) {
|
|||
},
|
||||
|
||||
uiExports: {
|
||||
app: {
|
||||
id: 'kibana',
|
||||
title: 'Kibana',
|
||||
listed: false,
|
||||
main: 'plugins/kibana/kibana',
|
||||
},
|
||||
styleSheetPaths: resolve(__dirname, 'public/index.scss'),
|
||||
links: [],
|
||||
|
||||
injectDefaultVars(server, options) {
|
||||
const mapConfig = server.config().get('map');
|
||||
const tilemap = mapConfig.tilemap;
|
||||
|
||||
return {
|
||||
kbnIndex: options.index,
|
||||
kbnBaseUrl,
|
||||
|
||||
// required on all pages due to hacks that use these values
|
||||
mapConfig,
|
||||
tilemapsConfig: {
|
||||
deprecated: {
|
||||
// If url is set, old settings must be used for backward compatibility
|
||||
isOverridden: typeof tilemap.url === 'string' && tilemap.url !== '',
|
||||
config: tilemap,
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
uiSettingDefaults: getUiSettingDefaults(),
|
||||
},
|
||||
|
||||
|
@ -90,7 +59,6 @@ export default function (kibana) {
|
|||
init: async function (server) {
|
||||
const { usageCollection } = server.newPlatform.setup.plugins;
|
||||
registerCspCollector(usageCollection, server);
|
||||
server.injectUiAppVars('kibana', () => injectVars(server));
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -35,4 +35,5 @@ const pluginInstance = new TableVisPlugin({} as PluginInitializerContext);
|
|||
export const setup = pluginInstance.setup(npSetup.core, plugins);
|
||||
export const start = pluginInstance.start(npStart.core, {
|
||||
data: npStart.plugins.data,
|
||||
kibanaLegacy: npStart.plugins.kibanaLegacy,
|
||||
});
|
||||
|
|
|
@ -7,12 +7,3 @@
|
|||
// Public UI styles
|
||||
@import 'src/legacy/ui/public/index';
|
||||
|
||||
// Has to come after visualize because of some
|
||||
// bad cascading in the Editor layout
|
||||
@import '../../../../plugins/maps_legacy/public/index';
|
||||
|
||||
// Management styles
|
||||
@import './management/index';
|
||||
|
||||
// Local application mount wrapper styles
|
||||
@import 'local_application_service/index';
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
// autoloading
|
||||
|
||||
// preloading (for faster webpack builds)
|
||||
import routes from 'ui/routes';
|
||||
import { npSetup } from 'ui/new_platform';
|
||||
|
||||
// import the uiExports that we want to "use"
|
||||
import 'uiExports/savedObjectTypes';
|
||||
import 'uiExports/fieldFormatEditors';
|
||||
import 'uiExports/navbarExtensions';
|
||||
import 'uiExports/contextMenuActions';
|
||||
import 'uiExports/managementSections';
|
||||
import 'uiExports/indexManagement';
|
||||
import 'uiExports/embeddableFactories';
|
||||
import 'uiExports/embeddableActions';
|
||||
import 'uiExports/inspectorViews';
|
||||
import 'uiExports/search';
|
||||
import 'uiExports/shareContextMenuExtensions';
|
||||
import 'uiExports/interpreter';
|
||||
|
||||
import 'ui/autoload/all';
|
||||
|
||||
import { localApplicationService } from './local_application_service';
|
||||
|
||||
npSetup.plugins.kibanaLegacy.registerLegacyAppAlias('doc', 'discover', { keepPrefix: true });
|
||||
npSetup.plugins.kibanaLegacy.registerLegacyAppAlias('context', 'discover', { keepPrefix: true });
|
||||
|
||||
npSetup.plugins.kibanaLegacy.forwardApp('management', 'management', (path) => {
|
||||
return path.replace('/management', '');
|
||||
});
|
||||
|
||||
localApplicationService.attachToAngular(routes);
|
||||
|
||||
routes.enable();
|
||||
|
||||
const { config } = npSetup.plugins.kibanaLegacy;
|
||||
|
||||
routes.otherwise({
|
||||
redirectTo: `/${config.defaultAppId || 'discover'}`,
|
||||
});
|
|
@ -1 +0,0 @@
|
|||
@import 'local_application_service';
|
|
@ -1,5 +0,0 @@
|
|||
.kbnLocalApplicationWrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
export * from './local_application_service';
|
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { App, AppUnmount, AppMountDeprecated } from 'kibana/public';
|
||||
import { UIRoutes } from 'ui/routes';
|
||||
import { ILocationService, IScope } from 'angular';
|
||||
import { npStart } from 'ui/new_platform';
|
||||
import { htmlIdGenerator } from '@elastic/eui';
|
||||
|
||||
const matchAllWithPrefix = (prefixOrApp: string | App) =>
|
||||
`/${typeof prefixOrApp === 'string' ? prefixOrApp : prefixOrApp.id}/:tail*?`;
|
||||
|
||||
/**
|
||||
* To be able to migrate and shim parts of the Kibana app plugin
|
||||
* while still running some parts of it in the legacy world, this
|
||||
* service emulates the core application service while using the global
|
||||
* angular router to switch between apps without page reload.
|
||||
*
|
||||
* The id of the apps is used as prefix of the route - when switching between
|
||||
* to apps, the current application is unmounted.
|
||||
*
|
||||
* This service becomes unnecessary once the platform provides a central
|
||||
* router that handles switching between applications without page reload.
|
||||
*/
|
||||
export class LocalApplicationService {
|
||||
private idGenerator = htmlIdGenerator('kibanaAppLocalApp');
|
||||
|
||||
/**
|
||||
* Wires up listeners to handle mounting and unmounting of apps to
|
||||
* the legacy angular route manager. Once all apps within the Kibana
|
||||
* plugin are using the local route manager, this implementation can
|
||||
* be switched to a more lightweight implementation.
|
||||
*
|
||||
* @param angularRouteManager The current `ui/routes` instance
|
||||
*/
|
||||
attachToAngular(angularRouteManager: UIRoutes) {
|
||||
npStart.plugins.kibanaLegacy.getApps().forEach((app) => {
|
||||
const wrapperElementId = this.idGenerator();
|
||||
angularRouteManager.when(matchAllWithPrefix(app), {
|
||||
outerAngularWrapperRoute: true,
|
||||
reloadOnSearch: false,
|
||||
reloadOnUrl: false,
|
||||
template: `<div class="kbnLocalApplicationWrapper" id="${wrapperElementId}"></div>`,
|
||||
controller($scope: IScope) {
|
||||
const element = document.getElementById(wrapperElementId)!;
|
||||
let unmountHandler: AppUnmount | null = null;
|
||||
let isUnmounted = false;
|
||||
$scope.$on('$destroy', () => {
|
||||
if (unmountHandler) {
|
||||
unmountHandler();
|
||||
}
|
||||
isUnmounted = true;
|
||||
});
|
||||
(async () => {
|
||||
const params = {
|
||||
element,
|
||||
appBasePath: '',
|
||||
onAppLeave: () => undefined,
|
||||
// TODO: adapt to use Core's ScopedHistory
|
||||
history: {} as any,
|
||||
};
|
||||
unmountHandler = isAppMountDeprecated(app.mount)
|
||||
? await app.mount({ core: npStart.core }, params)
|
||||
: await app.mount(params);
|
||||
// immediately unmount app if scope got destroyed in the meantime
|
||||
if (isUnmounted) {
|
||||
unmountHandler();
|
||||
}
|
||||
})();
|
||||
},
|
||||
});
|
||||
|
||||
if (app.updater$) {
|
||||
app.updater$.subscribe((updater) => {
|
||||
const updatedFields = updater(app);
|
||||
if (updatedFields && updatedFields.activeUrl) {
|
||||
npStart.core.chrome.navLinks.update(app.navLinkId || app.id, {
|
||||
url: updatedFields.activeUrl,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
npStart.plugins.kibanaLegacy.getForwards().forEach((forwardDefinition) => {
|
||||
angularRouteManager.when(matchAllWithPrefix(forwardDefinition.legacyAppId), {
|
||||
outerAngularWrapperRoute: true,
|
||||
reloadOnSearch: false,
|
||||
reloadOnUrl: false,
|
||||
template: '<span></span>',
|
||||
controller($location: ILocationService) {
|
||||
const newPath = forwardDefinition.rewritePath($location.url());
|
||||
window.location.replace(
|
||||
npStart.core.http.basePath.prepend(`/app/${forwardDefinition.newAppId}${newPath}`)
|
||||
);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
npStart.plugins.kibanaLegacy
|
||||
.getLegacyAppAliases()
|
||||
.forEach(({ legacyAppId, newAppId, keepPrefix }) => {
|
||||
angularRouteManager.when(matchAllWithPrefix(legacyAppId), {
|
||||
resolveRedirectTo: ($location: ILocationService) => {
|
||||
const url = $location.url();
|
||||
return `/${newAppId}${keepPrefix ? url : url.replace(legacyAppId, '')}`;
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const localApplicationService = new LocalApplicationService();
|
||||
|
||||
function isAppMountDeprecated(mount: (...args: any[]) => any): mount is AppMountDeprecated {
|
||||
// Mount functions with two arguments are assumed to expect deprecated `context` object.
|
||||
return mount.length === 2;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
// This file is imported into src/core_plugings/kibana/publix/index.scss
|
||||
|
||||
// Prefix all styles with "dsh" to avoid conflicts.
|
||||
// Examples
|
||||
// mgtChart
|
||||
// mgtChart__legend
|
||||
// mgtChart__legend--small
|
||||
// mgtChart__legend-isLoading
|
||||
|
||||
// Core
|
||||
@import '../../../../../plugins/advanced_settings/public/index';
|
||||
|
||||
@import 'sections/index_patterns/index';
|
|
@ -1,25 +0,0 @@
|
|||
#indexPatternListReact {
|
||||
display: flex;
|
||||
|
||||
.indexPatternList__headerWrapper {
|
||||
padding-bottom: $euiSizeS;
|
||||
}
|
||||
|
||||
.euiButtonEmpty__content {
|
||||
justify-content: left;
|
||||
padding: 0;
|
||||
|
||||
span {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.indexPatternListPrompt__descList {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.indexPatternList__badge {
|
||||
margin-left: $euiSizeS;
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import { PluginInitializerContext } from 'kibana/public';
|
||||
import { npSetup } from 'ui/new_platform';
|
||||
import { npSetup, npStart } from 'ui/new_platform';
|
||||
import { plugin } from '.';
|
||||
import { TimelionPluginSetupDependencies } from './plugin';
|
||||
import { LegacyDependenciesPlugin } from './shim';
|
||||
|
@ -32,4 +32,4 @@ const setupPlugins: Readonly<TimelionPluginSetupDependencies> = {
|
|||
const pluginInstance = plugin({} as PluginInitializerContext);
|
||||
|
||||
export const setup = pluginInstance.setup(npSetup.core, setupPlugins);
|
||||
export const start = pluginInstance.start();
|
||||
export const start = pluginInstance.start(npStart.core, npStart.plugins);
|
||||
|
|
|
@ -16,10 +16,17 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { CoreSetup, Plugin, PluginInitializerContext, IUiSettingsClient } from 'kibana/public';
|
||||
import {
|
||||
CoreSetup,
|
||||
Plugin,
|
||||
PluginInitializerContext,
|
||||
IUiSettingsClient,
|
||||
CoreStart,
|
||||
} from 'kibana/public';
|
||||
import { getTimeChart } from './panels/timechart/timechart';
|
||||
import { Panel } from './panels/panel';
|
||||
import { LegacyDependenciesPlugin, LegacyDependenciesPluginSetup } from './shim';
|
||||
import { KibanaLegacyStart } from '../../../../plugins/kibana_legacy/public';
|
||||
|
||||
/** @internal */
|
||||
export interface TimelionVisualizationDependencies extends LegacyDependenciesPluginSetup {
|
||||
|
@ -59,7 +66,9 @@ export class TimelionPlugin implements Plugin<Promise<void>, void> {
|
|||
dependencies.timelionPanels.set(timeChartPanel.name, timeChartPanel);
|
||||
}
|
||||
|
||||
public start() {}
|
||||
public start(core: CoreStart, { kibanaLegacy }: { kibanaLegacy: KibanaLegacyStart }) {
|
||||
kibanaLegacy.loadFontAwesome();
|
||||
}
|
||||
|
||||
public stop(): void {}
|
||||
}
|
||||
|
|
|
@ -20,4 +20,3 @@
|
|||
import './accessibility';
|
||||
import './modules';
|
||||
import './settings';
|
||||
import './styles';
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import 'ui/styles/font_awesome.less';
|
|
@ -21,6 +21,7 @@ import expect from '@kbn/expect';
|
|||
import ngMock from 'ng_mock';
|
||||
import $ from 'jquery';
|
||||
import '../input_focus';
|
||||
import uiRoutes from 'ui/routes';
|
||||
|
||||
describe('Input focus directive', function () {
|
||||
let $compile;
|
||||
|
@ -32,6 +33,8 @@ describe('Input focus directive', function () {
|
|||
let selectedText;
|
||||
const inputValue = 'Input Text Value';
|
||||
|
||||
uiRoutes.enable();
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(
|
||||
ngMock.inject(function (_$compile_, _$rootScope_, _$timeout_) {
|
||||
|
|
|
@ -263,7 +263,6 @@ export const npSetup = {
|
|||
},
|
||||
kibanaLegacy: {
|
||||
registerLegacyApp: () => {},
|
||||
registerLegacyAppAlias: () => {},
|
||||
forwardApp: () => {},
|
||||
config: {
|
||||
defaultAppId: 'home',
|
||||
|
@ -379,9 +378,8 @@ export const npStart = {
|
|||
registerType: sinon.fake(),
|
||||
},
|
||||
kibanaLegacy: {
|
||||
getApps: () => [],
|
||||
getForwards: () => [],
|
||||
getLegacyAppAliases: () => [],
|
||||
loadFontAwesome: () => {},
|
||||
config: {
|
||||
defaultAppId: 'home',
|
||||
},
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
// Needs to remain a LESS file to point to the correct path for the fonts themeselves
|
||||
@import "~font-awesome/less/font-awesome";
|
||||
|
||||
// new file icon
|
||||
.@{fa-css-prefix}-file-new-o:before { content: @fa-var-file-o; }
|
||||
.@{fa-css-prefix}-file-new-o:after { content: @fa-var-plus; position: relative; margin-left: -1.0em; font-size: 0.5em; }
|
||||
|
||||
// alias for alert types - allows class="fa fa-{{alertType}}"
|
||||
.fa-success:before { content: @fa-var-check; }
|
||||
.fa-danger:before { content: @fa-var-exclamation-circle; }
|
|
@ -130,7 +130,6 @@ export function uiRenderMixin(kbnServer, server, config) {
|
|||
`${basePath}/node_modules/@kbn/ui-framework/dist/kui_light.css`,
|
||||
`${regularBundlePath}/light_theme.style.css`,
|
||||
]),
|
||||
`${regularBundlePath}/commons.style.css`,
|
||||
...(isCore
|
||||
? []
|
||||
: [
|
||||
|
@ -155,13 +154,7 @@ export function uiRenderMixin(kbnServer, server, config) {
|
|||
(filename) => `${regularBundlePath}/kbn-ui-shared-deps/${filename}`
|
||||
),
|
||||
`${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.jsFilename}`,
|
||||
...(isCore
|
||||
? []
|
||||
: [
|
||||
`${dllBundlePath}/vendors_runtime.bundle.dll.js`,
|
||||
...dllJsChunks,
|
||||
`${regularBundlePath}/commons.bundle.js`,
|
||||
]),
|
||||
...(isCore ? [] : [`${dllBundlePath}/vendors_runtime.bundle.dll.js`, ...dllJsChunks]),
|
||||
|
||||
`${regularBundlePath}/core/core.entry.js`,
|
||||
...kpPluginIds.map(
|
||||
|
|
|
@ -266,13 +266,6 @@ export default class BaseOptimizer {
|
|||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
commons: {
|
||||
name: 'commons',
|
||||
chunks: (chunk) =>
|
||||
chunk.canBeInitial() && chunk.name !== 'light_theme' && chunk.name !== 'dark_theme',
|
||||
minChunks: 2,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
light_theme: {
|
||||
name: 'light_theme',
|
||||
test: (m) =>
|
||||
|
|
|
@ -29,6 +29,8 @@ import { AdvancedSettings } from './advanced_settings';
|
|||
import { ManagementAppMountParams } from '../../../management/public';
|
||||
import { ComponentRegistry } from '../types';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const title = i18n.translate('advancedSettings.advancedSettingsLabel', {
|
||||
defaultMessage: 'Advanced Settings',
|
||||
});
|
||||
|
|
|
@ -68,11 +68,12 @@ export interface RenderDeps {
|
|||
embeddable: EmbeddableStart;
|
||||
localStorage: Storage;
|
||||
share?: SharePluginStart;
|
||||
config: KibanaLegacyStart['config'];
|
||||
usageCollection?: UsageCollectionSetup;
|
||||
navigateToDefaultApp: KibanaLegacyStart['navigateToDefaultApp'];
|
||||
navigateToLegacyKibanaUrl: KibanaLegacyStart['navigateToLegacyKibanaUrl'];
|
||||
scopedHistory: () => ScopedHistory;
|
||||
savedObjects: SavedObjectsStart;
|
||||
restorePreviousUrl: () => void;
|
||||
}
|
||||
|
||||
let angularModuleInstance: IModule | null = null;
|
||||
|
|
|
@ -242,9 +242,17 @@ export function initDashboardApp(app, deps) {
|
|||
},
|
||||
})
|
||||
.otherwise({
|
||||
template: '<span></span>',
|
||||
controller: function () {
|
||||
deps.navigateToDefaultApp();
|
||||
resolveRedirectTo: function ($rootScope) {
|
||||
const path = window.location.hash.substr(1);
|
||||
deps.restorePreviousUrl();
|
||||
$rootScope.$applyAsync(() => {
|
||||
const { navigated } = deps.navigateToLegacyKibanaUrl(path);
|
||||
if (!navigated) {
|
||||
deps.navigateToDefaultApp();
|
||||
}
|
||||
});
|
||||
// prevent angular from completing the navigation
|
||||
return new Promise(() => {});
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
@ -215,7 +215,13 @@ export class DashboardPlugin
|
|||
const placeholderFactory = new PlaceholderEmbeddableFactory();
|
||||
embeddable.registerEmbeddableFactory(placeholderFactory.type, placeholderFactory);
|
||||
|
||||
const { appMounted, appUnMounted, stop: stopUrlTracker, getActiveUrl } = createKbnUrlTracker({
|
||||
const {
|
||||
appMounted,
|
||||
appUnMounted,
|
||||
stop: stopUrlTracker,
|
||||
getActiveUrl,
|
||||
restorePreviousUrl,
|
||||
} = createKbnUrlTracker({
|
||||
baseUrl: core.http.basePath.prepend('/app/dashboards'),
|
||||
defaultSubUrl: `#${DashboardConstants.LANDING_PAGE_PATH}`,
|
||||
storageKey: `lastUrl:${core.http.basePath.get()}:dashboard`,
|
||||
|
@ -260,7 +266,7 @@ export class DashboardPlugin
|
|||
navigation,
|
||||
share: shareStart,
|
||||
data: dataStart,
|
||||
kibanaLegacy: { dashboardConfig, navigateToDefaultApp },
|
||||
kibanaLegacy: { dashboardConfig, navigateToDefaultApp, navigateToLegacyKibanaUrl },
|
||||
savedObjects,
|
||||
} = pluginsStart;
|
||||
|
||||
|
@ -269,6 +275,7 @@ export class DashboardPlugin
|
|||
core: coreStart,
|
||||
dashboardConfig,
|
||||
navigateToDefaultApp,
|
||||
navigateToLegacyKibanaUrl,
|
||||
navigation,
|
||||
share: shareStart,
|
||||
data: dataStart,
|
||||
|
@ -277,7 +284,6 @@ export class DashboardPlugin
|
|||
chrome: coreStart.chrome,
|
||||
addBasePath: coreStart.http.basePath.prepend,
|
||||
uiSettings: coreStart.uiSettings,
|
||||
config: kibanaLegacy.config,
|
||||
savedQueryService: dataStart.query.savedQueries,
|
||||
embeddable: embeddableStart,
|
||||
dashboardCapabilities: coreStart.application.capabilities.dashboard,
|
||||
|
@ -289,6 +295,7 @@ export class DashboardPlugin
|
|||
usageCollection,
|
||||
scopedHistory: () => this.currentHistory!,
|
||||
savedObjects,
|
||||
restorePreviousUrl,
|
||||
};
|
||||
// make sure the index pattern list is up to date
|
||||
await dataStart.indexPatterns.clearCache();
|
||||
|
@ -305,6 +312,15 @@ export class DashboardPlugin
|
|||
initAngularBootstrap();
|
||||
|
||||
core.application.register(app);
|
||||
kibanaLegacy.forwardApp(
|
||||
DashboardConstants.DASHBOARDS_ID,
|
||||
DashboardConstants.DASHBOARDS_ID,
|
||||
(path) => {
|
||||
const [, tail] = /(\?.*)/.exec(path) || [];
|
||||
// carry over query if it exists
|
||||
return `#/list${tail || ''}`;
|
||||
}
|
||||
);
|
||||
kibanaLegacy.forwardApp(
|
||||
DashboardConstants.DASHBOARD_ID,
|
||||
DashboardConstants.DASHBOARDS_ID,
|
||||
|
@ -322,15 +338,6 @@ export class DashboardPlugin
|
|||
return `#/view/${id}${tail || ''}`;
|
||||
}
|
||||
);
|
||||
kibanaLegacy.forwardApp(
|
||||
DashboardConstants.DASHBOARDS_ID,
|
||||
DashboardConstants.DASHBOARDS_ID,
|
||||
(path) => {
|
||||
const [, tail] = /(\?.*)/.exec(path) || [];
|
||||
// carry over query if it exists
|
||||
return `#/list${tail || ''}`;
|
||||
}
|
||||
);
|
||||
|
||||
if (home) {
|
||||
home.featureCatalogue.register({
|
||||
|
|
|
@ -198,7 +198,7 @@ export class IndexPattern implements IIndexPattern {
|
|||
|
||||
private updateFromElasticSearch(response: any, forceFieldRefresh: boolean = false) {
|
||||
if (!response.found) {
|
||||
throw new SavedObjectNotFound(type, this.id, 'kibana#/management/kibana/indexPatterns');
|
||||
throw new SavedObjectNotFound(type, this.id, 'management/kibana/indexPatterns');
|
||||
}
|
||||
|
||||
_.forOwn(this.mapping, (fieldMapping: FieldMappingSpec, name: string | undefined) => {
|
||||
|
|
|
@ -36,7 +36,7 @@ export const searchSavedObjectType: SavedObjectsType = {
|
|||
},
|
||||
getInAppUrl(obj) {
|
||||
return {
|
||||
path: `/app/discover#/${encodeURIComponent(obj.id)}`,
|
||||
path: `/app/discover#/view/${encodeURIComponent(obj.id)}`,
|
||||
uiCapabilitiesPath: 'discover.show',
|
||||
};
|
||||
},
|
||||
|
|
|
@ -2,5 +2,3 @@
|
|||
.tab-discover {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ app.config(($routeProvider) => {
|
|||
};
|
||||
},
|
||||
};
|
||||
$routeProvider.when('/:id?', {
|
||||
const discoverRoute = {
|
||||
...defaults,
|
||||
template: indexTemplate,
|
||||
reloadOnSearch: false,
|
||||
|
@ -177,7 +177,10 @@ app.config(($routeProvider) => {
|
|||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
$routeProvider.when('/view/:id?', discoverRoute);
|
||||
$routeProvider.when('/', discoverRoute);
|
||||
});
|
||||
|
||||
app.directive('discoverApp', function () {
|
||||
|
@ -415,7 +418,7 @@ function discoverController(
|
|||
testId: 'discoverOpenButton',
|
||||
run: () => {
|
||||
showOpenSearchPanel({
|
||||
makeUrl: (searchId) => `#/${encodeURIComponent(searchId)}`,
|
||||
makeUrl: (searchId) => `#/view/${encodeURIComponent(searchId)}`,
|
||||
I18nContext: core.i18n.Context,
|
||||
});
|
||||
},
|
||||
|
@ -747,7 +750,7 @@ function discoverController(
|
|||
});
|
||||
|
||||
if (savedSearch.id !== $route.current.params.id) {
|
||||
history.push(`/${encodeURIComponent(savedSearch.id)}`);
|
||||
history.push(`/view/${encodeURIComponent(savedSearch.id)}`);
|
||||
} else {
|
||||
// Update defaults so that "reload saved query" functions correctly
|
||||
setAppState(getStateDefaults());
|
||||
|
@ -926,7 +929,9 @@ function discoverController(
|
|||
};
|
||||
|
||||
$scope.resetQuery = function () {
|
||||
history.push(`/${encodeURIComponent($route.current.params.id)}`);
|
||||
history.push(
|
||||
$route.current.params.id ? `/view/${encodeURIComponent($route.current.params.id)}` : '/'
|
||||
);
|
||||
$route.reload();
|
||||
};
|
||||
|
||||
|
|
|
@ -144,8 +144,7 @@ export function createTableRowDirective($compile: ng.ICompileService, $httpParam
|
|||
cellTemplate({
|
||||
timefield: true,
|
||||
formatted: _displayField(row, indexPattern.timeFieldName),
|
||||
filterable:
|
||||
mapping(indexPattern.timeFieldName).filterable && _.isFunction($scope.filter),
|
||||
filterable: mapping(indexPattern.timeFieldName).filterable && $scope.filter,
|
||||
column: indexPattern.timeFieldName,
|
||||
})
|
||||
);
|
||||
|
@ -156,7 +155,7 @@ export function createTableRowDirective($compile: ng.ICompileService, $httpParam
|
|||
$scope.flattenedRow[column] !== undefined &&
|
||||
mapping(column) &&
|
||||
mapping(column).filterable &&
|
||||
_.isFunction($scope.filter);
|
||||
$scope.filter;
|
||||
|
||||
newHtmls.push(
|
||||
cellTemplate({
|
||||
|
|
|
@ -25,4 +25,5 @@ import './discover';
|
|||
import './doc';
|
||||
import './context';
|
||||
import './doc_viewer';
|
||||
import './redirect';
|
||||
import './directives';
|
||||
|
|
|
@ -16,8 +16,22 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { getAngularModule, getServices, getUrlTracker } from '../../kibana_services';
|
||||
|
||||
export {
|
||||
ProcessedImportResponse,
|
||||
processImportResponse,
|
||||
} from '../../../../plugins/saved_objects_management/public/lib'; // eslint-disable-line @kbn/eslint/no-restricted-paths
|
||||
getAngularModule().config(($routeProvider: any) => {
|
||||
$routeProvider.otherwise({
|
||||
resolveRedirectTo: ($rootScope: any) => {
|
||||
const path = window.location.hash.substr(1);
|
||||
getUrlTracker().restorePreviousUrl();
|
||||
$rootScope.$applyAsync(() => {
|
||||
const { kibanaLegacy } = getServices();
|
||||
const { navigated } = kibanaLegacy.navigateToLegacyKibanaUrl(path);
|
||||
if (!navigated) {
|
||||
kibanaLegacy.navigateToDefaultApp();
|
||||
}
|
||||
});
|
||||
// prevent angular from completing the navigation
|
||||
return new Promise(() => {});
|
||||
},
|
||||
});
|
||||
});
|
|
@ -19,11 +19,14 @@
|
|||
|
||||
import './index.scss';
|
||||
import angular from 'angular';
|
||||
import { getServices } from '../kibana_services';
|
||||
|
||||
/**
|
||||
* Here's where Discover's inner angular is mounted and rendered
|
||||
*/
|
||||
export async function renderApp(moduleName: string, element: HTMLElement) {
|
||||
// do not wait for fontawesome
|
||||
getServices().kibanaLegacy.loadFontAwesome();
|
||||
await import('./angular');
|
||||
const $injector = mountDiscoverApp(moduleName, element);
|
||||
return () => $injector.get('$rootScope').$destroy();
|
||||
|
|
|
@ -42,6 +42,7 @@ import { SavedObjectKibanaServices } from 'src/plugins/saved_objects/public';
|
|||
import { DiscoverStartPlugins } from './plugin';
|
||||
import { createSavedSearchesLoader, SavedSearch } from './saved_searches';
|
||||
import { getHistory } from './kibana_services';
|
||||
import { KibanaLegacyStart } from '../../kibana_legacy/public';
|
||||
|
||||
export interface DiscoverServices {
|
||||
addBasePath: (path: string) => string;
|
||||
|
@ -57,6 +58,7 @@ export interface DiscoverServices {
|
|||
inspector: InspectorPublicPluginStart;
|
||||
metadata: { branch: string };
|
||||
share?: SharePluginStart;
|
||||
kibanaLegacy: KibanaLegacyStart;
|
||||
timefilter: TimefilterContract;
|
||||
toastNotifications: ToastsStart;
|
||||
getSavedSearchById: (id: string) => Promise<SavedSearch>;
|
||||
|
@ -97,6 +99,7 @@ export async function buildServices(
|
|||
branch: context.env.packageInfo.branch,
|
||||
},
|
||||
share: plugins.share,
|
||||
kibanaLegacy: plugins.kibanaLegacy,
|
||||
timefilter: plugins.data.query.timefilter.timefilter,
|
||||
toastNotifications: core.notifications.toasts,
|
||||
uiSettings: core.uiSettings,
|
||||
|
|
|
@ -53,6 +53,7 @@ export function setServices(newServices: any) {
|
|||
|
||||
export const [getUrlTracker, setUrlTracker] = createGetterSetter<{
|
||||
setTrackedUrl: (url: string) => void;
|
||||
restorePreviousUrl: () => void;
|
||||
}>('urlTracker');
|
||||
|
||||
export const [getDocViewsRegistry, setDocViewsRegistry] = createGetterSetter<DocViewsRegistry>(
|
||||
|
|
|
@ -36,7 +36,7 @@ import { ChartsPluginStart } from 'src/plugins/charts/public';
|
|||
import { NavigationPublicPluginStart as NavigationStart } from 'src/plugins/navigation/public';
|
||||
import { SharePluginStart, SharePluginSetup, UrlGeneratorContract } from 'src/plugins/share/public';
|
||||
import { VisualizationsStart, VisualizationsSetup } from 'src/plugins/visualizations/public';
|
||||
import { KibanaLegacySetup } from 'src/plugins/kibana_legacy/public';
|
||||
import { KibanaLegacySetup, KibanaLegacyStart } from 'src/plugins/kibana_legacy/public';
|
||||
import { HomePublicPluginSetup } from 'src/plugins/home/public';
|
||||
import { Start as InspectorPublicPluginStart } from 'src/plugins/inspector/public';
|
||||
import { DataPublicPluginStart, DataPublicPluginSetup, esFilters } from '../../data/public';
|
||||
|
@ -55,6 +55,7 @@ import {
|
|||
setServices,
|
||||
setScopedHistory,
|
||||
getScopedHistory,
|
||||
getServices,
|
||||
} from './kibana_services';
|
||||
import { createSavedSearchesLoader } from './saved_searches';
|
||||
import { registerFeature } from './register_feature';
|
||||
|
@ -130,6 +131,7 @@ export interface DiscoverStartPlugins {
|
|||
charts: ChartsPluginStart;
|
||||
data: DataPublicPluginStart;
|
||||
share?: SharePluginStart;
|
||||
kibanaLegacy: KibanaLegacyStart;
|
||||
inspector: InspectorPublicPluginStart;
|
||||
visualizations: VisualizationsStart;
|
||||
}
|
||||
|
@ -195,6 +197,7 @@ export class DiscoverPlugin
|
|||
appUnMounted,
|
||||
stop: stopUrlTracker,
|
||||
setActiveUrl: setTrackedUrl,
|
||||
restorePreviousUrl,
|
||||
} = createKbnUrlTracker({
|
||||
// we pass getter here instead of plain `history`,
|
||||
// so history is lazily created (when app is mounted)
|
||||
|
@ -220,7 +223,7 @@ export class DiscoverPlugin
|
|||
},
|
||||
],
|
||||
});
|
||||
setUrlTracker({ setTrackedUrl });
|
||||
setUrlTracker({ setTrackedUrl, restorePreviousUrl });
|
||||
this.stopUrlTracking = () => {
|
||||
stopUrlTracker();
|
||||
};
|
||||
|
@ -260,7 +263,19 @@ export class DiscoverPlugin
|
|||
},
|
||||
});
|
||||
|
||||
plugins.kibanaLegacy.forwardApp('discover', 'discover');
|
||||
plugins.kibanaLegacy.forwardApp('doc', 'discover', (path) => {
|
||||
return `#${path}`;
|
||||
});
|
||||
plugins.kibanaLegacy.forwardApp('context', 'discover', (path) => {
|
||||
return `#${path}`;
|
||||
});
|
||||
plugins.kibanaLegacy.forwardApp('discover', 'discover', (path) => {
|
||||
const [, id, tail] = /discover\/([^\?]+)(.*)/.exec(path) || [];
|
||||
if (!id) {
|
||||
return `#${path.replace('/discover', '') || '/'}`;
|
||||
}
|
||||
return `#/view/${id}${tail || ''}`;
|
||||
});
|
||||
|
||||
if (plugins.home) {
|
||||
registerFeature(plugins.home);
|
||||
|
@ -356,6 +371,7 @@ export class DiscoverPlugin
|
|||
throw Error('Discover plugin getEmbeddableInjector: initializeServices is undefined');
|
||||
}
|
||||
const { core, plugins } = await this.initializeServices();
|
||||
getServices().kibanaLegacy.loadFontAwesome();
|
||||
const { getInnerAngularModuleEmbeddable } = await import('./get_inner_angular');
|
||||
getInnerAngularModuleEmbeddable(
|
||||
embeddableAngularName,
|
||||
|
|
|
@ -66,7 +66,7 @@ export function createSavedSearchClass(services: SavedObjectKibanaServices) {
|
|||
});
|
||||
this.showInRecentlyAccessed = true;
|
||||
this.id = id;
|
||||
this.getFullPath = () => `/app/discover#/${String(id)}`;
|
||||
this.getFullPath = () => `/app/discover#/view/${String(id)}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ export function createSavedSearchesLoader(services: SavedObjectKibanaServices) {
|
|||
nouns: 'saved searches',
|
||||
};
|
||||
|
||||
savedSearchLoader.urlFor = (id: string) => `#/${encodeURIComponent(id)}`;
|
||||
savedSearchLoader.urlFor = (id: string) => (id ? `#/view/${encodeURIComponent(id)}` : '#/');
|
||||
|
||||
return savedSearchLoader;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
@font-face {
|
||||
font-family: 'FontAwesome';
|
||||
src: url('~font-awesome/fonts/fontawesome-webfont.eot?v=4.7.0');
|
||||
src: url('~font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),
|
||||
url('~font-awesome/fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),
|
||||
url('~font-awesome/fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),
|
||||
url('~font-awesome/fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),
|
||||
url('~font-awesome/fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@import "font-awesome/scss/variables";
|
||||
@import "font-awesome/scss/core";
|
||||
@import "font-awesome/scss/icons";
|
||||
|
||||
// new file icon
|
||||
.#{$fa-css-prefix}-file-new-o:before { content: $fa-var-file-o; }
|
||||
.#{$fa-css-prefix}-file-new-o:after { content: $fa-var-plus; position: relative; margin-left: -1.0em; font-size: 0.5em; }
|
||||
|
||||
// alias for alert types - allows class="fa fa-{{alertType}}"
|
||||
.fa-success:before { content: $fa-var-check; }
|
||||
.fa-danger:before { content: $fa-var-exclamation-circle; }
|
|
@ -17,4 +17,4 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
@import './management_app/index';
|
||||
import './font_awesome.scss';
|
|
@ -22,10 +22,8 @@ import { AppNavLinkStatus } from '../../../../core/public';
|
|||
import { navigateToLegacyKibanaUrl } from './navigate_to_legacy_kibana_url';
|
||||
import { ForwardDefinition } from '../plugin';
|
||||
|
||||
export const createLegacyUrlForwardApp = (
|
||||
core: CoreSetup<{}, { getForwards: () => ForwardDefinition[] }>
|
||||
): App => ({
|
||||
id: 'url_migrate',
|
||||
export const createLegacyUrlForwardApp = (core: CoreSetup, forwards: ForwardDefinition[]): App => ({
|
||||
id: 'kibana',
|
||||
chromeless: true,
|
||||
title: 'Legacy URL migration',
|
||||
navLinkStatus: AppNavLinkStatus.hidden,
|
||||
|
@ -33,7 +31,7 @@ export const createLegacyUrlForwardApp = (
|
|||
const hash = params.history.location.hash.substr(1);
|
||||
|
||||
if (!hash) {
|
||||
throw new Error('Could not forward URL');
|
||||
core.fatalErrors.add('Could not forward URL');
|
||||
}
|
||||
|
||||
const [
|
||||
|
@ -41,11 +39,13 @@ export const createLegacyUrlForwardApp = (
|
|||
application,
|
||||
http: { basePath },
|
||||
},
|
||||
,
|
||||
{ getForwards },
|
||||
] = await core.getStartServices();
|
||||
|
||||
navigateToLegacyKibanaUrl(hash, getForwards(), basePath, application, window.location);
|
||||
const result = await navigateToLegacyKibanaUrl(hash, forwards, basePath, application);
|
||||
|
||||
if (!result.navigated) {
|
||||
core.fatalErrors.add('Could not forward URL');
|
||||
}
|
||||
|
||||
return () => {};
|
||||
},
|
||||
|
|
|
@ -25,7 +25,6 @@ import { coreMock } from '../../../../core/public/mocks';
|
|||
describe('migrate legacy kibana urls', () => {
|
||||
let forwardDefinitions: ForwardDefinition[];
|
||||
let coreStart: CoreStart;
|
||||
let locationMock: Location;
|
||||
|
||||
beforeEach(() => {
|
||||
coreStart = coreMock.createStart({ basePath: '/base/path' });
|
||||
|
@ -36,34 +35,33 @@ describe('migrate legacy kibana urls', () => {
|
|||
rewritePath: jest.fn(() => '/new/path'),
|
||||
},
|
||||
];
|
||||
locationMock = { href: '' } as Location;
|
||||
});
|
||||
|
||||
it('should redirect to kibana if no forward definition is found', () => {
|
||||
navigateToLegacyKibanaUrl(
|
||||
it('should do nothing if no forward definition is found', () => {
|
||||
const result = navigateToLegacyKibanaUrl(
|
||||
'/myOtherApp/deep/path',
|
||||
forwardDefinitions,
|
||||
coreStart.http.basePath,
|
||||
coreStart.application,
|
||||
locationMock
|
||||
coreStart.application
|
||||
);
|
||||
|
||||
expect(locationMock.href).toEqual('/base/path/app/kibana#/myOtherApp/deep/path');
|
||||
expect(result).toEqual({ navigated: false });
|
||||
expect(coreStart.application.navigateToApp).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call navigateToApp with migrated URL', () => {
|
||||
navigateToLegacyKibanaUrl(
|
||||
const result = navigateToLegacyKibanaUrl(
|
||||
'/myApp/deep/path',
|
||||
forwardDefinitions,
|
||||
coreStart.http.basePath,
|
||||
coreStart.application,
|
||||
locationMock
|
||||
coreStart.application
|
||||
);
|
||||
|
||||
expect(coreStart.application.navigateToApp).toHaveBeenCalledWith('updatedApp', {
|
||||
path: '/new/path',
|
||||
replace: true,
|
||||
});
|
||||
expect(forwardDefinitions[0].rewritePath).toHaveBeenCalledWith('/myApp/deep/path');
|
||||
expect(locationMock.href).toEqual('');
|
||||
expect(result).toEqual({ navigated: true });
|
||||
});
|
||||
});
|
||||
|
|
|
@ -19,30 +19,26 @@
|
|||
|
||||
import { ApplicationStart, IBasePath } from 'kibana/public';
|
||||
import { ForwardDefinition } from '../index';
|
||||
import { normalizePath } from '../utils/normalize_path';
|
||||
|
||||
export const navigateToLegacyKibanaUrl = (
|
||||
path: string,
|
||||
forwards: ForwardDefinition[],
|
||||
basePath: IBasePath,
|
||||
application: ApplicationStart,
|
||||
location: Location
|
||||
) => {
|
||||
// navigate to the respective path in the legacy kibana plugin by default (for unmigrated plugins)
|
||||
let targetAppId = 'kibana';
|
||||
let targetAppPath = path;
|
||||
application: ApplicationStart
|
||||
): { navigated: boolean } => {
|
||||
const normalizedPath = normalizePath(path);
|
||||
|
||||
// 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) => path.startsWith(`/${forward.legacyAppId}`));
|
||||
if (relevantForward) {
|
||||
targetAppPath = relevantForward.rewritePath(path);
|
||||
targetAppId = relevantForward.newAppId;
|
||||
}
|
||||
|
||||
if (targetAppId === 'kibana') {
|
||||
// exception for kibana app because redirect won't work right otherwise
|
||||
location.href = basePath.prepend(`/app/kibana#${targetAppPath}`);
|
||||
} else {
|
||||
application.navigateToApp(targetAppId, { path: targetAppPath });
|
||||
const relevantForward = forwards.find((forward) =>
|
||||
normalizedPath.startsWith(`/${forward.legacyAppId}`)
|
||||
);
|
||||
if (!relevantForward) {
|
||||
return { navigated: false };
|
||||
}
|
||||
const targetAppPath = relevantForward.rewritePath(normalizedPath);
|
||||
const targetAppId = relevantForward.newAppId;
|
||||
application.navigateToApp(targetAppId, { path: targetAppPath, replace: true });
|
||||
return { navigated: true };
|
||||
};
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { EnvironmentMode, PackageInfo } from 'kibana/server';
|
||||
import { KibanaLegacyPlugin } from './plugin';
|
||||
|
||||
export type Setup = jest.Mocked<ReturnType<KibanaLegacyPlugin['setup']>>;
|
||||
|
@ -25,20 +24,9 @@ export type Start = jest.Mocked<ReturnType<KibanaLegacyPlugin['start']>>;
|
|||
|
||||
const createSetupContract = (): Setup => ({
|
||||
forwardApp: jest.fn(),
|
||||
registerLegacyAppAlias: jest.fn(),
|
||||
registerLegacyApp: jest.fn(),
|
||||
config: {
|
||||
defaultAppId: 'home',
|
||||
},
|
||||
env: {} as {
|
||||
mode: Readonly<EnvironmentMode>;
|
||||
packageInfo: Readonly<PackageInfo>;
|
||||
},
|
||||
});
|
||||
|
||||
const createStartContract = (): Start => ({
|
||||
getApps: jest.fn(),
|
||||
getLegacyAppAliases: jest.fn(),
|
||||
getForwards: jest.fn(),
|
||||
config: {
|
||||
defaultAppId: 'home',
|
||||
|
@ -48,6 +36,8 @@ const createStartContract = (): Start => ({
|
|||
getHideWriteControls: jest.fn(),
|
||||
},
|
||||
navigateToDefaultApp: jest.fn(),
|
||||
navigateToLegacyKibanaUrl: jest.fn(),
|
||||
loadFontAwesome: jest.fn(),
|
||||
});
|
||||
|
||||
export const kibanaLegacyPluginMock = {
|
||||
|
|
|
@ -43,12 +43,7 @@ export function navigateToDefaultApp(
|
|||
// 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) {
|
||||
if (targetAppId === 'kibana') {
|
||||
// exception for kibana app because redirect won't work right otherwise
|
||||
window.location.href = basePath.prepend(`/app/kibana${targetAppPath}`);
|
||||
} else {
|
||||
application.navigateToApp(targetAppId, { path: targetAppPath });
|
||||
}
|
||||
application.navigateToApp(targetAppId, { path: targetAppPath, replace: true });
|
||||
} else if (overwriteHash) {
|
||||
window.location.hash = targetAppPath;
|
||||
}
|
||||
|
|
|
@ -17,26 +17,14 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
App,
|
||||
AppBase,
|
||||
PluginInitializerContext,
|
||||
AppUpdatableFields,
|
||||
CoreStart,
|
||||
CoreSetup,
|
||||
} from 'kibana/public';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { PluginInitializerContext, CoreStart, CoreSetup } from 'kibana/public';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { ConfigSchema } from '../config';
|
||||
import { getDashboardConfig } from './dashboard_config';
|
||||
import { navigateToDefaultApp } from './navigate_to_default_app';
|
||||
import { createLegacyUrlForwardApp } from './forward_app';
|
||||
import { injectHeaderStyle } from './utils/inject_header_style';
|
||||
|
||||
interface LegacyAppAliasDefinition {
|
||||
legacyAppId: string;
|
||||
newAppId: string;
|
||||
keepPrefix: boolean;
|
||||
}
|
||||
import { navigateToLegacyKibanaUrl } from './forward_app/navigate_to_legacy_kibana_url';
|
||||
|
||||
export interface ForwardDefinition {
|
||||
legacyAppId: string;
|
||||
|
@ -44,27 +32,7 @@ export interface ForwardDefinition {
|
|||
rewritePath: (legacyPath: string) => string;
|
||||
}
|
||||
|
||||
export type AngularRenderedAppUpdater = (
|
||||
app: AppBase
|
||||
) => Partial<AppUpdatableFields & { activeUrl: string }> | undefined;
|
||||
|
||||
export interface AngularRenderedApp extends App {
|
||||
/**
|
||||
* Angular rendered apps are able to update the active url in the nav link (which is currently not
|
||||
* possible for actual NP apps). When regular applications have the same functionality, this type
|
||||
* override can be removed.
|
||||
*/
|
||||
updater$?: Observable<AngularRenderedAppUpdater>;
|
||||
/**
|
||||
* If the active url is updated via the updater$ subject, the app id is assumed to be identical with
|
||||
* the nav link id. If this is not the case, it is possible to provide another nav link id here.
|
||||
*/
|
||||
navLinkId?: string;
|
||||
}
|
||||
|
||||
export class KibanaLegacyPlugin {
|
||||
private apps: AngularRenderedApp[] = [];
|
||||
private legacyAppAliases: LegacyAppAliasDefinition[] = [];
|
||||
private forwardDefinitions: ForwardDefinition[] = [];
|
||||
private currentAppId: string | undefined;
|
||||
private currentAppIdSubscription: Subscription | undefined;
|
||||
|
@ -72,57 +40,8 @@ export class KibanaLegacyPlugin {
|
|||
constructor(private readonly initializerContext: PluginInitializerContext<ConfigSchema>) {}
|
||||
|
||||
public setup(core: CoreSetup<{}, KibanaLegacyStart>) {
|
||||
core.application.register(createLegacyUrlForwardApp(core));
|
||||
core.application.register(createLegacyUrlForwardApp(core, this.forwardDefinitions));
|
||||
return {
|
||||
/**
|
||||
* @deprecated
|
||||
* Register an app to be managed by the application service.
|
||||
* This method works exactly as `core.application.register`.
|
||||
*
|
||||
* When an app is mounted, it is responsible for routing. The app
|
||||
* won't be mounted again if the route changes within the prefix
|
||||
* of the app (its id). It is fine to use whatever means for handling
|
||||
* routing within the app.
|
||||
*
|
||||
* When switching to a URL outside of the current prefix, the app router
|
||||
* shouldn't do anything because it doesn't own the routing anymore -
|
||||
* the local application service takes over routing again,
|
||||
* unmounts the current app and mounts the next app.
|
||||
*
|
||||
* @param app The app descriptor
|
||||
*/
|
||||
registerLegacyApp: (app: AngularRenderedApp) => {
|
||||
this.apps.push(app);
|
||||
},
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Forwards every URL starting with `legacyAppId` to the same URL starting
|
||||
* with `newAppId` - e.g. `/legacy/my/legacy/path?q=123` gets forwarded to
|
||||
* `/newApp/my/legacy/path?q=123`.
|
||||
*
|
||||
* When setting the `keepPrefix` option, the new app id is simply prepended.
|
||||
* The example above would become `/newApp/legacy/my/legacy/path?q=123`.
|
||||
*
|
||||
* This method can be used to provide backwards compatibility for URLs when
|
||||
* renaming or nesting plugins. For route changes after the prefix, please
|
||||
* use the routing mechanism of your app.
|
||||
*
|
||||
* This method just redirects URLs within the legacy `kibana` app.
|
||||
*
|
||||
* @param legacyAppId The name of the old app to forward URLs from
|
||||
* @param newAppId The name of the new app that handles the URLs now
|
||||
* @param options Whether the prefix of the old app is kept to nest the legacy
|
||||
* path into the new path
|
||||
*/
|
||||
registerLegacyAppAlias: (
|
||||
legacyAppId: string,
|
||||
newAppId: string,
|
||||
options: { keepPrefix: boolean } = { keepPrefix: false }
|
||||
) => {
|
||||
this.legacyAppAliases.push({ legacyAppId, newAppId, ...options });
|
||||
},
|
||||
|
||||
/**
|
||||
* Forwards URLs within the legacy `kibana` app to a new platform application.
|
||||
*
|
||||
|
@ -164,18 +83,6 @@ export class KibanaLegacyPlugin {
|
|||
rewritePath: rewritePath || ((path) => `#${path.replace(`/${legacyAppId}`, '') || '/'}`),
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* The `defaultAppId` config key is temporarily exposed to be used in the legacy platform.
|
||||
* As this setting is going away, no new code should depend on it.
|
||||
*/
|
||||
config: this.initializerContext.config.get(),
|
||||
/**
|
||||
* @deprecated
|
||||
* Temporarily exposing the NP env to simulate initializer contexts in the LP.
|
||||
*/
|
||||
env: this.initializerContext.env,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -186,21 +93,9 @@ export class KibanaLegacyPlugin {
|
|||
injectHeaderStyle(uiSettings);
|
||||
return {
|
||||
/**
|
||||
* Used to power dashboard mode. Should be removed when dashboard mode is removed eventually.
|
||||
* @deprecated
|
||||
* Just exported for wiring up with legacy platform, should not be used.
|
||||
*/
|
||||
getApps: () => this.apps,
|
||||
/**
|
||||
* @deprecated
|
||||
* Just exported for wiring up with legacy platform, should not be used.
|
||||
*/
|
||||
getLegacyAppAliases: () => this.legacyAppAliases,
|
||||
/**
|
||||
* @deprecated
|
||||
* Just exported for wiring up with legacy platform, should not be used.
|
||||
*/
|
||||
getForwards: () => this.forwardDefinitions,
|
||||
config: this.initializerContext.config.get(),
|
||||
dashboardConfig: getDashboardConfig(!application.capabilities.dashboard.showWriteControls),
|
||||
/**
|
||||
* Navigates to the app defined as kibana.defaultAppId.
|
||||
|
@ -218,6 +113,32 @@ export class KibanaLegacyPlugin {
|
|||
overwriteHash
|
||||
);
|
||||
},
|
||||
/**
|
||||
* Resolves the provided hash using the registered forwards and navigates to the target app.
|
||||
* If a navigation happened, `{ navigated: true }` will be returned.
|
||||
* If no matching forward is found, `{ navigated: false }` will be returned.
|
||||
* @param hash
|
||||
*/
|
||||
navigateToLegacyKibanaUrl: (hash: string) => {
|
||||
return navigateToLegacyKibanaUrl(hash, this.forwardDefinitions, basePath, application);
|
||||
},
|
||||
/**
|
||||
* Loads the font-awesome icon font. Should be removed once the last consumer has migrated to EUI
|
||||
* @deprecated
|
||||
*/
|
||||
loadFontAwesome: async () => {
|
||||
await import('./font_awesome');
|
||||
},
|
||||
/**
|
||||
* @deprecated
|
||||
* Just exported for wiring up with legacy platform, should not be used.
|
||||
*/
|
||||
getForwards: () => this.forwardDefinitions,
|
||||
/**
|
||||
* @deprecated
|
||||
* Just exported for wiring up with dashboard mode, should not be used.
|
||||
*/
|
||||
config: this.initializerContext.config.get(),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
export * from './migrate_legacy_query';
|
||||
export * from './system_api';
|
||||
export * from './normalize_path';
|
||||
// @ts-ignore
|
||||
export { KbnAccessibleClickProvider } from './kbn_accessible_click';
|
||||
// @ts-ignore
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export function injectVars(server) {
|
||||
const serverConfig = server.config();
|
||||
import { normalize } from 'path';
|
||||
|
||||
return {
|
||||
autocompleteTerminateAfter: serverConfig.get('kibana.autocompleteTerminateAfter'),
|
||||
autocompleteTimeout: serverConfig.get('kibana.autocompleteTimeout'),
|
||||
};
|
||||
export function normalizePath(path: string) {
|
||||
// resolve ../ within the path
|
||||
const normalizedPath = normalize(path);
|
||||
// strip any leading slashes and dots and replace with single leading slash
|
||||
return normalizedPath.replace(/(\.?\.?\/?)*/, '/');
|
||||
}
|
|
@ -38,6 +38,10 @@ export interface KbnUrlTracker {
|
|||
stop: () => void;
|
||||
setActiveUrl: (newUrl: string) => void;
|
||||
getActiveUrl: () => string;
|
||||
/**
|
||||
* Resets internal state to the last active url, discarding the most recent change
|
||||
*/
|
||||
restorePreviousUrl: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,6 +126,8 @@ export function createKbnUrlTracker({
|
|||
}): KbnUrlTracker {
|
||||
const storageInstance = storage || sessionStorage;
|
||||
|
||||
// local state storing previous active url to make restore possible
|
||||
let previousActiveUrl: string = '';
|
||||
// local state storing current listeners and active url
|
||||
let activeUrl: string = '';
|
||||
let unsubscribeURLHistory: UnregisterCallback | undefined;
|
||||
|
@ -157,6 +163,7 @@ export function createKbnUrlTracker({
|
|||
toastNotifications.addDanger(e.message);
|
||||
}
|
||||
|
||||
previousActiveUrl = activeUrl;
|
||||
activeUrl = getActiveSubUrl(urlWithStates || urlWithHashes);
|
||||
storageInstance.setItem(storageKey, activeUrl);
|
||||
}
|
||||
|
@ -183,6 +190,7 @@ export function createKbnUrlTracker({
|
|||
{ useHash: false },
|
||||
baseUrl + (activeUrl || defaultSubUrl)
|
||||
);
|
||||
previousActiveUrl = activeUrl;
|
||||
// remove baseUrl prefix (just storing the sub url part)
|
||||
activeUrl = getActiveSubUrl(updatedUrl);
|
||||
storageInstance.setItem(storageKey, activeUrl);
|
||||
|
@ -198,6 +206,7 @@ export function createKbnUrlTracker({
|
|||
const storedUrl = storageInstance.getItem(storageKey);
|
||||
if (storedUrl) {
|
||||
activeUrl = storedUrl;
|
||||
previousActiveUrl = storedUrl;
|
||||
setNavLink(storedUrl);
|
||||
}
|
||||
|
||||
|
@ -217,5 +226,8 @@ export function createKbnUrlTracker({
|
|||
getActiveUrl() {
|
||||
return activeUrl;
|
||||
},
|
||||
restorePreviousUrl() {
|
||||
activeUrl = previousActiveUrl;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
@import './map/index';
|
|
@ -44,6 +44,8 @@ import {
|
|||
// @ts-ignore
|
||||
import { mapTooltipProvider } from './tooltip_provider';
|
||||
|
||||
import './map/index.scss';
|
||||
|
||||
export interface MapsLegacyConfigType {
|
||||
regionmap: any;
|
||||
emsTileLayerId: string;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"visualizations",
|
||||
"expressions",
|
||||
"mapsLegacy",
|
||||
"kibanaLegacy",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
import { NotificationsStart } from 'kibana/public';
|
||||
import { createGetterSetter } from '../../kibana_utils/public';
|
||||
import { DataPublicPluginStart } from '../../data/public';
|
||||
import { KibanaLegacyStart } from '../../kibana_legacy/public';
|
||||
|
||||
export const [getFormatService, setFormatService] = createGetterSetter<
|
||||
DataPublicPluginStart['fieldFormats']
|
||||
|
@ -28,3 +29,7 @@ export const [getFormatService, setFormatService] = createGetterSetter<
|
|||
export const [getNotifications, setNotifications] = createGetterSetter<NotificationsStart>(
|
||||
'Notifications'
|
||||
);
|
||||
|
||||
export const [getKibanaLegacy, setKibanaLegacy] = createGetterSetter<KibanaLegacyStart>(
|
||||
'KibanaLegacy'
|
||||
);
|
||||
|
|
|
@ -31,10 +31,11 @@ import { createRegionMapFn } from './region_map_fn';
|
|||
// @ts-ignore
|
||||
import { createRegionMapTypeDefinition } from './region_map_type';
|
||||
import { getBaseMapsVis, IServiceSettings, MapsLegacyPluginSetup } from '../../maps_legacy/public';
|
||||
import { setFormatService, setNotifications } from './kibana_services';
|
||||
import { setFormatService, setNotifications, setKibanaLegacy } from './kibana_services';
|
||||
import { DataPublicPluginStart } from '../../data/public';
|
||||
import { RegionMapsConfigType } from './index';
|
||||
import { ConfigSchema } from '../../maps_legacy/config';
|
||||
import { KibanaLegacyStart } from '../../kibana_legacy/public';
|
||||
|
||||
/** @private */
|
||||
interface RegionMapVisualizationDependencies {
|
||||
|
@ -55,6 +56,7 @@ export interface RegionMapPluginSetupDependencies {
|
|||
export interface RegionMapPluginStartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
notifications: NotificationsStart;
|
||||
kibanaLegacy: KibanaLegacyStart;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
@ -107,8 +109,9 @@ export class RegionMapPlugin implements Plugin<RegionMapPluginSetup, RegionMapPl
|
|||
}
|
||||
|
||||
// @ts-ignore
|
||||
public start(core: CoreStart, { data }: RegionMapPluginStartDependencies) {
|
||||
public start(core: CoreStart, { data, kibanaLegacy }: RegionMapPluginStartDependencies) {
|
||||
setFormatService(data.fieldFormats);
|
||||
setNotifications(core.notifications);
|
||||
setKibanaLegacy(kibanaLegacy);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import ChoroplethLayer from './choropleth_layer';
|
||||
import { getFormatService, getNotifications } from './kibana_services';
|
||||
import { getFormatService, getNotifications, getKibanaLegacy } from './kibana_services';
|
||||
import { truncatedColorMaps } from '../../charts/public';
|
||||
import { tooltipFormatter } from './tooltip_formatter';
|
||||
import { mapTooltipProvider } from '../../maps_legacy/public';
|
||||
|
@ -38,6 +38,7 @@ export function createRegionMapVisualization({
|
|||
}
|
||||
|
||||
async render(esResponse, visParams) {
|
||||
getKibanaLegacy().loadFontAwesome();
|
||||
await super.render(esResponse, visParams);
|
||||
if (this._choroplethLayer) {
|
||||
await this._choroplethLayer.whenDataLoaded();
|
||||
|
|
|
@ -29,6 +29,7 @@ export {
|
|||
ISavedObjectsManagementServiceRegistry,
|
||||
SavedObjectsManagementServiceRegistryEntry,
|
||||
} from './services';
|
||||
export { ProcessedImportResponse, processImportResponse } from './lib';
|
||||
export { SavedObjectRelation, SavedObjectWithMetadata, SavedObjectMetadata } from './types';
|
||||
|
||||
export function plugin(initializerContext: PluginInitializerContext) {
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { SavedObjectMigrationFn } from 'kibana/server';
|
||||
|
||||
/**
|
||||
* To avoid loading the client twice for old short urls pointing to the /app/kibana app,
|
||||
* this PR rewrites them to point to the new platform app url_migrate instead. This app will
|
||||
* migrate the url on the fly and redirect the user to the actual new location of the short url
|
||||
* without loading the page again.
|
||||
* @param doc
|
||||
*/
|
||||
export const migrateLegacyKibanaAppShortUrls: SavedObjectMigrationFn<any, any> = (doc) => ({
|
||||
...doc,
|
||||
attributes: {
|
||||
...doc.attributes,
|
||||
url:
|
||||
typeof doc.attributes.url === 'string' && doc.attributes.url.startsWith('/app/kibana')
|
||||
? doc.attributes.url.replace('/app/kibana', '/app/url_migrate')
|
||||
: doc.attributes.url,
|
||||
},
|
||||
});
|
|
@ -16,9 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { SavedObjectMigrationFn, SavedObjectsType } from 'kibana/server';
|
||||
import { flow } from 'lodash';
|
||||
import { migrateLegacyKibanaAppShortUrls } from './kibana_app_migration';
|
||||
import { SavedObjectsType } from 'kibana/server';
|
||||
|
||||
export const url: SavedObjectsType = {
|
||||
name: 'url',
|
||||
|
@ -32,9 +30,6 @@ export const url: SavedObjectsType = {
|
|||
return `/goto/${encodeURIComponent(obj.id)}`;
|
||||
},
|
||||
},
|
||||
migrations: {
|
||||
'7.9.0': flow<SavedObjectMigrationFn>(migrateLegacyKibanaAppShortUrls),
|
||||
},
|
||||
mappings: {
|
||||
properties: {
|
||||
accessCount: {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"visualizations",
|
||||
"expressions",
|
||||
"mapsLegacy",
|
||||
"kibanaLegacy",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ import { createTileMapTypeDefinition } from './tile_map_type';
|
|||
import { getBaseMapsVis, MapsLegacyPluginSetup } from '../../maps_legacy/public';
|
||||
import { DataPublicPluginStart } from '../../data/public';
|
||||
import { setFormatService, setQueryService } from './services';
|
||||
import { setKibanaLegacy } from './services';
|
||||
import { KibanaLegacyStart } from '../../kibana_legacy/public';
|
||||
|
||||
export interface TileMapConfigType {
|
||||
tilemap: any;
|
||||
|
@ -58,6 +60,7 @@ export interface TileMapPluginSetupDependencies {
|
|||
/** @internal */
|
||||
export interface TileMapPluginStartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
kibanaLegacy: KibanaLegacyStart;
|
||||
}
|
||||
|
||||
export interface TileMapPluginSetup {
|
||||
|
@ -96,9 +99,10 @@ export class TileMapPlugin implements Plugin<TileMapPluginSetup, TileMapPluginSt
|
|||
};
|
||||
}
|
||||
|
||||
public start(core: CoreStart, { data }: TileMapPluginStartDependencies) {
|
||||
public start(core: CoreStart, { data, kibanaLegacy }: TileMapPluginStartDependencies) {
|
||||
setFormatService(data.fieldFormats);
|
||||
setQueryService(data.query);
|
||||
setKibanaLegacy(kibanaLegacy);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
import { createGetterSetter } from '../../kibana_utils/public';
|
||||
import { DataPublicPluginStart } from '../../data/public';
|
||||
import { KibanaLegacyStart } from '../../kibana_legacy/public';
|
||||
|
||||
export const [getFormatService, setFormatService] = createGetterSetter<
|
||||
DataPublicPluginStart['fieldFormats']
|
||||
|
@ -27,3 +28,7 @@ export const [getFormatService, setFormatService] = createGetterSetter<
|
|||
export const [getQueryService, setQueryService] = createGetterSetter<
|
||||
DataPublicPluginStart['query']
|
||||
>('Query');
|
||||
|
||||
export const [getKibanaLegacy, setKibanaLegacy] = createGetterSetter<KibanaLegacyStart>(
|
||||
'KibanaLegacy'
|
||||
);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { get } from 'lodash';
|
||||
import { GeohashLayer } from './geohash_layer';
|
||||
import { getFormatService, getQueryService } from './services';
|
||||
import { getFormatService, getQueryService, getKibanaLegacy } from './services';
|
||||
import { scaleBounds, geoContains, mapTooltipProvider } from '../../maps_legacy/public';
|
||||
import { tooltipFormatter } from './tooltip_formatter';
|
||||
|
||||
|
@ -60,6 +60,11 @@ export const createTileMapVisualization = (dependencies) => {
|
|||
this.vis.eventsSubject.next(updateVarsObject);
|
||||
};
|
||||
|
||||
async render(esResponse, visParams) {
|
||||
getKibanaLegacy().loadFontAwesome();
|
||||
await super.render(esResponse, visParams);
|
||||
}
|
||||
|
||||
async _makeKibanaMap() {
|
||||
await super._makeKibanaMap();
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"requiredPlugins": [
|
||||
"expressions",
|
||||
"visualizations",
|
||||
"data"
|
||||
"data",
|
||||
"kibanaLegacy"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ import { VisualizationsSetup } from '../../visualizations/public';
|
|||
import { createTableVisFn } from './table_vis_fn';
|
||||
import { getTableVisTypeDefinition } from './table_vis_type';
|
||||
import { DataPublicPluginStart } from '../../data/public';
|
||||
import { setFormatService } from './services';
|
||||
import { setFormatService, setKibanaLegacy } from './services';
|
||||
import { KibanaLegacyStart } from '../../kibana_legacy/public';
|
||||
|
||||
/** @internal */
|
||||
export interface TablePluginSetupDependencies {
|
||||
|
@ -34,6 +35,7 @@ export interface TablePluginSetupDependencies {
|
|||
/** @internal */
|
||||
export interface TablePluginStartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
kibanaLegacy: KibanaLegacyStart;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
@ -55,7 +57,8 @@ export class TableVisPlugin implements Plugin<Promise<void>, void> {
|
|||
);
|
||||
}
|
||||
|
||||
public start(core: CoreStart, { data }: TablePluginStartDependencies) {
|
||||
public start(core: CoreStart, { data, kibanaLegacy }: TablePluginStartDependencies) {
|
||||
setFormatService(data.fieldFormats);
|
||||
setKibanaLegacy(kibanaLegacy);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,12 @@
|
|||
|
||||
import { createGetterSetter } from '../../kibana_utils/public';
|
||||
import { DataPublicPluginStart } from '../../data/public';
|
||||
import { KibanaLegacyStart } from '../../kibana_legacy/public';
|
||||
|
||||
export const [getFormatService, setFormatService] = createGetterSetter<
|
||||
DataPublicPluginStart['fieldFormats']
|
||||
>('table data.fieldFormats');
|
||||
|
||||
export const [getKibanaLegacy, setKibanaLegacy] = createGetterSetter<KibanaLegacyStart>(
|
||||
'table kibanaLegacy'
|
||||
);
|
||||
|
|
|
@ -22,6 +22,7 @@ import $ from 'jquery';
|
|||
|
||||
import { VisParams, ExprVis } from '../../visualizations/public';
|
||||
import { getAngularModule } from './get_inner_angular';
|
||||
import { getKibanaLegacy } from './services';
|
||||
import { initTableVisLegacyModule } from './table_vis_legacy_module';
|
||||
|
||||
const innerAngularName = 'kibana/table_vis';
|
||||
|
@ -64,6 +65,7 @@ export function getTableVisualizationControllerClass(
|
|||
}
|
||||
|
||||
async render(esResponse: object, visParams: VisParams) {
|
||||
getKibanaLegacy().loadFontAwesome();
|
||||
await this.initLocalAngular();
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
"version": "kibana",
|
||||
"server": true,
|
||||
"ui": true,
|
||||
"requiredPlugins": ["charts", "data", "expressions", "visualizations"],
|
||||
"requiredPlugins": ["charts", "data", "expressions", "visualizations", "kibanaLegacy"],
|
||||
"optionalPlugins": ["visTypeXy"]
|
||||
}
|
||||
|
|
|
@ -44,7 +44,8 @@ import {
|
|||
} from './vis_type_vislib_vis_types';
|
||||
import { ChartsPluginSetup } from '../../charts/public';
|
||||
import { DataPublicPluginStart } from '../../data/public';
|
||||
import { setFormatService, setDataActions } from './services';
|
||||
import { setFormatService, setDataActions, setKibanaLegacy } from './services';
|
||||
import { KibanaLegacyStart } from '../../kibana_legacy/public';
|
||||
|
||||
export interface VisTypeVislibDependencies {
|
||||
uiSettings: IUiSettingsClient;
|
||||
|
@ -62,6 +63,7 @@ export interface VisTypeVislibPluginSetupDependencies {
|
|||
/** @internal */
|
||||
export interface VisTypeVislibPluginStartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
kibanaLegacy: KibanaLegacyStart;
|
||||
}
|
||||
|
||||
type VisTypeVislibCoreSetup = CoreSetup<VisTypeVislibPluginStartDependencies, void>;
|
||||
|
@ -109,8 +111,9 @@ export class VisTypeVislibPlugin implements Plugin<void, void> {
|
|||
);
|
||||
}
|
||||
|
||||
public start(core: CoreStart, { data }: VisTypeVislibPluginStartDependencies) {
|
||||
public start(core: CoreStart, { data, kibanaLegacy }: VisTypeVislibPluginStartDependencies) {
|
||||
setFormatService(data.fieldFormats);
|
||||
setDataActions(data.actions);
|
||||
setKibanaLegacy(kibanaLegacy);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
import { createGetterSetter } from '../../kibana_utils/public';
|
||||
import { DataPublicPluginStart } from '../../data/public';
|
||||
import { KibanaLegacyStart } from '../../kibana_legacy/public';
|
||||
|
||||
export const [getDataActions, setDataActions] = createGetterSetter<
|
||||
DataPublicPluginStart['actions']
|
||||
|
@ -27,3 +28,7 @@ export const [getDataActions, setDataActions] = createGetterSetter<
|
|||
export const [getFormatService, setFormatService] = createGetterSetter<
|
||||
DataPublicPluginStart['fieldFormats']
|
||||
>('vislib data.fieldFormats');
|
||||
|
||||
export const [getKibanaLegacy, setKibanaLegacy] = createGetterSetter<KibanaLegacyStart>(
|
||||
'vislib kibanalegacy'
|
||||
);
|
||||
|
|
|
@ -27,6 +27,7 @@ import { VisTypeVislibDependencies } from './plugin';
|
|||
import { mountReactNode } from '../../../core/public/utils';
|
||||
import { VisLegend, CUSTOM_LEGEND_VIS_TYPES } from './vislib/components/legend';
|
||||
import { VisParams, ExprVis } from '../../visualizations/public';
|
||||
import { getKibanaLegacy } from './services';
|
||||
|
||||
const legendClassName = {
|
||||
top: 'visLib--legend-top',
|
||||
|
@ -72,6 +73,8 @@ export const createVislibVisController = (deps: VisTypeVislibDependencies) => {
|
|||
this.destroy();
|
||||
}
|
||||
|
||||
getKibanaLegacy().loadFontAwesome();
|
||||
|
||||
return new Promise(async (resolve) => {
|
||||
if (this.el.clientWidth === 0 || this.el.clientHeight === 0) {
|
||||
return resolve();
|
||||
|
|
|
@ -244,9 +244,17 @@ export function initVisualizeApp(app, deps) {
|
|||
},
|
||||
})
|
||||
.otherwise({
|
||||
template: '<span></span>',
|
||||
controller: function () {
|
||||
deps.kibanaLegacy.navigateToDefaultApp();
|
||||
resolveRedirectTo: function ($rootScope) {
|
||||
const path = window.location.hash.substr(1);
|
||||
deps.restorePreviousUrl();
|
||||
$rootScope.$applyAsync(() => {
|
||||
const { navigated } = deps.kibanaLegacy.navigateToLegacyKibanaUrl(path);
|
||||
if (!navigated) {
|
||||
deps.kibanaLegacy.navigateToDefaultApp();
|
||||
}
|
||||
});
|
||||
// prevent angular from completing the navigation
|
||||
return new Promise(() => {});
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
@ -55,6 +55,7 @@ export interface VisualizeKibanaServices {
|
|||
embeddable: EmbeddableStart;
|
||||
I18nContext: I18nStart['Context'];
|
||||
setActiveUrl: (newUrl: string) => void;
|
||||
restorePreviousUrl: () => void;
|
||||
createVisEmbeddableFromObject: VisualizationsStart['__LEGACY']['createVisEmbeddableFromObject'];
|
||||
scopedHistory: () => ScopedHistory;
|
||||
savedObjects: SavedObjectsStart;
|
||||
|
|
|
@ -73,7 +73,13 @@ export class VisualizePlugin
|
|||
core: CoreSetup<VisualizePluginStartDependencies>,
|
||||
{ home, kibanaLegacy, data }: VisualizePluginSetupDependencies
|
||||
) {
|
||||
const { appMounted, appUnMounted, stop: stopUrlTracker, setActiveUrl } = createKbnUrlTracker({
|
||||
const {
|
||||
appMounted,
|
||||
appUnMounted,
|
||||
stop: stopUrlTracker,
|
||||
setActiveUrl,
|
||||
restorePreviousUrl,
|
||||
} = createKbnUrlTracker({
|
||||
baseUrl: core.http.basePath.prepend('/app/visualize'),
|
||||
defaultSubUrl: '#/',
|
||||
storageKey: `lastUrl:${core.http.basePath.get()}:visualize`,
|
||||
|
@ -136,6 +142,7 @@ export class VisualizePlugin
|
|||
pluginsStart.visualizations.__LEGACY.createVisEmbeddableFromObject,
|
||||
scopedHistory: () => this.currentHistory!,
|
||||
savedObjects: pluginsStart.savedObjects,
|
||||
restorePreviousUrl,
|
||||
};
|
||||
setServices(deps);
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
editUrl:
|
||||
'/management/kibana/objects/savedSearches/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
inAppUrl: {
|
||||
path: '/app/discover#/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
path: '/app/discover#/view/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
uiCapabilitiesPath: 'discover.show',
|
||||
},
|
||||
});
|
||||
|
|
|
@ -283,7 +283,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
editUrl:
|
||||
'/management/kibana/objects/savedSearches/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
inAppUrl: {
|
||||
path: '/app/discover#/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
path: '/app/discover#/view/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
uiCapabilitiesPath: 'discover.show',
|
||||
},
|
||||
},
|
||||
|
@ -323,7 +323,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
editUrl:
|
||||
'/management/kibana/objects/savedSearches/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
inAppUrl: {
|
||||
path: '/app/discover#/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
path: '/app/discover#/view/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
uiCapabilitiesPath: 'discover.show',
|
||||
},
|
||||
},
|
||||
|
@ -366,7 +366,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
editUrl:
|
||||
'/management/kibana/objects/savedSearches/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
inAppUrl: {
|
||||
path: '/app/discover#/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
path: '/app/discover#/view/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
uiCapabilitiesPath: 'discover.show',
|
||||
},
|
||||
},
|
||||
|
@ -406,7 +406,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
editUrl:
|
||||
'/management/kibana/objects/savedSearches/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
inAppUrl: {
|
||||
path: '/app/discover#/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
path: '/app/discover#/view/960372e0-3224-11e8-a572-ffca06da1357',
|
||||
uiCapabilitiesPath: 'discover.show',
|
||||
},
|
||||
},
|
||||
|
|
|
@ -65,7 +65,7 @@ export default function ({ getService }) {
|
|||
|
||||
it('returns gzip files when no brotli version exists', () =>
|
||||
supertest
|
||||
.get(`/${buildNum}/bundles/commons.style.css`) // legacy optimizer does not create brotli outputs
|
||||
.get(`/${buildNum}/bundles/light_theme.style.css`) // legacy optimizer does not create brotli outputs
|
||||
.set('Accept-Encoding', 'gzip, br')
|
||||
.expect(200)
|
||||
.expect('Content-Encoding', 'gzip'));
|
||||
|
|
|
@ -58,6 +58,7 @@ export default function ({ getService, loadTestFile }) {
|
|||
loadTestFile(require.resolve('./embed_mode'));
|
||||
loadTestFile(require.resolve('./dashboard_back_button'));
|
||||
loadTestFile(require.resolve('./dashboard_error_handling'));
|
||||
loadTestFile(require.resolve('./legacy_urls'));
|
||||
|
||||
// Note: This one must be last because it unloads some data for one of its tests!
|
||||
// No, this isn't ideal, but loading/unloading takes so much time and these are all bunched
|
||||
|
|
111
test/functional/apps/dashboard/legacy_urls.ts
Normal file
111
test/functional/apps/dashboard/legacy_urls.ts
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const PageObjects = getPageObjects([
|
||||
'dashboard',
|
||||
'header',
|
||||
'common',
|
||||
'timePicker',
|
||||
'visualize',
|
||||
'visEditor',
|
||||
]);
|
||||
const pieChart = getService('pieChart');
|
||||
const browser = getService('browser');
|
||||
const find = getService('find');
|
||||
const log = getService('log');
|
||||
const dashboardAddPanel = getService('dashboardAddPanel');
|
||||
const listingTable = getService('listingTable');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
let kibanaLegacyBaseUrl: string;
|
||||
let kibanaVisualizeBaseUrl: string;
|
||||
let testDashboardId: string;
|
||||
|
||||
describe('legacy urls', function describeIndexTests() {
|
||||
before(async function () {
|
||||
await esArchiver.load('dashboard/current/kibana');
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await dashboardAddPanel.addVisualization('Rendering-Test:-animal-sounds-pie');
|
||||
await PageObjects.dashboard.saveDashboard('legacyTest', { waitDialogIsClosed: true });
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
const currentUrl = await browser.getCurrentUrl();
|
||||
await log.debug(`Current url is ${currentUrl}`);
|
||||
testDashboardId = /#\/view\/(.+)\?/.exec(currentUrl)![1];
|
||||
kibanaLegacyBaseUrl =
|
||||
currentUrl.substring(0, currentUrl.indexOf('/app/dashboards')) + '/app/kibana';
|
||||
kibanaVisualizeBaseUrl =
|
||||
currentUrl.substring(0, currentUrl.indexOf('/app/dashboards')) + '/app/visualize';
|
||||
await log.debug(`id is ${testDashboardId}`);
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.deleteItem('legacyTest', testDashboardId);
|
||||
});
|
||||
|
||||
describe('kibana link redirect', () => {
|
||||
it('redirects from old kibana app URL', async () => {
|
||||
const url = `${kibanaLegacyBaseUrl}#/dashboard/${testDashboardId}`;
|
||||
await browser.get(url, true);
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.timePicker.setDefaultDataRange();
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await pieChart.expectPieSliceCount(5);
|
||||
});
|
||||
|
||||
it('redirects from legacy hash in wrong app', async () => {
|
||||
const url = `${kibanaVisualizeBaseUrl}#/dashboard/${testDashboardId}`;
|
||||
await browser.get(url, true);
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.timePicker.setDefaultDataRange();
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await pieChart.expectPieSliceCount(5);
|
||||
});
|
||||
|
||||
it('resolves markdown link', async () => {
|
||||
await PageObjects.visualize.navigateToNewVisualization();
|
||||
await PageObjects.visualize.clickMarkdownWidget();
|
||||
await PageObjects.visEditor.setMarkdownTxt(`[abc](#/dashboard/${testDashboardId})`);
|
||||
await PageObjects.visEditor.clickGo();
|
||||
(await find.byLinkText('abc')).click();
|
||||
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.timePicker.setDefaultDataRange();
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await pieChart.expectPieSliceCount(5);
|
||||
});
|
||||
|
||||
it('back button works', async () => {
|
||||
// back to default time range
|
||||
await browser.goBack();
|
||||
// back to last app
|
||||
await browser.goBack();
|
||||
await PageObjects.visEditor.expectMarkdownTextArea();
|
||||
await browser.goForward();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -109,7 +109,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
const expectedUrl =
|
||||
baseUrl +
|
||||
'/app/discover#' +
|
||||
'/ab12e3c0-f231-11e6-9486-733b1ac9221a' +
|
||||
'/view/ab12e3c0-f231-11e6-9486-733b1ac9221a' +
|
||||
'?_g=(filters%3A!()%2CrefreshInterval%3A(pause%3A!t%2Cvalue%3A0)' +
|
||||
"%2Ctime%3A(from%3A'2015-09-19T06%3A31%3A44.000Z'%2C" +
|
||||
"to%3A'2015-09-23T18%3A31%3A44.000Z'))";
|
||||
|
|
|
@ -230,6 +230,10 @@ export function VisualizeEditorPageProvider({ getService, getPageObjects }: FtrP
|
|||
await testSubjects.click('dropPartialBucketsCheckbox');
|
||||
}
|
||||
|
||||
public async expectMarkdownTextArea() {
|
||||
await testSubjects.existOrFail('markdownTextarea');
|
||||
}
|
||||
|
||||
public async setMarkdownTxt(markdownTxt: string) {
|
||||
const input = await testSubjects.find('markdownTextarea');
|
||||
await input.clearValue();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"kibanaVersion": "kibana",
|
||||
"server": true,
|
||||
"ui": true,
|
||||
"requiredPlugins": ["licensing", "data", "navigation", "savedObjects"],
|
||||
"requiredPlugins": ["licensing", "data", "navigation", "savedObjects", "kibanaLegacy"],
|
||||
"optionalPlugins": ["home", "features"],
|
||||
"configPath": ["xpack", "graph"]
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import {
|
|||
configureAppAngularModule,
|
||||
createTopNavDirective,
|
||||
createTopNavHelper,
|
||||
KibanaLegacyStart,
|
||||
} from '../../../../src/plugins/kibana_legacy/public';
|
||||
|
||||
import './index.scss';
|
||||
|
@ -67,9 +68,11 @@ export interface GraphDependencies {
|
|||
graphSavePolicy: string;
|
||||
overlays: OverlayStart;
|
||||
savedObjects: SavedObjectsStart;
|
||||
kibanaLegacy: KibanaLegacyStart;
|
||||
}
|
||||
|
||||
export const renderApp = ({ appBasePath, element, ...deps }: GraphDependencies) => {
|
||||
export const renderApp = ({ appBasePath, element, kibanaLegacy, ...deps }: GraphDependencies) => {
|
||||
kibanaLegacy.loadFontAwesome();
|
||||
const graphAngularModule = createLocalAngularModule(deps.navigation);
|
||||
configureAppAngularModule(
|
||||
graphAngularModule,
|
||||
|
|
|
@ -10,7 +10,10 @@ import { AppMountParameters, Plugin } from 'src/core/public';
|
|||
import { PluginInitializerContext } from 'kibana/public';
|
||||
|
||||
import { Storage } from '../../../../src/plugins/kibana_utils/public';
|
||||
import { initAngularBootstrap } from '../../../../src/plugins/kibana_legacy/public';
|
||||
import {
|
||||
initAngularBootstrap,
|
||||
KibanaLegacyStart,
|
||||
} from '../../../../src/plugins/kibana_legacy/public';
|
||||
import { NavigationPublicPluginStart as NavigationStart } from '../../../../src/plugins/navigation/public';
|
||||
import { DataPublicPluginStart } from '../../../../src/plugins/data/public';
|
||||
|
||||
|
@ -34,6 +37,7 @@ export interface GraphPluginStartDependencies {
|
|||
navigation: NavigationStart;
|
||||
data: DataPublicPluginStart;
|
||||
savedObjects: SavedObjectsStart;
|
||||
kibanaLegacy: KibanaLegacyStart;
|
||||
}
|
||||
|
||||
export class GraphPlugin
|
||||
|
@ -85,6 +89,7 @@ export class GraphPlugin
|
|||
core: coreStart,
|
||||
navigation: pluginsStart.navigation,
|
||||
data: pluginsStart.data,
|
||||
kibanaLegacy: pluginsStart.kibanaLegacy,
|
||||
savedObjectsClient: coreStart.savedObjects.client,
|
||||
addBasePath: core.http.basePath.prepend,
|
||||
getBasePath: core.http.basePath.get,
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
"usageCollection",
|
||||
"share",
|
||||
"embeddable",
|
||||
"uiActions"
|
||||
"uiActions",
|
||||
"kibanaLegacy"
|
||||
],
|
||||
"optionalPlugins": [
|
||||
"security",
|
||||
|
|
|
@ -78,6 +78,8 @@ export const renderApp = (
|
|||
urlGenerators: deps.share.urlGenerators,
|
||||
});
|
||||
|
||||
deps.kibanaLegacy.loadFontAwesome();
|
||||
|
||||
const mlLicense = setLicenseCache(deps.licensing);
|
||||
|
||||
appMountParams.onAppLeave((actions) => actions.default());
|
||||
|
|
|
@ -30,10 +30,12 @@ import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public';
|
|||
import { registerEmbeddables } from './embeddables';
|
||||
import { UiActionsSetup } from '../../../../src/plugins/ui_actions/public';
|
||||
import { registerMlUiActions } from './ui_actions';
|
||||
import { KibanaLegacyStart } from '../../../../src/plugins/kibana_legacy/public';
|
||||
|
||||
export interface MlStartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
share: SharePluginStart;
|
||||
kibanaLegacy: KibanaLegacyStart;
|
||||
}
|
||||
export interface MlSetupDependencies {
|
||||
security?: SecurityPluginSetup;
|
||||
|
@ -70,6 +72,7 @@ export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> {
|
|||
{
|
||||
data: pluginsStart.data,
|
||||
share: pluginsStart.share,
|
||||
kibanaLegacy: pluginsStart.kibanaLegacy,
|
||||
security: pluginsSetup.security,
|
||||
licensing: pluginsSetup.licensing,
|
||||
management: pluginsSetup.management,
|
||||
|
|
|
@ -25,12 +25,22 @@ export class AngularApp {
|
|||
isCloud,
|
||||
pluginInitializerContext,
|
||||
externalConfig,
|
||||
kibanaLegacy,
|
||||
} = deps;
|
||||
const app: IModule = localAppModule(deps);
|
||||
app.run(($injector: angular.auto.IInjectorService) => {
|
||||
this.injector = $injector;
|
||||
Legacy.init(
|
||||
{ core, element, data, navigation, isCloud, pluginInitializerContext, externalConfig },
|
||||
{
|
||||
core,
|
||||
element,
|
||||
data,
|
||||
navigation,
|
||||
isCloud,
|
||||
pluginInitializerContext,
|
||||
externalConfig,
|
||||
kibanaLegacy,
|
||||
},
|
||||
this.injector
|
||||
);
|
||||
});
|
||||
|
|
|
@ -70,6 +70,7 @@ export class MonitoringPlugin
|
|||
const { AngularApp } = await import('./angular');
|
||||
const deps: MonitoringPluginDependencies = {
|
||||
navigation: pluginsStart.navigation,
|
||||
kibanaLegacy: pluginsStart.kibanaLegacy,
|
||||
element: params.element,
|
||||
core: coreStart,
|
||||
data: pluginsStart.data,
|
||||
|
@ -78,6 +79,7 @@ export class MonitoringPlugin
|
|||
externalConfig: this.getExternalConfig(),
|
||||
};
|
||||
|
||||
pluginsStart.kibanaLegacy.loadFontAwesome();
|
||||
this.setInitialTimefilter(deps);
|
||||
this.overrideAlertingEmailDefaults(deps);
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import { PluginInitializerContext, CoreStart } from 'kibana/public';
|
||||
import { NavigationPublicPluginStart as NavigationStart } from '../../../../src/plugins/navigation/public';
|
||||
import { DataPublicPluginStart } from '../../../../src/plugins/data/public';
|
||||
import { KibanaLegacyStart } from '../../../../src/plugins/kibana_legacy/public';
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
export { MonitoringConfig } from '../server';
|
||||
|
@ -14,6 +15,7 @@ export { MonitoringConfig } from '../server';
|
|||
export interface MonitoringPluginDependencies {
|
||||
navigation: NavigationStart;
|
||||
data: DataPublicPluginStart;
|
||||
kibanaLegacy: KibanaLegacyStart;
|
||||
element: HTMLElement;
|
||||
core: CoreStart;
|
||||
isCloud: boolean;
|
||||
|
|
|
@ -22,10 +22,6 @@ import { mapValues } from 'lodash';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { ToastsStart } from 'src/core/public';
|
||||
import {
|
||||
ProcessedImportResponse,
|
||||
processImportResponse,
|
||||
} from '../../../../../../src/legacy/core_plugins/kibana/public';
|
||||
import { SavedObjectsManagementRecord } from '../../../../../../src/plugins/saved_objects_management/public';
|
||||
import { Space } from '../../../common/model/space';
|
||||
import { SpacesManager } from '../../spaces_manager';
|
||||
|
@ -33,6 +29,10 @@ import { ProcessingCopyToSpace } from './processing_copy_to_space';
|
|||
import { CopyToSpaceFlyoutFooter } from './copy_to_space_flyout_footer';
|
||||
import { CopyToSpaceForm } from './copy_to_space_form';
|
||||
import { CopyOptions, ImportRetry } from '../types';
|
||||
import {
|
||||
ProcessedImportResponse,
|
||||
processImportResponse,
|
||||
} from '../../../../../../src/plugins/saved_objects_management/public';
|
||||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
|
|
|
@ -8,8 +8,8 @@ import React, { Fragment } from 'react';
|
|||
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiStat, EuiHorizontalRule } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ProcessedImportResponse } from '../../../../../../src/legacy/core_plugins/kibana/public';
|
||||
import { ImportRetry } from '../types';
|
||||
import { ProcessedImportResponse } from '../../../../../../src/plugins/saved_objects_management/public';
|
||||
|
||||
interface Props {
|
||||
copyInProgress: boolean;
|
||||
|
|
|
@ -13,8 +13,10 @@ import {
|
|||
EuiHorizontalRule,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { ProcessedImportResponse } from '../../../../../../src/legacy/core_plugins/kibana/public';
|
||||
import { SavedObjectsManagementRecord } from '../../../../../../src/plugins/saved_objects_management/public';
|
||||
import {
|
||||
ProcessedImportResponse,
|
||||
SavedObjectsManagementRecord,
|
||||
} from 'src/plugins/saved_objects_management/public';
|
||||
import { Space } from '../../../common/model/space';
|
||||
import { CopyOptions, ImportRetry } from '../types';
|
||||
import { SpaceResult } from './space_result';
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { summarizeCopyResult } from './summarize_copy_result';
|
||||
import { ProcessedImportResponse } from 'src/legacy/core_plugins/kibana/public';
|
||||
import { ProcessedImportResponse } from 'src/plugins/saved_objects_management/public';
|
||||
|
||||
const createSavedObjectsManagementRecord = () => ({
|
||||
type: 'dashboard',
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { ProcessedImportResponse } from 'src/legacy/core_plugins/kibana/public';
|
||||
import { SavedObjectsManagementRecord } from 'src/plugins/saved_objects_management/public';
|
||||
import {
|
||||
SavedObjectsManagementRecord,
|
||||
ProcessedImportResponse,
|
||||
} from 'src/plugins/saved_objects_management/public';
|
||||
|
||||
export interface SummarizedSavedObjectResult {
|
||||
type: string;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue