diff --git a/src/legacy/core_plugins/kibana/index.js b/src/legacy/core_plugins/kibana/index.js
index 33e820a5300c6..659ca36d84090 100644
--- a/src/legacy/core_plugins/kibana/index.js
+++ b/src/legacy/core_plugins/kibana/index.js
@@ -62,6 +62,7 @@ export default function (kibana) {
hacks: [
'plugins/kibana/discover',
'plugins/kibana/dev_tools',
+ 'plugins/kibana/visualize',
],
savedObjectTypes: [
'plugins/kibana/visualize/saved_visualizations/saved_visualization_register',
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html
index 4f41ab5d4fad6..c7fd8600b73bb 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html
+++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html
@@ -35,7 +35,7 @@
-->
{
+ if (!angularModuleInstance) {
+ angularModuleInstance = createLocalAngularModule(deps.core, deps.navigation);
+ // global routing stuff
+ configureAppAngularModule(angularModuleInstance, deps.core as LegacyCoreStart, true);
+ // custom routing stuff
+ initVisualizeApp(angularModuleInstance, deps);
+ }
+ const $injector = mountVisualizeApp(appBasePath, element);
+ return () => $injector.get('$rootScope').$destroy();
+};
+
+const mainTemplate = (basePath: string) => `
+`;
+
+const moduleName = 'app/visualize';
+
+const thirdPartyAngularDependencies = ['ngSanitize', 'ngRoute', 'react'];
+
+function mountVisualizeApp(appBasePath: string, element: HTMLElement) {
+ const mountpoint = document.createElement('div');
+ mountpoint.setAttribute('style', 'height: 100%');
+ mountpoint.innerHTML = mainTemplate(appBasePath);
+ // bootstrap angular into detached element and attach it later to
+ // make angular-within-angular possible
+ const $injector = angular.bootstrap(mountpoint, [moduleName]);
+ // initialize global state handler
+ element.appendChild(mountpoint);
+ return $injector;
+}
+
+function createLocalAngularModule(core: AppMountContext['core'], navigation: NavigationStart) {
+ createLocalI18nModule();
+ createLocalPrivateModule();
+ createLocalPromiseModule();
+ createLocalConfigModule(core);
+ createLocalKbnUrlModule();
+ createLocalStateModule();
+ createLocalPersistedStateModule();
+ createLocalTopNavModule(navigation);
+ createLocalConfirmModalModule();
+
+ const visualizeAngularModule: IModule = angular.module(moduleName, [
+ ...thirdPartyAngularDependencies,
+ 'app/visualize/Config',
+ 'app/visualize/I18n',
+ 'app/visualize/Private',
+ 'app/visualize/PersistedState',
+ 'app/visualize/TopNav',
+ 'app/visualize/State',
+ 'app/visualize/ConfirmModal',
+ ]);
+ return visualizeAngularModule;
+}
+
+function createLocalConfirmModalModule() {
+ angular
+ .module('app/visualize/ConfirmModal', ['react'])
+ .factory('confirmModal', confirmModalFactory)
+ .directive('confirmModal', reactDirective => reactDirective(EuiConfirmModal));
+}
+
+function createLocalStateModule() {
+ angular
+ .module('app/visualize/State', [
+ 'app/visualize/Private',
+ 'app/visualize/Config',
+ 'app/visualize/KbnUrl',
+ 'app/visualize/Promise',
+ 'app/visualize/PersistedState',
+ ])
+ .factory('AppState', function(Private: IPrivate) {
+ return Private(AppStateProvider);
+ })
+ .service('getAppState', function(Private: IPrivate) {
+ return Private(AppStateProvider).getAppState;
+ })
+ .service('globalState', function(Private: IPrivate) {
+ return Private(GlobalStateProvider);
+ });
+}
+
+function createLocalPersistedStateModule() {
+ angular
+ .module('app/visualize/PersistedState', ['app/visualize/Private', 'app/visualize/Promise'])
+ .factory('PersistedState', (Private: IPrivate) => {
+ const Events = Private(EventsProvider);
+ return class AngularPersistedState extends PersistedState {
+ constructor(value: any, path: any) {
+ super(value, path, Events);
+ }
+ };
+ });
+}
+
+function createLocalKbnUrlModule() {
+ angular
+ .module('app/visualize/KbnUrl', ['app/visualize/Private', 'ngRoute'])
+ .service('kbnUrl', (Private: IPrivate) => Private(KbnUrlProvider))
+ .service('redirectWhenMissing', (Private: IPrivate) => Private(RedirectWhenMissingProvider));
+}
+
+function createLocalConfigModule(core: AppMountContext['core']) {
+ angular
+ .module('app/visualize/Config', ['app/visualize/Private'])
+ .provider('stateManagementConfig', StateManagementConfigProvider)
+ .provider('config', () => {
+ return {
+ $get: () => ({
+ get: core.uiSettings.get.bind(core.uiSettings),
+ }),
+ };
+ });
+}
+
+function createLocalPromiseModule() {
+ angular.module('app/visualize/Promise', []).service('Promise', PromiseServiceCreator);
+}
+
+function createLocalPrivateModule() {
+ angular.module('app/visualize/Private', []).provider('Private', PrivateProvider);
+}
+
+function createLocalTopNavModule(navigation: NavigationStart) {
+ angular
+ .module('app/visualize/TopNav', ['react'])
+ .directive('kbnTopNav', createTopNavDirective)
+ .directive('kbnTopNavHelper', createTopNavHelper(navigation.ui));
+}
+
+function createLocalI18nModule() {
+ angular
+ .module('app/visualize/I18n', [])
+ .provider('i18n', I18nProvider)
+ .filter('i18n', i18nFilter)
+ .directive('i18nId', i18nDirective);
+}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.html b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.html
index bf9ac9b9bbe36..6190b92c9be3e 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.html
+++ b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.html
@@ -39,7 +39,7 @@
show-search-bar="true"
show-query-bar="true"
show-query-input="showQueryInput()"
- show-filter-bar="showFilterBar() && chrome.getVisible()"
+ show-filter-bar="showFilterBar() && isVisible"
show-date-picker="showQueryBarTimePicker()"
show-auto-refresh-only="!showQueryBarTimePicker()"
query="state.query"
@@ -67,7 +67,7 @@
-->
savedVisualizations.get($route.current.params))
- .then(savedVis => {
- if (savedVis.vis.type.setup) {
- return savedVis.vis.type.setup(savedVis)
- .catch(() => savedVis);
- }
- return savedVis;
- })
- .catch(redirectWhenMissing({
- '*': '/visualize'
- }));
- }
- }
- })
- .when(`${VisualizeConstants.EDIT_PATH}/:id`, {
- template: editorTemplate,
- k7Breadcrumbs: getEditBreadcrumbs,
- resolve: {
- savedVis: function (savedVisualizations, redirectWhenMissing, $route, $rootScope, kbnUrl) {
- return ensureDefaultIndexPattern(core, npData, $rootScope, kbnUrl)
- .then(() => savedVisualizations.get($route.current.params.id))
- .then((savedVis) => {
- chrome.recentlyAccessed.add(
- savedVis.getFullPath(),
- savedVis.title,
- savedVis.id
- );
- return savedVis;
- })
- .then(savedVis => {
- if (savedVis.vis.type.setup) {
- return savedVis.vis.type.setup(savedVis).catch(() => savedVis);
- }
- return savedVis;
- })
- .catch(
- redirectWhenMissing({
- visualization: '/visualize',
- search: '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
- 'index-pattern':
- '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
- 'index-pattern-field':
- '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
- })
- );
- }
- }
- });
+import { getServices } from '../kibana_services';
-uiModules
- .get('app/visualize', [
- 'kibana/url'
- ])
- .directive('visualizeApp', function () {
+export function initEditorDirective(app, deps) {
+ app.directive('visualizeApp', function () {
return {
restrict: 'E',
controllerAs: 'visualizeApp',
- controller: VisEditor,
+ controller: VisualizeAppController,
};
});
-function VisEditor(
+ initVisEditorDirective(app, deps);
+ initVisualizationDirective(app, deps);
+}
+
+function VisualizeAppController(
$scope,
$element,
$route,
@@ -154,19 +70,42 @@ function VisEditor(
$window,
$injector,
$timeout,
- indexPatterns,
kbnUrl,
redirectWhenMissing,
- Private,
Promise,
- config,
kbnBaseUrl,
- localStorage,
+ getAppState,
+ globalState,
) {
- const queryFilter = Private(FilterBarQueryFilterProvider);
-
+ const {
+ indexPatterns,
+ localStorage,
+ visualizeCapabilities,
+ share,
+ data: {
+ query: {
+ filterManager,
+ timefilter: { timefilter },
+ },
+ },
+ toastNotifications,
+ legacyChrome,
+ chrome,
+ getBasePath,
+ core: { docLinks },
+ savedQueryService,
+ uiSettings,
+ } = getServices();
+
+ const filterStateManager = new FilterStateManager(globalState, getAppState, filterManager);
+ const queryFilter = filterManager;
// Retrieve the resolved SavedVis instance.
const savedVis = $route.current.locals.savedVis;
+ const _applyVis = () => {
+ $scope.$apply();
+ };
+ // This will trigger a digest cycle. This is needed when vis is updated from a global angular like in visualize_embeddable.js.
+ savedVis.vis.on('apply', _applyVis);
// vis is instance of src/legacy/ui/public/vis/vis.js.
// SearchSource is a promise-based stream of search results that can inherit from other search sources.
const { vis, searchSource } = savedVis;
@@ -177,7 +116,7 @@ function VisEditor(
dirty: !savedVis.id
};
- $scope.topNavMenu = [...(capabilities.visualize.save ? [{
+ $scope.topNavMenu = [...(visualizeCapabilities.save ? [{
id: 'save',
label: i18n.translate('kbn.topNavMenu.saveVisualizationButtonLabel', { defaultMessage: 'save' }),
description: i18n.translate('kbn.visualize.topNavMenu.saveVisualizationButtonAriaLabel', {
@@ -246,7 +185,7 @@ function VisEditor(
share.toggleShareContextMenu({
anchorElement,
allowEmbed: true,
- allowShortUrl: capabilities.visualize.createShortUrl,
+ allowShortUrl: visualizeCapabilities.createShortUrl,
shareableUrl: unhashUrl(window.location.href),
objectId: savedVis.id,
objectType: 'visualization',
@@ -295,7 +234,7 @@ function VisEditor(
let stateMonitor;
if (savedVis.id) {
- docTitle.change(savedVis.title);
+ chrome.docTitle.change(savedVis.title);
}
// Extract visualization state with filtered aggs. You can see these filtered aggs in the URL.
@@ -306,7 +245,7 @@ function VisEditor(
linked: !!savedVis.savedSearchId,
query: searchSource.getOwnField('query') || {
query: '',
- language: localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage')
+ language: localStorage.get('kibana.userQueryLanguage') || uiSettings.get('search:queryLanguage')
},
filters: searchSource.getOwnField('filter') || [],
vis: savedVisState
@@ -345,9 +284,9 @@ function VisEditor(
queryFilter.setFilters(filters);
};
- $scope.showSaveQuery = capabilities.visualize.saveQuery;
+ $scope.showSaveQuery = visualizeCapabilities.saveQuery;
- $scope.$watch(() => capabilities.visualize.saveQuery, (newCapability) => {
+ $scope.$watch(() => visualizeCapabilities.saveQuery, (newCapability) => {
$scope.showSaveQuery = newCapability;
});
@@ -455,13 +394,15 @@ function VisEditor(
}
}));
- $scope.$on('$destroy', function () {
+ $scope.$on('$destroy', () => {
if ($scope._handler) {
$scope._handler.destroy();
}
savedVis.destroy();
stateMonitor.destroy();
+ filterStateManager.destroy();
subscriptions.unsubscribe();
+ $scope.vis.off('apply', _applyVis);
});
@@ -503,7 +444,7 @@ function VisEditor(
delete $state.savedQuery;
$state.query = {
query: '',
- language: localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage')
+ language: localStorage.get('kibana.userQueryLanguage') || uiSettings.get('search:queryLanguage')
};
queryFilter.removeAll();
$state.save();
@@ -589,14 +530,14 @@ function VisEditor(
// Since we aren't reloading the page, only inserting a new browser history item, we need to manually update
// the last url for this app, so directly clicking on the Visualize tab will also bring the user to the saved
// url, not the unsaved one.
- chromeLegacy.trackSubUrlForApp('kibana:visualize', savedVisualizationParsedUrl);
+ legacyChrome.trackSubUrlForApp('kibana:visualize', savedVisualizationParsedUrl);
const lastDashboardAbsoluteUrl = chrome.navLinks.get('kibana:dashboard').url;
const dashboardParsedUrl = absoluteToParsedUrl(lastDashboardAbsoluteUrl, getBasePath());
dashboardParsedUrl.addQueryParameter(DashboardConstants.NEW_VISUALIZATION_ID_PARAM, savedVis.id);
kbnUrl.change(dashboardParsedUrl.appPath);
} else if (savedVis.id === $route.current.params.id) {
- docTitle.change(savedVis.lastSavedTitle);
+ chrome.docTitle.change(savedVis.lastSavedTitle);
chrome.setBreadcrumbs($injector.invoke(getEditBreadcrumbs));
savedVis.vis.title = savedVis.title;
savedVis.vis.description = savedVis.description;
@@ -661,7 +602,7 @@ function VisEditor(
vis.type.feedbackMessage;
};
- addHelpMenuToAppChrome(chrome);
+ addHelpMenuToAppChrome(chrome, docLinks);
init();
}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/editor/visualization.js b/src/legacy/core_plugins/kibana/public/visualize/editor/visualization.js
index 198fbe19a0b7a..d3651735c1a1d 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/editor/visualization.js
+++ b/src/legacy/core_plugins/kibana/public/visualize/editor/visualization.js
@@ -17,13 +17,8 @@
* under the License.
*/
-import { getServices } from '../kibana_services';
-
-const { embeddables, uiModules } = getServices();
-
-uiModules
- .get('kibana/directive', ['ngSanitize'])
- .directive('visualizationEmbedded', function (Private, $timeout, getAppState) {
+export function initVisualizationDirective(app, deps) {
+ app.directive('visualizationEmbedded', function ($timeout, getAppState) {
return {
restrict: 'E',
@@ -37,7 +32,7 @@ uiModules
link: function ($scope, element) {
$scope.renderFunction = async () => {
if (!$scope._handler) {
- $scope._handler = await embeddables.getEmbeddableFactory('visualization').createFromObject($scope.savedObj, {
+ $scope._handler = await deps.embeddables.getEmbeddableFactory('visualization').createFromObject($scope.savedObj, {
timeRange: $scope.timeRange,
filters: $scope.filters || [],
query: $scope.query,
@@ -66,3 +61,4 @@ uiModules
}
};
});
+}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/editor/visualization_editor.js b/src/legacy/core_plugins/kibana/public/visualize/editor/visualization_editor.js
index ead77e6bc41d5..bc6d4d4c48466 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/editor/visualization_editor.js
+++ b/src/legacy/core_plugins/kibana/public/visualize/editor/visualization_editor.js
@@ -17,15 +17,8 @@
* under the License.
*/
-import { getServices, VisEditorTypesRegistryProvider } from '../kibana_services';
-
-const { uiModules } = getServices();
-
-uiModules
- .get('kibana/directive', ['ngSanitize'])
- .directive('visualizationEditor', function (Private, $timeout, getAppState) {
- const editorTypes = Private(VisEditorTypesRegistryProvider);
-
+export function initVisEditorDirective(app, deps) {
+ app.directive('visualizationEditor', function ($timeout, getAppState) {
return {
restrict: 'E',
scope: {
@@ -38,7 +31,8 @@ uiModules
link: function ($scope, element) {
const editorType = $scope.savedObj.vis.type.editor;
const Editor = typeof editorType === 'function' ? editorType :
- editorTypes.find(editor => editor.key === editorType);
+ deps.editorTypes.find(editor => editor.key === editorType);
+
const editor = new Editor(element[0], $scope.savedObj);
$scope.renderFunction = () => {
@@ -62,3 +56,4 @@ uiModules
}
};
});
+}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/embeddable/disabled_lab_embeddable.tsx b/src/legacy/core_plugins/kibana/public/visualize/embeddable/disabled_lab_embeddable.tsx
index 065feae045597..d8792a761b186 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/embeddable/disabled_lab_embeddable.tsx
+++ b/src/legacy/core_plugins/kibana/public/visualize/embeddable/disabled_lab_embeddable.tsx
@@ -19,8 +19,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
+import { Embeddable, EmbeddableOutput } from '../../../../../../plugins/embeddable/public';
-import { Embeddable, EmbeddableOutput } from '../kibana_services';
import { DisabledLabVisualization } from './disabled_lab_visualization';
import { VisualizeInput } from './visualize_embeddable';
import { VISUALIZE_EMBEDDABLE_TYPE } from './constants';
diff --git a/src/legacy/core_plugins/kibana/public/visualize/embeddable/get_index_pattern.ts b/src/legacy/core_plugins/kibana/public/visualize/embeddable/get_index_pattern.ts
index 9bc9ab99c4aff..7fe3678bb1f77 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/embeddable/get_index_pattern.ts
+++ b/src/legacy/core_plugins/kibana/public/visualize/embeddable/get_index_pattern.ts
@@ -17,11 +17,10 @@
* under the License.
*/
-import { getServices, getFromSavedObject, VisSavedObject } from '../kibana_services';
+import { npStart } from 'ui/new_platform';
-import { IIndexPattern } from '../../../../../../plugins/data/public';
-
-const { savedObjectsClient, uiSettings } = getServices();
+import { VisSavedObject } from './visualize_embeddable';
+import { indexPatterns, IIndexPattern } from '../../../../../../plugins/data/public';
export async function getIndexPattern(
savedVis: VisSavedObject
@@ -30,7 +29,8 @@ export async function getIndexPattern(
return savedVis.vis.indexPattern;
}
- const defaultIndex = uiSettings.get('defaultIndex');
+ const savedObjectsClient = npStart.core.savedObjects.client;
+ const defaultIndex = npStart.core.uiSettings.get('defaultIndex');
if (savedVis.vis.params.index_pattern) {
const indexPatternObjects = await savedObjectsClient.find({
@@ -39,10 +39,10 @@ export async function getIndexPattern(
search: `"${savedVis.vis.params.index_pattern}"`,
searchFields: ['title'],
});
- const [indexPattern] = indexPatternObjects.savedObjects.map(getFromSavedObject);
+ const [indexPattern] = indexPatternObjects.savedObjects.map(indexPatterns.getFromSavedObject);
return indexPattern;
}
const savedObject = await savedObjectsClient.get('index-pattern', defaultIndex);
- return getFromSavedObject(savedObject);
+ return indexPatterns.getFromSavedObject(savedObject);
}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts
index e5a723a99eafd..7ab60f8867c38 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts
+++ b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts
@@ -375,6 +375,8 @@ export class VisualizeEmbeddable extends Embeddable {
diff --git a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.tsx b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.tsx
index 15ad9a33232ef..7c9efa280c9f1 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.tsx
+++ b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.tsx
@@ -17,36 +17,48 @@
* under the License.
*/
+import 'uiExports/contextMenuActions';
+import 'uiExports/devTools';
+import 'uiExports/docViews';
+import 'uiExports/embeddableActions';
+import 'uiExports/fieldFormatEditors';
+import 'uiExports/fieldFormats';
+import 'uiExports/home';
+import 'uiExports/indexManagement';
+import 'uiExports/inspectorViews';
+import 'uiExports/savedObjectTypes';
+import 'uiExports/search';
+import 'uiExports/shareContextMenuExtensions';
+import 'uiExports/visTypes';
+import 'uiExports/visualize';
+
import { i18n } from '@kbn/i18n';
+import chrome from 'ui/chrome';
+import { npStart } from 'ui/new_platform';
+
import { Legacy } from 'kibana';
import { SavedObjectAttributes } from 'kibana/server';
+import {
+ EmbeddableFactory,
+ ErrorEmbeddable,
+ Container,
+ EmbeddableOutput,
+} from '../../../../../../plugins/embeddable/public';
+import { start as visualizations } from '../../../../visualizations/public/np_ready/public/legacy';
import { showNewVisModal } from '../wizard';
import { SavedVisualizations } from '../types';
import { DisabledLabEmbeddable } from './disabled_lab_embeddable';
import { getIndexPattern } from './get_index_pattern';
-import { VisualizeEmbeddable, VisualizeInput, VisualizeOutput } from './visualize_embeddable';
-import { VISUALIZE_EMBEDDABLE_TYPE } from './constants';
-import { TypesStart } from '../../../../visualizations/public/np_ready/public/types';
-
import {
- getServices,
- Container,
- EmbeddableFactory,
- EmbeddableOutput,
- ErrorEmbeddable,
+ VisualizeEmbeddable,
+ VisualizeInput,
+ VisualizeOutput,
VisSavedObject,
-} from '../kibana_services';
-
-const {
- addBasePath,
- capabilities,
- embeddable,
- getInjector,
- uiSettings,
- visualizations,
-} = getServices();
+} from './visualize_embeddable';
+import { VISUALIZE_EMBEDDABLE_TYPE } from './constants';
+import { TypesStart } from '../../../../visualizations/public/np_ready/public/types';
interface VisualizationAttributes extends SavedObjectAttributes {
visState: string;
@@ -96,7 +108,7 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory<
if (!visType) {
return false;
}
- if (uiSettings.get('visualize:enableLabs')) {
+ if (npStart.core.uiSettings.get('visualize:enableLabs')) {
return true;
}
return visType.stage !== 'experimental';
@@ -108,7 +120,7 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory<
}
public isEditable() {
- return capabilities.visualize.save as boolean;
+ return npStart.core.application.capabilities.visualize.save as boolean;
}
public getDisplayName() {
@@ -122,14 +134,16 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory<
input: Partial & { id: string },
parent?: Container
): Promise {
- const $injector = await getInjector();
+ const $injector = await chrome.dangerouslyGetActiveInjector();
const config = $injector.get('config');
const savedVisualizations = $injector.get('savedVisualizations');
try {
const visId = savedObject.id as string;
- const editUrl = visId ? addBasePath(`/app/kibana${savedVisualizations.urlFor(visId)}`) : '';
+ const editUrl = visId
+ ? npStart.core.http.basePath.prepend(`/app/kibana${savedVisualizations.urlFor(visId)}`)
+ : '';
const isLabsEnabled = config.get('visualize:enableLabs');
if (!isLabsEnabled && savedObject.vis.type.stage === 'experimental') {
@@ -161,7 +175,7 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory<
input: Partial & { id: string },
parent?: Container
): Promise {
- const $injector = await getInjector();
+ const $injector = await chrome.dangerouslyGetActiveInjector();
const savedVisualizations = $injector.get('savedVisualizations');
try {
@@ -179,14 +193,15 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory<
// TODO: This is a bit of a hack to preserve the original functionality. Ideally we will clean this up
// to allow for in place creation of visualizations without having to navigate away to a new URL.
if (this.visTypes) {
- showNewVisModal(this.visTypes, {
- editorParams: ['addToDashboard'],
- });
+ showNewVisModal(
+ this.visTypes,
+ {
+ editorParams: ['addToDashboard'],
+ },
+ npStart.core.http.basePath.prepend,
+ npStart.core.uiSettings
+ );
}
return undefined;
}
}
-
-VisualizeEmbeddableFactory.createVisualizeEmbeddableFactory().then(embeddableFactory => {
- embeddable.registerEmbeddableFactory(VISUALIZE_EMBEDDABLE_TYPE, embeddableFactory);
-});
diff --git a/src/legacy/core_plugins/kibana/public/visualize/global_state_sync.ts b/src/legacy/core_plugins/kibana/public/visualize/global_state_sync.ts
new file mode 100644
index 0000000000000..71156bc38d498
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/visualize/global_state_sync.ts
@@ -0,0 +1,67 @@
+/*
+ * 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 { State } from './legacy_imports';
+import { DataPublicPluginStart as DataStart } from '../../../../../plugins/data/public';
+
+/**
+ * Helper function to sync the global state with the various state providers
+ * when a local angular application mounts. There are three different ways
+ * global state can be passed into the application:
+ * * parameter in the URL hash - e.g. shared link
+ * * in-memory state in the data plugin exports (timefilter and filterManager) - e.g. default values
+ *
+ * This function looks up the three sources (earlier in the list means it takes precedence),
+ * puts it into the globalState object and syncs it with the url.
+ *
+ * Currently the legacy chrome takes care of restoring the global state when navigating from
+ * one app to another - to migrate away from that it will become necessary to also write the current
+ * state to local storage
+ */
+export function syncOnMount(
+ globalState: State,
+ {
+ query: {
+ filterManager,
+ timefilter: { timefilter },
+ },
+ }: DataStart
+) {
+ // pull in global state information from the URL
+ globalState.fetch();
+ // remember whether there were info in the URL
+ const hasGlobalURLState = Boolean(Object.keys(globalState.toObject()).length);
+
+ // sync kibana platform state with the angular global state
+ if (!globalState.time) {
+ globalState.time = timefilter.getTime();
+ }
+ if (!globalState.refreshInterval) {
+ globalState.refreshInterval = timefilter.getRefreshInterval();
+ }
+ if (!globalState.filters && filterManager.getGlobalFilters().length > 0) {
+ globalState.filters = filterManager.getGlobalFilters();
+ }
+ // only inject cross app global state if there is none in the url itself (that takes precedence)
+ if (hasGlobalURLState) {
+ // set flag the global state is set from the URL
+ globalState.$inheritedGlobalState = true;
+ }
+ globalState.save();
+}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/help_menu/help_menu_util.js b/src/legacy/core_plugins/kibana/public/visualize/help_menu/help_menu_util.js
index d27003f39d4c0..9c00947d7663c 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/help_menu/help_menu_util.js
+++ b/src/legacy/core_plugins/kibana/public/visualize/help_menu/help_menu_util.js
@@ -18,10 +18,8 @@
*/
import { i18n } from '@kbn/i18n';
-import { getServices } from '../kibana_services';
-const { docLinks } = getServices();
-export function addHelpMenuToAppChrome(chrome) {
+export function addHelpMenuToAppChrome(chrome, docLinks) {
chrome.setHelpExtension({
appName: i18n.translate('kbn.visualize.helpMenu.appName', {
defaultMessage: 'Visualize',
diff --git a/src/legacy/core_plugins/kibana/public/visualize/index.js b/src/legacy/core_plugins/kibana/public/visualize/index.js
deleted file mode 100644
index d42c72f67f815..0000000000000
--- a/src/legacy/core_plugins/kibana/public/visualize/index.js
+++ /dev/null
@@ -1,89 +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 { ensureDefaultIndexPattern } from 'ui/legacy_compat';
-import './editor/editor';
-import { i18n } from '@kbn/i18n';
-import './saved_visualizations/_saved_vis';
-import './saved_visualizations/saved_visualizations';
-import visualizeListingTemplate from './listing/visualize_listing.html';
-import { VisualizeListingController } from './listing/visualize_listing';
-import { VisualizeConstants } from './visualize_constants';
-import { getLandingBreadcrumbs, getWizardStep1Breadcrumbs } from './breadcrumbs';
-
-import { getServices, FeatureCatalogueCategory } from './kibana_services';
-
-const { FeatureCatalogueRegistryProvider, uiRoutes } = getServices();
-
-uiRoutes
- .defaults(/visualize/, {
- requireUICapability: 'visualize.show',
- badge: uiCapabilities => {
- if (uiCapabilities.visualize.save) {
- return undefined;
- }
-
- return {
- text: i18n.translate('kbn.visualize.badge.readOnly.text', {
- defaultMessage: 'Read only',
- }),
- tooltip: i18n.translate('kbn.visualize.badge.readOnly.tooltip', {
- defaultMessage: 'Unable to save visualizations',
- }),
- iconType: 'glasses'
- };
- }
- })
- .when(VisualizeConstants.LANDING_PAGE_PATH, {
- template: visualizeListingTemplate,
- k7Breadcrumbs: getLandingBreadcrumbs,
- controller: VisualizeListingController,
- controllerAs: 'listingController',
- resolve: {
- createNewVis: () => false,
- hasDefaultIndex: ($rootScope, kbnUrl) => ensureDefaultIndexPattern(getServices().core, getServices().npData, $rootScope, kbnUrl)
- },
- })
- .when(VisualizeConstants.WIZARD_STEP_1_PAGE_PATH, {
- template: visualizeListingTemplate,
- k7Breadcrumbs: getWizardStep1Breadcrumbs,
- controller: VisualizeListingController,
- controllerAs: 'listingController',
- resolve: {
- createNewVis: () => true,
- hasDefaultIndex: ($rootScope, kbnUrl) => ensureDefaultIndexPattern(getServices().core, getServices().npData, $rootScope, kbnUrl)
- },
- });
-
-FeatureCatalogueRegistryProvider.register(() => {
- return {
- id: 'visualize',
- title: 'Visualize',
- description: i18n.translate(
- 'kbn.visualize.visualizeDescription',
- {
- defaultMessage: 'Create visualizations and aggregate data stores in your Elasticsearch indices.',
- }
- ),
- icon: 'visualizeApp',
- path: `/app/kibana#${VisualizeConstants.LANDING_PAGE_PATH}`,
- showOnHomePage: true,
- category: FeatureCatalogueCategory.DATA
- };
-});
diff --git a/src/legacy/core_plugins/kibana/public/visualize/index.ts b/src/legacy/core_plugins/kibana/public/visualize/index.ts
new file mode 100644
index 0000000000000..5e9f2fdeb8999
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/visualize/index.ts
@@ -0,0 +1,70 @@
+/*
+ * 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/collapsible_sidebar'; // used in default editor
+import 'ui/vis/editors/default/sidebar';
+
+import {
+ IPrivate,
+ legacyChrome,
+ npSetup,
+ npStart,
+ SavedObjectRegistryProvider,
+ VisEditorTypesRegistryProvider,
+} from './legacy_imports';
+import { VisualizePlugin, LegacyAngularInjectedDependencies } from './plugin';
+import { start as embeddables } from '../../../embeddable_api/public/np_ready/public/legacy';
+import { start as navigation } from '../../../navigation/public/legacy';
+import { start as visualizations } from '../../../visualizations/public/np_ready/public/legacy';
+
+/**
+ * Get dependencies relying on the global angular context.
+ * They also have to get resolved together with the legacy imports above
+ */
+async function getAngularDependencies(): Promise {
+ const injector = await legacyChrome.dangerouslyGetActiveInjector();
+
+ const Private = injector.get('Private');
+
+ const editorTypes = Private(VisEditorTypesRegistryProvider);
+ const savedObjectRegistry = Private(SavedObjectRegistryProvider);
+
+ return {
+ legacyChrome,
+ editorTypes,
+ savedObjectRegistry,
+ savedVisualizations: injector.get('savedVisualizations'),
+ };
+}
+
+(() => {
+ const instance = new VisualizePlugin();
+ instance.setup(npSetup.core, {
+ ...npSetup.plugins,
+ __LEGACY: {
+ getAngularDependencies,
+ },
+ });
+ instance.start(npStart.core, {
+ ...npStart.plugins,
+ embeddables,
+ navigation,
+ visualizations,
+ });
+})();
diff --git a/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts b/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts
index 40d36dab227fa..36a9ecf3fcf8c 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts
+++ b/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts
@@ -17,108 +17,59 @@
* under the License.
*/
-import 'angular-sanitize'; // used in visualization_editor.js and visualization.js
-import 'ui/collapsible_sidebar'; // used in default editor
-import 'ui/vis/editors/default/sidebar';
-// load directives
-import '../../../data/public';
+import {
+ ChromeStart,
+ LegacyCoreStart,
+ SavedObjectsClientContract,
+ ToastsStart,
+ IUiSettingsClient,
+} from 'kibana/public';
-import { npStart } from 'ui/new_platform';
-import angular from 'angular'; // just used in editor.js
-import chromeLegacy from 'ui/chrome';
+import { NavigationStart } from '../../../navigation/public';
+import { Storage } from '../../../../../plugins/kibana_utils/public';
+import { IEmbeddableStart } from '../../../../../plugins/embeddable/public';
+import { SharePluginStart } from '../../../../../plugins/share/public';
+import { DataPublicPluginStart, IndexPatternsContract } from '../../../../../plugins/data/public';
+import { VisualizationsStart } from '../../../visualizations/public';
+import { SavedVisualizations } from './types';
-import uiRoutes from 'ui/routes';
-
-// @ts-ignore
-import { docTitle } from 'ui/doc_title';
-import { FilterBarQueryFilterProvider } from 'ui/filter_manager/query_filter';
-import { wrapInI18nContext } from 'ui/i18n';
-// @ts-ignore
-import { uiModules } from 'ui/modules';
-import { FeatureCatalogueRegistryProvider } from 'ui/registry/feature_catalogue';
-
-// Saved objects
-import { SavedObjectsClientProvider } from 'ui/saved_objects';
-// @ts-ignore
-import { SavedObject, SavedObjectProvider } from 'ui/saved_objects/saved_object';
-import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_registry';
-
-import { createUiStatsReporter, METRIC_TYPE } from '../../../ui_metric/public';
-import { start as visualizations } from '../../../visualizations/public/np_ready/public/legacy';
-import { start as embeddables } from '../../../../core_plugins/embeddable_api/public/np_ready/public/legacy';
-import { start as data } from '../../../data/public/legacy';
-
-const services = {
- // new platform
- addBasePath: npStart.core.http.basePath.prepend,
- capabilities: npStart.core.application.capabilities,
- chrome: npStart.core.chrome,
- docLinks: npStart.core.docLinks,
- embeddable: npStart.plugins.embeddable,
- getBasePath: npStart.core.http.basePath.get,
- savedObjectsClient: npStart.core.savedObjects.client,
- toastNotifications: npStart.core.notifications.toasts,
- uiSettings: npStart.core.uiSettings,
- core: npStart.core,
-
- share: npStart.plugins.share,
- npData: npStart.plugins.data,
- data,
- embeddables,
- visualizations,
-
- // legacy
- chromeLegacy,
- docTitle,
- FeatureCatalogueRegistryProvider,
- FilterBarQueryFilterProvider,
- getInjector: () => {
- return chromeLegacy.dangerouslyGetActiveInjector();
- },
- SavedObjectProvider,
- SavedObjectRegistryProvider,
- SavedObjectsClientProvider,
- timefilter: npStart.plugins.data.query.timefilter.timefilter,
- uiModules,
- uiRoutes,
- wrapInI18nContext,
+export interface VisualizeKibanaServices {
+ addBasePath: (url: string) => string;
+ chrome: ChromeStart;
+ core: LegacyCoreStart;
+ data: DataPublicPluginStart;
+ editorTypes: any;
+ embeddables: IEmbeddableStart;
+ getBasePath: () => string;
+ indexPatterns: IndexPatternsContract;
+ legacyChrome: any;
+ localStorage: Storage;
+ navigation: NavigationStart;
+ toastNotifications: ToastsStart;
+ savedObjectsClient: SavedObjectsClientContract;
+ savedObjectRegistry: any;
+ savedQueryService: DataPublicPluginStart['query']['savedQueries'];
+ savedVisualizations: SavedVisualizations;
+ share: SharePluginStart;
+ uiSettings: IUiSettingsClient;
+ visualizeCapabilities: any;
+ visualizations: VisualizationsStart;
+}
- createUiStatsReporter,
-};
+let services: VisualizeKibanaServices | null = null;
+export function setServices(newServices: VisualizeKibanaServices) {
+ services = newServices;
+}
export function getServices() {
+ if (!services) {
+ throw new Error(
+ 'Kibana services not set - are you trying to import this module from outside of the visualize app?'
+ );
+ }
return services;
}
-// export legacy static dependencies
-export { angular };
-export { getFromSavedObject } from 'ui/index_patterns';
-export { PersistedState } from 'ui/persisted_state';
-// @ts-ignore
-export { VisEditorTypesRegistryProvider } from 'ui/registry/vis_editor_types';
-export { showSaveModal } from 'ui/saved_objects/show_saved_object_save_modal';
-export { stateMonitorFactory } from 'ui/state_management/state_monitor_factory';
-export { absoluteToParsedUrl } from 'ui/url/absolute_to_parsed_url';
-export { KibanaParsedUrl } from 'ui/url/kibana_parsed_url';
-export { migrateLegacyQuery } from 'ui/utils/migrate_legacy_query';
-export { subscribeWithScope } from 'ui/utils/subscribe_with_scope';
-export { SavedObjectSaveModal } from 'ui/saved_objects/components/saved_object_save_modal';
-export { unhashUrl } from '../../../../../plugins/kibana_utils/public';
-export {
- Container,
- Embeddable,
- EmbeddableFactory,
- EmbeddableInput,
- EmbeddableOutput,
- ErrorEmbeddable,
-} from '../../../../../plugins/embeddable/public';
-
-// export types
-export { METRIC_TYPE };
-export { AppState } from 'ui/state_management/app_state';
-export { VisType } from 'ui/vis';
-
-// export const
-export { FeatureCatalogueCategory } from 'ui/registry/feature_catalogue';
-
-export { VisSavedObject } from './embeddable/visualize_embeddable';
+export function clearServices() {
+ services = null;
+}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/legacy_app.js b/src/legacy/core_plugins/kibana/public/visualize/legacy_app.js
new file mode 100644
index 0000000000000..f47552e99a5c7
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/visualize/legacy_app.js
@@ -0,0 +1,169 @@
+/*
+ * 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 { find } from 'lodash';
+import { i18n } from '@kbn/i18n';
+
+import editorTemplate from './editor/editor.html';
+import visualizeListingTemplate from './listing/visualize_listing.html';
+
+import { initVisualizeAppDirective } from './visualize_app';
+import { VisualizeConstants } from './visualize_constants';
+import { VisualizeListingController } from './listing/visualize_listing';
+import { ensureDefaultIndexPattern, registerTimefilterWithGlobalStateFactory } from './legacy_imports';
+import { syncOnMount } from './global_state_sync';
+
+import {
+ getLandingBreadcrumbs,
+ getWizardStep1Breadcrumbs,
+ getCreateBreadcrumbs,
+ getEditBreadcrumbs
+} from './breadcrumbs';
+
+export function initVisualizeApp(app, deps) {
+ initVisualizeAppDirective(app, deps);
+
+ app.run(globalState => {
+ syncOnMount(globalState, deps.data);
+ });
+
+ app.run((globalState, $rootScope) => {
+ registerTimefilterWithGlobalStateFactory(
+ deps.data.query.timefilter.timefilter,
+ globalState,
+ $rootScope
+ );
+ });
+
+ app.config(function ($routeProvider) {
+ const defaults = {
+ reloadOnSearch: false,
+ requireUICapability: 'visualize.show',
+ badge: () => {
+ if (deps.visualizeCapabilities.save) {
+ return undefined;
+ }
+
+ return {
+ text: i18n.translate('kbn.visualize.badge.readOnly.text', {
+ defaultMessage: 'Read only',
+ }),
+ tooltip: i18n.translate('kbn.visualize.badge.readOnly.tooltip', {
+ defaultMessage: 'Unable to save visualizations',
+ }),
+ iconType: 'glasses',
+ };
+ },
+ };
+
+ $routeProvider
+ .when(VisualizeConstants.LANDING_PAGE_PATH, {
+ ...defaults,
+ template: visualizeListingTemplate,
+ k7Breadcrumbs: getLandingBreadcrumbs,
+ controller: VisualizeListingController,
+ controllerAs: 'listingController',
+ resolve: {
+ createNewVis: () => false,
+ hasDefaultIndex: ($rootScope, kbnUrl) => ensureDefaultIndexPattern(deps.core, deps.data, $rootScope, kbnUrl),
+ },
+ })
+ .when(VisualizeConstants.WIZARD_STEP_1_PAGE_PATH, {
+ ...defaults,
+ template: visualizeListingTemplate,
+ k7Breadcrumbs: getWizardStep1Breadcrumbs,
+ controller: VisualizeListingController,
+ controllerAs: 'listingController',
+ resolve: {
+ createNewVis: () => true,
+ hasDefaultIndex: ($rootScope, kbnUrl) => ensureDefaultIndexPattern(deps.core, deps.data, $rootScope, kbnUrl),
+ },
+ })
+ .when(VisualizeConstants.CREATE_PATH, {
+ ...defaults,
+ template: editorTemplate,
+ k7Breadcrumbs: getCreateBreadcrumbs,
+ resolve: {
+ savedVis: function (redirectWhenMissing, $route, $rootScope, kbnUrl) {
+ const { core, data, savedVisualizations, visualizations } = deps;
+ const visTypes = visualizations.types.all();
+ const visType = find(visTypes, { name: $route.current.params.type });
+ const shouldHaveIndex = visType.requiresSearch && visType.options.showIndexSelection;
+ const hasIndex = $route.current.params.indexPattern || $route.current.params.savedSearchId;
+ if (shouldHaveIndex && !hasIndex) {
+ throw new Error(
+ i18n.translate('kbn.visualize.createVisualization.noIndexPatternOrSavedSearchIdErrorMessage', {
+ defaultMessage: 'You must provide either an indexPattern or a savedSearchId',
+ })
+ );
+ }
+
+ return ensureDefaultIndexPattern(core, data, $rootScope, kbnUrl).then(() => savedVisualizations.get($route.current.params))
+ .then(savedVis => {
+ if (savedVis.vis.type.setup) {
+ return savedVis.vis.type.setup(savedVis)
+ .catch(() => savedVis);
+ }
+ return savedVis;
+ })
+ .catch(redirectWhenMissing({
+ '*': '/visualize'
+ }));
+ }
+ }
+ })
+ .when(`${VisualizeConstants.EDIT_PATH}/:id`, {
+ ...defaults,
+ template: editorTemplate,
+ k7Breadcrumbs: getEditBreadcrumbs,
+ resolve: {
+ savedVis: function (redirectWhenMissing, $route, $rootScope, kbnUrl) {
+ const { chrome, core, data, savedVisualizations } = deps;
+ return ensureDefaultIndexPattern(core, data, $rootScope, kbnUrl)
+ .then(() => savedVisualizations.get($route.current.params.id))
+ .then(savedVis => {
+ chrome.recentlyAccessed.add(
+ savedVis.getFullPath(),
+ savedVis.title,
+ savedVis.id
+ );
+ return savedVis;
+ })
+ .then(savedVis => {
+ if (savedVis.vis.type.setup) {
+ return savedVis.vis.type.setup(savedVis).catch(() => savedVis);
+ }
+ return savedVis;
+ })
+ .catch(
+ redirectWhenMissing({
+ 'visualization': '/visualize',
+ 'search': '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
+ 'index-pattern': '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
+ 'index-pattern-field': '/management/kibana/objects/savedVisualizations/' + $route.current.params.id
+ })
+ );
+ }
+ }
+ })
+ .when(`visualize/:tail*?`, {
+ redirectTo: `/${deps.core.injectedMetadata.getInjectedVar('kbnDefaultAppId')}`,
+ });
+ });
+}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts b/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts
new file mode 100644
index 0000000000000..6adcfd2cc7186
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+/**
+ * The imports in this file are static functions and types which still live in legacy folders and are used
+ * within dashboard. To consolidate them all in one place, they are re-exported from this file. Eventually
+ * this list should become empty. Imports from the top level of shimmed or moved plugins can be imported
+ * directly where they are needed.
+ */
+
+import chrome from 'ui/chrome';
+
+export const legacyChrome = chrome;
+
+// @ts-ignore
+export { AppState, AppStateProvider } from 'ui/state_management/app_state';
+export { State } from 'ui/state_management/state';
+// @ts-ignore
+export { GlobalStateProvider } from 'ui/state_management/global_state';
+// @ts-ignore
+export { StateManagementConfigProvider } from 'ui/state_management/config_provider';
+export { stateMonitorFactory } from 'ui/state_management/state_monitor_factory';
+export { PersistedState } from 'ui/persisted_state';
+
+export { npSetup, npStart } from 'ui/new_platform';
+export { IPrivate } from 'ui/private';
+// @ts-ignore
+export { PrivateProvider } from 'ui/private/private';
+
+export { SavedObjectRegistryProvider } from 'ui/saved_objects';
+export { SavedObjectSaveModal } from 'ui/saved_objects/components/saved_object_save_modal';
+export { SavedObjectFinder } from 'ui/saved_objects/components/saved_object_finder';
+export { showSaveModal } from 'ui/saved_objects/show_saved_object_save_modal';
+
+export { subscribeWithScope } from 'ui/utils/subscribe_with_scope';
+export { migrateLegacyQuery } from 'ui/utils/migrate_legacy_query';
+// @ts-ignore
+export { EventsProvider } from 'ui/events';
+// @ts-ignore
+export { createTopNavDirective, createTopNavHelper } from 'ui/kbn_top_nav/kbn_top_nav';
+// @ts-ignore
+export { PromiseServiceCreator } from 'ui/promises/promises';
+// @ts-ignore
+export { confirmModalFactory } from 'ui/modals/confirm_modal';
+export { configureAppAngularModule, ensureDefaultIndexPattern } from 'ui/legacy_compat';
+export { registerTimefilterWithGlobalStateFactory } from 'ui/timefilter/setup_router';
+// @ts-ignore
+export { VisEditorTypesRegistryProvider } from 'ui/registry/vis_editor_types';
+
+// @ts-ignore
+export { KbnUrlProvider, RedirectWhenMissingProvider } from 'ui/url';
+export { absoluteToParsedUrl } from 'ui/url/absolute_to_parsed_url';
+export { KibanaParsedUrl } from 'ui/url/kibana_parsed_url';
+
+// @ts-ignore
+export { defaultEditor } from 'ui/vis/editors/default/default';
+export { VisType } from 'ui/vis';
+export { wrapInI18nContext } from 'ui/i18n';
+
+export { VisSavedObject } from './embeddable/visualize_embeddable';
diff --git a/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing.html b/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing.html
index edb7cccbd46a2..4511ac61f7396 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing.html
+++ b/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing.html
@@ -14,6 +14,8 @@
is-open="listingController.showNewVisModal"
on-close="listingController.closeNewVisModal"
vis-types-registry="listingController.visTypeRegistry"
+ add-base-path="listingController.addBasePath"
+ ui-settings="listingController.uiSettings"
>
diff --git a/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing.js b/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing.js
index f9e3a1a90115a..9b02be0581b8d 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing.js
+++ b/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing.js
@@ -24,36 +24,46 @@ import { VisualizeConstants } from '../visualize_constants';
import { i18n } from '@kbn/i18n';
import { getServices } from '../kibana_services';
-
-const {
- addBasePath,
- chrome,
- chromeLegacy,
- SavedObjectRegistryProvider,
- SavedObjectsClientProvider,
- timefilter,
- toastNotifications,
- uiModules,
- wrapInI18nContext,
- visualizations,
-} = getServices();
-
-const app = uiModules.get('app/visualize', ['ngRoute', 'react']);
-app.directive('visualizeListingTable', reactDirective =>
- reactDirective(wrapInI18nContext(VisualizeListingTable))
-);
-app.directive('newVisModal', reactDirective => reactDirective(wrapInI18nContext(NewVisModal)));
+import { wrapInI18nContext } from '../legacy_imports';
+
+export function initListingDirective(app) {
+ app.directive('visualizeListingTable', reactDirective => reactDirective(wrapInI18nContext(VisualizeListingTable)));
+ app.directive('newVisModal', reactDirective =>
+ reactDirective(wrapInI18nContext(NewVisModal), [
+ ['visTypesRegistry', { watchDepth: 'collection' }],
+ ['onClose', { watchDepth: 'reference' }],
+ ['addBasePath', { watchDepth: 'reference' }],
+ ['uiSettings', { watchDepth: 'reference' }],
+ 'isOpen',
+ ])
+ );
+}
export function VisualizeListingController($injector, createNewVis) {
- const Private = $injector.get('Private');
- const config = $injector.get('config');
+ const {
+ addBasePath,
+ chrome,
+ legacyChrome,
+ savedObjectRegistry,
+ savedObjectsClient,
+ data: {
+ query: {
+ timefilter: { timefilter },
+ },
+ },
+ toastNotifications,
+ uiSettings,
+ visualizations,
+ core: { docLinks },
+ } = getServices();
const kbnUrl = $injector.get('kbnUrl');
- const savedObjectClient = Private(SavedObjectsClientProvider);
timefilter.disableAutoRefreshSelector();
timefilter.disableTimeRangeSelector();
this.showNewVisModal = false;
+ this.addBasePath = addBasePath;
+ this.uiSettings = uiSettings;
this.createNewVis = () => {
this.showNewVisModal = true;
@@ -82,14 +92,14 @@ export function VisualizeListingController($injector, createNewVis) {
}
// TODO: Extract this into an external service.
- const services = Private(SavedObjectRegistryProvider).byLoaderPropertiesName;
+ const services = savedObjectRegistry.byLoaderPropertiesName;
const visualizationService = services.visualizations;
this.visTypeRegistry = visualizations.types;
this.fetchItems = filter => {
- const isLabsEnabled = config.get('visualize:enableLabs');
+ const isLabsEnabled = uiSettings.get('visualize:enableLabs');
return visualizationService
- .findListItems(filter, config.get('savedObjects:listingLimit'))
+ .findListItems(filter, uiSettings.get('savedObjects:listingLimit'))
.then(result => {
this.totalItems = result.total;
@@ -103,11 +113,11 @@ export function VisualizeListingController($injector, createNewVis) {
this.deleteSelectedItems = function deleteSelectedItems(selectedItems) {
return Promise.all(
selectedItems.map(item => {
- return savedObjectClient.delete(item.savedObjectType, item.id);
+ return savedObjectsClient.delete(item.savedObjectType, item.id);
})
)
.then(() => {
- chromeLegacy.untrackNavLinksForDeletedSavedObjects(selectedItems.map(item => item.id));
+ legacyChrome.untrackNavLinksForDeletedSavedObjects(selectedItems.map(item => item.id));
})
.catch(error => {
toastNotifications.addError(error, {
@@ -126,7 +136,7 @@ export function VisualizeListingController($injector, createNewVis) {
},
]);
- this.listingLimit = config.get('savedObjects:listingLimit');
+ this.listingLimit = uiSettings.get('savedObjects:listingLimit');
- addHelpMenuToAppChrome(chrome);
+ addHelpMenuToAppChrome(chrome, docLinks);
}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing_table.js b/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing_table.js
index efab03303aa80..890fa64af9693 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing_table.js
+++ b/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing_table.js
@@ -27,22 +27,21 @@ import { EuiIcon, EuiBetaBadge, EuiLink, EuiButton, EuiEmptyPrompt } from '@elas
import { getServices } from '../kibana_services';
-const { capabilities, toastNotifications, uiSettings } = getServices();
-
class VisualizeListingTable extends Component {
constructor(props) {
super(props);
}
render() {
+ const { visualizeCapabilities, uiSettings, toastNotifications } = getServices();
return (
item.canDelete}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/plugin.ts b/src/legacy/core_plugins/kibana/public/visualize/plugin.ts
new file mode 100644
index 0000000000000..1aa2d70dabea6
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/visualize/plugin.ts
@@ -0,0 +1,161 @@
+/*
+ * 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 { i18n } from '@kbn/i18n';
+
+import {
+ CoreSetup,
+ CoreStart,
+ LegacyCoreStart,
+ Plugin,
+ SavedObjectsClientContract,
+} from 'kibana/public';
+
+import { Storage } from '../../../../../plugins/kibana_utils/public';
+import { DataPublicPluginStart } from '../../../../../plugins/data/public';
+import { IEmbeddableStart } from '../../../../../plugins/embeddable/public';
+import { NavigationStart } from '../../../navigation/public';
+import { SharePluginStart } from '../../../../../plugins/share/public';
+import { KibanaLegacySetup } from '../../../../../plugins/kibana_legacy/public';
+import { VisualizationsStart } from '../../../visualizations/public';
+import { VisualizeEmbeddableFactory } from './embeddable/visualize_embeddable_factory';
+import { VISUALIZE_EMBEDDABLE_TYPE } from './embeddable/constants';
+import { VisualizeConstants } from './visualize_constants';
+import { setServices, VisualizeKibanaServices } from './kibana_services';
+import {
+ FeatureCatalogueCategory,
+ HomePublicPluginSetup,
+} from '../../../../../plugins/home/public';
+import { defaultEditor, VisEditorTypesRegistryProvider } from './legacy_imports';
+import { SavedVisualizations } from './types';
+
+export interface LegacyAngularInjectedDependencies {
+ legacyChrome: any;
+ editorTypes: any;
+ savedObjectRegistry: any;
+ savedVisualizations: SavedVisualizations;
+}
+
+export interface VisualizePluginStartDependencies {
+ data: DataPublicPluginStart;
+ embeddables: IEmbeddableStart;
+ navigation: NavigationStart;
+ share: SharePluginStart;
+ visualizations: VisualizationsStart;
+}
+
+export interface VisualizePluginSetupDependencies {
+ __LEGACY: {
+ getAngularDependencies: () => Promise;
+ };
+ home: HomePublicPluginSetup;
+ kibana_legacy: KibanaLegacySetup;
+}
+
+export class VisualizePlugin implements Plugin {
+ private startDependencies: {
+ data: DataPublicPluginStart;
+ embeddables: IEmbeddableStart;
+ navigation: NavigationStart;
+ savedObjectsClient: SavedObjectsClientContract;
+ share: SharePluginStart;
+ visualizations: VisualizationsStart;
+ } | null = null;
+
+ public async setup(
+ core: CoreSetup,
+ { home, kibana_legacy, __LEGACY: { getAngularDependencies } }: VisualizePluginSetupDependencies
+ ) {
+ kibana_legacy.registerLegacyApp({
+ id: 'visualize',
+ title: 'Visualize',
+ mount: async ({ core: contextCore }, params) => {
+ if (this.startDependencies === null) {
+ throw new Error('not started yet');
+ }
+
+ const {
+ savedObjectsClient,
+ embeddables,
+ navigation,
+ visualizations,
+ data,
+ share,
+ } = this.startDependencies;
+
+ const angularDependencies = await getAngularDependencies();
+ const deps: VisualizeKibanaServices = {
+ ...angularDependencies,
+ addBasePath: contextCore.http.basePath.prepend,
+ core: contextCore as LegacyCoreStart,
+ chrome: contextCore.chrome,
+ data,
+ embeddables,
+ getBasePath: core.http.basePath.get,
+ indexPatterns: data.indexPatterns,
+ localStorage: new Storage(localStorage),
+ navigation,
+ savedObjectsClient,
+ savedQueryService: data.query.savedQueries,
+ share,
+ toastNotifications: contextCore.notifications.toasts,
+ uiSettings: contextCore.uiSettings,
+ visualizeCapabilities: contextCore.application.capabilities.visualize,
+ visualizations,
+ };
+ setServices(deps);
+
+ const { renderApp } = await import('./application');
+ return renderApp(params.element, params.appBasePath, deps);
+ },
+ });
+
+ home.featureCatalogue.register({
+ id: 'visualize',
+ title: 'Visualize',
+ description: i18n.translate('kbn.visualize.visualizeDescription', {
+ defaultMessage:
+ 'Create visualizations and aggregate data stores in your Elasticsearch indices.',
+ }),
+ icon: 'visualizeApp',
+ path: `/app/kibana#${VisualizeConstants.LANDING_PAGE_PATH}`,
+ showOnHomePage: true,
+ category: FeatureCatalogueCategory.DATA,
+ });
+
+ VisEditorTypesRegistryProvider.register(defaultEditor);
+ }
+
+ public start(
+ { savedObjects: { client: savedObjectsClient } }: CoreStart,
+ { embeddables, navigation, data, share, visualizations }: VisualizePluginStartDependencies
+ ) {
+ this.startDependencies = {
+ data,
+ embeddables,
+ navigation,
+ savedObjectsClient,
+ share,
+ visualizations,
+ };
+
+ const embeddableFactory = new VisualizeEmbeddableFactory(visualizations.types);
+ embeddables.registerEmbeddableFactory(VISUALIZE_EMBEDDABLE_TYPE, embeddableFactory);
+ }
+}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/types.d.ts b/src/legacy/core_plugins/kibana/public/visualize/types.d.ts
index c83f7f5a5da8b..b6a3981215384 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/types.d.ts
+++ b/src/legacy/core_plugins/kibana/public/visualize/types.d.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import { VisSavedObject } from './kibana_services';
+import { VisSavedObject } from './legacy_imports';
export interface SavedVisualizations {
urlFor: (id: string) => string;
diff --git a/src/legacy/core_plugins/kibana/public/visualize/visualize_app.ts b/src/legacy/core_plugins/kibana/public/visualize/visualize_app.ts
new file mode 100644
index 0000000000000..c64287a0e63b8
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/visualize/visualize_app.ts
@@ -0,0 +1,31 @@
+/*
+ * 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 { IModule } from 'angular';
+import { VisualizeKibanaServices } from './kibana_services';
+
+// @ts-ignore
+import { initEditorDirective } from './editor/editor';
+// @ts-ignore
+import { initListingDirective } from './listing/visualize_listing';
+
+export function initVisualizeAppDirective(app: IModule, deps: VisualizeKibanaServices) {
+ initEditorDirective(app, deps);
+ initListingDirective(app);
+}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap b/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap
index 4aa614b68ea23..5be5f58994887 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap
+++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap
@@ -2,6 +2,7 @@
exports[`NewVisModal filter for visualization types should render as expected 1`] = `
@@ -1287,6 +1307,7 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
exports[`NewVisModal should render as expected 1`] = `
diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.tsx b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.tsx
index 99d9590e750fd..0dd2091bbfee0 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.tsx
+++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.tsx
@@ -20,33 +20,17 @@
import React from 'react';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
-import { NewVisModal } from './new_vis_modal';
-import { VisType } from '../kibana_services';
+import { VisType } from '../legacy_imports';
import { TypesStart } from '../../../../visualizations/public/np_ready/public/types';
-jest.mock('../kibana_services', () => {
- const mock = {
- addBasePath: jest.fn(path => `root${path}`),
- uiSettings: { get: jest.fn() },
- createUiStatsReporter: () => jest.fn(),
- };
-
- return {
- getServices: () => mock,
- VisType: {},
- METRIC_TYPE: 'metricType',
- };
-});
-
-import { getServices } from '../kibana_services';
+jest.mock('../legacy_imports', () => ({
+ State: () => null,
+ AppState: () => null,
+}));
-beforeEach(() => {
- jest.clearAllMocks();
-});
+import { NewVisModal } from './new_vis_modal';
describe('NewVisModal', () => {
- const settingsGet = getServices().uiSettings.get as jest.Mock;
-
const defaultVisTypeParams = {
hidden: false,
visualization: class Controller {
@@ -76,17 +60,36 @@ describe('NewVisModal', () => {
},
getAliases: () => [],
};
+ const addBasePath = (url: string) => `testbasepath${url}`;
+ const settingsGet = jest.fn();
+ const uiSettings: any = { get: settingsGet };
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
it('should render as expected', () => {
const wrapper = mountWithIntl(
- null} visTypesRegistry={visTypes} />
+ null}
+ visTypesRegistry={visTypes}
+ addBasePath={addBasePath}
+ uiSettings={uiSettings}
+ />
);
expect(wrapper).toMatchSnapshot();
});
it('should show a button for regular visualizations', () => {
const wrapper = mountWithIntl(
- null} visTypesRegistry={visTypes} />
+ null}
+ visTypesRegistry={visTypes}
+ addBasePath={addBasePath}
+ uiSettings={uiSettings}
+ />
);
expect(wrapper.find('[data-test-subj="visType-vis"]').exists()).toBe(true);
});
@@ -95,7 +98,13 @@ describe('NewVisModal', () => {
it('should open the editor for visualizations without search', () => {
window.location.assign = jest.fn();
const wrapper = mountWithIntl(
- null} visTypesRegistry={visTypes} />
+ null}
+ visTypesRegistry={visTypes}
+ addBasePath={addBasePath}
+ uiSettings={uiSettings}
+ />
);
const visButton = wrapper.find('button[data-test-subj="visType-vis"]');
visButton.simulate('click');
@@ -110,6 +119,8 @@ describe('NewVisModal', () => {
onClose={() => null}
visTypesRegistry={visTypes}
editorParams={['foo=true', 'bar=42']}
+ addBasePath={addBasePath}
+ uiSettings={uiSettings}
/>
);
const visButton = wrapper.find('button[data-test-subj="visType-vis"]');
@@ -121,7 +132,13 @@ describe('NewVisModal', () => {
describe('filter for visualization types', () => {
it('should render as expected', () => {
const wrapper = mountWithIntl(
- null} visTypesRegistry={visTypes} />
+ null}
+ visTypesRegistry={visTypes}
+ addBasePath={addBasePath}
+ uiSettings={uiSettings}
+ />
);
const searchBox = wrapper.find('input[data-test-subj="filterVisType"]');
searchBox.simulate('change', { target: { value: 'with' } });
@@ -133,7 +150,13 @@ describe('NewVisModal', () => {
it('should not show experimental visualizations if visualize:enableLabs is false', () => {
settingsGet.mockReturnValue(false);
const wrapper = mountWithIntl(
- null} visTypesRegistry={visTypes} />
+ null}
+ visTypesRegistry={visTypes}
+ addBasePath={addBasePath}
+ uiSettings={uiSettings}
+ />
);
expect(wrapper.find('[data-test-subj="visType-visExp"]').exists()).toBe(false);
});
@@ -141,7 +164,13 @@ describe('NewVisModal', () => {
it('should show experimental visualizations if visualize:enableLabs is true', () => {
settingsGet.mockReturnValue(true);
const wrapper = mountWithIntl(
- null} visTypesRegistry={visTypes} />
+ null}
+ visTypesRegistry={visTypes}
+ addBasePath={addBasePath}
+ uiSettings={uiSettings}
+ />
);
expect(wrapper.find('[data-test-subj="visType-visExp"]').exists()).toBe(true);
});
diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.tsx b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.tsx
index 420f0e5198056..0b46b562f2146 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.tsx
+++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.tsx
@@ -22,20 +22,21 @@ import React from 'react';
import { EuiModal, EuiOverlayMask } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
+import { IUiSettingsClient } from 'kibana/public';
+import { VisType } from '../legacy_imports';
import { VisualizeConstants } from '../visualize_constants';
+import { createUiStatsReporter, METRIC_TYPE } from '../../../../ui_metric/public';
import { SearchSelection } from './search_selection';
import { TypeSelection } from './type_selection';
import { TypesStart, VisTypeAlias } from '../../../../visualizations/public/np_ready/public/types';
-import { getServices, METRIC_TYPE, VisType } from '../kibana_services';
-
-const { addBasePath, createUiStatsReporter, uiSettings } = getServices();
-
interface TypeSelectionProps {
isOpen: boolean;
onClose: () => void;
visTypesRegistry: TypesStart;
editorParams?: string[];
+ addBasePath: (path: string) => string;
+ uiSettings: IUiSettingsClient;
}
interface TypeSelectionState {
@@ -55,7 +56,7 @@ class NewVisModal extends React.Component
);
@@ -124,7 +126,7 @@ class NewVisModal extends React.Component void;
diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/show_new_vis.tsx b/src/legacy/core_plugins/kibana/public/visualize/wizard/show_new_vis.tsx
index fa2ca6747bc40..92320f7bb443a 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/wizard/show_new_vis.tsx
+++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/show_new_vis.tsx
@@ -20,7 +20,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
-import { I18nContext } from 'ui/i18n';
+import { I18nProvider } from '@kbn/i18n/react';
+import { IUiSettingsClient } from 'kibana/public';
import { NewVisModal } from './new_vis_modal';
import { TypesStart } from '../../../../visualizations/public/np_ready/public/types';
@@ -30,7 +31,9 @@ interface ShowNewVisModalParams {
export function showNewVisModal(
visTypeRegistry: TypesStart,
- { editorParams = [] }: ShowNewVisModalParams = {}
+ { editorParams = [] }: ShowNewVisModalParams = {},
+ addBasePath: (path: string) => string,
+ uiSettings: IUiSettingsClient
) {
const container = document.createElement('div');
const onClose = () => {
@@ -40,14 +43,16 @@ export function showNewVisModal(
document.body.appendChild(container);
const element = (
-
+
-
+
);
ReactDOM.render(element, container);
}
diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/type_selection/new_vis_help.test.tsx b/src/legacy/core_plugins/kibana/public/visualize/wizard/type_selection/new_vis_help.test.tsx
index 382f475669f5d..3093499a030c8 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/wizard/type_selection/new_vis_help.test.tsx
+++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/type_selection/new_vis_help.test.tsx
@@ -21,18 +21,6 @@ import React from 'react';
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
import { NewVisHelp } from './new_vis_help';
-jest.mock('../../kibana_services', () => {
- return {
- getServices: () => ({
- addBasePath: jest.fn((url: string) => `testbasepath${url}`),
- }),
- };
-});
-
-beforeEach(() => {
- jest.clearAllMocks();
-});
-
describe('NewVisHelp', () => {
it('should render as expected', () => {
expect(
@@ -53,6 +41,7 @@ describe('NewVisHelp', () => {
stage: 'production',
},
]}
+ addBasePath={(url: string) => `testbasepath${url}`}
/>
)
).toMatchInlineSnapshot(`
diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/type_selection/new_vis_help.tsx b/src/legacy/core_plugins/kibana/public/visualize/wizard/type_selection/new_vis_help.tsx
index 44c36f7d17d55..107cbc0e754b5 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/wizard/type_selection/new_vis_help.tsx
+++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/type_selection/new_vis_help.tsx
@@ -22,10 +22,9 @@ import React, { Fragment } from 'react';
import { EuiText, EuiButton } from '@elastic/eui';
import { VisTypeAliasListEntry } from './type_selection';
-import { getServices } from '../../kibana_services';
-
interface Props {
promotedTypes: VisTypeAliasListEntry[];
+ addBasePath: (path: string) => string;
}
export function NewVisHelp(props: Props) {
@@ -43,7 +42,7 @@ export function NewVisHelp(props: Props) {
{t.promotion!.description}
string;
onVisTypeSelected: (visType: VisType | VisTypeAlias) => void;
visTypesRegistry: TypesStart;
showExperimental: boolean;
@@ -153,6 +154,7 @@ class TypeSelection extends React.Component
t.promotion)}
+ addBasePath={this.props.addBasePath}
/>
)}
diff --git a/src/legacy/ui/public/vis/editors/default/default.js b/src/legacy/ui/public/vis/editors/default/default.js
index 43d2962df0a1e..9df866d29a8a2 100644
--- a/src/legacy/ui/public/vis/editors/default/default.js
+++ b/src/legacy/ui/public/vis/editors/default/default.js
@@ -33,12 +33,11 @@ import { keyCodes } from '@elastic/eui';
import { parentPipelineAggHelper } from 'ui/agg_types/metrics/lib/parent_pipeline_agg_helper';
import { DefaultEditorSize } from '../../editor_size';
-import { VisEditorTypesRegistryProvider } from '../../../registry/vis_editor_types';
import { AggGroupNames } from './agg_groups';
import { start as embeddables } from '../../../../../core_plugins/embeddable_api/public/np_ready/public/legacy';
-const defaultEditor = function ($rootScope, $compile, getAppState) {
+const defaultEditor = function ($rootScope, $compile) {
return class DefaultEditor {
static key = 'default';
@@ -58,7 +57,7 @@ const defaultEditor = function ($rootScope, $compile, getAppState) {
}
}
- render({ uiState, timeRange, filters, query }) {
+ render({ uiState, timeRange, filters, query, appState }) {
let $scope;
const updateScope = () => {
@@ -161,7 +160,7 @@ const defaultEditor = function ($rootScope, $compile, getAppState) {
this._handler = await embeddables.getEmbeddableFactory('visualization').createFromObject(this.savedObj, {
uiState: uiState,
- appState: getAppState(),
+ appState,
timeRange: timeRange,
filters: filters || [],
query: query,
@@ -195,6 +194,4 @@ const defaultEditor = function ($rootScope, $compile, getAppState) {
};
};
-VisEditorTypesRegistryProvider.register(defaultEditor);
-
export { defaultEditor };
diff --git a/src/legacy/ui/ui_exports/ui_export_defaults.js b/src/legacy/ui/ui_exports/ui_export_defaults.js
index 291d9feea3c40..80bee41175771 100644
--- a/src/legacy/ui/ui_exports/ui_export_defaults.js
+++ b/src/legacy/ui/ui_exports/ui_export_defaults.js
@@ -50,12 +50,6 @@ export const UI_EXPORT_DEFAULTS = {
fieldFormatEditors: [
'ui/field_editor/components/field_format_editor/register'
],
- visEditorTypes: [
- 'ui/vis/editors/default/default',
- ],
- embeddableFactories: [
- 'plugins/kibana/visualize/embeddable/visualize_embeddable_factory',
- ],
search: [
'ui/courier/search_strategy/default_search_strategy',
],
diff --git a/tasks/config/run.js b/tasks/config/run.js
index e4071c8b7d0ab..97a0f381f2aa4 100644
--- a/tasks/config/run.js
+++ b/tasks/config/run.js
@@ -269,7 +269,6 @@ module.exports = function (grunt) {
'--config', 'test/plugin_functional/config.js',
'--bail',
'--debug',
- '--kibana-install-dir', KIBANA_INSTALL_DIR,
],
}),
diff --git a/x-pack/legacy/plugins/canvas/public/legacy_start.ts b/x-pack/legacy/plugins/canvas/public/legacy_start.ts
index 49ec7acd6375d..972427e166afc 100644
--- a/x-pack/legacy/plugins/canvas/public/legacy_start.ts
+++ b/x-pack/legacy/plugins/canvas/public/legacy_start.ts
@@ -11,7 +11,6 @@ import 'ui/autoload/all';
import 'uiExports/visTypes';
import 'uiExports/visResponseHandlers';
import 'uiExports/visRequestHandlers';
-import 'uiExports/visEditorTypes';
import 'uiExports/savedObjectTypes';
import 'uiExports/spyModes';
import 'uiExports/embeddableFactories';
diff --git a/x-pack/legacy/plugins/dashboard_mode/public/dashboard_viewer.js b/x-pack/legacy/plugins/dashboard_mode/public/dashboard_viewer.js
index 8093c57d2631a..8c6ddfebcb6cc 100644
--- a/x-pack/legacy/plugins/dashboard_mode/public/dashboard_viewer.js
+++ b/x-pack/legacy/plugins/dashboard_mode/public/dashboard_viewer.js
@@ -18,7 +18,6 @@ import 'uiExports/contextMenuActions';
import 'uiExports/visTypes';
import 'uiExports/visResponseHandlers';
import 'uiExports/visRequestHandlers';
-import 'uiExports/visEditorTypes';
import 'uiExports/inspectorViews';
import 'uiExports/interpreter';
import 'uiExports/savedObjectTypes';