diff --git a/.eslintrc.js b/.eslintrc.js index 3d6a5c262c453..af05af0f6e402 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -69,12 +69,6 @@ module.exports = { 'jsx-a11y/no-onchange': 'off', }, }, - { - files: ['src/legacy/core_plugins/data/**/*.{js,ts,tsx}'], - rules: { - 'react-hooks/exhaustive-deps': 'off', - }, - }, { files: ['src/legacy/core_plugins/expressions/**/*.{js,ts,tsx}'], rules: { diff --git a/.i18nrc.json b/.i18nrc.json index 07878ed3c15fb..bffe99bf3654b 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -4,10 +4,7 @@ "console": "src/plugins/console", "core": "src/core", "dashboard": "src/plugins/dashboard", - "data": [ - "src/legacy/core_plugins/data", - "src/plugins/data" - ], + "data": "src/plugins/data", "embeddableApi": "src/plugins/embeddable", "embeddableExamples": "examples/embeddable_examples", "share": "src/plugins/share", diff --git a/Jenkinsfile b/Jenkinsfile index d43da6e0bee04..79d3c93006cb6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -40,7 +40,12 @@ kibanaPipeline(timeoutMinutes: 135, checkPrChanges: true) { 'xpack-ciGroup9': kibanaPipeline.xpackCiGroupProcess(9), 'xpack-ciGroup10': kibanaPipeline.xpackCiGroupProcess(10), 'xpack-accessibility': kibanaPipeline.functionalTestProcess('xpack-accessibility', './test/scripts/jenkins_xpack_accessibility.sh'), - 'xpack-siemCypress': kibanaPipeline.functionalTestProcess('xpack-siemCypress', './test/scripts/jenkins_siem_cypress.sh'), + 'xpack-siemCypress': { processNumber -> + whenChanged(['x-pack/legacy/plugins/siem/', 'x-pack/test/siem_cypress/']) { + kibanaPipeline.functionalTestProcess('xpack-siemCypress', './test/scripts/jenkins_siem_cypress.sh')(processNumber) + } + }, + // 'xpack-visualRegression': kibanaPipeline.functionalTestProcess('xpack-visualRegression', './test/scripts/jenkins_xpack_visual_regression.sh'), ]), ]) diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md new file mode 100644 index 0000000000000..2ef8c797f4054 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [enabled](./kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md) + +## AggConfigOptions.enabled property + +Signature: + +```typescript +enabled?: boolean; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.id.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.id.md new file mode 100644 index 0000000000000..8939854ab19ca --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [id](./kibana-plugin-plugins-data-public.aggconfigoptions.id.md) + +## AggConfigOptions.id property + +Signature: + +```typescript +id?: string; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.md new file mode 100644 index 0000000000000..b841d9b04d6a7 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) + +## AggConfigOptions interface + +Signature: + +```typescript +export interface AggConfigOptions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [enabled](./kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md) | boolean | | +| [id](./kibana-plugin-plugins-data-public.aggconfigoptions.id.md) | string | | +| [params](./kibana-plugin-plugins-data-public.aggconfigoptions.params.md) | Record<string, any> | | +| [schema](./kibana-plugin-plugins-data-public.aggconfigoptions.schema.md) | string | | +| [type](./kibana-plugin-plugins-data-public.aggconfigoptions.type.md) | IAggType | | + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.params.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.params.md new file mode 100644 index 0000000000000..45219a837cc33 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.params.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [params](./kibana-plugin-plugins-data-public.aggconfigoptions.params.md) + +## AggConfigOptions.params property + +Signature: + +```typescript +params?: Record; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.schema.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.schema.md new file mode 100644 index 0000000000000..b2b42eb2e5b4d --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.schema.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [schema](./kibana-plugin-plugins-data-public.aggconfigoptions.schema.md) + +## AggConfigOptions.schema property + +Signature: + +```typescript +schema?: string; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.type.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.type.md new file mode 100644 index 0000000000000..866065ce52ba6 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [type](./kibana-plugin-plugins-data-public.aggconfigoptions.type.md) + +## AggConfigOptions.type property + +Signature: + +```typescript +type: IAggType; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md index e7341caf7b3cd..c5e01715534d1 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md @@ -30,6 +30,7 @@ export declare enum ES_FIELD_TYPES | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | | HALF\_FLOAT | "half_float" | | +| HISTOGRAM | "histogram" | | | INTEGER | "integer" | | | IP | "ip" | | | KEYWORD | "keyword" | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md index e5ae8ffbd2877..30c3aa946c1ce 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md @@ -23,6 +23,7 @@ export declare enum KBN_FIELD_TYPES | DATE | "date" | | | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | +| HISTOGRAM | "histogram" | | | IP | "ip" | | | MURMUR3 | "murmur3" | | | NESTED | "nested" | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index f8516ec476e88..ea77d6f39389b 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -48,6 +48,7 @@ | Interface | Description | | --- | --- | +| [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) | | | [AggParamOption](./kibana-plugin-plugins-data-public.aggparamoption.md) | | | [DataPublicPluginSetup](./kibana-plugin-plugins-data-public.datapublicpluginsetup.md) | | | [DataPublicPluginStart](./kibana-plugin-plugins-data-public.datapublicpluginstart.md) | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md index 81a7cbca77c48..d071955f4f522 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md @@ -30,6 +30,7 @@ export declare enum ES_FIELD_TYPES | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | | HALF\_FLOAT | "half_float" | | +| HISTOGRAM | "histogram" | | | INTEGER | "integer" | | | IP | "ip" | | | KEYWORD | "keyword" | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md index 40b81d2f6ac4d..a0a64190497c8 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md @@ -23,6 +23,7 @@ export declare enum KBN_FIELD_TYPES | DATE | "date" | | | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | +| HISTOGRAM | "histogram" | | | IP | "ip" | | | MURMUR3 | "murmur3" | | | NESTED | "nested" | | diff --git a/src/legacy/core_plugins/data/index.ts b/src/legacy/core_plugins/data/index.ts deleted file mode 100644 index 10c8cf464b82d..0000000000000 --- a/src/legacy/core_plugins/data/index.ts +++ /dev/null @@ -1,41 +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 { resolve } from 'path'; -import { Legacy } from '../../../../kibana'; - -// eslint-disable-next-line import/no-default-export -export default function DataPlugin(kibana: any) { - const config: Legacy.PluginSpecOptions = { - id: 'data', - require: ['elasticsearch'], - publicDir: resolve(__dirname, 'public'), - config: (Joi: any) => { - return Joi.object({ - enabled: Joi.boolean().default(true), - }).default(); - }, - init: (server: Legacy.Server) => ({}), - uiExports: { - injectDefaultVars: () => ({}), - }, - }; - - return new kibana.Plugin(config); -} diff --git a/src/legacy/core_plugins/data/package.json b/src/legacy/core_plugins/data/package.json deleted file mode 100644 index 3f40374650ad7..0000000000000 --- a/src/legacy/core_plugins/data/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "data", - "version": "kibana" -} diff --git a/src/legacy/core_plugins/data/public/legacy.ts b/src/legacy/core_plugins/data/public/legacy.ts deleted file mode 100644 index 370b412127db8..0000000000000 --- a/src/legacy/core_plugins/data/public/legacy.ts +++ /dev/null @@ -1,44 +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. - */ - -/** - * New Platform Shim - * - * In this file, we import any legacy dependencies we have, and shim them into - * our plugin by manually constructing the values that the new platform will - * eventually be passing to the `setup` method of our plugin definition. - * - * The idea is that our `plugin.ts` can stay "pure" and not contain any legacy - * world code. Then when it comes time to migrate to the new platform, we can - * simply delete this shim file. - * - * We are also calling `setup` here and exporting our public contract so that - * other legacy plugins are able to import from '../core_plugins/data/legacy' - * and receive the response value of the `setup` contract, mimicking the - * data that will eventually be injected by the new platform. - */ - -import { npSetup, npStart } from 'ui/new_platform'; -import { plugin } from '.'; - -const dataPlugin = plugin(); - -export const setup = dataPlugin.setup(npSetup.core); - -export const start = dataPlugin.start(npStart.core); diff --git a/src/legacy/core_plugins/data/public/plugin.ts b/src/legacy/core_plugins/data/public/plugin.ts deleted file mode 100644 index 76a3d92d20283..0000000000000 --- a/src/legacy/core_plugins/data/public/plugin.ts +++ /dev/null @@ -1,58 +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 { CoreSetup, CoreStart, Plugin } from 'kibana/public'; - -/** - * Interface for this plugin's returned `setup` contract. - * - * @public - */ -export interface DataSetup {} // eslint-disable-line @typescript-eslint/no-empty-interface - -/** - * Interface for this plugin's returned `start` contract. - * - * @public - */ -export interface DataStart {} // eslint-disable-line @typescript-eslint/no-empty-interface - -/** - * Data Plugin - public - * - * This is the entry point for the entire client-side public contract of the plugin. - * If something is not explicitly exported here, you can safely assume it is private - * to the plugin and not considered stable. - * - * All stateful contracts will be injected by the platform at runtime, and are defined - * in the setup/start interfaces. The remaining items exported here are either types, - * or static code. - */ - -export class DataPlugin implements Plugin { - public setup(core: CoreSetup) { - return {}; - } - - public start(core: CoreStart): DataStart { - return {}; - } - - public stop() {} -} diff --git a/src/legacy/core_plugins/data/public/setup.ts b/src/legacy/core_plugins/data/public/setup.ts deleted file mode 100644 index a99a2a4d06efe..0000000000000 --- a/src/legacy/core_plugins/data/public/setup.ts +++ /dev/null @@ -1,23 +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 { setup } from './legacy'; - -// for backwards compatibility with 7.3 -export const data = setup; diff --git a/src/legacy/core_plugins/input_control_vis/index.ts b/src/legacy/core_plugins/input_control_vis/index.ts index 8f6178e26126b..d67472ac4b95f 100644 --- a/src/legacy/core_plugins/input_control_vis/index.ts +++ b/src/legacy/core_plugins/input_control_vis/index.ts @@ -25,7 +25,7 @@ import { LegacyPluginApi, LegacyPluginInitializer } from '../../../../src/legacy const inputControlVisPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) => new Plugin({ id: 'input_control_vis', - require: ['kibana', 'elasticsearch', 'visualizations', 'interpreter', 'data'], + require: ['kibana', 'elasticsearch', 'visualizations', 'interpreter'], publicDir: resolve(__dirname, 'public'), uiExports: { styleSheetPaths: resolve(__dirname, 'public/index.scss'), diff --git a/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts b/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts index dae6c9abb625e..023e6ebb7125c 100644 --- a/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts +++ b/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts @@ -22,7 +22,6 @@ import { i18n } from '@kbn/i18n'; import { createInputControlVisController } from './vis_controller'; import { getControlsTab } from './components/editor/controls_tab'; import { OptionsTab } from './components/editor/options_tab'; -import { Status } from '../../visualizations/public'; import { InputControlVisDependencies } from './plugin'; import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/common'; @@ -40,7 +39,6 @@ export function createInputControlVisTypeDefinition(deps: InputControlVisDepende defaultMessage: 'Create interactive controls for easy dashboard manipulation.', }), stage: 'experimental', - requiresUpdateStatus: [Status.PARAMS, Status.TIME], feedbackMessage: defaultFeedbackMessage, visualization: InputControlVisController, visConfig: { diff --git a/src/legacy/core_plugins/input_control_vis/public/vis_controller.tsx b/src/legacy/core_plugins/input_control_vis/public/vis_controller.tsx index 624d000dd8d7a..c0ab235c1b9d1 100644 --- a/src/legacy/core_plugins/input_control_vis/public/vis_controller.tsx +++ b/src/legacy/core_plugins/input_control_vis/public/vis_controller.tsx @@ -54,7 +54,7 @@ export const createInputControlVisController = (deps: InputControlVisDependencie .subscribe(this.queryBarUpdateHandler); } - async render(visData: any, visParams: VisParams, status: any) { + async render(visData: any, visParams: VisParams) { this.visParams = visParams; this.controls = []; this.controls = await this.initControls(); diff --git a/src/legacy/core_plugins/kibana/public/.eslintrc.js b/src/legacy/core_plugins/kibana/public/.eslintrc.js index e7171a5291d26..1153706eb8566 100644 --- a/src/legacy/core_plugins/kibana/public/.eslintrc.js +++ b/src/legacy/core_plugins/kibana/public/.eslintrc.js @@ -43,8 +43,6 @@ function buildRestrictedPaths(shimmedPlugins) { 'ui/**/*', 'src/legacy/ui/**/*', 'src/legacy/core_plugins/kibana/public/**/*', - 'src/legacy/core_plugins/data/public/**/*', - '!src/legacy/core_plugins/data/public/index.ts', `!src/legacy/core_plugins/kibana/public/${shimmedPlugin}/**/*`, ], allowSameFolder: false, diff --git a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts index cf76a9355e384..d369eb9679de6 100644 --- a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts +++ b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts @@ -52,9 +52,6 @@ export { angular }; export { wrapInI18nContext } from 'ui/i18n'; import { search } from '../../../../../plugins/data/public'; export const { getRequestInspectorStats, getResponseInspectorStats, tabifyAggResponse } = search; -// @ts-ignore -// @ts-ignore -export { timezoneProvider } from 'ui/vis/lib/timezone'; export { unhashUrl, redirectWhenMissing, diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx index 107c30ec5e688..f788347ac016c 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx @@ -42,9 +42,10 @@ import { } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; +import { IUiSettingsClient } from 'kibana/public'; import { EuiChartThemeType } from '@elastic/eui/dist/eui_charts_theme'; import { Subscription } from 'rxjs'; -import { getServices, timezoneProvider } from '../../../kibana_services'; +import { getServices } from '../../../kibana_services'; export interface DiscoverHistogramProps { chartData: any; @@ -86,6 +87,16 @@ function getIntervalInMs( } } +function getTimezone(uiSettings: IUiSettingsClient) { + if (uiSettings.isDefault('dateFormat:tz')) { + const detectedTimezone = moment.tz.guess(); + if (detectedTimezone) return detectedTimezone; + else return moment().format('Z'); + } else { + return uiSettings.get('dateFormat:tz', 'Browser'); + } +} + export function findMinInterval( xValues: number[], esValue: number, @@ -193,7 +204,7 @@ export class DiscoverHistogram extends Component { if (!$scope.vis) return; - return $scope.vis.getAggConfig().onSearchRequestStart(searchSource, options); + return $scope.vis.data.aggs.onSearchRequestStart(searchSource, options); }); $scope.searchSource.setField('aggs', function() { if (!$scope.vis) return; - return $scope.vis.getAggConfig().toDsl(); + return $scope.vis.data.aggs.toDsl(); }); } diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/breadcrumbs.ts b/src/legacy/core_plugins/kibana/public/visualize/np_ready/breadcrumbs.ts index c334172805b9f..b6a63d50b205b 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/breadcrumbs.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/breadcrumbs.ts @@ -69,7 +69,7 @@ export function getEditBreadcrumbs($route: any) { return [ ...getLandingBreadcrumbs(), { - text: $route.current.locals.savedVis.title, + text: $route.current.locals.resolved.savedVis.title, }, ]; } diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.html b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.html index 28baf21925cbe..0dcacd30fba4e 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.html +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.html @@ -69,7 +69,8 @@ diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js index 7d1c29fbf48da..c5325ca3108b4 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js @@ -22,6 +22,7 @@ import _ from 'lodash'; import { Subscription } from 'rxjs'; import { map } from 'rxjs/operators'; import { i18n } from '@kbn/i18n'; +import { EventEmitter } from 'events'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -84,6 +85,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState uiSettings, I18nContext, setActiveUrl, + visualizations, } = getServices(); const { @@ -98,27 +100,63 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState ); // Retrieve the resolved SavedVis instance. - const savedVis = $route.current.locals.savedVis; + const { vis, savedVis, savedSearch, embeddableHandler } = $route.current.locals.resolved; + $scope.eventEmitter = new EventEmitter(); 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); + $scope.eventEmitter.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, savedSearch } = savedVis; + const searchSource = vis.data.searchSource; $scope.vis = vis; + $scope.savedSearch = savedSearch; const $appStatus = { dirty: !savedVis.id, }; - vis.on('dirtyStateChange', ({ isDirty }) => { - vis.dirty = isDirty; - $scope.$digest(); + const defaultQuery = { + query: '', + language: + localStorage.get('kibana.userQueryLanguage') || uiSettings.get('search:queryLanguage'), + }; + + const visStateToEditorState = () => { + const savedVisState = visualizations.convertFromSerializedVis(vis.serialize()); + return { + uiState: vis.uiState.toJSON(), + query: vis.data.searchSource.getOwnField('query') || defaultQuery, + filters: vis.data.searchSource.getOwnField('filter') || [], + vis: { ...savedVisState.visState, title: vis.title }, + linked: !!savedVis.savedSearchId, + }; + }; + + const stateDefaults = visStateToEditorState(); + + const { stateContainer, stopStateSync } = useVisualizeAppState({ + stateDefaults, + kbnUrlStateStorage, + }); + + $scope.eventEmitter.on('dirtyStateChange', ({ isDirty }) => { + if (!isDirty) { + stateContainer.transitions.updateVisState(visStateToEditorState().vis); + } + $timeout(() => { + $scope.dirty = isDirty; + }); + }); + + $scope.eventEmitter.on('updateVis', () => { + embeddableHandler.reload(); }); + $scope.embeddableHandler = embeddableHandler; + $scope.topNavMenu = [ ...(visualizeCapabilities.save ? [ @@ -135,10 +173,10 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState ), testId: 'visualizeSaveButton', disableButton() { - return Boolean(vis.dirty); + return Boolean($scope.dirty); }, tooltip() { - if (vis.dirty) { + if ($scope.dirty) { return i18n.translate( 'kbn.visualize.topNavMenu.saveVisualizationDisabledButtonTooltip', { @@ -207,7 +245,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState }), testId: 'shareTopNavButton', run: anchorElement => { - const hasUnappliedChanges = vis.dirty; + const hasUnappliedChanges = $scope.dirty; const hasUnsavedChanges = $appStatus.dirty; share.toggleShareContextMenu({ anchorElement, @@ -233,17 +271,17 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState }), testId: 'openInspectorButton', disableButton() { - return !vis.hasInspector || !vis.hasInspector(); + return !embeddableHandler.hasInspector || !embeddableHandler.hasInspector(); }, run() { - const inspectorSession = vis.openInspector(); + const inspectorSession = embeddableHandler.openInspector(); // Close the inspector if this scope is destroyed (e.g. because the user navigates away). const removeWatch = $scope.$on('$destroy', () => inspectorSession.close()); // Remove that watch in case the user closes the inspector session herself. inspectorSession.onClose.finally(removeWatch); }, tooltip() { - if (!vis.hasInspector || !vis.hasInspector()) { + if (!embeddableHandler.hasInspector || !embeddableHandler.hasInspector()) { return i18n.translate('kbn.visualize.topNavMenu.openInspectorDisabledButtonTooltip', { defaultMessage: `This visualization doesn't support any inspectors.`, }); @@ -257,7 +295,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState defaultMessage: 'Refresh', }), run: function() { - vis.forceReload(); + embeddableHandler.reload(); }, testId: 'visualizeRefreshButton', }, @@ -267,28 +305,6 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState chrome.docTitle.change(savedVis.title); } - const defaultQuery = { - query: '', - language: - localStorage.get('kibana.userQueryLanguage') || uiSettings.get('search:queryLanguage'), - }; - - // Extract visualization state with filtered aggs. You can see these filtered aggs in the URL. - // Consists of things like aggs, params, listeners, title, type, etc. - const savedVisState = vis.getState(); - const stateDefaults = { - uiState: savedVis.uiStateJSON ? JSON.parse(savedVis.uiStateJSON) : {}, - query: searchSource.getOwnField('query') || defaultQuery, - filters: searchSource.getOwnField('filter') || [], - vis: savedVisState, - linked: !!savedVis.savedSearchId, - }; - - const { stateContainer, stopStateSync } = useVisualizeAppState({ - stateDefaults, - kbnUrlStateStorage, - }); - // sync initial app filters from state to filterManager filterManager.setAppFilters(_.cloneDeep(stateContainer.getState().filters)); // setup syncing of app filters between appState and filterManager @@ -315,7 +331,8 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState // appState then they won't be equal. if (!_.isEqual(stateContainer.getState().vis, stateDefaults.vis)) { try { - vis.setState(stateContainer.getState().vis); + const { aggs, ...visState } = stateContainer.getState().vis; + vis.setState({ ...visState, data: { aggs } }); } catch (error) { // stop syncing url updtes with the state to prevent extra syncing stopAllSyncing(); @@ -369,8 +386,8 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState }; function init() { - if (vis.indexPattern) { - $scope.indexPattern = vis.indexPattern; + if (vis.data.indexPattern) { + $scope.indexPattern = vis.data.indexPattern; } else { indexPatterns.getDefault().then(defaultIndexPattern => { $scope.indexPattern = defaultIndexPattern; @@ -379,22 +396,14 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState const initialState = stateContainer.getState(); - $scope.appState = { - // mock implementation of the legacy appState.save() - // this could be even replaced by passing only "updateAppState" callback - save() { - stateContainer.transitions.updateVisState(vis.getState()); - }, - }; - const handleLinkedSearch = linked => { if (linked && !savedVis.savedSearchId && savedSearch) { savedVis.savedSearchId = savedSearch.id; - vis.savedSearchId = savedSearch.id; + vis.data.savedSearchId = savedSearch.id; searchSource.setParent(savedSearch.searchSource); } else if (!linked && savedVis.savedSearchId) { delete savedVis.savedSearchId; - delete vis.savedSearchId; + delete vis.data.savedSearchId; } }; @@ -403,6 +412,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState 'uiState', stateContainer ); + vis.uiState = persistedState; $scope.uiState = persistedState; $scope.savedVis = savedVis; $scope.query = initialState.query; @@ -427,7 +437,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState $scope.showQueryBarTimePicker = () => { // tsvb loads without an indexPattern initially (TODO investigate). // hide timefilter only if timeFieldName is explicitly undefined. - const hasTimeField = vis.indexPattern ? !!vis.indexPattern.timeFieldName : true; + const hasTimeField = vis.data.indexPattern ? !!vis.data.indexPattern.timeFieldName : true; return vis.type.options.showTimePicker && hasTimeField; }; @@ -442,10 +452,24 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState updateSavedQueryFromUrl(state.savedQuery); // if the browser history was changed manually we need to reflect changes in the editor - if (!_.isEqual(vis.getState(), state.vis)) { - vis.setState(state.vis); - vis.forceReload(); - vis.emit('updateEditor'); + if ( + !_.isEqual( + { + ...visualizations.convertFromSerializedVis(vis.serialize()).visState, + title: vis.title, + }, + state.vis + ) + ) { + const { aggs, ...visState } = state.vis; + vis.setState({ + ...visState, + data: { + aggs, + }, + }); + embeddableHandler.reload(); + $scope.eventEmitter.emit('updateEditor'); } $appStatus.dirty = true; @@ -498,8 +522,8 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState const { query, linked, filters } = stateContainer.getState(); $scope.query = query; handleLinkedSearch(linked); - savedVis.searchSource.setField('query', query); - savedVis.searchSource.setField('filter', filters); + vis.data.searchSource.setField('query', query); + vis.data.searchSource.setField('filter', filters); $scope.$broadcast('render'); }; @@ -533,7 +557,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState } savedVis.destroy(); subscriptions.unsubscribe(); - $scope.vis.off('apply', _applyVis); + $scope.eventEmitter.off('apply', _applyVis); unsubscribePersisted(); unsubscribeStateUpdates(); @@ -556,7 +580,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState // If nothing has changed, trigger the fetch manually, otherwise it will happen as a result of the changes if (!isUpdate) { - $scope.vis.forceReload(); + embeddableHandler.reload(); } }; @@ -605,8 +629,10 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState title: savedVis.title, type: savedVis.type || stateContainer.getState().vis.type, }); + savedVis.searchSource.setField('query', stateContainer.getState().query); + savedVis.searchSource.setField('filter', stateContainer.getState().filters); savedVis.visState = stateContainer.getState().vis; - savedVis.uiStateJSON = angular.toJson($scope.uiState.getChanges()); + savedVis.uiStateJSON = angular.toJson($scope.uiState.toJSON()); $appStatus.dirty = false; return savedVis.save(saveOptions).then( @@ -720,7 +746,7 @@ function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlState ); }; - vis.on('unlinkFromSavedSearch', unlinkFromSavedSearch); + $scope.eventEmitter.on('unlinkFromSavedSearch', unlinkFromSavedSearch); addHelpMenuToAppChrome(chrome, docLinks); diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js index c8acea168444f..fbabd6fc87c98 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js @@ -17,12 +17,12 @@ * under the License. */ -export function initVisualizationDirective(app, deps) { +export function initVisualizationDirective(app) { app.directive('visualizationEmbedded', function($timeout) { return { restrict: 'E', scope: { - savedObj: '=', + embeddableHandler: '=', uiState: '=?', timeRange: '=', filters: '=', @@ -31,24 +31,16 @@ export function initVisualizationDirective(app, deps) { }, link: function($scope, element) { $scope.renderFunction = async () => { - if (!$scope._handler) { - $scope._handler = await deps.embeddable - .getEmbeddableFactory('visualization') - .createFromObject($scope.savedObj, { - timeRange: $scope.timeRange, - filters: $scope.filters || [], - query: $scope.query, - appState: $scope.appState, - uiState: $scope.uiState, - }); - $scope._handler.render(element[0]); - } else { - $scope._handler.updateInput({ - timeRange: $scope.timeRange, - filters: $scope.filters || [], - query: $scope.query, - }); + if (!$scope.rendered) { + $scope.embeddableHandler.render(element[0]); + $scope.rendered = true; } + + $scope.embeddableHandler.updateInput({ + timeRange: $scope.timeRange, + filters: $scope.filters || [], + query: $scope.query, + }); }; $scope.$on('render', event => { @@ -59,8 +51,8 @@ export function initVisualizationDirective(app, deps) { }); $scope.$on('$destroy', () => { - if ($scope._handler) { - $scope._handler.destroy(); + if ($scope.embeddableHandler) { + $scope.embeddableHandler.destroy(); } }); }, diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js index f2d9cbe2ad84c..ef174dbaa5865 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js @@ -22,16 +22,23 @@ export function initVisEditorDirective(app, deps) { return { restrict: 'E', scope: { - savedObj: '=', + vis: '=', uiState: '=?', timeRange: '=', filters: '=', query: '=', - appState: '=', + savedSearch: '=', + embeddableHandler: '=', + eventEmitter: '=', }, link: function($scope, element) { - const Editor = $scope.savedObj.vis.type.editor || deps.DefaultVisualizationEditor; - const editor = new Editor(element[0], $scope.savedObj); + const Editor = $scope.vis.type.editor || deps.DefaultVisualizationEditor; + const editor = new Editor( + element[0], + $scope.vis, + $scope.eventEmitter, + $scope.embeddableHandler + ); $scope.renderFunction = () => { editor.render({ @@ -42,8 +49,8 @@ export function initVisEditorDirective(app, deps) { timeRange: $scope.timeRange, filters: $scope.filters, query: $scope.query, - appState: $scope.appState, - linked: !!$scope.savedObj.savedSearchId, + linked: !!$scope.vis.data.savedSearchId, + savedSearch: $scope.savedSearch, }); }; diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js index 0f1d50b149cd9..b0b1ae31a02a5 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js @@ -40,6 +40,50 @@ import { getCreateBreadcrumbs, getEditBreadcrumbs, } from './breadcrumbs'; +import { createSavedSearchesLoader } from '../../../../../../plugins/discover/public'; + +const getResolvedResults = deps => { + const { core, data, visualizations } = deps; + + const results = {}; + + return savedVis => { + results.savedVis = savedVis; + return visualizations + .convertToSerializedVis(savedVis) + .then(serializedVis => visualizations.createVis(serializedVis.type, serializedVis)) + .then(vis => { + if (vis.type.setup) { + return vis.type.setup(vis).catch(() => vis); + } + return vis; + }) + .then(vis => { + results.vis = vis; + return deps.embeddable.getEmbeddableFactory('visualization').createFromObject(results.vis, { + timeRange: data.query.timefilter.timefilter.getTime(), + filters: data.query.filterManager.getFilters(), + }); + }) + .then(embeddableHandler => { + results.embeddableHandler = embeddableHandler; + if (results.vis.data.savedSearchId) { + return createSavedSearchesLoader({ + savedObjectsClient: core.savedObjects.client, + indexPatterns: data.indexPatterns, + chrome: core.chrome, + overlays: core.overlays, + }).get(results.vis.data.savedSearchId); + } + }) + .then(savedSearch => { + if (savedSearch) { + results.savedSearch = savedSearch; + } + return results; + }); + }; +}; export function initVisualizeApp(app, deps) { initVisualizeAppDirective(app, deps); @@ -101,7 +145,7 @@ export function initVisualizeApp(app, deps) { template: editorTemplate, k7Breadcrumbs: getCreateBreadcrumbs, resolve: { - savedVis: function($route, history) { + resolved: function($route, history) { const { core, data, savedVisualizations, visualizations, toastNotifications } = deps; const visTypes = visualizations.all(); const visType = find(visTypes, { name: $route.current.params.type }); @@ -121,12 +165,7 @@ export function initVisualizeApp(app, deps) { return ensureDefaultIndexPattern(core, data, history) .then(() => savedVisualizations.get($route.current.params)) - .then(savedVis => { - if (savedVis.vis.type.setup) { - return savedVis.vis.type.setup(savedVis).catch(() => savedVis); - } - return savedVis; - }) + .then(getResolvedResults(deps)) .catch( redirectWhenMissing({ history, @@ -142,20 +181,16 @@ export function initVisualizeApp(app, deps) { template: editorTemplate, k7Breadcrumbs: getEditBreadcrumbs, resolve: { - savedVis: function($route, history) { + resolved: function($route, history) { const { chrome, core, data, savedVisualizations, toastNotifications } = deps; + return ensureDefaultIndexPattern(core, data, history) .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; - }) + .then(getResolvedResults(deps)) .catch( redirectWhenMissing({ history, diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/types.d.ts b/src/legacy/core_plugins/kibana/public/visualize/np_ready/types.d.ts index 01ce872aeb679..246a031f05769 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/types.d.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/types.d.ts @@ -29,8 +29,10 @@ import { PersistedState } from 'src/plugins/visualizations/public'; import { LegacyCoreStart } from 'kibana/public'; import { Vis } from 'src/legacy/core_plugins/visualizations/public'; import { VisSavedObject } from '../legacy_imports'; +import { SavedVisState } from '../../../../visualizations/public/np_ready/public/types'; +import { SavedSearch } from '../../../../../../plugins/discover/public'; -export type PureVisState = ReturnType; +export type PureVisState = SavedVisState; export interface VisualizeAppState { filters: Filter[]; @@ -58,14 +60,13 @@ export interface VisualizeAppStateTransitions { } export interface EditorRenderProps { - appState: { save(): void }; core: LegacyCoreStart; data: DataPublicPluginStart; - embeddable: EmbeddableStart; filters: Filter[]; - uiState: PersistedState; timeRange: TimeRange; query?: Query; + savedSearch?: SavedSearch; + uiState: PersistedState; /** * Flag to determine if visualiztion is linked to the saved search */ diff --git a/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js b/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js index 6bdb5d00e67d8..23ca99791e92e 100644 --- a/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js +++ b/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js @@ -21,7 +21,6 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; import ChoroplethLayer from '../choropleth_layer'; -import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; import { ImageComparator } from 'test_utils/image_comparator'; import worldJson from './world.json'; import EMS_CATALOGUE from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_manifest.json'; @@ -38,13 +37,11 @@ import afterdatachangePng from './afterdatachange.png'; import afterdatachangeandresizePng from './afterdatachangeandresize.png'; import aftercolorchangePng from './aftercolorchange.png'; import changestartupPng from './changestartup.png'; -import { - setup as visualizationsSetup, - start as visualizationsStart, -} from '../../../visualizations/public/np_ready/public/legacy'; +import { setup as visualizationsSetup } from '../../../visualizations/public/np_ready/public/legacy'; import { createRegionMapVisualization } from '../region_map_visualization'; import { createRegionMapTypeDefinition } from '../region_map_type'; +import { ExprVis } from '../../../visualizations/public/np_ready/public/expressions/vis'; const THRESHOLD = 0.45; const PIXEL_DIFF = 96; @@ -52,7 +49,6 @@ const PIXEL_DIFF = 96; describe('RegionMapsVisualizationTests', function() { let domNode; let RegionMapsVisualization; - let indexPattern; let vis; let dependencies; @@ -115,7 +111,6 @@ describe('RegionMapsVisualizationTests', function() { } RegionMapsVisualization = createRegionMapVisualization(dependencies); - indexPattern = Private(LogstashIndexPatternStubProvider); ChoroplethLayer.prototype._makeJsonAjaxCall = async function() { //simulate network call @@ -158,7 +153,7 @@ describe('RegionMapsVisualizationTests', function() { imageComparator = new ImageComparator(); - vis = visualizationsStart.createVis(indexPattern, { + vis = new ExprVis({ type: 'region_map', }); diff --git a/src/legacy/core_plugins/region_map/public/region_map_type.js b/src/legacy/core_plugins/region_map/public/region_map_type.js index 9a1a76362e094..4faa3f92abb5a 100644 --- a/src/legacy/core_plugins/region_map/public/region_map_type.js +++ b/src/legacy/core_plugins/region_map/public/region_map_type.js @@ -20,7 +20,6 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { mapToLayerWithId } from './util'; import { createRegionMapVisualization } from './region_map_visualization'; -import { Status } from '../../visualizations/public'; import { RegionMapOptions } from './components/region_map_options'; import { truncatedColorSchemas } from '../../../../plugins/charts/public'; import { Schemas } from '../../vis_default_editor/public'; @@ -55,7 +54,6 @@ provided base maps, or add your own. Darker colors represent higher values.', showAllShapes: true, //still under consideration }, }, - requiresUpdateStatus: [Status.AGGS, Status.PARAMS, Status.RESIZE, Status.DATA, Status.UI_STATE], visualization, editorConfig: { optionsTemplate: props => , @@ -100,9 +98,7 @@ provided base maps, or add your own. Darker colors represent higher values.', }, ]), }, - setup: async savedVis => { - const vis = savedVis.vis; - + setup: async vis => { const tmsLayers = await serviceSettings.getTMSServices(); vis.type.editorConfig.collections.tmsLayers = tmsLayers; if (!vis.params.wms.selectedTmsLayer && tmsLayers.length) { @@ -146,7 +142,7 @@ provided base maps, or add your own. Darker colors represent higher values.', vis.params.selectedJoinField = selectedJoinField; } - return savedVis; + return vis; }, }; } diff --git a/src/legacy/core_plugins/region_map/public/region_map_visualization.js b/src/legacy/core_plugins/region_map/public/region_map_visualization.js index 8b5812052a395..25641ea76809d 100644 --- a/src/legacy/core_plugins/region_map/public/region_map_visualization.js +++ b/src/legacy/core_plugins/region_map/public/region_map_visualization.js @@ -39,8 +39,8 @@ export function createRegionMapVisualization({ serviceSettings, $injector, uiSet this._choroplethLayer = null; } - async render(esResponse, visParams, status) { - await super.render(esResponse, visParams, status); + async render(esResponse, visParams) { + await super.render(esResponse, visParams); if (this._choroplethLayer) { await this._choroplethLayer.whenDataLoaded(); } diff --git a/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js b/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js index 6a08405b5b6a5..3b8a7dfbed313 100644 --- a/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js +++ b/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js @@ -19,7 +19,6 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; import { ImageComparator } from 'test_utils/image_comparator'; import dummyESResponse from './dummy_es_response.json'; import initial from './initial.png'; @@ -32,13 +31,11 @@ import EMS_TILES from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_ import EMS_STYLE_ROAD_MAP_BRIGHT from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_bright'; import EMS_STYLE_ROAD_MAP_DESATURATED from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_desaturated'; import EMS_STYLE_DARK_MAP from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_dark'; -import { - setup as visualizationsSetup, - start as visualizationsStart, -} from '../../../visualizations/public/np_ready/public/legacy'; +import { setup as visualizationsSetup } from '../../../visualizations/public/np_ready/public/legacy'; import { createTileMapVisualization } from '../tile_map_visualization'; import { createTileMapTypeDefinition } from '../tile_map_type'; +import { ExprVis } from '../../../visualizations/public/np_ready/public/expressions/vis'; function mockRawData() { const stack = [dummyESResponse]; @@ -67,7 +64,6 @@ let visRegComplete = false; describe('CoordinateMapsVisualizationTest', function() { let domNode; let CoordinateMapsVisualization; - let indexPattern; let vis; let dependencies; @@ -92,7 +88,6 @@ describe('CoordinateMapsVisualizationTest', function() { } CoordinateMapsVisualization = createTileMapVisualization(dependencies); - indexPattern = Private(LogstashIndexPatternStubProvider); getManifestStub = serviceSettings.__debugStubManifestCalls(async url => { //simulate network calls @@ -124,7 +119,7 @@ describe('CoordinateMapsVisualizationTest', function() { setupDOM('512px', '512px'); imageComparator = new ImageComparator(); - vis = visualizationsStart.createVis(indexPattern, { + vis = new ExprVis({ type: 'tile_map', }); vis.params = { diff --git a/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js b/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js index ebb0c24243263..d38159c91ef9f 100644 --- a/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js +++ b/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js @@ -63,28 +63,21 @@ export function BaseMapsVisualizationProvider(serviceSettings) { * @param status * @return {Promise} */ - async render(esResponse, visParams, status) { + async render(esResponse, visParams) { if (!this._kibanaMap) { //the visualization has been destroyed; return; } await this._mapIsLoaded; - - if (status.resize) { - this._kibanaMap.resize(); - } - if (status.params || status.aggs) { - this._params = visParams; - await this._updateParams(); - } + this._kibanaMap.resize(); + this._params = visParams; + await this._updateParams(); if (this._hasESResponseChanged(esResponse)) { await this._updateData(esResponse); } - if (status.uiState) { - this._kibanaMap.useUiStateFromVisualization(this.vis); - } + this._kibanaMap.useUiStateFromVisualization(this.vis); await this._whenBaseLayerIsLoaded(); } diff --git a/src/legacy/core_plugins/tile_map/public/tile_map_type.js b/src/legacy/core_plugins/tile_map/public/tile_map_type.js index 0809bf6ecbab6..39d39a4c8f8fc 100644 --- a/src/legacy/core_plugins/tile_map/public/tile_map_type.js +++ b/src/legacy/core_plugins/tile_map/public/tile_map_type.js @@ -23,7 +23,6 @@ import { i18n } from '@kbn/i18n'; import { convertToGeoJson } from 'ui/vis/map/convert_to_geojson'; import { Schemas } from '../../vis_default_editor/public'; -import { Status } from '../../visualizations/public'; import { createTileMapVisualization } from './tile_map_visualization'; import { TileMapOptions } from './components/tile_map_options'; import { MapTypes } from './map_types'; @@ -57,7 +56,6 @@ export function createTileMapTypeDefinition(dependencies) { wms: uiSettings.get('visualization:tileMap:WMSdefaults'), }, }, - requiresUpdateStatus: [Status.AGGS, Status.PARAMS, Status.RESIZE, Status.UI_STATE], requiresPartialRows: true, visualization: CoordinateMapsVisualization, responseHandler: convertToGeoJson, @@ -143,21 +141,20 @@ export function createTileMapTypeDefinition(dependencies) { }, ]), }, - setup: async savedVis => { - const vis = savedVis.vis; + setup: async vis => { let tmsLayers; try { tmsLayers = await serviceSettings.getTMSServices(); } catch (e) { - return savedVis; + return vis; } vis.type.editorConfig.collections.tmsLayers = tmsLayers; if (!vis.params.wms.selectedTmsLayer && tmsLayers.length) { vis.params.wms.selectedTmsLayer = tmsLayers[0]; } - return savedVis; + return vis; }, }; } diff --git a/src/legacy/core_plugins/timelion/index.ts b/src/legacy/core_plugins/timelion/index.ts index 9e2bfd4023bd9..41a15dc4e0186 100644 --- a/src/legacy/core_plugins/timelion/index.ts +++ b/src/legacy/core_plugins/timelion/index.ts @@ -29,7 +29,7 @@ const experimentalLabel = i18n.translate('timelion.uiSettings.experimentalLabel' const timelionPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) => new Plugin({ - require: ['kibana', 'elasticsearch', 'data'], + require: ['kibana', 'elasticsearch'], config(Joi: any) { return Joi.object({ enabled: Joi.boolean().default(true), diff --git a/src/legacy/core_plugins/timelion/public/app.js b/src/legacy/core_plugins/timelion/public/app.js index a9d678cfea79c..a50f8a2cd3e8d 100644 --- a/src/legacy/core_plugins/timelion/public/app.js +++ b/src/legacy/core_plugins/timelion/public/app.js @@ -24,10 +24,10 @@ import { i18n } from '@kbn/i18n'; import { capabilities } from 'ui/capabilities'; import { docTitle } from 'ui/doc_title'; import { fatalError, toastNotifications } from 'ui/notify'; -import { timezoneProvider } from 'ui/vis/lib/timezone'; import { timefilter } from 'ui/timefilter'; import { npStart } from 'ui/new_platform'; import { getSavedSheetBreadcrumbs, getCreateBreadcrumbs } from './breadcrumbs'; +import { getTimezone } from '../../vis_type_timelion/public'; import 'uiExports/savedObjectTypes'; @@ -38,7 +38,6 @@ import 'ui/directives/input_focus'; import './directives/saved_object_finder'; import 'ui/directives/listen'; import './directives/saved_object_save_as_checkbox'; -import '../../data/public/legacy'; import './services/saved_sheet_register'; import rootTemplate from 'plugins/timelion/index.html'; @@ -116,8 +115,7 @@ app.controller('timelion', function( $timeout, AppState, config, - kbnUrl, - Private + kbnUrl ) { // Keeping this at app scope allows us to keep the current page when the user // switches to say, the timepicker. @@ -128,7 +126,7 @@ app.controller('timelion', function( timefilter.enableTimeRangeSelector(); const savedVisualizations = visualizations.savedVisualizationsLoader; - const timezone = Private(timezoneProvider)(); + const timezone = getTimezone(config); const defaultExpression = '.es(*)'; const savedSheet = $route.current.locals.savedSheet; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx index 7e715be25bff3..feb5b3caa023b 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx @@ -22,12 +22,12 @@ import { mount, shallow } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { IndexPattern, IAggType, AggGroupNames } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { DefaultEditorAgg, DefaultEditorAggProps } from './agg'; import { DefaultEditorAggParams } from './agg_params'; import { AGGS_ACTION_KEYS } from './agg_group_state'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; jest.mock('./agg_params', () => ({ DefaultEditorAggParams: () => null, @@ -67,7 +67,7 @@ describe('DefaultEditorAgg component', () => { isLastBucket: false, isRemovable: false, metricAggs: [], - state: { params: {} } as VisState, + state: { params: {} } as EditorVisState, setAggParamValue, setStateParamValue, onAggTypeChange: () => {}, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts index ec92f511b6eee..3aae10879138a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts @@ -17,9 +17,10 @@ * under the License. */ -import { VisState, VisParams } from 'src/legacy/core_plugins/visualizations/public'; +import { VisParams } from 'src/legacy/core_plugins/visualizations/public'; import { IAggType, IAggConfig, IAggGroupNames } from 'src/plugins/data/public'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; type AggId = IAggConfig['id']; type AggParams = IAggConfig['params']; @@ -31,7 +32,7 @@ export interface DefaultEditorCommonProps { formIsTouched: boolean; groupName: IAggGroupNames; metricAggs: IAggConfig[]; - state: VisState; + state: EditorVisState; setAggParamValue: ( aggId: AggId, paramName: T, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx index 63f5e696c99f4..5d02f0a2c759e 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx @@ -20,12 +20,12 @@ import React from 'react'; import { mount, shallow } from 'enzyme'; import { act } from 'react-dom/test-utils'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { IAggConfigs, IAggConfig } from 'src/plugins/data/public'; import { DefaultEditorAggGroup, DefaultEditorAggGroupProps } from './agg_group'; import { DefaultEditorAgg } from './agg'; import { DefaultEditorAggAdd } from './agg_add'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; jest.mock('@elastic/eui', () => ({ EuiTitle: 'eui-title', @@ -93,8 +93,8 @@ describe('DefaultEditorAgg component', () => { metricAggs: [], groupName: 'metrics', state: { - aggs, - } as VisState, + data: { aggs }, + } as EditorVisState, schemas: [ { name: 'metrics', @@ -147,8 +147,8 @@ describe('DefaultEditorAgg component', () => { }); expect(reorderAggs).toHaveBeenCalledWith( - defaultProps.state.aggs.aggs[0], - defaultProps.state.aggs.aggs[1] + defaultProps.state.data.aggs!.aggs[0], + defaultProps.state.data.aggs!.aggs[1] ); }); diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx index 600612f2cf9d8..08b69ef37f528 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx @@ -73,9 +73,10 @@ function DefaultEditorAggGroup({ const schemaNames = getSchemasByGroup(schemas, groupName).map(s => s.name); const group: IAggConfig[] = useMemo( () => - state.aggs.aggs.filter((agg: IAggConfig) => agg.schema && schemaNames.includes(agg.schema)) || - [], - [state.aggs.aggs, schemaNames] + state.data.aggs!.aggs.filter( + (agg: IAggConfig) => agg.schema && schemaNames.includes(agg.schema) + ) || [], + [state.data.aggs, schemaNames] ); const stats = { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts index 7c2852798b403..aec332e8674d7 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts @@ -18,10 +18,10 @@ */ import { IAggConfig, AggParam, IndexPatternField } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { ComboBoxGroupedOptions } from '../utils'; import { EditorConfig } from './utils'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; // NOTE: we cannot export the interface with export { InterfaceName } // as there is currently a bug on babel typescript transform plugin for it @@ -35,7 +35,7 @@ export interface AggParamCommonProps { formIsTouched: boolean; indexedFields?: ComboBoxGroupedOptions; showValidation: boolean; - state: VisState; + state: EditorVisState; value?: T; metricAggs: IAggConfig[]; schemas: Schema[]; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx index cd6486b6a1532..1c49ebf40640e 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx @@ -20,7 +20,6 @@ import React from 'react'; import { mount } from 'enzyme'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { IndexPattern, IAggConfig, AggGroupNames } from 'src/plugins/data/public'; import { DefaultEditorAggParams as PureDefaultEditorAggParams, @@ -28,6 +27,7 @@ import { } from './agg_params'; import { KibanaContextProvider } from '../../../../../plugins/kibana_react/public'; import { dataPluginMock } from '../../../../../plugins/data/public/mocks'; +import { EditorVisState } from './sidebar/state/reducers'; const mockEditorConfig = { useNormalizedEsInterval: { hidden: false, fixedValue: false }, @@ -108,7 +108,7 @@ describe('DefaultEditorAggParams component', () => { formIsTouched: false, indexPattern: {} as IndexPattern, metricAggs: [], - state: {} as VisState, + state: {} as EditorVisState, setAggParamValue, onAggTypeChange, setTouched, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts index f2ebbdc87a60a..bed2561341737 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts @@ -25,7 +25,6 @@ import { IndexPattern, IndexPatternField, } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { getAggParamsToRender, getAggTypeOptions, @@ -34,6 +33,7 @@ import { import { FieldParamEditor, OrderByParamEditor } from './controls'; import { EditorConfig } from './utils'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; jest.mock('../utils', () => ({ groupAndSortBy: jest.fn(() => ['indexedFields']), @@ -58,7 +58,7 @@ describe('DefaultEditorAggParams helpers', () => { hideCustomLabel: true, } as Schema, ]; - const state = {} as VisState; + const state = {} as EditorVisState; const metricAggs: IAggConfig[] = []; const emptyParams = { basic: [], diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts index e07bf81697579..10590e1a59f4a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts @@ -28,7 +28,6 @@ import { IndexPattern, IndexPatternField, } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { groupAndSortBy, ComboBoxGroupedOptions } from '../utils'; import { AggTypeState, AggParamsState } from './agg_params_state'; import { AggParamEditorProps } from './agg_param_props'; @@ -36,12 +35,13 @@ import { aggParamsMap } from './agg_params_map'; import { EditorConfig } from './utils'; import { Schema, getSchemaByName } from '../schemas'; import { search } from '../../../../../plugins/data/public'; +import { EditorVisState } from './sidebar/state/reducers'; interface ParamInstanceBase { agg: IAggConfig; editorConfig: EditorConfig; metricAggs: IAggConfig[]; - state: VisState; + state: EditorVisState; schemas: Schema[]; hideCustomLabel?: boolean; } diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx index 1043431475494..b33149dc51a19 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx @@ -23,9 +23,9 @@ import { mount, shallow, ReactWrapper } from 'enzyme'; import { EuiComboBoxProps, EuiComboBox } from '@elastic/eui'; import { IAggConfig, IndexPatternField } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { ComboBoxGroupedOptions } from '../../utils'; import { FieldParamEditor, FieldParamEditorProps } from './field'; +import { EditorVisState } from '../sidebar/state/reducers'; function callComboBoxOnChange(comp: ReactWrapper, value: any = []) { const comboBoxProps = comp.find(EuiComboBox).props() as EuiComboBoxProps; @@ -78,7 +78,7 @@ describe('FieldParamEditor component', () => { setValue, setValidity, setTouched, - state: {} as VisState, + state: {} as EditorVisState, metricAggs: [] as IAggConfig[], schemas: [], }; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx index 76eb12af8c4e2..82166440cf8e8 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx @@ -20,9 +20,9 @@ import React from 'react'; import { AggParamEditorProps } from '../agg_param_props'; import { IAggConfig } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { mount } from 'enzyme'; import { PercentilesEditor } from './percentiles'; +import { EditorVisState } from '../sidebar/state/reducers'; describe('PercentilesEditor component', () => { let setValue: jest.Mock; @@ -45,7 +45,7 @@ describe('PercentilesEditor component', () => { setValue, setValidity, setTouched, - state: {} as VisState, + state: {} as EditorVisState, metricAggs: [] as IAggConfig[], schemas: [], }; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts b/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts index b816e61cce355..7c7431015d175 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts @@ -17,9 +17,9 @@ * under the License. */ -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { IAggConfig, AggParam } from 'src/plugins/data/public'; import { EditorConfig } from '../utils'; +import { EditorVisState } from '../sidebar/state/reducers'; export const aggParamCommonPropsMock = { agg: {} as IAggConfig, @@ -27,7 +27,7 @@ export const aggParamCommonPropsMock = { editorConfig: {} as EditorConfig, formIsTouched: false, metricAggs: [] as IAggConfig[], - state: {} as VisState, + state: {} as EditorVisState, showValidation: false, schemas: [], }; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx index 6f92c27e90ec1..a6a1980210be4 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx @@ -21,7 +21,6 @@ import React, { useMemo, useCallback } from 'react'; import { findLast } from 'lodash'; import { EuiSpacer } from '@elastic/eui'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { AggGroupNames, IAggConfig, @@ -40,6 +39,7 @@ import { } from './state'; import { AddSchema, ReorderAggs, DefaultEditorAggCommonProps } from '../agg_common_props'; import { ISchemas } from '../../schemas'; +import { EditorVisState } from './state/reducers'; export interface DefaultEditorDataTabProps { dispatch: React.Dispatch; @@ -47,7 +47,7 @@ export interface DefaultEditorDataTabProps { isTabSelected: boolean; metricAggs: IAggConfig[]; schemas: ISchemas; - state: VisState; + state: EditorVisState; setTouched(isTouched: boolean): void; setValidity(modelName: string, value: boolean): void; setStateValue: DefaultEditorAggCommonProps['setStateParamValue']; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx index 2508ef3a55537..04c931f593e5a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx @@ -21,6 +21,7 @@ import React, { useMemo, useState, useCallback, KeyboardEventHandler, useEffect import { get, isEqual } from 'lodash'; import { i18n } from '@kbn/i18n'; import { keyCodes, EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EventEmitter } from 'events'; import { Vis } from 'src/legacy/core_plugins/visualizations/public'; import { DefaultEditorNavBar, OptionTab } from './navbar'; @@ -40,6 +41,7 @@ interface DefaultEditorSideBarProps { uiState: PersistedState; vis: Vis; isLinkedSearch: boolean; + eventEmitter: EventEmitter; savedSearch?: SavedSearch; } @@ -50,14 +52,17 @@ function DefaultEditorSideBar({ uiState, vis, isLinkedSearch, + eventEmitter, savedSearch, }: DefaultEditorSideBarProps) { const [selectedTab, setSelectedTab] = useState(optionTabs[0].name); const [isDirty, setDirty] = useState(false); - const [state, dispatch] = useEditorReducer(vis); + const [state, dispatch] = useEditorReducer(vis, eventEmitter); const { formState, setTouched, setValidity, resetValidity } = useEditorFormState(); - const responseAggs = useMemo(() => state.aggs.getResponseAggs(), [state.aggs]); + const responseAggs = useMemo(() => (state.data.aggs ? state.data.aggs.getResponseAggs() : []), [ + state.data.aggs, + ]); const metricSchemas = getSchemasByGroup(vis.type.schemas.all || [], AggGroupNames.Metrics).map( s => s.name ); @@ -90,17 +95,20 @@ function DefaultEditorSideBar({ const applyChanges = useCallback(() => { if (formState.invalid || !isDirty) { setTouched(true); - return; } - vis.setCurrentState(state); - vis.updateState(); - vis.emit('dirtyStateChange', { + vis.setState({ + ...vis.serialize(), + params: state.params, + data: { aggs: state.data.aggs ? (state.data.aggs.aggs.map(agg => agg.toJSON()) as any) : [] }, + }); + eventEmitter.emit('updateVis'); + eventEmitter.emit('dirtyStateChange', { isDirty: false, }); setTouched(false); - }, [vis, state, formState.invalid, setTouched, isDirty]); + }, [vis, state, formState.invalid, setTouched, isDirty, eventEmitter]); const onSubmit: KeyboardEventHandler = useCallback( event => { @@ -122,18 +130,22 @@ function DefaultEditorSideBar({ resetValidity(); } }; - vis.on('dirtyStateChange', changeHandler); + eventEmitter.on('dirtyStateChange', changeHandler); - return () => vis.off('dirtyStateChange', changeHandler); - }, [resetValidity, vis]); + return () => { + eventEmitter.off('dirtyStateChange', changeHandler); + }; + }, [resetValidity, eventEmitter]); // subscribe on external vis changes using browser history, for example press back button useEffect(() => { const resetHandler = () => dispatch(discardChanges(vis)); - vis.on('updateEditor', resetHandler); + eventEmitter.on('updateEditor', resetHandler); - return () => vis.off('updateEditor', resetHandler); - }, [dispatch, vis]); + return () => { + eventEmitter.off('updateEditor', resetHandler); + }; + }, [dispatch, vis, eventEmitter]); const dataTabProps = { dispatch, @@ -147,7 +159,7 @@ function DefaultEditorSideBar({ }; const optionTabProps = { - aggs: state.aggs, + aggs: state.data.aggs!, hasHistogramAgg, stateParams: state.params, vis, @@ -173,7 +185,12 @@ function DefaultEditorSideBar({ onKeyDownCapture={onSubmit} > {vis.type.requiresSearch && ( - + )} {optionTabs.length > 1 && ( diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx index 876404851aed4..575ad5ae2a95c 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx @@ -18,6 +18,7 @@ */ import React, { useCallback, useState } from 'react'; +import { EventEmitter } from 'events'; import { EuiButton, EuiButtonEmpty, @@ -39,23 +40,24 @@ import { SavedSearch } from '../../../../../../plugins/discover/public'; interface LinkedSearchProps { savedSearch: SavedSearch; - vis: Vis; + eventEmitter: EventEmitter; } interface SidebarTitleProps { isLinkedSearch: boolean; savedSearch?: SavedSearch; vis: Vis; + eventEmitter: EventEmitter; } -export function LinkedSearch({ savedSearch, vis }: LinkedSearchProps) { +export function LinkedSearch({ savedSearch, eventEmitter }: LinkedSearchProps) { const [showPopover, setShowPopover] = useState(false); const closePopover = useCallback(() => setShowPopover(false), []); const onClickButtonLink = useCallback(() => setShowPopover(v => !v), []); const onClickUnlikFromSavedSearch = useCallback(() => { setShowPopover(false); - vis.emit('unlinkFromSavedSearch'); - }, [vis]); + eventEmitter.emit('unlinkFromSavedSearch'); + }, [eventEmitter]); const linkButtonAriaLabel = i18n.translate( 'visDefaultEditor.sidebar.savedSearch.linkButtonAriaLabel', @@ -151,20 +153,20 @@ export function LinkedSearch({ savedSearch, vis }: LinkedSearchProps) { ); } -function SidebarTitle({ savedSearch, vis, isLinkedSearch }: SidebarTitleProps) { +function SidebarTitle({ savedSearch, vis, isLinkedSearch, eventEmitter }: SidebarTitleProps) { return isLinkedSearch && savedSearch ? ( - + ) : vis.type.options.showIndexSelection ? (

- {vis.indexPattern.title} + {vis.data.indexPattern!.title}

) : ( diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts index 6383ac866dcfc..11cbc3f93e9d3 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts @@ -17,20 +17,23 @@ * under the License. */ -import { useEffect, useReducer, useCallback } from 'react'; -import { isEqual } from 'lodash'; +import { useReducer, useCallback } from 'react'; +import { EventEmitter } from 'events'; -import { Vis, VisState, VisParams } from 'src/legacy/core_plugins/visualizations/public'; -import { createEditorStateReducer, initEditorState } from './reducers'; +import { Vis } from 'src/legacy/core_plugins/visualizations/public'; +import { createEditorStateReducer, initEditorState, EditorVisState } from './reducers'; import { EditorStateActionTypes } from './constants'; -import { EditorAction, updateStateParams } from './actions'; +import { EditorAction } from './actions'; import { useKibana } from '../../../../../../../plugins/kibana_react/public'; import { VisDefaultEditorKibanaServices } from '../../../types'; export * from './editor_form_state'; export * from './actions'; -export function useEditorReducer(vis: Vis): [VisState, React.Dispatch] { +export function useEditorReducer( + vis: Vis, + eventEmitter: EventEmitter +): [EditorVisState, React.Dispatch] { const { services } = useKibana(); const [state, dispatch] = useReducer( createEditorStateReducer(services.data.search), @@ -38,28 +41,15 @@ export function useEditorReducer(vis: Vis): [VisState, React.Dispatch { - const handleVisUpdate = (params: VisParams) => { - if (!isEqual(params, state.params)) { - dispatch(updateStateParams(params)); - } - }; - - // fires when visualization state changes, and we need to copy changes to editorState - vis.on('updateEditorStateParams', handleVisUpdate); - - return () => vis.off('updateEditorStateParams', handleVisUpdate); - }, [vis, state.params]); - const wrappedDispatch = useCallback( (action: EditorAction) => { dispatch(action); - vis.emit('dirtyStateChange', { + eventEmitter.emit('dirtyStateChange', { isDirty: action.type !== EditorStateActionTypes.DISCARD_CHANGES, }); }, - [vis] + [eventEmitter] ); return [state, wrappedDispatch]; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts index 67220fd9fd91b..6e5bec7c69c90 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts @@ -19,35 +19,45 @@ import { cloneDeep } from 'lodash'; -import { Vis, VisState } from 'src/legacy/core_plugins/visualizations/public'; +import { Vis } from 'src/legacy/core_plugins/visualizations/public'; import { AggGroupNames, DataPublicPluginStart } from '../../../../../../../plugins/data/public'; import { EditorStateActionTypes } from './constants'; import { getEnabledMetricAggsCount } from '../../agg_group_helper'; import { EditorAction } from './actions'; function initEditorState(vis: Vis) { - return vis.copyCurrentState(true); + return { + ...vis.clone(), + }; } +export type EditorVisState = Pick; + const createEditorStateReducer = ({ aggs: { createAggConfigs }, -}: DataPublicPluginStart['search']) => (state: VisState, action: EditorAction): VisState => { +}: DataPublicPluginStart['search']) => ( + state: EditorVisState, + action: EditorAction +): EditorVisState => { switch (action.type) { case EditorStateActionTypes.ADD_NEW_AGG: { const { schema } = action.payload; const defaultConfig = - !state.aggs.aggs.find(agg => agg.schema === schema.name) && schema.defaults + !state.data.aggs!.aggs.find(agg => agg.schema === schema.name) && schema.defaults ? (schema as any).defaults.slice(0, schema.max) : { schema: schema.name }; - const aggConfig = state.aggs.createAggConfig(defaultConfig, { + const aggConfig = state.data.aggs!.createAggConfig(defaultConfig, { addToAggConfigs: false, }); aggConfig.brandNew = true; - const newAggs = [...state.aggs.aggs, aggConfig]; + const newAggs = [...state.data.aggs!.aggs, aggConfig]; return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } @@ -58,7 +68,7 @@ const createEditorStateReducer = ({ case EditorStateActionTypes.CHANGE_AGG_TYPE: { const { aggId, value } = action.payload; - const newAggs = state.aggs.aggs.map(agg => { + const newAggs = state.data.aggs!.aggs.map(agg => { if (agg.id === aggId) { agg.type = value; @@ -70,14 +80,17 @@ const createEditorStateReducer = ({ return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } case EditorStateActionTypes.SET_AGG_PARAM_VALUE: { const { aggId, paramName, value } = action.payload; - const newAggs = state.aggs.aggs.map(agg => { + const newAggs = state.data.aggs!.aggs.map(agg => { if (agg.id === aggId) { const parsedAgg = agg.toJSON(); @@ -95,7 +108,10 @@ const createEditorStateReducer = ({ return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } @@ -113,7 +129,7 @@ const createEditorStateReducer = ({ case EditorStateActionTypes.REMOVE_AGG: { let isMetric = false; - const newAggs = state.aggs.aggs.filter(({ id, schema }) => { + const newAggs = state.data.aggs!.aggs.filter(({ id, schema }) => { if (id === action.payload.aggId) { const schemaDef = action.payload.schemas.find(s => s.name === schema); if (schemaDef && schemaDef.group === AggGroupNames.Metrics) { @@ -136,26 +152,36 @@ const createEditorStateReducer = ({ return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } case EditorStateActionTypes.REORDER_AGGS: { const { sourceAgg, destinationAgg } = action.payload; - const destinationIndex = state.aggs.aggs.indexOf(destinationAgg); - const newAggs = [...state.aggs.aggs]; - newAggs.splice(destinationIndex, 0, newAggs.splice(state.aggs.aggs.indexOf(sourceAgg), 1)[0]); + const destinationIndex = state.data.aggs!.aggs.indexOf(destinationAgg); + const newAggs = [...state.data.aggs!.aggs]; + newAggs.splice( + destinationIndex, + 0, + newAggs.splice(state.data.aggs!.aggs.indexOf(sourceAgg), 1)[0] + ); return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } case EditorStateActionTypes.TOGGLE_ENABLED_AGG: { const { aggId, enabled } = action.payload; - const newAggs = state.aggs.aggs.map(agg => { + const newAggs = state.data.aggs!.aggs.map(agg => { if (agg.id === aggId) { const parsedAgg = agg.toJSON(); @@ -170,7 +196,10 @@ const createEditorStateReducer = ({ return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } diff --git a/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx b/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx index fa3213d244e7e..b504dfd6a55e9 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx @@ -20,10 +20,6 @@ import React, { useEffect, useRef, useState, useCallback } from 'react'; import { EditorRenderProps } from '../../kibana/public/visualize/np_ready/types'; -import { - VisualizeEmbeddableContract as VisualizeEmbeddable, - VisualizeEmbeddableFactoryContract as VisualizeEmbeddableFactory, -} from '../../visualizations/public/'; import { PanelsContainer, Panel } from '../../../../plugins/kibana_react/public'; import './vis_type_agg_filter'; @@ -32,68 +28,44 @@ import { DefaultEditorControllerState } from './default_editor_controller'; import { getInitialWidth } from './editor_size'; function DefaultEditor({ - embeddable, - savedObj, + vis, uiState, timeRange, filters, - appState, optionTabs, query, + embeddableHandler, + eventEmitter, linked, + savedSearch, }: DefaultEditorControllerState & Omit) { const visRef = useRef(null); - const visHandler = useRef(null); const [isCollapsed, setIsCollapsed] = useState(false); - const [factory, setFactory] = useState(null); - const { vis, savedSearch } = savedObj; const onClickCollapse = useCallback(() => { setIsCollapsed(value => !value); }, []); useEffect(() => { - async function visualize() { - if (!visRef.current || (!visHandler.current && factory)) { - return; - } - - if (!visHandler.current) { - const embeddableFactory = embeddable.getEmbeddableFactory( - 'visualization' - ) as VisualizeEmbeddableFactory; - setFactory(embeddableFactory); - - visHandler.current = (await embeddableFactory.createFromObject(savedObj, { - // should be look through createFromObject interface again because of "id" param - id: '', - uiState, - appState, - timeRange, - filters, - query, - })) as VisualizeEmbeddable; - - visHandler.current.render(visRef.current); - } else { - visHandler.current.updateInput({ - timeRange, - filters, - query, - }); - } + if (!visRef.current) { + return; } - visualize(); - }, [uiState, savedObj, timeRange, filters, appState, query, factory, embeddable]); + embeddableHandler.render(visRef.current); + setTimeout(() => { + eventEmitter.emit('apply'); + }); + + return () => embeddableHandler.destroy(); + }, [embeddableHandler, eventEmitter]); useEffect(() => { - return () => { - if (visHandler.current) { - visHandler.current.destroy(); - } - }; - }, []); + embeddableHandler.updateInput({ + timeRange, + filters, + query, + }); + }, [embeddableHandler, timeRange, filters, query]); const editorInitialWidth = getInitialWidth(vis.type.editorConfig.defaultSize); @@ -120,6 +92,7 @@ function DefaultEditor({ uiState={uiState} isLinkedSearch={linked} savedSearch={savedSearch} + eventEmitter={eventEmitter} /> diff --git a/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx b/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx index db910604eddd1..13fcabd799959 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx @@ -21,18 +21,22 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { i18n } from '@kbn/i18n'; import { I18nProvider } from '@kbn/i18n/react'; +import { EventEmitter } from 'events'; import { EditorRenderProps } from 'src/legacy/core_plugins/kibana/public/visualize/np_ready/types'; -import { VisSavedObject } from 'src/legacy/core_plugins/visualizations/public/'; +import { Vis } from 'src/legacy/core_plugins/visualizations/public/'; import { Storage } from '../../../../plugins/kibana_utils/public'; import { KibanaContextProvider } from '../../../../plugins/kibana_react/public'; import { DefaultEditor } from './default_editor'; import { DefaultEditorDataTab, OptionTab } from './components/sidebar'; +import { VisualizeEmbeddable } from '../../visualizations/public/np_ready/public/embeddable'; const localStorage = new Storage(window.localStorage); export interface DefaultEditorControllerState { - savedObj: VisSavedObject; + vis: Vis; + eventEmitter: EventEmitter; + embeddableHandler: VisualizeEmbeddable; optionTabs: OptionTab[]; } @@ -40,9 +44,9 @@ class DefaultEditorController { private el: HTMLElement; private state: DefaultEditorControllerState; - constructor(el: HTMLElement, savedObj: VisSavedObject) { + constructor(el: HTMLElement, vis: Vis, eventEmitter: EventEmitter, embeddableHandler: any) { this.el = el; - const { type: visType } = savedObj.vis; + const { type: visType } = vis; const optionTabs = [ ...(visType.schemas.buckets || visType.schemas.metrics @@ -71,8 +75,10 @@ class DefaultEditorController { ]; this.state = { - savedObj, + vis, optionTabs, + eventEmitter, + embeddableHandler, }; } diff --git a/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx b/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx index 2e8f20946c73a..3239e871a2465 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx @@ -17,8 +17,8 @@ * under the License. */ +import { PersistedState } from 'src/plugins/visualizations/public'; import { IAggConfigs } from 'src/plugins/data/public'; -import { PersistedState } from '../../../../plugins/visualizations/public'; import { Vis } from '../../visualizations/public'; export interface VisOptionsProps { diff --git a/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx b/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx index 5bcb2961c42de..103879cb6e6df 100644 --- a/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx +++ b/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx @@ -21,11 +21,6 @@ import React from 'react'; import { render, mount } from 'enzyme'; import { MarkdownVisWrapper } from './markdown_vis_controller'; -// We need Markdown to do these tests, so mock data plugin -jest.mock('../../data/public/legacy', () => { - return {}; -}); - describe('markdown vis controller', () => { it('should set html from markdown params', () => { const vis = { diff --git a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx index 6a466c9cd0211..7ba4fe017522d 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx +++ b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx @@ -20,12 +20,12 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { Vis } from 'src/legacy/core_plugins/visualizations/public'; import { MetricVisComponent, MetricVisComponentProps } from './metric_vis_component'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { npStart } from 'ui/new_platform'; import { fieldFormats } from '../../../../../plugins/data/public'; import { identity } from 'lodash'; +import { ExprVis } from '../../../visualizations/public/np_ready/public/expressions/vis'; jest.mock('ui/new_platform'); @@ -37,7 +37,7 @@ const baseVisData = { } as any; describe('MetricVisComponent', function() { - const vis: Vis = { + const vis: ExprVis = { params: { metric: { colorSchema: 'Green to Red', @@ -57,7 +57,7 @@ describe('MetricVisComponent', function() { const getComponent = (propOverrides: Partial = {} as Partial) => { const props: Props = { vis, - visParams: vis.params, + visParams: vis.params as any, visData: baseVisData, renderComplete: jest.fn(), ...propOverrides, diff --git a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.tsx b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.tsx index a93bb618da31f..175458497a05e 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.tsx +++ b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.tsx @@ -27,12 +27,13 @@ import { FieldFormatsContentType, IFieldFormat } from '../../../../../plugins/da import { KibanaDatatable } from '../../../../../plugins/expressions/public'; import { getHeatmapColors } from '../../../../../plugins/charts/public'; import { VisParams, MetricVisMetric } from '../types'; -import { SchemaConfig, Vis } from '../../../visualizations/public'; +import { SchemaConfig } from '../../../visualizations/public'; +import { ExprVis } from '../../../visualizations/public/np_ready/public/expressions/vis'; export interface MetricVisComponentProps { visParams: VisParams; visData: Input; - vis: Vis; + vis: ExprVis; renderComplete: () => void; } diff --git a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts index cce5864aa50a1..c0bfa47bff502 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts @@ -61,11 +61,22 @@ describe('metric_vis - createMetricVisTypeDefinition', () => { labelTemplate: 'ip[{{value}}]', }); + const searchSource = { + getField: (name: string) => { + if (name === 'index') { + return stubIndexPattern; + } + }, + }; + // TODO: remove when Vis is converted to typescript. Only importing Vis as type // @ts-ignore - vis = visualizationsStart.createVis(stubIndexPattern, { + vis = visualizationsStart.createVis('metric', { type: 'metric', - aggs: [{ id: '1', type: 'top_hits', schema: 'metric', params: { field: 'ip' } }], + data: { + searchSource, + aggs: [{ id: '1', type: 'top_hits', schema: 'metric', params: { field: 'ip' } }], + }, }); vis.params.dimensions = { diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js index 8edef2ea16353..211b79e915038 100644 --- a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js +++ b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js @@ -50,57 +50,73 @@ describe('Table Vis - AggTable Directive', function() { const tabifiedData = {}; const init = () => { - const vis1 = visualizationsStart.createVis(indexPattern, 'table'); - tabifiedData.metricOnly = tabifyAggResponse(vis1.aggs, metricOnly); + const searchSource = { + getField: name => { + if (name === 'index') { + return indexPattern; + } + }, + }; + const vis1 = visualizationsStart.createVis('table', { + type: 'table', + data: { searchSource, aggs: [] }, + }); + tabifiedData.metricOnly = tabifyAggResponse(vis1.data.aggs, metricOnly); - const vis2 = visualizationsStart.createVis(indexPattern, { + const vis2 = visualizationsStart.createVis('table', { type: 'table', params: { showMetricsAtAllLevels: true, }, - aggs: [ - { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, - { type: 'terms', schema: 'bucket', params: { field: 'extension' } }, - { type: 'terms', schema: 'bucket', params: { field: 'geo.src' } }, - { type: 'terms', schema: 'bucket', params: { field: 'machine.os' } }, - ], + data: { + aggs: [ + { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, + { type: 'terms', schema: 'bucket', params: { field: 'extension' } }, + { type: 'terms', schema: 'bucket', params: { field: 'geo.src' } }, + { type: 'terms', schema: 'bucket', params: { field: 'machine.os' } }, + ], + searchSource, + }, }); - vis2.aggs.aggs.forEach(function(agg, i) { + vis2.data.aggs.aggs.forEach(function(agg, i) { agg.id = 'agg_' + (i + 1); }); - tabifiedData.threeTermBuckets = tabifyAggResponse(vis2.aggs, threeTermBuckets, { + tabifiedData.threeTermBuckets = tabifyAggResponse(vis2.data.aggs, threeTermBuckets, { metricsAtAllLevels: true, }); - const vis3 = visualizationsStart.createVis(indexPattern, { + const vis3 = visualizationsStart.createVis('table', { type: 'table', - aggs: [ - { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, - { type: 'min', schema: 'metric', params: { field: '@timestamp' } }, - { type: 'terms', schema: 'bucket', params: { field: 'extension' } }, - { - type: 'date_histogram', - schema: 'bucket', - params: { field: '@timestamp', interval: 'd' }, - }, - { - type: 'derivative', - schema: 'metric', - params: { metricAgg: 'custom', customMetric: { id: '5-orderAgg', type: 'count' } }, - }, - { - type: 'top_hits', - schema: 'metric', - params: { field: 'bytes', aggregate: { val: 'min' }, size: 1 }, - }, - ], + data: { + aggs: [ + { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, + { type: 'min', schema: 'metric', params: { field: '@timestamp' } }, + { type: 'terms', schema: 'bucket', params: { field: 'extension' } }, + { + type: 'date_histogram', + schema: 'bucket', + params: { field: '@timestamp', interval: 'd' }, + }, + { + type: 'derivative', + schema: 'metric', + params: { metricAgg: 'custom', customMetric: { id: '5-orderAgg', type: 'count' } }, + }, + { + type: 'top_hits', + schema: 'metric', + params: { field: 'bytes', aggregate: { val: 'min' }, size: 1 }, + }, + ], + searchSource, + }, }); - vis3.aggs.aggs.forEach(function(agg, i) { + vis3.data.aggs.aggs.forEach(function(agg, i) { agg.id = 'agg_' + (i + 1); }); tabifiedData.oneTermOneHistogramBucketWithTwoMetricsOneTopHitOneDerivative = tabifyAggResponse( - vis3.aggs, + vis3.data.aggs, oneTermOneHistogramBucketWithTwoMetricsOneTopHitOneDerivative ); }; diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js index 89900d2144030..77f817e44ba79 100644 --- a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js +++ b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js @@ -38,22 +38,35 @@ describe('Table Vis - AggTableGroup Directive', function() { const tabifiedData = {}; const init = () => { - const vis1 = visualizationsStart.createVis(indexPattern, 'table'); - tabifiedData.metricOnly = tabifyAggResponse(vis1.aggs, metricOnly); + const searchSource = { + getField: name => { + if (name === 'index') { + return indexPattern; + } + }, + }; + const vis1 = visualizationsStart.createVis('table', { + type: 'table', + data: { searchSource, aggs: [] }, + }); + tabifiedData.metricOnly = tabifyAggResponse(vis1.data.aggs, metricOnly); - const vis2 = visualizationsStart.createVis(indexPattern, { + const vis2 = visualizationsStart.createVis('pie', { type: 'pie', - aggs: [ - { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, - { type: 'terms', schema: 'split', params: { field: 'extension' } }, - { type: 'terms', schema: 'segment', params: { field: 'geo.src' } }, - { type: 'terms', schema: 'segment', params: { field: 'machine.os' } }, - ], + data: { + aggs: [ + { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, + { type: 'terms', schema: 'split', params: { field: 'extension' } }, + { type: 'terms', schema: 'segment', params: { field: 'geo.src' } }, + { type: 'terms', schema: 'segment', params: { field: 'machine.os' } }, + ], + searchSource, + }, }); - vis2.aggs.aggs.forEach(function(agg, i) { + vis2.data.aggs.aggs.forEach(function(agg, i) { agg.id = 'agg_' + (i + 1); }); - tabifiedData.threeTermBuckets = tabifyAggResponse(vis2.aggs, threeTermBuckets); + tabifiedData.threeTermBuckets = tabifyAggResponse(vis2.data.aggs, threeTermBuckets); }; const initLocalAngular = () => { diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts b/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts index 327a47093f535..ad56607e9296c 100644 --- a/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts +++ b/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts @@ -118,20 +118,22 @@ describe('Table Vis - Controller', () => { return ({ type: tableVisTypeDefinition, params: Object.assign({}, tableVisTypeDefinition.visConfig.defaults, params), - aggs: createAggConfigs(stubIndexPattern, [ - { type: 'count', schema: 'metric' }, - { - type: 'range', - schema: 'bucket', - params: { - field: 'bytes', - ranges: [ - { from: 0, to: 1000 }, - { from: 1000, to: 2000 }, - ], + data: { + aggs: createAggConfigs(stubIndexPattern, [ + { type: 'count', schema: 'metric' }, + { + type: 'range', + schema: 'bucket', + params: { + field: 'bytes', + ranges: [ + { from: 0, to: 1000 }, + { from: 1000, to: 2000 }, + ], + }, }, - }, - ]), + ]), + }, } as unknown) as Vis; } @@ -151,11 +153,11 @@ describe('Table Vis - Controller', () => { // basically a parameterized beforeEach function initController(vis: Vis) { - vis.aggs.aggs.forEach((agg: IAggConfig, i: number) => { + vis.data.aggs!.aggs.forEach((agg: IAggConfig, i: number) => { agg.id = 'agg_' + (i + 1); }); - tabifiedResponse = tabifyAggResponse(vis.aggs, oneRangeBucket); + tabifiedResponse = tabifyAggResponse(vis.data.aggs!, oneRangeBucket); $rootScope.vis = vis; $rootScope.visParams = vis.params; $rootScope.uiState = { diff --git a/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts b/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts index 2d27a99bdd8af..2feaad9f4e6b6 100644 --- a/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts +++ b/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts @@ -19,12 +19,12 @@ import angular, { IModule, auto, IRootScopeService, IScope, ICompileService } from 'angular'; import $ from 'jquery'; -import { isEqual } from 'lodash'; -import { Vis, VisParams } from '../../visualizations/public'; +import { VisParams } from '../../visualizations/public'; import { npStart } from './legacy_imports'; import { getAngularModule } from './get_inner_angular'; import { initTableVisLegacyModule } from './table_vis_legacy_module'; +import { ExprVis } from '../../visualizations/public/np_ready/public/expressions/vis'; const innerAngularName = 'kibana/table_vis'; @@ -32,12 +32,12 @@ export class TableVisualizationController { private tableVisModule: IModule | undefined; private injector: auto.IInjectorService | undefined; el: JQuery; - vis: Vis; + vis: ExprVis; $rootScope: IRootScopeService | null = null; $scope: (IScope & { [key: string]: any }) | undefined; $compile: ICompileService | undefined; - constructor(domeElement: Element, vis: Vis) { + constructor(domeElement: Element, vis: ExprVis) { this.el = $(domeElement); this.vis = vis; } @@ -60,7 +60,7 @@ export class TableVisualizationController { } } - async render(esResponse: object, visParams: VisParams, status: { [key: string]: boolean }) { + async render(esResponse: object, visParams: VisParams) { this.initLocalAngular(); return new Promise(async (resolve, reject) => { @@ -77,15 +77,10 @@ export class TableVisualizationController { this.$scope.visState = { params: visParams }; this.$scope.esResponse = esResponse; - if (!isEqual(this.$scope.visParams, visParams)) { - this.vis.emit('updateEditorStateParams', visParams); - } - this.$scope.visParams = visParams; this.$scope.renderComplete = resolve; this.$scope.renderFailed = reject; this.$scope.resize = Date.now(); - this.$scope.updateStatus = status; this.$scope.$apply(); }; @@ -93,7 +88,7 @@ export class TableVisualizationController { this.$scope = this.$rootScope.$new(); this.$scope.uiState = this.vis.getUiState(); updateScope(); - this.el.find('div').append(this.$compile(this.vis.type.visConfig.template)(this.$scope)); + this.el.find('div').append(this.$compile(this.vis.type!.visConfig.template)(this.$scope)); this.$scope.$apply(); } else { updateScope(); diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js b/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js index 3091b3340cd6d..6f54744a2f508 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js @@ -19,7 +19,6 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; import { start as visualizationsStart } from '../../../../../core_plugins/visualizations/public/np_ready/public/legacy'; import { ImageComparator } from 'test_utils/image_comparator'; import { createTagCloudVisualization } from '../tag_cloud_visualization'; @@ -36,7 +35,6 @@ const PIXEL_DIFF = 64; describe('TagCloudVisualizationTest', function() { let domNode; - let indexPattern; let vis; let imageComparator; @@ -66,22 +64,18 @@ describe('TagCloudVisualizationTest', function() { }); beforeEach(ngMock.module('kibana')); - beforeEach( - ngMock.inject(Private => { - indexPattern = Private(LogstashIndexPatternStubProvider); - }) - ); describe('TagCloudVisualization - basics', function() { beforeEach(async function() { setupDOM('512px', '512px'); imageComparator = new ImageComparator(); - vis = visualizationsStart.createVis(indexPattern, { + vis = visualizationsStart.createVis('tagcloud', { type: 'tagcloud', params: { bucket: { accessor: 0, format: {} }, metric: { accessor: 0, format: {} }, }, + data: {}, }); }); diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js index 114643c9a74e0..04f447bf78d50 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js @@ -79,17 +79,10 @@ export function createTagCloudVisualization({ colors }) { render(