From 8fcae1ca9787806c574dfaad766ef16cbc4c7325 Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Mon, 26 Nov 2018 21:24:36 -0700 Subject: [PATCH 01/32] Resolve merge conflicts --- .../kbn-interpreter/src/public/interpreter.js | 4 ++-- .../interpreter/public/load_browser_plugins.js | 16 ++++++++++++++-- .../canvas/public/components/app/index.js | 12 +++--------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/packages/kbn-interpreter/src/public/interpreter.js b/packages/kbn-interpreter/src/public/interpreter.js index ba38df27b6f85..5747eafcd274c 100644 --- a/packages/kbn-interpreter/src/public/interpreter.js +++ b/packages/kbn-interpreter/src/public/interpreter.js @@ -48,13 +48,13 @@ export async function initializeInterpreter() { } // Use the above promise to seed the interpreter with the functions it can defer to -export async function interpretAst(ast, context) { +export async function interpretAst(ast, context, handlers) { // Load plugins before attempting to get functions, otherwise this gets racey return Promise.all([functionList, getBrowserRegistries()]) .then(([serverFunctionList]) => { return socketInterpreterProvider({ types: typesRegistry.toJS(), - handlers: createHandlers(socket), + handlers: { ...handlers, ...createHandlers(socket) }, functions: functionsRegistry.toJS(), referableFunctions: serverFunctionList, socket: socket, diff --git a/src/core_plugins/interpreter/public/load_browser_plugins.js b/src/core_plugins/interpreter/public/load_browser_plugins.js index de550f5c6a351..f843590416931 100644 --- a/src/core_plugins/interpreter/public/load_browser_plugins.js +++ b/src/core_plugins/interpreter/public/load_browser_plugins.js @@ -18,8 +18,11 @@ */ import chrome from 'ui/chrome'; -import { populateBrowserRegistries } from '@kbn/interpreter/public'; +import { populateBrowserRegistries, createSocket, initialize } from '@kbn/interpreter/public'; import { typesRegistry, functionsRegistry } from '@kbn/interpreter/common'; +import { functions } from './functions'; + +const basePath = chrome.getBasePath(); const types = { commonFunctions: functionsRegistry, @@ -27,4 +30,13 @@ const types = { types: typesRegistry }; -populateBrowserRegistries(types, chrome.getBasePath()); +function addFunction(fnDef) { + functionsRegistry.register(fnDef); +} + +functions.forEach(addFunction); + +createSocket(basePath).then(async () => { + await populateBrowserRegistries(types); + await initialize(); +}); diff --git a/x-pack/plugins/canvas/public/components/app/index.js b/x-pack/plugins/canvas/public/components/app/index.js index f5fc65e029f36..428a0a1652c6c 100644 --- a/x-pack/plugins/canvas/public/components/app/index.js +++ b/x-pack/plugins/canvas/public/components/app/index.js @@ -4,11 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - createSocket, - initializeInterpreter, - populateBrowserRegistries, -} from '@kbn/interpreter/public'; +import { populateBrowserRegistries, } from '@kbn/interpreter/public'; import { connect } from 'react-redux'; import { compose, withProps } from 'recompose'; import { getAppReady, getBasePath } from '../../state/selectors/app'; @@ -48,13 +44,11 @@ const types = { const mapDispatchToProps = dispatch => ({ // TODO: the correct socket path should come from upstream, using the constant here is not ideal - setAppReady: basePath => async () => { + setAppReady: () => async () => { try { // initialize the socket and interpreter - await createSocket(basePath); loadPrivateBrowserFunctions(); - await populateBrowserRegistries(types, basePath); - await initializeInterpreter(); + await populateBrowserRegistries(types); // set app state to ready dispatch(appReady()); From ffaaafc846a28c69c8dccd961a1ec8b2ccd06784 Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Mon, 26 Nov 2018 21:31:07 -0700 Subject: [PATCH 02/32] Fix broken imports --- src/core_plugins/interpreter/public/load_browser_plugins.js | 4 ++-- x-pack/plugins/canvas/public/components/app/index.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core_plugins/interpreter/public/load_browser_plugins.js b/src/core_plugins/interpreter/public/load_browser_plugins.js index f843590416931..909b35b6c6490 100644 --- a/src/core_plugins/interpreter/public/load_browser_plugins.js +++ b/src/core_plugins/interpreter/public/load_browser_plugins.js @@ -18,7 +18,7 @@ */ import chrome from 'ui/chrome'; -import { populateBrowserRegistries, createSocket, initialize } from '@kbn/interpreter/public'; +import { populateBrowserRegistries, createSocket, initializeInterpreter } from '@kbn/interpreter/public'; import { typesRegistry, functionsRegistry } from '@kbn/interpreter/common'; import { functions } from './functions'; @@ -38,5 +38,5 @@ functions.forEach(addFunction); createSocket(basePath).then(async () => { await populateBrowserRegistries(types); - await initialize(); + await initializeInterpreter(); }); diff --git a/x-pack/plugins/canvas/public/components/app/index.js b/x-pack/plugins/canvas/public/components/app/index.js index 428a0a1652c6c..2024746e27755 100644 --- a/x-pack/plugins/canvas/public/components/app/index.js +++ b/x-pack/plugins/canvas/public/components/app/index.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { populateBrowserRegistries, } from '@kbn/interpreter/public'; +import { populateBrowserRegistries } from '@kbn/interpreter/public'; import { connect } from 'react-redux'; import { compose, withProps } from 'recompose'; import { getAppReady, getBasePath } from '../../state/selectors/app'; From 3e1ecec5ad12b848e0931afeee81daa9a8b60b4f Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 21 Nov 2018 10:36:47 +0100 Subject: [PATCH 03/32] adding canvas functions --- .../kbn-interpreter/src/plugin/types/index.js | 4 + .../src/plugin/types/kibana_context.js | 36 +++++ .../src/plugin/types/kibana_table.js | 138 ++++++++++++++++++ .../interpreter/public/functions/esaggs.js | 100 +++++++++++++ .../interpreter/public/functions/index.js | 40 +++++ .../public/functions/input_control.js | 48 ++++++ .../interpreter/public/functions/kibana.js | 34 +++++ .../public/functions/kibana_context.js | 90 ++++++++++++ .../interpreter/public/functions/markdown.js | 57 ++++++++ .../interpreter/public/functions/metric.js | 75 ++++++++++ .../interpreter/public/functions/pie.js | 86 +++++++++++ .../interpreter/public/functions/regionmap.js | 76 ++++++++++ .../interpreter/public/functions/table.js | 97 ++++++++++++ .../interpreter/public/functions/tagcloud.js | 76 ++++++++++ .../interpreter/public/functions/tilemap.js | 82 +++++++++++ .../public/functions/timelion_vis.js | 73 +++++++++ .../interpreter/public/functions/tsvb.js | 81 ++++++++++ .../interpreter/public/functions/vega.js | 68 +++++++++ .../interpreter/public/functions/vislib.js | 93 ++++++++++++ .../public/functions/visualization.js | 54 +++++++ 20 files changed, 1408 insertions(+) create mode 100644 packages/kbn-interpreter/src/plugin/types/kibana_context.js create mode 100644 packages/kbn-interpreter/src/plugin/types/kibana_table.js create mode 100644 src/core_plugins/interpreter/public/functions/esaggs.js create mode 100644 src/core_plugins/interpreter/public/functions/index.js create mode 100644 src/core_plugins/interpreter/public/functions/input_control.js create mode 100644 src/core_plugins/interpreter/public/functions/kibana.js create mode 100644 src/core_plugins/interpreter/public/functions/kibana_context.js create mode 100644 src/core_plugins/interpreter/public/functions/markdown.js create mode 100644 src/core_plugins/interpreter/public/functions/metric.js create mode 100644 src/core_plugins/interpreter/public/functions/pie.js create mode 100644 src/core_plugins/interpreter/public/functions/regionmap.js create mode 100644 src/core_plugins/interpreter/public/functions/table.js create mode 100644 src/core_plugins/interpreter/public/functions/tagcloud.js create mode 100644 src/core_plugins/interpreter/public/functions/tilemap.js create mode 100644 src/core_plugins/interpreter/public/functions/timelion_vis.js create mode 100644 src/core_plugins/interpreter/public/functions/tsvb.js create mode 100644 src/core_plugins/interpreter/public/functions/vega.js create mode 100644 src/core_plugins/interpreter/public/functions/vislib.js create mode 100644 src/core_plugins/interpreter/public/functions/visualization.js diff --git a/packages/kbn-interpreter/src/plugin/types/index.js b/packages/kbn-interpreter/src/plugin/types/index.js index 1ae5f874835c3..ea3aa7d519891 100644 --- a/packages/kbn-interpreter/src/plugin/types/index.js +++ b/packages/kbn-interpreter/src/plugin/types/index.js @@ -29,6 +29,8 @@ import { render } from './render'; import { shape } from './shape'; import { string } from './string'; import { style } from './style'; +import { kibanaTable } from './kibana_table'; +import { kibanaContext } from './kibana_context'; export const typeSpecs = [ boolean, @@ -43,4 +45,6 @@ export const typeSpecs = [ shape, string, style, + kibanaTable, + kibanaContext, ]; diff --git a/packages/kbn-interpreter/src/plugin/types/kibana_context.js b/packages/kbn-interpreter/src/plugin/types/kibana_context.js new file mode 100644 index 0000000000000..b186ae135788d --- /dev/null +++ b/packages/kbn-interpreter/src/plugin/types/kibana_context.js @@ -0,0 +1,36 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const kibanaContext = () => ({ + name: 'kibana_context', + from: { + null: () => { + return { + type: 'kibana_context', + }; + }, + }, + to: { + null: () => { + return { + type: 'null', + }; + }, + } +}); diff --git a/packages/kbn-interpreter/src/plugin/types/kibana_table.js b/packages/kbn-interpreter/src/plugin/types/kibana_table.js new file mode 100644 index 0000000000000..bdc8da9fecf41 --- /dev/null +++ b/packages/kbn-interpreter/src/plugin/types/kibana_table.js @@ -0,0 +1,138 @@ +/* + * 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 _ from 'lodash'; + +export const kibanaTable = () => ({ + name: 'kibana_table', + serialize: context => { + context.columns.forEach(column => { + column.aggConfig = column.aggConfig.toJSON(); + }); + return context; + }, + deserialize: () => { + // config.visData.columns.forEach(column => { + // column.aggConfig = new AggConfig(a, column.aggConfig); + // }); + }, + validate: tabify => { + if (!tabify.columns) { + throw new Error('tabify must have a columns array, even if it is empty'); + } + }, + from: { + null: () => { + return { + type: 'kibana_table', + columns: [], + }; + }, + datatable: context => { + const converted = { + columns: context.columns.map(column => { + return { + id: column.name, + title: column.name, + ...column + }; + }), + rows: context.rows.map(row => { + const crow = {}; + context.columns.forEach(column => { + crow[column.name] = (row[column.name]); + }); + return crow; + }) + }; + return { + type: 'kibana_table', + ...converted, + }; + }, + number: context => { + return { + type: 'kibana_table', + columns: [{ id: 'col-0', title: 'Count' }], + rows: [{ 'col-0': context }] + }; + }, + pointseries: context => { + const converted = { + tables: [{ + columns: _.map(context.columns, (column, name) => { + return { + title: column.name || name, + ...column + }; + }), + rows: context.rows.map(row => { + const crow = []; + _.each(context.columns, (column, i) => { + crow.push(row[i]); + }); + return crow; + }) + }] + }; + return { + type: 'kibana_table', + value: converted, + }; + } + }, + to: { + datatable: context => { + const columns = context.columns.map(column => { + return { name: column.title, ...column }; + }); + const rows = context.rows.map(row => { + const converted = {}; + columns.forEach((column) => { + converted[column.name] = row[column.id]; + }); + return converted; + }); + + return { + type: 'datatable', + columns: columns, + rows: rows, + }; + }, + pointseries: context => { + const columns = context.value.tables[0].columns.map(column => { + return { name: column.title, ...column }; + }); + const rows = context.value.tables[0].rows.map(row => { + const converted = {}; + columns.forEach((column, i) => { + converted[column.name] = row[i]; + }); + return converted; + }); + + return { + type: 'pointseries', + columns: columns, + rows: rows, + }; + } + } +}); diff --git a/src/core_plugins/interpreter/public/functions/esaggs.js b/src/core_plugins/interpreter/public/functions/esaggs.js new file mode 100644 index 0000000000000..945ad83c13af2 --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/esaggs.js @@ -0,0 +1,100 @@ +/* + * 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 _ from 'lodash'; +import { CourierRequestHandlerProvider } from 'ui/vis/request_handlers/courier'; +import { AggConfigs } from 'ui/vis/agg_configs'; + +// need to get rid of angular from these +import { IndexPatternsProvider } from 'ui/index_patterns'; +import { SearchSourceProvider } from 'ui/courier/search_source'; +import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; + +import chrome from 'ui/chrome'; + +const courierRequestHandlerProvider = CourierRequestHandlerProvider; +const courierRequestHandler = courierRequestHandlerProvider().handler; + +export default () => ({ + name: 'esaggs', + type: 'kibana_table', + context: { + types: [ + 'kibana_context', + 'null', + ], + }, + help: 'Run AggConfig aggregation.', + args: { + index: { + types: ['string', 'null'], + default: null, + }, + metricsAtAllLevels: { + types: ['boolean'], + default: false, + }, + partialRows: { + types: ['boolean'], + default: false, + }, + aggConfigs: { + types: ['string'], + default: '""', + help: 'AggConfig definition', + multi: false, + }, + }, + fn(context, args, handlers) { + return chrome.dangerouslyGetActiveInjector().then(async $injector => { + const Private = $injector.get('Private'); + const indexPatterns = Private(IndexPatternsProvider); + const SearchSource = Private(SearchSourceProvider); + const queryFilter = Private(FilterBarQueryFilterProvider); + + const aggConfigsState = JSON.parse(args.aggConfigs); + const indexPattern = await indexPatterns.get(args.index); + const aggs = new AggConfigs(indexPattern, aggConfigsState); + + // we should move searchSource creation inside courier request handler + const searchSource = new SearchSource(); + searchSource.setField('index', indexPattern); + + const response = await courierRequestHandler({ + searchSource: searchSource, + aggs: aggs, + timeRange: _.get(context, 'timeRange', null), + query: _.get(context, 'query', null), + filters: _.get(context, 'filters', null), + forceFetch: true, + isHierarchical: args.metricsAtAllLevels, + partialRows: args.partialRows, + inspectorAdapters: handlers.inspectorAdapters, + queryFilter, + }); + + return { + type: 'kibana_table', + index: args.index, + ...response, + }; + + }); + }, +}); diff --git a/src/core_plugins/interpreter/public/functions/index.js b/src/core_plugins/interpreter/public/functions/index.js new file mode 100644 index 0000000000000..89b96ed92283d --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/index.js @@ -0,0 +1,40 @@ +/* + * 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 esaggs from './esaggs'; +import kibana from './kibana'; +import kibanaContext from './kibana_context'; +import vega from './vega'; +import timelion from './timelion_vis'; +import tsvb from './tsvb'; +import markdown from './markdown'; +import inputControl from './input_control'; +import metric from './metric'; +import pie from './pie'; +import regionMap from './regionmap'; +import tileMap from './tilemap'; +import table from './table'; +import tagCloud from './tagcloud'; +import vislib from './vislib'; +import visualization from './visualization'; + +export const functions = [ + esaggs, kibana, kibanaContext, vega, timelion, tsvb, markdown, inputControl, + metric, pie, regionMap, tileMap, table, tagCloud, vislib, visualization +]; diff --git a/src/core_plugins/interpreter/public/functions/input_control.js b/src/core_plugins/interpreter/public/functions/input_control.js new file mode 100644 index 0000000000000..29356fb06340f --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/input_control.js @@ -0,0 +1,48 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export default () => ({ + name: 'input_control_vis', + type: 'render', + context: { + types: [], + }, + help: 'A input control visualization.', + args: { + visConfig: { + types: ['string'], + default: '"{}"', + help: 'markdown configuration object', + multi: false, + } + }, + fn(context, args) { + const params = args.visConfig ? JSON.parse(args.visConfig) : {}; + return { + type: 'render', + as: 'visualization', + value: { + visConfig: { + type: 'input_controls_vis', + params: params + }, + } + }; + } +}); diff --git a/src/core_plugins/interpreter/public/functions/kibana.js b/src/core_plugins/interpreter/public/functions/kibana.js new file mode 100644 index 0000000000000..9b580c54f7e0a --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/kibana.js @@ -0,0 +1,34 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export default () => ({ + name: 'kibana', + type: 'kibana_context', + context: {}, + help: 'Gets kibana global context.', + args: {}, + fn(context) { + return { + type: 'kibana_context', + query: context.query, + filters: context.filters, + timeRange: context.timeRange, + }; + }, +}); diff --git a/src/core_plugins/interpreter/public/functions/kibana_context.js b/src/core_plugins/interpreter/public/functions/kibana_context.js new file mode 100644 index 0000000000000..4b5ea69dcee14 --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/kibana_context.js @@ -0,0 +1,90 @@ +/* + * 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 chrome from 'ui/chrome'; + +export default () => ({ + name: 'kibana_context', + type: 'kibana_context', + context: { + types: [ + 'kibana_context', + 'null', + ], + }, + help: 'Gets kibana global context.', + args: { + q: { + types: ['string', 'null'], + aliases: ['query'], + help: 'A Lucene query string', + default: null, + }, + filters: { + types: ['string', 'null'], + help: 'Filters object', + default: '"[]"', + }, + timeRange: { + types: ['string', 'null'], + help: 'Sets date range to query', + default: null, + }, + savedSearchId: { + types: ['string', 'null'], + help: 'Sets date range to query', + default: null, + } + }, + fn(context, args) { + return chrome.dangerouslyGetActiveInjector().then(async $injector => { + const savedSearches = $injector.get('savedSearches'); + const queryArg = args.q ? JSON.parse(args.q) : []; + let queries = Array.isArray(queryArg) ? queryArg : [queryArg]; + let filters = args.filters ? JSON.parse(args.filters) : []; + + if (args.savedSearchId) { + const savedSearch = await savedSearches.get(args.savedSearchId); + const searchQuery = savedSearch.searchSource.getField('query'); + const searchFilters = savedSearch.searchSource.getField('filter'); + queries = queries.concat(searchQuery); + filters = filters.concat(searchFilters); + } + + if (context.query) { + const contextQueries = Array.isArray(context.query) ? context.query : [context.query]; + queries = queries.concat(contextQueries); + } + + if (context.filters) { + // merge filters + filters = filters.concat(context.filters); + } + + const timeRange = args.timeRange ? JSON.parse(args.timeRange) : context.timeRange; + + return { + type: 'kibana_context', + query: queries, + filters: filters, + timeRange: timeRange, + }; + }); + }, +}); diff --git a/src/core_plugins/interpreter/public/functions/markdown.js b/src/core_plugins/interpreter/public/functions/markdown.js new file mode 100644 index 0000000000000..a553d86891675 --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/markdown.js @@ -0,0 +1,57 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export default () => ({ + name: 'markdown', + type: 'render', + context: { + types: [], + }, + help: 'A markdown visualization.', + args: { + spec: { + types: ['string'], + default: '', + help: 'markdown', + multi: false, + }, + params: { + types: ['string'], + default: '"{}"', + help: 'markdown configuration object', + multi: false, + } + }, + fn(context, args) { + const params = args.params ? JSON.parse(args.params) : {}; + return { + type: 'render', + as: 'visualization', + value: { + visConfig: { + type: 'markdown', + params: { + markdown: args.spec, + ...params, + } + }, + } + }; + } +}); diff --git a/src/core_plugins/interpreter/public/functions/metric.js b/src/core_plugins/interpreter/public/functions/metric.js new file mode 100644 index 0000000000000..44eb69934a39e --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/metric.js @@ -0,0 +1,75 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export default () => ({ + name: 'kibana_metric', + type: 'render', + context: { + types: [ + 'kibana_table' + ], + }, + help: 'A simple metric visualization.', + args: { + bucket: { + types: ['string', 'null'], + default: null, + help: 'bucket column index id or name', + multi: false, + }, + metric: { + types: ['string'], + default: '1', + help: 'metric column index id or name', + multi: true, + }, + visConfig: { + types: ['string', 'null'], + default: '"{}"', + help: 'config of the visualization', + multi: false, + }, + }, + fn(context, args) { + const visConfigParams = JSON.parse(args.visConfig || {}); + const metricColumn = context.columns.find((column, i) => + column.id === args.metric || column.name === args.metric || i === parseInt(args.metric)); + metricColumn.aggConfig.schema = 'metric'; + if (args.bucket) { + const bucketColumn = context.columns.find((column, i) => + column.id === args.bucket || column.name === args.bucket || i === parseInt(args.bucket)); + bucketColumn.aggConfig.schema = 'segment'; + } + + return { + type: 'render', + as: 'visualization', + value: { + visData: context, + visConfig: { + type: 'metric', + params: visConfigParams, + }, + params: { + listenOnChange: true, + } + }, + }; + }, +}); diff --git a/src/core_plugins/interpreter/public/functions/pie.js b/src/core_plugins/interpreter/public/functions/pie.js new file mode 100644 index 0000000000000..0bd61523b5cf0 --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/pie.js @@ -0,0 +1,86 @@ +/* + * 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 { VisTypesRegistryProvider } from 'ui/registry/vis_types'; +import { VislibSlicesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib'; +import chrome from 'ui/chrome'; + +export default () => ({ + name: 'kibana_pie', + type: 'render', + context: { + types: [ + 'kibana_table', 'null' + ], + }, + help: 'A vislib pie visualization.', + args: { + schemas: { + types: ['string'], + default: '"{}"', + help: 'schemas configuration object', + multi: false, + }, + visConfig: { + types: ['string', 'null'], + default: '"{}"', + help: 'config of the visualization', + multi: false, + }, + }, + fn(context, args) { + return chrome.dangerouslyGetActiveInjector().then(async $injector => { + const Private = $injector.get('Private'); + const responseHandler = Private(VislibSlicesResponseHandlerProvider).handler; + const visTypes = Private(VisTypesRegistryProvider); + const visConfigParams = JSON.parse(args.visConfig || {}); + const visType = visTypes.byName.pie; + const schemas = JSON.parse(args.schemas); + + if (context.columns) { + context.columns.forEach(column => { + column.aggConfig.aggConfigs.schemas = visType.schemas.all; + }); + + Object.keys(schemas).forEach(key => { + schemas[key].forEach(i => { + context.columns[i].aggConfig.schema = key; + }); + }); + } + + const convertedData = await responseHandler(context); + + return { + type: 'render', + as: 'visualization', + value: { + visData: convertedData, + visConfig: { + type: args.type, + params: visConfigParams, + }, + params: { + listenOnChange: true, + } + }, + }; + }); + }, +}); diff --git a/src/core_plugins/interpreter/public/functions/regionmap.js b/src/core_plugins/interpreter/public/functions/regionmap.js new file mode 100644 index 0000000000000..ed033ed39a5a0 --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/regionmap.js @@ -0,0 +1,76 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export default () => ({ + name: 'regionmap', + type: 'render', + context: { + types: [ + 'kibana_table' + ], + }, + help: 'A simple regionmap visualization.', + args: { + bucket: { + types: ['string'], + default: '0', + help: 'bucket column index id or name', + multi: false, + }, + metric: { + types: ['string'], + default: '1', + help: 'metric column index id or name', + multi: false, + }, + visConfig: { + types: ['string', 'null'], + default: '"{}"', + help: 'config of the visualization', + multi: false, + }, + }, + fn(context, args) { + const visConfigParams = JSON.parse(args.visConfig || {}); + const metricColumn = context.columns.find((column, i) => + column.id === args.metric || column.name === args.metric || i === parseInt(args.metric) + ); + const bucketColumn = context.columns.find((column, i) => + column.id === args.bucket || column.name === args.bucket || i === parseInt(args.bucket) + ); + + metricColumn.aggConfig.schema = 'metric'; + bucketColumn.aggConfig.schema = 'segment'; + + return { + type: 'render', + as: 'visualization', + value: { + visData: context, + visConfig: { + type: 'region_map', + params: visConfigParams, + }, + params: { + listenOnChange: true, + } + }, + }; + }, +}); diff --git a/src/core_plugins/interpreter/public/functions/table.js b/src/core_plugins/interpreter/public/functions/table.js new file mode 100644 index 0000000000000..94e9f4389f6ea --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/table.js @@ -0,0 +1,97 @@ +/* + * 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 { LegacyResponseHandlerProvider } from 'ui/vis/response_handlers/legacy'; + +// eslint-disable-next-line new-cap +const responseHandler = LegacyResponseHandlerProvider().handler; + +export default () => ({ + name: 'kibana_table', + type: 'render', + context: { + types: [ + 'kibana_table' + ], + }, + help: 'A simple metric visualization.', + args: { + bucket: { + types: ['string'], + help: 'bucket column index id or name', + multi: true, + }, + split: { + types: ['string'], + help: 'chart split column index id or name', + multi: true, + }, + metric: { + types: ['string'], + default: '1', + help: 'metric column index id or name', + multi: true, + }, + visConfig: { + types: ['string', 'null'], + default: '"{}"', + help: 'config of the visualization', + multi: false, + }, + }, + async fn(context, args) { + const visConfigParams = JSON.parse(args.visConfig || {}); + args.metric.forEach(metric => { + const metricColumn = context.columns.find((column, i) => + column.id === metric || column.name === metric || i === parseInt(metric)); + metricColumn.aggConfig.schema = 'metric'; + }); + if (args.bucket) { + args.bucket.forEach(bucket => { + const bucketColumn = context.columns.find((column, i) => + column.id === bucket || column.name === bucket || i === parseInt(bucket)); + bucketColumn.aggConfig.schema = 'bucket'; + }); + } + if (args.split) { + args.split.forEach(split => { + const splitColumn = context.columns.find((column, i) => + column.id === split || column.name === split || i === parseInt(split)); + splitColumn.aggConfig.schema = 'split'; + }); + } + + const convertedData = await responseHandler(context); + + return { + type: 'render', + as: 'visualization', + value: { + visData: convertedData, + visConfig: { + type: 'table', + params: visConfigParams, + }, + params: { + listenOnChange: true, + } + }, + }; + }, +}); diff --git a/src/core_plugins/interpreter/public/functions/tagcloud.js b/src/core_plugins/interpreter/public/functions/tagcloud.js new file mode 100644 index 0000000000000..c235a2d4a9609 --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/tagcloud.js @@ -0,0 +1,76 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export default () => ({ + name: 'tagcloud', + type: 'render', + context: { + types: [ + 'kibana_table' + ], + }, + help: 'A simple tagcloud visualization.', + args: { + bucket: { + types: ['string'], + default: '0', + help: 'bucket column index id or name', + multi: false, + }, + metric: { + types: ['string'], + default: '1', + help: 'metric column index id or name', + multi: false, + }, + visConfig: { + types: ['string', 'null'], + default: '"{}"', + help: 'config of the visualization', + multi: false, + }, + }, + fn(context, args) { + const visConfigParams = JSON.parse(args.visConfig || {}); + const metricColumn = context.columns.find((column, i) => + column.id === args.metric || column.name === args.metric || i === parseInt(args.metric) + ); + const bucketColumn = context.columns.find((column, i) => + column.id === args.bucket || column.name === args.bucket || i === parseInt(args.bucket) + ); + + metricColumn.aggConfig.schema = 'metric'; + bucketColumn.aggConfig.schema = 'segment'; + + return { + type: 'render', + as: 'visualization', + value: { + visData: context, + visConfig: { + type: 'tag_cloud', + params: visConfigParams, + }, + params: { + listenOnChange: true, + } + }, + }; + }, +}); diff --git a/src/core_plugins/interpreter/public/functions/tilemap.js b/src/core_plugins/interpreter/public/functions/tilemap.js new file mode 100644 index 0000000000000..827e418d4bb9b --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/tilemap.js @@ -0,0 +1,82 @@ +/* + * 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 { makeGeoJsonResponseHandler } from 'plugins/tile_map/coordinatemap_response_handler'; + +const responseHandler = makeGeoJsonResponseHandler(); + +export default () => ({ + name: 'tilemap', + type: 'render', + context: { + types: [ + 'kibana_table' + ], + }, + help: 'A simple tilemap visualization.', + args: { + bucket: { + types: ['string'], + default: '0', + help: 'bucket column index id or name', + multi: false, + }, + metric: { + types: ['string'], + default: '1', + help: 'metric column index id or name', + multi: false, + }, + visConfig: { + types: ['string', 'null'], + default: '"{}"', + help: 'config of the visualization', + multi: false, + }, + }, + fn(context, args) { + const visConfigParams = JSON.parse(args.visConfig || {}); + const metricColumn = context.columns.find((column, i) => + column.id === args.metric || column.name === args.metric || i === parseInt(args.metric) + ); + const bucketColumn = context.columns.find((column, i) => + column.id === args.bucket || column.name === args.bucket || i === parseInt(args.bucket) + ); + + metricColumn.aggConfig.schema = 'metric'; + bucketColumn.aggConfig.schema = 'segment'; + + const convertedData = responseHandler(context); + + return { + type: 'render', + as: 'visualization', + value: { + visData: convertedData, + visConfig: { + type: 'tile_map', + params: visConfigParams, + }, + params: { + listenOnChange: true, + } + }, + }; + }, +}); diff --git a/src/core_plugins/interpreter/public/functions/timelion_vis.js b/src/core_plugins/interpreter/public/functions/timelion_vis.js new file mode 100644 index 0000000000000..bd1af09e32769 --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/timelion_vis.js @@ -0,0 +1,73 @@ +/* + * 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 _ from 'lodash'; + +import { TimelionRequestHandlerProvider } from '../../../timelion/public/vis/timelion_request_handler'; + + +import chrome from 'ui/chrome'; + + +export default () => ({ + name: 'timelion_vis', + type: 'render', + context: { + types: [ + 'kibana_context', + 'null', + ], + }, + help: 'Run tsvb request.', + args: { + expression: { + types: ['string'], + default: '".es(*)"', + help: 'timelion expression definition', + multi: false, + }, + interval: { + types: ['string', 'null'], + default: 'auto', + help: 'timelion interval', + multi: false, + } + }, + fn(context, args) { + return chrome.dangerouslyGetActiveInjector().then(async $injector => { + const Private = $injector.get('Private'); + const timelionRequestHandler = Private(TimelionRequestHandlerProvider).handler; + + const response = await timelionRequestHandler({ + timeRange: _.get(context, 'timeRange', null), + query: _.get(context, 'query', null), + filters: _.get(context, 'filters', null), + forceFetch: true, + visParams: { expression: args.expression, interval: args.interval } + }); + + return { + type: 'render', + as: 'visualization', + value: response, + }; + + }); + }, +}); diff --git a/src/core_plugins/interpreter/public/functions/tsvb.js b/src/core_plugins/interpreter/public/functions/tsvb.js new file mode 100644 index 0000000000000..ce2619f890d0c --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/tsvb.js @@ -0,0 +1,81 @@ +/* + * 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 _ from 'lodash'; + +import { MetricsRequestHandlerProvider } from '../../../metrics/public/kbn_vis_types/request_handler'; +import { PersistedState } from 'ui/persisted_state'; + +import chrome from 'ui/chrome'; + + +export default () => ({ + name: 'tsvb', + type: 'render', + context: { + types: [ + 'kibana_context', + 'null', + ], + }, + help: 'Run tsvb request.', + args: { + index: { + types: ['string', 'null'], + default: null, + }, + params: { + types: ['string'], + default: '""', + help: 'tsvb params definition', + multi: false, + }, + uiState: { + types: ['string'], + default: '""', + help: 'tsvb uiState', + multi: false + } + }, + fn(context, args) { + return chrome.dangerouslyGetActiveInjector().then(async $injector => { + const Private = $injector.get('Private'); + const metricsRequestHandler = Private(MetricsRequestHandlerProvider).handler; + + const params = JSON.parse(args.params); + const uiStateParams = args.uiState ? JSON.parse(args.uiState) : {}; + const uiState = new PersistedState(uiStateParams); + + const response = await metricsRequestHandler({ + timeRange: _.get(context, 'timeRange', null), + query: _.get(context, 'query', null), + filters: _.get(context, 'filters', null), + visParams: params, + uiState: uiState, + }); + + return { + type: 'render', + as: 'visualization', + value: response, + }; + + }); + }, +}); diff --git a/src/core_plugins/interpreter/public/functions/vega.js b/src/core_plugins/interpreter/public/functions/vega.js new file mode 100644 index 0000000000000..09733cb26234d --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/vega.js @@ -0,0 +1,68 @@ +/* + * 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 chrome from 'ui/chrome'; + +import { VegaRequestHandlerProvider } from '../../../vega/public/vega_request_handler'; +import _ from 'lodash'; + +export default () => ({ + name: 'vega', + type: 'render', + context: { + types: [], + }, + help: 'A vega visualization.', + args: { + spec: { + types: ['string'], + default: '{}', + help: 'config of the visualization', + multi: false, + }, + }, + fn(context, args) { + return chrome.dangerouslyGetActiveInjector().then(async $injector => { + const Private = $injector.get('Private'); + const vegaRequestHandler = Private(VegaRequestHandlerProvider).handler; + + const response = await vegaRequestHandler({ + timeRange: _.get(context, 'timeRange', null), + query: _.get(context, 'q', null), + filters: _.get(context, 'filters', null), + visParams: { spec: args.spec }, + forceFetch: true + }); + + return { + type: 'render', + as: 'visualization', + value: { + visData: response, + visConfig: { + type: 'vega', + params: { + spec: args.spec + } + }, + } + }; + }); + } +}); diff --git a/src/core_plugins/interpreter/public/functions/vislib.js b/src/core_plugins/interpreter/public/functions/vislib.js new file mode 100644 index 0000000000000..46beef81d4c46 --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/vislib.js @@ -0,0 +1,93 @@ +/* + * 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 { VisTypesRegistryProvider } from 'ui/registry/vis_types'; +import { VislibSeriesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib'; +import chrome from 'ui/chrome'; + +export default () => ({ + name: 'vislib', + type: 'render', + context: { + types: [ + 'kibana_table', 'null' + ], + }, + help: 'A vislib visualization.', + args: { + type: { + types: ['string'], + default: 'metric', + help: 'visualization type', + multi: false, + }, + schemas: { + types: ['string'], + default: '"{}"', + help: 'schemas configuration object', + multi: false, + }, + visConfig: { + types: ['string', 'null'], + default: '"{}"', + help: 'config of the visualization', + multi: false, + }, + }, + fn(context, args) { + return chrome.dangerouslyGetActiveInjector().then(async $injector => { + const Private = $injector.get('Private'); + const responseHandler = Private(VislibSeriesResponseHandlerProvider).handler; + const visTypes = Private(VisTypesRegistryProvider); + const visConfigParams = JSON.parse(args.visConfig || {}); + const schemas = JSON.parse(args.schemas); + const visType = visTypes.byName[args.type || 'histogram']; + + if (context.columns) { + // assign schemas to aggConfigs + context.columns.forEach(column => { + column.aggConfig.aggConfigs.schemas = visType.schemas.all; + }); + + Object.keys(schemas).forEach(key => { + schemas[key].forEach(i => { + context.columns[i].aggConfig.schema = key; + }); + }); + } + + const convertedData = await responseHandler(context); + + return { + type: 'render', + as: 'visualization', + value: { + visData: convertedData, + visConfig: { + type: args.type, + params: visConfigParams, + }, + params: { + listenOnChange: true, + } + }, + }; + }); + }, +}); diff --git a/src/core_plugins/interpreter/public/functions/visualization.js b/src/core_plugins/interpreter/public/functions/visualization.js new file mode 100644 index 0000000000000..2c85d8d9702e9 --- /dev/null +++ b/src/core_plugins/interpreter/public/functions/visualization.js @@ -0,0 +1,54 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export default () => ({ + name: 'visualization', + type: 'render', + context: { + types: [], + }, + help: 'A simple visualization.', + args: { + type: { + types: ['string'], + default: '', + help: 'visualization type', + multi: false, + }, + visConfig: { + types: ['string'], + default: '"{}"', + help: 'markdown configuration object', + multi: false, + } + }, + fn(context, args) { + const params = args.params ? JSON.parse(args.params) : {}; + return { + type: 'render', + as: 'visualization', + value: { + visConfig: { + type: args.type, + params: params + }, + } + }; + } +}); From 7150369b1e233237917618a8ef64e7d197d8e4ad Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 21 Nov 2018 10:37:20 +0100 Subject: [PATCH 04/32] using pipeline in visualize --- src/ui/public/vis/response_handlers/legacy.js | 22 ++- .../loader/__tests__/visualize_data_loader.js | 8 -- .../loader/__tests__/visualize_loader.js | 6 +- .../loader/embedded_visualize_handler.ts | 21 ++- .../visualize/loader/pipeline_data_loader.ts | 64 +++++++++ .../visualize/loader/pipeline_helpers.js | 134 ++++++++++++++++++ 6 files changed, 232 insertions(+), 23 deletions(-) create mode 100644 src/ui/public/visualize/loader/pipeline_data_loader.ts create mode 100644 src/ui/public/visualize/loader/pipeline_helpers.js diff --git a/src/ui/public/vis/response_handlers/legacy.js b/src/ui/public/vis/response_handlers/legacy.js index c91d562f1dc72..d90e426b9fa71 100644 --- a/src/ui/public/vis/response_handlers/legacy.js +++ b/src/ui/public/vis/response_handlers/legacy.js @@ -21,6 +21,14 @@ import _ from 'lodash'; import AggConfigResult from '../../vis/agg_config_result'; import { VisResponseHandlersRegistryProvider } from '../../registry/vis_response_handlers'; +const getSchema = column => { + return _.get(column, 'aggConfig.schema.name') || _.get(column, 'aggConfig.schema'); +}; + +const getType = column => { + return _.get(column, 'aggConfig.type.type') || _.get(column, 'aggConfig.type'); +}; + const LegacyResponseHandlerProvider = function () { return { @@ -30,12 +38,12 @@ const LegacyResponseHandlerProvider = function () { const converted = { tables: [] }; // check if there are buckets after the first metric - const metricsAtAllLevels = table.columns.findIndex(column => _.get(column, 'aggConfig.type.type') === 'metrics') < - _.findLastIndex(table.columns, column => _.get(column, 'aggConfig.type.type') === 'buckets'); + const metricsAtAllLevels = table.columns.findIndex(column => getType(column) === 'metrics') < + _.findLastIndex(table.columns, column => getType(column) === 'buckets'); - const splitColumn = table.columns.find(column => _.get(column, 'aggConfig.schema.name') === 'split'); - const numberOfMetrics = table.columns.filter(column => _.get(column, 'aggConfig.type.type') === 'metrics').length; - const numberOfBuckets = table.columns.filter(column => _.get(column, 'aggConfig.type.type') === 'buckets').length; + const splitColumn = table.columns.find(column => getSchema(column) === 'split'); + const numberOfMetrics = table.columns.filter(column => getType(column) === 'metrics').length; + const numberOfBuckets = table.columns.filter(column => getType(column) === 'buckets').length; const metricsPerBucket = numberOfMetrics / numberOfBuckets; if (splitColumn) { @@ -84,7 +92,7 @@ const LegacyResponseHandlerProvider = function () { column: table.columns.findIndex(c => c.id === column.id), row: rowIndex, }; - if (column.aggConfig.type.type === 'buckets') { + if (getType(column) === 'buckets') { previousSplitAgg = aggConfigResult; } return aggConfigResult; @@ -106,7 +114,7 @@ const LegacyResponseHandlerProvider = function () { column: columnIndex, row: rowIndex, }; - if (column.aggConfig.type.type === 'buckets') { + if (getType(column) === 'buckets') { previousSplitAgg = aggConfigResult; } return aggConfigResult; diff --git a/src/ui/public/visualize/loader/__tests__/visualize_data_loader.js b/src/ui/public/visualize/loader/__tests__/visualize_data_loader.js index fcd2b4b930618..4c2e31a46d7cb 100644 --- a/src/ui/public/visualize/loader/__tests__/visualize_data_loader.js +++ b/src/ui/public/visualize/loader/__tests__/visualize_data_loader.js @@ -60,14 +60,6 @@ describe('visualize data loader', () => { })); setupAndTeardownInjectorStub(); - it('should have a requestHandler', () => { - expect(visualizeDataLoader.requestHandler).to.be.a('function'); - }); - - it('should have a responseHandler', () => { - expect(visualizeDataLoader.responseHandler).to.be.a('function'); - }); - describe('fetch', () => { it('should be a function', () => { expect(visualizeDataLoader.fetch).to.be.a('function'); diff --git a/src/ui/public/visualize/loader/__tests__/visualize_loader.js b/src/ui/public/visualize/loader/__tests__/visualize_loader.js index 3f870e94d65e9..6f73ac872c539 100644 --- a/src/ui/public/visualize/loader/__tests__/visualize_loader.js +++ b/src/ui/public/visualize/loader/__tests__/visualize_loader.js @@ -32,7 +32,7 @@ import { getVisualizeLoader } from '../visualize_loader'; import { EmbeddedVisualizeHandler } from '../embedded_visualize_handler'; import { Inspector } from '../../../inspector/inspector'; import { dispatchRenderComplete } from '../../../render_complete'; -import { VisualizeDataLoader } from '../visualize_data_loader'; +import { PipelineDataLoader } from '../pipeline_data_loader'; import { PersistedState } from '../../../persisted_state'; import { DataAdapter } from '../../../inspector/adapters/data'; import { RequestAdapter } from '../../../inspector/adapters/request'; @@ -420,7 +420,7 @@ describe('visualize loader', () => { }); it('should allow updating the time range of the visualization', async () => { - const spy = sandbox.spy(VisualizeDataLoader.prototype, 'fetch'); + const spy = sandbox.spy(PipelineDataLoader.prototype, 'fetch'); const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), { timeRange: { from: 'now-7d', to: 'now' } @@ -442,7 +442,7 @@ describe('visualize loader', () => { }); it('should not set forceFetch on uiState change', async () => { - const spy = sandbox.spy(VisualizeDataLoader.prototype, 'fetch'); + const spy = sandbox.spy(PipelineDataLoader.prototype, 'fetch'); const uiState = new PersistedState(); loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), { diff --git a/src/ui/public/visualize/loader/embedded_visualize_handler.ts b/src/ui/public/visualize/loader/embedded_visualize_handler.ts index 66a630d331392..6f7a1c846b4e7 100644 --- a/src/ui/public/visualize/loader/embedded_visualize_handler.ts +++ b/src/ui/public/visualize/loader/embedded_visualize_handler.ts @@ -29,8 +29,9 @@ import { RenderCompleteHelper } from '../../render_complete'; import { AppState } from '../../state_management/app_state'; import { timefilter } from '../../timefilter'; import { RequestHandlerParams, Vis } from '../../vis'; +// import { VisualizeDataLoader } from './visualize_data_loader'; +import { PipelineDataLoader } from './pipeline_data_loader'; import { visualizationLoader } from './visualization_loader'; -import { VisualizeDataLoader } from './visualize_data_loader'; import { DataAdapter, RequestAdapter } from '../../inspector/adapters'; @@ -78,7 +79,7 @@ export class EmbeddedVisualizeHandler { private dataLoaderParams: RequestHandlerParams; private readonly appState?: AppState; private uiState: PersistedState; - private dataLoader: VisualizeDataLoader; + private dataLoader: PipelineDataLoader; private dataSubject: Rx.Subject; private readonly inspectorAdapters: Adapters = {}; private actions: any = {}; @@ -91,7 +92,7 @@ export class EmbeddedVisualizeHandler { ) { const { searchSource, vis } = savedObject; - const { appState, uiState, queryFilter, timeRange, filters, query, Private } = params; + const { appState, uiState, queryFilter, timeRange, filters, query } = params; this.dataLoaderParams = { searchSource, @@ -124,7 +125,7 @@ export class EmbeddedVisualizeHandler { this.uiState.on('change', this.onUiStateChange); timefilter.on('autoRefreshFetch', this.reload); - this.dataLoader = new VisualizeDataLoader(vis, Private); + this.dataLoader = new PipelineDataLoader(vis); this.renderCompleteHelper = new RenderCompleteHelper(element); this.inspectorAdapters = this.getActiveInspectorAdapters(); this.vis.openInspector = this.openInspector; @@ -346,13 +347,23 @@ export class EmbeddedVisualizeHandler { this.dataLoaderParams.forceFetch = forceFetch; this.dataLoaderParams.inspectorAdapters = this.inspectorAdapters; + this.vis.filters = { timeRange: this.dataLoaderParams.timeRange }; + return this.dataLoader.fetch(this.dataLoaderParams).then(data => { this.dataSubject.next(data); return data; }); }; - private render = (visData: any = null) => { + private render = (pipelineResponse: any = null) => { + let visData; + if (pipelineResponse) { + if (!pipelineResponse.value) { + throw new Error(pipelineResponse.error); + return; + } + visData = pipelineResponse.value.visData || pipelineResponse.value; + } return visualizationLoader .render(this.element, this.vis, visData, this.uiState, { listenOnChange: false, diff --git a/src/ui/public/visualize/loader/pipeline_data_loader.ts b/src/ui/public/visualize/loader/pipeline_data_loader.ts new file mode 100644 index 0000000000000..ad45aa80bad7d --- /dev/null +++ b/src/ui/public/visualize/loader/pipeline_data_loader.ts @@ -0,0 +1,64 @@ +/* + * 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 { toastNotifications } from 'ui/notify'; +import { RequestHandlerParams, Vis } from '../../vis'; + +// @ts-ignore No typing present +import { buildPipeline, runPipeline } from './pipeline_helpers'; + +export class PipelineDataLoader { + constructor(private readonly vis: Vis) {} + + public async fetch(params: RequestHandlerParams): Promise { + this.vis.requestError = undefined; + this.vis.showRequestError = false; + this.vis.pipelineExpression = buildPipeline(this.vis, params); + + try { + return await runPipeline( + this.vis.pipelineExpression, + { + query: params.query, + timeRange: params.timeRange, + filters: params.filters + ? params.filters.filter(filter => !filter.meta.disabled) + : undefined, + }, + { + inspectorAdapters: params.inspectorAdapters, + } + ); + } catch (error) { + params.searchSource.cancelQueued(); + + this.vis.requestError = error; + this.vis.showRequestError = + error.type && ['NO_OP_SEARCH_STRATEGY', 'UNSUPPORTED_QUERY'].includes(error.type); + + // tslint:disable-next-line + console.error(error); + + toastNotifications.addDanger({ + title: 'Error in visualization', + text: error.message, + }); + } + } +} diff --git a/src/ui/public/visualize/loader/pipeline_helpers.js b/src/ui/public/visualize/loader/pipeline_helpers.js new file mode 100644 index 0000000000000..8d8f76e64b1d5 --- /dev/null +++ b/src/ui/public/visualize/loader/pipeline_helpers.js @@ -0,0 +1,134 @@ +/* + * 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 { fromExpression } from '@kbn/interpreter/common/lib/ast'; +import { interpretAst } from '@kbn/interpreter/public/interpreter'; + +const getSchemas = (vis) => { + let cnt = 0; + const schemas = { + metric: [], + }; + const responseAggs = vis.aggs.getResponseAggs(); + const isHierarchical = vis.isHierarchical(); + const metrics = responseAggs.filter(agg => agg.type.type === 'metrics'); + responseAggs.forEach((agg) => { + if (!agg.enabled) return; + let schemaName = agg.schema ? agg.schema.name || agg.schema : null; + if (typeof schemaName === 'object') schemaName = null; + if (!schemaName) return; + if (!schemas[schemaName]) schemas[schemaName] = []; + if (!isHierarchical || agg.type.type !== 'metrics') { + schemas[schemaName].push(cnt++); + } + if (isHierarchical && agg.type.type !== 'metrics') { + metrics.forEach(() => { + schemas.metric.push(cnt++); + }); + } + }); + return schemas; +}; + +const vislibCharts = ['histogram', 'line', 'area', 'gauge', 'goal', 'heatmap', 'horizontal_bar']; + +export const buildPipeline = (vis, params) => { + const { searchSource } = params; + const { indexPattern } = vis; + const query = searchSource.getField('query'); + const filters = searchSource.getField('filter'); + const visState = vis.getCurrentState(); + + let pipeline = `kibana | kibana_context `; + if (query) { + pipeline += `q='${JSON.stringify(query).replace(/'/g, `\\'`)}' `; + } + if (filters) { + pipeline += `filters='${JSON.stringify(filters).replace(/'/g, `\\'`)}' `; + } + if (vis.savedSearchId) { + pipeline += `savedSearchId='${vis.savedSearchId}' `; + } + pipeline += '| '; + if (vis.type.requestHandler === 'courier') { + pipeline += ` + esaggs index='${indexPattern.id}' metricsAtAllLevels=${vis.isHierarchical()} + partialRows=${vis.params.showPartialRows || vis.type.name === 'tile_map'} + aggConfigs='${JSON.stringify(visState.aggs)}' | `; + } + if (vis.type.name === 'vega') { + pipeline += `vega spec='${visState.params.spec.replace(/'/g, `\\'`)}'`; + } else if (vis.type.name === 'input_control_vis') { + pipeline += `input_control_vis visConfig='${JSON.stringify(visState.params)}'`; + } else if (vis.type.name === 'metrics') { + pipeline += `tsvb params='${JSON.stringify(visState.params)}'`; + } else if (vis.type.name === 'timelion') { + pipeline += `timelion_vis expression='${visState.params.expression}' interval='${visState.params.interval}'`; + } else if (vis.type.name === 'markdown') { + pipeline += `markdown spec='${visState.params.markdown.replace(/'/g, `\\'`)}' + params='${JSON.stringify(visState.params).replace(/'/g, `\\'`)}'`; + } else if (vis.type.name === 'table') { + const schemas = getSchemas(vis); + pipeline += `kibana_table visConfig='${JSON.stringify(visState.params)}' `; + if (schemas.split) schemas.split.forEach(split => pipeline += `split='${split}' `); + if (schemas.bucket) schemas.bucket.forEach(bucket => pipeline += `bucket='${bucket}' `); + schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + } else if (vis.type.name === 'metric') { + const schemas = getSchemas(vis); + pipeline += `kibana_metric visConfig='${JSON.stringify(visState.params)}' `; + if (schemas.bucket) schemas.bucket.forEach(bucket => pipeline += `bucket='${bucket}' `); + schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + } else if (vis.type.name === 'tagcloud') { + const schemas = getSchemas(vis); + pipeline += `tagcloud visConfig='${JSON.stringify(visState.params)}' `; + schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); + schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + } else if (vis.type.name === 'region_map') { + const schemas = getSchemas(vis); + pipeline += `regionmap visConfig='${JSON.stringify(visState.params)}' `; + schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); + schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + } else if (vis.type.name === 'pie') { + pipeline += `kibana_pie visConfig='${JSON.stringify(visState.params)}' schemas='${JSON.stringify(getSchemas(vis))}'`; + } else if (vis.type.name === 'tile_map') { + const schemas = getSchemas(vis); + pipeline += `tilemap visConfig='${JSON.stringify(visState.params)}' `; + if (schemas.segment) schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); + schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + } else if (vislibCharts.includes(vis.type.name)) { + pipeline += `vislib type='${vis.type.name}' + visConfig='${JSON.stringify(visState.params)}' schemas='${JSON.stringify(getSchemas(vis))}'`; + } else { + pipeline += `visualization type='${vis.type.name}' visConfig='${JSON.stringify(visState.params)}'`; + } + + return pipeline; +}; + +export const runPipeline = async (pipeline, context, handlers) => { + try { + const ast = fromExpression(pipeline); + const pipelineResponse = await interpretAst(ast, context, handlers); + return pipelineResponse; + } catch (e) { + // eslint-disable-next-line no-console + console.log(e, pipeline); + } +}; From 44e9a2085a11465d0226e6a508930c9f43a9350c Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 21 Nov 2018 10:38:25 +0100 Subject: [PATCH 05/32] skipping irrelevant tests --- test/functional/apps/visualize/_data_table.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/functional/apps/visualize/_data_table.js b/test/functional/apps/visualize/_data_table.js index 5cd9b280c5550..0c3d200cf8000 100644 --- a/test/functional/apps/visualize/_data_table.js +++ b/test/functional/apps/visualize/_data_table.js @@ -392,9 +392,9 @@ export default function ({ getService, getPageObjects }) { ]); }); - it('should allow nesting multiple splits', async () => { + it.skip('should allow nesting multiple splits', async () => { // This test can be removed as soon as we remove the nested split table - // feature (https://github.com/elastic/kibana/issues/24560). + // feature (https://github.com/elastic/kibana/issues/24560). (7.0) await PageObjects.visualize.clickData(); await PageObjects.visualize.clickAddBucket(); await PageObjects.visualize.clickBucket('Split Table'); From 55478d480140f27f46a776538b95b7f54664d36d Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 21 Nov 2018 13:05:51 +0100 Subject: [PATCH 06/32] fixing test --- .../test_suites/embedding_visualizations/embed_by_id.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/plugin_functional/test_suites/embedding_visualizations/embed_by_id.js b/test/plugin_functional/test_suites/embedding_visualizations/embed_by_id.js index e068627e5e80e..bd0866882c1fc 100644 --- a/test/plugin_functional/test_suites/embedding_visualizations/embed_by_id.js +++ b/test/plugin_functional/test_suites/embedding_visualizations/embed_by_id.js @@ -18,6 +18,7 @@ */ import expect from 'expect.js'; +import { delay } from 'bluebird'; export default function ({ getService }) { const testSubjects = getService('testSubjects'); @@ -36,6 +37,7 @@ export default function ({ getService }) { await retry.try(async () => { await testSubjects.waitForDeleted('visLoadingIndicator'); }); + await delay(1000); } async function getTableData() { From 23284288c92af775dad0f386b9b6899d82f217ca Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 26 Nov 2018 10:15:23 +0100 Subject: [PATCH 07/32] fixing based on review from tim --- .../src/plugin/types/kibana_table.js | 6 +- .../interpreter/public/functions/esaggs.js | 8 +- .../public/functions/kibana_context.js | 2 +- .../interpreter/public/functions/markdown.js | 3 +- .../public/functions/timelion_vis.js | 13 ++-- .../interpreter/public/functions/tsvb.js | 13 +--- .../interpreter/public/functions/vega.js | 14 ++-- .../loader/embedded_visualize_handler.ts | 1 - .../visualize/loader/pipeline_helpers.js | 75 +++++++++++-------- 9 files changed, 73 insertions(+), 62 deletions(-) diff --git a/packages/kbn-interpreter/src/plugin/types/kibana_table.js b/packages/kbn-interpreter/src/plugin/types/kibana_table.js index bdc8da9fecf41..8e8750e88c0aa 100644 --- a/packages/kbn-interpreter/src/plugin/types/kibana_table.js +++ b/packages/kbn-interpreter/src/plugin/types/kibana_table.js @@ -17,7 +17,7 @@ * under the License. */ -import _ from 'lodash'; +import { map, each } from 'lodash'; export const kibanaTable = () => ({ name: 'kibana_table', @@ -76,7 +76,7 @@ export const kibanaTable = () => ({ pointseries: context => { const converted = { tables: [{ - columns: _.map(context.columns, (column, name) => { + columns: map(context.columns, (column, name) => { return { title: column.name || name, ...column @@ -84,7 +84,7 @@ export const kibanaTable = () => ({ }), rows: context.rows.map(row => { const crow = []; - _.each(context.columns, (column, i) => { + each(context.columns, (column, i) => { crow.push(row[i]); }); return crow; diff --git a/src/core_plugins/interpreter/public/functions/esaggs.js b/src/core_plugins/interpreter/public/functions/esaggs.js index 945ad83c13af2..8cdbbbb0efbb3 100644 --- a/src/core_plugins/interpreter/public/functions/esaggs.js +++ b/src/core_plugins/interpreter/public/functions/esaggs.js @@ -17,7 +17,7 @@ * under the License. */ -import _ from 'lodash'; +import { get } from 'lodash'; import { CourierRequestHandlerProvider } from 'ui/vis/request_handlers/courier'; import { AggConfigs } from 'ui/vis/agg_configs'; @@ -79,9 +79,9 @@ export default () => ({ const response = await courierRequestHandler({ searchSource: searchSource, aggs: aggs, - timeRange: _.get(context, 'timeRange', null), - query: _.get(context, 'query', null), - filters: _.get(context, 'filters', null), + timeRange: get(context, 'timeRange', null), + query: get(context, 'query', null), + filters: get(context, 'filters', null), forceFetch: true, isHierarchical: args.metricsAtAllLevels, partialRows: args.partialRows, diff --git a/src/core_plugins/interpreter/public/functions/kibana_context.js b/src/core_plugins/interpreter/public/functions/kibana_context.js index 4b5ea69dcee14..ae77d6a43ba1d 100644 --- a/src/core_plugins/interpreter/public/functions/kibana_context.js +++ b/src/core_plugins/interpreter/public/functions/kibana_context.js @@ -32,7 +32,7 @@ export default () => ({ args: { q: { types: ['string', 'null'], - aliases: ['query'], + aliases: ['query', '_'], help: 'A Lucene query string', default: null, }, diff --git a/src/core_plugins/interpreter/public/functions/markdown.js b/src/core_plugins/interpreter/public/functions/markdown.js index a553d86891675..274a7b7ee8d5b 100644 --- a/src/core_plugins/interpreter/public/functions/markdown.js +++ b/src/core_plugins/interpreter/public/functions/markdown.js @@ -25,8 +25,9 @@ export default () => ({ }, help: 'A markdown visualization.', args: { - spec: { + md: { types: ['string'], + aliases: [ '_' ], default: '', help: 'markdown', multi: false, diff --git a/src/core_plugins/interpreter/public/functions/timelion_vis.js b/src/core_plugins/interpreter/public/functions/timelion_vis.js index bd1af09e32769..a67b14c5bd7e0 100644 --- a/src/core_plugins/interpreter/public/functions/timelion_vis.js +++ b/src/core_plugins/interpreter/public/functions/timelion_vis.js @@ -17,14 +17,12 @@ * under the License. */ -import _ from 'lodash'; - +import { get } from 'lodash'; import { TimelionRequestHandlerProvider } from '../../../timelion/public/vis/timelion_request_handler'; import chrome from 'ui/chrome'; - export default () => ({ name: 'timelion_vis', type: 'render', @@ -34,10 +32,11 @@ export default () => ({ 'null', ], }, - help: 'Run tsvb request.', + help: 'Timelion visualization.', args: { expression: { types: ['string'], + aliases: ['_'], default: '".es(*)"', help: 'timelion expression definition', multi: false, @@ -55,9 +54,9 @@ export default () => ({ const timelionRequestHandler = Private(TimelionRequestHandlerProvider).handler; const response = await timelionRequestHandler({ - timeRange: _.get(context, 'timeRange', null), - query: _.get(context, 'query', null), - filters: _.get(context, 'filters', null), + timeRange: get(context, 'timeRange', null), + query: get(context, 'query', null), + filters: get(context, 'filters', null), forceFetch: true, visParams: { expression: args.expression, interval: args.interval } }); diff --git a/src/core_plugins/interpreter/public/functions/tsvb.js b/src/core_plugins/interpreter/public/functions/tsvb.js index ce2619f890d0c..f37392009ad08 100644 --- a/src/core_plugins/interpreter/public/functions/tsvb.js +++ b/src/core_plugins/interpreter/public/functions/tsvb.js @@ -17,8 +17,7 @@ * under the License. */ -import _ from 'lodash'; - +import { get } from 'lodash'; import { MetricsRequestHandlerProvider } from '../../../metrics/public/kbn_vis_types/request_handler'; import { PersistedState } from 'ui/persisted_state'; @@ -36,10 +35,6 @@ export default () => ({ }, help: 'Run tsvb request.', args: { - index: { - types: ['string', 'null'], - default: null, - }, params: { types: ['string'], default: '""', @@ -63,9 +58,9 @@ export default () => ({ const uiState = new PersistedState(uiStateParams); const response = await metricsRequestHandler({ - timeRange: _.get(context, 'timeRange', null), - query: _.get(context, 'query', null), - filters: _.get(context, 'filters', null), + timeRange: get(context, 'timeRange', null), + query: get(context, 'query', null), + filters: get(context, 'filters', null), visParams: params, uiState: uiState, }); diff --git a/src/core_plugins/interpreter/public/functions/vega.js b/src/core_plugins/interpreter/public/functions/vega.js index 09733cb26234d..0028858fe1c79 100644 --- a/src/core_plugins/interpreter/public/functions/vega.js +++ b/src/core_plugins/interpreter/public/functions/vega.js @@ -17,16 +17,18 @@ * under the License. */ +import { get } from 'lodash'; import chrome from 'ui/chrome'; - import { VegaRequestHandlerProvider } from '../../../vega/public/vega_request_handler'; -import _ from 'lodash'; export default () => ({ name: 'vega', type: 'render', context: { - types: [], + types: [ + 'kibana_context', + 'null', + ], }, help: 'A vega visualization.', args: { @@ -43,9 +45,9 @@ export default () => ({ const vegaRequestHandler = Private(VegaRequestHandlerProvider).handler; const response = await vegaRequestHandler({ - timeRange: _.get(context, 'timeRange', null), - query: _.get(context, 'q', null), - filters: _.get(context, 'filters', null), + timeRange: get(context, 'timeRange', null), + query: get(context, 'q', null), + filters: get(context, 'filters', null), visParams: { spec: args.spec }, forceFetch: true }); diff --git a/src/ui/public/visualize/loader/embedded_visualize_handler.ts b/src/ui/public/visualize/loader/embedded_visualize_handler.ts index 6f7a1c846b4e7..457aa2e8aa502 100644 --- a/src/ui/public/visualize/loader/embedded_visualize_handler.ts +++ b/src/ui/public/visualize/loader/embedded_visualize_handler.ts @@ -360,7 +360,6 @@ export class EmbeddedVisualizeHandler { if (pipelineResponse) { if (!pipelineResponse.value) { throw new Error(pipelineResponse.error); - return; } visData = pipelineResponse.value.visData || pipelineResponse.value; } diff --git a/src/ui/public/visualize/loader/pipeline_helpers.js b/src/ui/public/visualize/loader/pipeline_helpers.js index 8d8f76e64b1d5..1d5a8d7bbfde4 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers.js +++ b/src/ui/public/visualize/loader/pipeline_helpers.js @@ -18,8 +18,8 @@ */ -import { fromExpression } from '@kbn/interpreter/common/lib/ast'; -import { interpretAst } from '@kbn/interpreter/public/interpreter'; +import { fromExpression } from '@kbn/interpreter/common'; +import { interpretAst } from '@kbn/interpreter/public'; const getSchemas = (vis) => { let cnt = 0; @@ -47,6 +47,14 @@ const getSchemas = (vis) => { return schemas; }; +const prepareJson = (variable, data) => { + return `${variable}='${JSON.stringify(data).replace(/'/g, `\\'`)}' `; +}; + +const prepareString = (variable, data) => { + return `${variable}='${data.replace(/'/g, `\\'`)}' `; +}; + const vislibCharts = ['histogram', 'line', 'area', 'gauge', 'goal', 'heatmap', 'horizontal_bar']; export const buildPipeline = (vis, params) => { @@ -56,79 +64,86 @@ export const buildPipeline = (vis, params) => { const filters = searchSource.getField('filter'); const visState = vis.getCurrentState(); + // context let pipeline = `kibana | kibana_context `; if (query) { - pipeline += `q='${JSON.stringify(query).replace(/'/g, `\\'`)}' `; + pipeline += prepareJson('query', query); } if (filters) { - pipeline += `filters='${JSON.stringify(filters).replace(/'/g, `\\'`)}' `; + pipeline += prepareJson('filters', filters); } if (vis.savedSearchId) { - pipeline += `savedSearchId='${vis.savedSearchId}' `; + pipeline += prepareString('savedSearchId', vis.savedSearchId); } pipeline += '| '; + + // request handler if (vis.type.requestHandler === 'courier') { - pipeline += ` - esaggs index='${indexPattern.id}' metricsAtAllLevels=${vis.isHierarchical()} + pipeline += `esaggs + ${prepareString('index', indexPattern.id)} + metricsAtAllLevels=${vis.isHierarchical()} partialRows=${vis.params.showPartialRows || vis.type.name === 'tile_map'} - aggConfigs='${JSON.stringify(visState.aggs)}' | `; + ${prepareJson('aggConfigs', visState.aggs)} | `; } + + // response handler/visualization if (vis.type.name === 'vega') { - pipeline += `vega spec='${visState.params.spec.replace(/'/g, `\\'`)}'`; + pipeline += `vega ${prepareString('spec', visState.params.spec)}`; } else if (vis.type.name === 'input_control_vis') { - pipeline += `input_control_vis visConfig='${JSON.stringify(visState.params)}'`; + pipeline += `input_control_vis ${prepareJson('visConfig', visState.params)}`; } else if (vis.type.name === 'metrics') { - pipeline += `tsvb params='${JSON.stringify(visState.params)}'`; + pipeline += `tsvb ${prepareJson('params', visState.params)}`; } else if (vis.type.name === 'timelion') { - pipeline += `timelion_vis expression='${visState.params.expression}' interval='${visState.params.interval}'`; + pipeline += `timelion_vis + ${prepareString('expression', visState.params.expression)} + interval='${visState.params.interval}'`; } else if (vis.type.name === 'markdown') { - pipeline += `markdown spec='${visState.params.markdown.replace(/'/g, `\\'`)}' - params='${JSON.stringify(visState.params).replace(/'/g, `\\'`)}'`; + pipeline += `markdown + ${prepareString('md', visState.params.markdown)} + ${prepareJson('visConfig', visState.params)}`; } else if (vis.type.name === 'table') { const schemas = getSchemas(vis); - pipeline += `kibana_table visConfig='${JSON.stringify(visState.params)}' `; + pipeline += `kibana_table ${prepareJson('visConfig', visState.params)} `; if (schemas.split) schemas.split.forEach(split => pipeline += `split='${split}' `); if (schemas.bucket) schemas.bucket.forEach(bucket => pipeline += `bucket='${bucket}' `); schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); } else if (vis.type.name === 'metric') { const schemas = getSchemas(vis); - pipeline += `kibana_metric visConfig='${JSON.stringify(visState.params)}' `; + pipeline += `kibana_metric ${prepareJson('visConfig', visState.params)} `; if (schemas.bucket) schemas.bucket.forEach(bucket => pipeline += `bucket='${bucket}' `); schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); } else if (vis.type.name === 'tagcloud') { const schemas = getSchemas(vis); - pipeline += `tagcloud visConfig='${JSON.stringify(visState.params)}' `; + pipeline += `tagcloud ${prepareJson('visConfig', visState.params)} `; schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); } else if (vis.type.name === 'region_map') { const schemas = getSchemas(vis); - pipeline += `regionmap visConfig='${JSON.stringify(visState.params)}' `; + pipeline += `regionmap ${prepareJson('visConfig', visState.params)} `; schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); } else if (vis.type.name === 'pie') { - pipeline += `kibana_pie visConfig='${JSON.stringify(visState.params)}' schemas='${JSON.stringify(getSchemas(vis))}'`; + pipeline += `kibana_pie + ${prepareJson('visConfig', visState.params)} + ${prepareJson('schemas', getSchemas(vis))}`; } else if (vis.type.name === 'tile_map') { const schemas = getSchemas(vis); - pipeline += `tilemap visConfig='${JSON.stringify(visState.params)}' `; + pipeline += `tilemap ${prepareJson('visConfig', visState.params)} `; if (schemas.segment) schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); } else if (vislibCharts.includes(vis.type.name)) { pipeline += `vislib type='${vis.type.name}' - visConfig='${JSON.stringify(visState.params)}' schemas='${JSON.stringify(getSchemas(vis))}'`; + ${prepareJson('visConfig', visState.params)} + ${prepareJson('schemas', getSchemas(vis))}`; } else { - pipeline += `visualization type='${vis.type.name}' visConfig='${JSON.stringify(visState.params)}'`; + pipeline += `visualization type='${vis.type.name}' ${prepareJson('visConfig', visState.params)}`; } return pipeline; }; export const runPipeline = async (pipeline, context, handlers) => { - try { - const ast = fromExpression(pipeline); - const pipelineResponse = await interpretAst(ast, context, handlers); - return pipelineResponse; - } catch (e) { - // eslint-disable-next-line no-console - console.log(e, pipeline); - } + const ast = fromExpression(pipeline); + const pipelineResponse = await interpretAst(ast, context, handlers); + return pipelineResponse; }; From 7ff1284c18e06ecf43c6e8842b94a3fb1e67ec7d Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 26 Nov 2018 10:38:41 +0100 Subject: [PATCH 08/32] i18n --- src/core_plugins/interpreter/public/functions/esaggs.js | 4 ++-- .../interpreter/public/functions/input_control.js | 7 +++++-- src/core_plugins/interpreter/public/functions/kibana.js | 6 +++++- .../interpreter/public/functions/kibana_context.js | 9 ++++----- .../interpreter/public/functions/markdown.js | 7 +++++-- src/core_plugins/interpreter/public/functions/metric.js | 9 +++++---- src/core_plugins/interpreter/public/functions/pie.js | 7 ++++--- .../interpreter/public/functions/regionmap.js | 9 +++++---- src/core_plugins/interpreter/public/functions/table.js | 9 ++++----- .../interpreter/public/functions/tagcloud.js | 9 +++++---- src/core_plugins/interpreter/public/functions/tilemap.js | 8 ++++---- .../interpreter/public/functions/timelion_vis.js | 9 +++++---- src/core_plugins/interpreter/public/functions/tsvb.js | 9 +++++---- src/core_plugins/interpreter/public/functions/vega.js | 8 +++++--- src/core_plugins/interpreter/public/functions/vislib.js | 8 ++++---- .../interpreter/public/functions/visualization.js | 8 +++++--- 16 files changed, 72 insertions(+), 54 deletions(-) diff --git a/src/core_plugins/interpreter/public/functions/esaggs.js b/src/core_plugins/interpreter/public/functions/esaggs.js index 8cdbbbb0efbb3..289791b897c5e 100644 --- a/src/core_plugins/interpreter/public/functions/esaggs.js +++ b/src/core_plugins/interpreter/public/functions/esaggs.js @@ -18,6 +18,7 @@ */ import { get } from 'lodash'; +import { i18n } from '@kbn/i18n'; import { CourierRequestHandlerProvider } from 'ui/vis/request_handlers/courier'; import { AggConfigs } from 'ui/vis/agg_configs'; @@ -40,7 +41,7 @@ export default () => ({ 'null', ], }, - help: 'Run AggConfig aggregation.', + help: i18n('common.core_plugins.interpreter.public.functions.esaggs.help', { defaultMessage: 'Run AggConfig aggregation' }), args: { index: { types: ['string', 'null'], @@ -57,7 +58,6 @@ export default () => ({ aggConfigs: { types: ['string'], default: '""', - help: 'AggConfig definition', multi: false, }, }, diff --git a/src/core_plugins/interpreter/public/functions/input_control.js b/src/core_plugins/interpreter/public/functions/input_control.js index 29356fb06340f..a8417298d2380 100644 --- a/src/core_plugins/interpreter/public/functions/input_control.js +++ b/src/core_plugins/interpreter/public/functions/input_control.js @@ -17,18 +17,21 @@ * under the License. */ +import { i18n } from '@kbn/i18n'; + export default () => ({ name: 'input_control_vis', type: 'render', context: { types: [], }, - help: 'A input control visualization.', + help: i18n('common.core_plugins.interpreter.public.functions.input_control.help', { + defaultMessage: 'Input control visualization' + }), args: { visConfig: { types: ['string'], default: '"{}"', - help: 'markdown configuration object', multi: false, } }, diff --git a/src/core_plugins/interpreter/public/functions/kibana.js b/src/core_plugins/interpreter/public/functions/kibana.js index 9b580c54f7e0a..28f8244e4e034 100644 --- a/src/core_plugins/interpreter/public/functions/kibana.js +++ b/src/core_plugins/interpreter/public/functions/kibana.js @@ -17,11 +17,15 @@ * under the License. */ +import { i18n } from '@kbn/i18n'; + export default () => ({ name: 'kibana', type: 'kibana_context', context: {}, - help: 'Gets kibana global context.', + help: i18n('common.core_plugins.interpreter.public.functions.kibana.help', { + defaultMessage: 'Gets kibana global context' + }), args: {}, fn(context) { return { diff --git a/src/core_plugins/interpreter/public/functions/kibana_context.js b/src/core_plugins/interpreter/public/functions/kibana_context.js index ae77d6a43ba1d..306f76450e9d5 100644 --- a/src/core_plugins/interpreter/public/functions/kibana_context.js +++ b/src/core_plugins/interpreter/public/functions/kibana_context.js @@ -18,6 +18,7 @@ */ import chrome from 'ui/chrome'; +import { i18n } from '@kbn/i18n'; export default () => ({ name: 'kibana_context', @@ -28,27 +29,25 @@ export default () => ({ 'null', ], }, - help: 'Gets kibana global context.', + help: i18n('common.core_plugins.interpreter.public.functions.kibana_context.help', { + defaultMessage: 'Updates kibana global context' + }), args: { q: { types: ['string', 'null'], aliases: ['query', '_'], - help: 'A Lucene query string', default: null, }, filters: { types: ['string', 'null'], - help: 'Filters object', default: '"[]"', }, timeRange: { types: ['string', 'null'], - help: 'Sets date range to query', default: null, }, savedSearchId: { types: ['string', 'null'], - help: 'Sets date range to query', default: null, } }, diff --git a/src/core_plugins/interpreter/public/functions/markdown.js b/src/core_plugins/interpreter/public/functions/markdown.js index 274a7b7ee8d5b..bcde548502921 100644 --- a/src/core_plugins/interpreter/public/functions/markdown.js +++ b/src/core_plugins/interpreter/public/functions/markdown.js @@ -17,13 +17,17 @@ * under the License. */ +import { i18n } from '@kbn/i18n'; + export default () => ({ name: 'markdown', type: 'render', context: { types: [], }, - help: 'A markdown visualization.', + help: i18n('common.core_plugins.interpreter.public.functions.markdown.help', { + defaultMessage: 'Markdown visualization' + }), args: { md: { types: ['string'], @@ -35,7 +39,6 @@ export default () => ({ params: { types: ['string'], default: '"{}"', - help: 'markdown configuration object', multi: false, } }, diff --git a/src/core_plugins/interpreter/public/functions/metric.js b/src/core_plugins/interpreter/public/functions/metric.js index 44eb69934a39e..87177458c6b6f 100644 --- a/src/core_plugins/interpreter/public/functions/metric.js +++ b/src/core_plugins/interpreter/public/functions/metric.js @@ -17,6 +17,8 @@ * under the License. */ +import { i18n } from '@kbn/i18n'; + export default () => ({ name: 'kibana_metric', type: 'render', @@ -25,24 +27,23 @@ export default () => ({ 'kibana_table' ], }, - help: 'A simple metric visualization.', + help: i18n('common.core_plugins.interpreter.public.functions.metric.help', { + defaultMessage: 'Metric visualization' + }), args: { bucket: { types: ['string', 'null'], default: null, - help: 'bucket column index id or name', multi: false, }, metric: { types: ['string'], default: '1', - help: 'metric column index id or name', multi: true, }, visConfig: { types: ['string', 'null'], default: '"{}"', - help: 'config of the visualization', multi: false, }, }, diff --git a/src/core_plugins/interpreter/public/functions/pie.js b/src/core_plugins/interpreter/public/functions/pie.js index 0bd61523b5cf0..b4bcb9c3a85b1 100644 --- a/src/core_plugins/interpreter/public/functions/pie.js +++ b/src/core_plugins/interpreter/public/functions/pie.js @@ -20,6 +20,7 @@ import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import { VislibSlicesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib'; import chrome from 'ui/chrome'; +import { i18n } from '@kbn/i18n'; export default () => ({ name: 'kibana_pie', @@ -29,18 +30,18 @@ export default () => ({ 'kibana_table', 'null' ], }, - help: 'A vislib pie visualization.', + help: i18n('common.core_plugins.interpreter.public.functions.pie.help', { + defaultMessage: 'Pie visualization' + }), args: { schemas: { types: ['string'], default: '"{}"', - help: 'schemas configuration object', multi: false, }, visConfig: { types: ['string', 'null'], default: '"{}"', - help: 'config of the visualization', multi: false, }, }, diff --git a/src/core_plugins/interpreter/public/functions/regionmap.js b/src/core_plugins/interpreter/public/functions/regionmap.js index ed033ed39a5a0..2c283eb2e67ce 100644 --- a/src/core_plugins/interpreter/public/functions/regionmap.js +++ b/src/core_plugins/interpreter/public/functions/regionmap.js @@ -17,6 +17,8 @@ * under the License. */ +import { i18n } from '@kbn/i18n'; + export default () => ({ name: 'regionmap', type: 'render', @@ -25,24 +27,23 @@ export default () => ({ 'kibana_table' ], }, - help: 'A simple regionmap visualization.', + help: i18n('common.core_plugins.interpreter.public.functions.regionmap.help', { + defaultMessage: 'Regionmap visualization' + }), args: { bucket: { types: ['string'], default: '0', - help: 'bucket column index id or name', multi: false, }, metric: { types: ['string'], default: '1', - help: 'metric column index id or name', multi: false, }, visConfig: { types: ['string', 'null'], default: '"{}"', - help: 'config of the visualization', multi: false, }, }, diff --git a/src/core_plugins/interpreter/public/functions/table.js b/src/core_plugins/interpreter/public/functions/table.js index 94e9f4389f6ea..3e01409aef19c 100644 --- a/src/core_plugins/interpreter/public/functions/table.js +++ b/src/core_plugins/interpreter/public/functions/table.js @@ -18,6 +18,7 @@ */ import { LegacyResponseHandlerProvider } from 'ui/vis/response_handlers/legacy'; +import { i18n } from '@kbn/i18n'; // eslint-disable-next-line new-cap const responseHandler = LegacyResponseHandlerProvider().handler; @@ -30,28 +31,26 @@ export default () => ({ 'kibana_table' ], }, - help: 'A simple metric visualization.', + help: i18n('common.core_plugins.interpreter.public.functions.table.help', { + defaultMessage: 'Table visualization' + }), args: { bucket: { types: ['string'], - help: 'bucket column index id or name', multi: true, }, split: { types: ['string'], - help: 'chart split column index id or name', multi: true, }, metric: { types: ['string'], default: '1', - help: 'metric column index id or name', multi: true, }, visConfig: { types: ['string', 'null'], default: '"{}"', - help: 'config of the visualization', multi: false, }, }, diff --git a/src/core_plugins/interpreter/public/functions/tagcloud.js b/src/core_plugins/interpreter/public/functions/tagcloud.js index c235a2d4a9609..add4d8b632da5 100644 --- a/src/core_plugins/interpreter/public/functions/tagcloud.js +++ b/src/core_plugins/interpreter/public/functions/tagcloud.js @@ -17,6 +17,8 @@ * under the License. */ +import { i18n } from '@kbn/i18n'; + export default () => ({ name: 'tagcloud', type: 'render', @@ -25,24 +27,23 @@ export default () => ({ 'kibana_table' ], }, - help: 'A simple tagcloud visualization.', + help: i18n('common.core_plugins.interpreter.public.functions.tagcloud.help', { + defaultMessage: 'Tagcloud visualization' + }), args: { bucket: { types: ['string'], default: '0', - help: 'bucket column index id or name', multi: false, }, metric: { types: ['string'], default: '1', - help: 'metric column index id or name', multi: false, }, visConfig: { types: ['string', 'null'], default: '"{}"', - help: 'config of the visualization', multi: false, }, }, diff --git a/src/core_plugins/interpreter/public/functions/tilemap.js b/src/core_plugins/interpreter/public/functions/tilemap.js index 827e418d4bb9b..b8c71b9c3d217 100644 --- a/src/core_plugins/interpreter/public/functions/tilemap.js +++ b/src/core_plugins/interpreter/public/functions/tilemap.js @@ -18,6 +18,7 @@ */ import { makeGeoJsonResponseHandler } from 'plugins/tile_map/coordinatemap_response_handler'; +import { i18n } from '@kbn/i18n'; const responseHandler = makeGeoJsonResponseHandler(); @@ -29,24 +30,23 @@ export default () => ({ 'kibana_table' ], }, - help: 'A simple tilemap visualization.', + help: i18n('common.core_plugins.interpreter.public.functions.tilemap.help', { + defaultMessage: 'Tilemap visualization' + }), args: { bucket: { types: ['string'], default: '0', - help: 'bucket column index id or name', multi: false, }, metric: { types: ['string'], default: '1', - help: 'metric column index id or name', multi: false, }, visConfig: { types: ['string', 'null'], default: '"{}"', - help: 'config of the visualization', multi: false, }, }, diff --git a/src/core_plugins/interpreter/public/functions/timelion_vis.js b/src/core_plugins/interpreter/public/functions/timelion_vis.js index a67b14c5bd7e0..f7626f2d0ea50 100644 --- a/src/core_plugins/interpreter/public/functions/timelion_vis.js +++ b/src/core_plugins/interpreter/public/functions/timelion_vis.js @@ -18,7 +18,8 @@ */ import { get } from 'lodash'; -import { TimelionRequestHandlerProvider } from '../../../timelion/public/vis/timelion_request_handler'; +import { i18n } from '@kbn/i18n'; +import { TimelionRequestHandlerProvider } from 'plugins/timelion/vis/timelion_request_handler'; import chrome from 'ui/chrome'; @@ -32,19 +33,19 @@ export default () => ({ 'null', ], }, - help: 'Timelion visualization.', + help: i18n('common.core_plugins.interpreter.public.functions.timelion.help', { + defaultMessage: 'Timelion visualization' + }), args: { expression: { types: ['string'], aliases: ['_'], default: '".es(*)"', - help: 'timelion expression definition', multi: false, }, interval: { types: ['string', 'null'], default: 'auto', - help: 'timelion interval', multi: false, } }, diff --git a/src/core_plugins/interpreter/public/functions/tsvb.js b/src/core_plugins/interpreter/public/functions/tsvb.js index f37392009ad08..d49647441effd 100644 --- a/src/core_plugins/interpreter/public/functions/tsvb.js +++ b/src/core_plugins/interpreter/public/functions/tsvb.js @@ -18,7 +18,8 @@ */ import { get } from 'lodash'; -import { MetricsRequestHandlerProvider } from '../../../metrics/public/kbn_vis_types/request_handler'; +import { i18n } from '@kbn/i18n'; +import { MetricsRequestHandlerProvider } from 'plugins/metrics/kbn_vis_types/request_handler'; import { PersistedState } from 'ui/persisted_state'; import chrome from 'ui/chrome'; @@ -33,18 +34,18 @@ export default () => ({ 'null', ], }, - help: 'Run tsvb request.', + help: i18n('common.core_plugins.interpreter.public.functions.tsvb.help', { + defaultMessage: 'TSVB visualization' + }), args: { params: { types: ['string'], default: '""', - help: 'tsvb params definition', multi: false, }, uiState: { types: ['string'], default: '""', - help: 'tsvb uiState', multi: false } }, diff --git a/src/core_plugins/interpreter/public/functions/vega.js b/src/core_plugins/interpreter/public/functions/vega.js index 0028858fe1c79..434fe772b5804 100644 --- a/src/core_plugins/interpreter/public/functions/vega.js +++ b/src/core_plugins/interpreter/public/functions/vega.js @@ -18,8 +18,9 @@ */ import { get } from 'lodash'; +import { i18n } from '@kbn/i18n'; import chrome from 'ui/chrome'; -import { VegaRequestHandlerProvider } from '../../../vega/public/vega_request_handler'; +import { VegaRequestHandlerProvider } from 'plugins/vega/vega_request_handler'; export default () => ({ name: 'vega', @@ -30,12 +31,13 @@ export default () => ({ 'null', ], }, - help: 'A vega visualization.', + help: i18n('common.core_plugins.interpreter.public.functions.vega.help', { + defaultMessage: 'Vega visualization' + }), args: { spec: { types: ['string'], default: '{}', - help: 'config of the visualization', multi: false, }, }, diff --git a/src/core_plugins/interpreter/public/functions/vislib.js b/src/core_plugins/interpreter/public/functions/vislib.js index 46beef81d4c46..bd81cde46a67e 100644 --- a/src/core_plugins/interpreter/public/functions/vislib.js +++ b/src/core_plugins/interpreter/public/functions/vislib.js @@ -17,6 +17,7 @@ * under the License. */ +import { i18n } from '@kbn/i18n'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import { VislibSeriesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib'; import chrome from 'ui/chrome'; @@ -29,24 +30,23 @@ export default () => ({ 'kibana_table', 'null' ], }, - help: 'A vislib visualization.', + help: i18n('common.core_plugins.interpreter.public.functions.vislib.help', { + defaultMessage: 'Vislib visualization' + }), args: { type: { types: ['string'], default: 'metric', - help: 'visualization type', multi: false, }, schemas: { types: ['string'], default: '"{}"', - help: 'schemas configuration object', multi: false, }, visConfig: { types: ['string', 'null'], default: '"{}"', - help: 'config of the visualization', multi: false, }, }, diff --git a/src/core_plugins/interpreter/public/functions/visualization.js b/src/core_plugins/interpreter/public/functions/visualization.js index 2c85d8d9702e9..25ba5f2393792 100644 --- a/src/core_plugins/interpreter/public/functions/visualization.js +++ b/src/core_plugins/interpreter/public/functions/visualization.js @@ -17,24 +17,26 @@ * under the License. */ +import { i18n } from '@kbn/i18n'; + export default () => ({ name: 'visualization', type: 'render', context: { types: [], }, - help: 'A simple visualization.', + help: i18n('common.core_plugins.interpreter.public.functions.visualization.help', { + defaultMessage: 'A simple visualization' + }), args: { type: { types: ['string'], default: '', - help: 'visualization type', multi: false, }, visConfig: { types: ['string'], default: '"{}"', - help: 'markdown configuration object', multi: false, } }, From de13cb2bfb3057c844014888d3214c8802b14ef2 Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Tue, 27 Nov 2018 17:01:28 -0700 Subject: [PATCH 09/32] Fix broken i18n calls in core_plugins/interpreter. --- src/core_plugins/interpreter/public/functions/esaggs.js | 2 +- src/core_plugins/interpreter/public/functions/input_control.js | 2 +- src/core_plugins/interpreter/public/functions/kibana.js | 2 +- src/core_plugins/interpreter/public/functions/kibana_context.js | 2 +- src/core_plugins/interpreter/public/functions/markdown.js | 2 +- src/core_plugins/interpreter/public/functions/metric.js | 2 +- src/core_plugins/interpreter/public/functions/pie.js | 2 +- src/core_plugins/interpreter/public/functions/regionmap.js | 2 +- src/core_plugins/interpreter/public/functions/table.js | 2 +- src/core_plugins/interpreter/public/functions/tagcloud.js | 2 +- src/core_plugins/interpreter/public/functions/tilemap.js | 2 +- src/core_plugins/interpreter/public/functions/timelion_vis.js | 2 +- src/core_plugins/interpreter/public/functions/tsvb.js | 2 +- src/core_plugins/interpreter/public/functions/vega.js | 2 +- src/core_plugins/interpreter/public/functions/vislib.js | 2 +- src/core_plugins/interpreter/public/functions/visualization.js | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core_plugins/interpreter/public/functions/esaggs.js b/src/core_plugins/interpreter/public/functions/esaggs.js index 289791b897c5e..c537118c2c18c 100644 --- a/src/core_plugins/interpreter/public/functions/esaggs.js +++ b/src/core_plugins/interpreter/public/functions/esaggs.js @@ -41,7 +41,7 @@ export default () => ({ 'null', ], }, - help: i18n('common.core_plugins.interpreter.public.functions.esaggs.help', { defaultMessage: 'Run AggConfig aggregation' }), + help: i18n.translate('common.core_plugins.interpreter.public.functions.esaggs.help', { defaultMessage: 'Run AggConfig aggregation' }), args: { index: { types: ['string', 'null'], diff --git a/src/core_plugins/interpreter/public/functions/input_control.js b/src/core_plugins/interpreter/public/functions/input_control.js index a8417298d2380..cc111cb5e2200 100644 --- a/src/core_plugins/interpreter/public/functions/input_control.js +++ b/src/core_plugins/interpreter/public/functions/input_control.js @@ -25,7 +25,7 @@ export default () => ({ context: { types: [], }, - help: i18n('common.core_plugins.interpreter.public.functions.input_control.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.input_control.help', { defaultMessage: 'Input control visualization' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/kibana.js b/src/core_plugins/interpreter/public/functions/kibana.js index 28f8244e4e034..a408285d1c5f6 100644 --- a/src/core_plugins/interpreter/public/functions/kibana.js +++ b/src/core_plugins/interpreter/public/functions/kibana.js @@ -23,7 +23,7 @@ export default () => ({ name: 'kibana', type: 'kibana_context', context: {}, - help: i18n('common.core_plugins.interpreter.public.functions.kibana.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.kibana.help', { defaultMessage: 'Gets kibana global context' }), args: {}, diff --git a/src/core_plugins/interpreter/public/functions/kibana_context.js b/src/core_plugins/interpreter/public/functions/kibana_context.js index 306f76450e9d5..2d0d7cdf060ed 100644 --- a/src/core_plugins/interpreter/public/functions/kibana_context.js +++ b/src/core_plugins/interpreter/public/functions/kibana_context.js @@ -29,7 +29,7 @@ export default () => ({ 'null', ], }, - help: i18n('common.core_plugins.interpreter.public.functions.kibana_context.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.kibana_context.help', { defaultMessage: 'Updates kibana global context' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/markdown.js b/src/core_plugins/interpreter/public/functions/markdown.js index bcde548502921..7d3fda98c5d33 100644 --- a/src/core_plugins/interpreter/public/functions/markdown.js +++ b/src/core_plugins/interpreter/public/functions/markdown.js @@ -25,7 +25,7 @@ export default () => ({ context: { types: [], }, - help: i18n('common.core_plugins.interpreter.public.functions.markdown.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.markdown.help', { defaultMessage: 'Markdown visualization' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/metric.js b/src/core_plugins/interpreter/public/functions/metric.js index 87177458c6b6f..96f71ee84b3f0 100644 --- a/src/core_plugins/interpreter/public/functions/metric.js +++ b/src/core_plugins/interpreter/public/functions/metric.js @@ -27,7 +27,7 @@ export default () => ({ 'kibana_table' ], }, - help: i18n('common.core_plugins.interpreter.public.functions.metric.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.metric.help', { defaultMessage: 'Metric visualization' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/pie.js b/src/core_plugins/interpreter/public/functions/pie.js index b4bcb9c3a85b1..76c871115c893 100644 --- a/src/core_plugins/interpreter/public/functions/pie.js +++ b/src/core_plugins/interpreter/public/functions/pie.js @@ -30,7 +30,7 @@ export default () => ({ 'kibana_table', 'null' ], }, - help: i18n('common.core_plugins.interpreter.public.functions.pie.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.pie.help', { defaultMessage: 'Pie visualization' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/regionmap.js b/src/core_plugins/interpreter/public/functions/regionmap.js index 2c283eb2e67ce..4b8f7717c5f82 100644 --- a/src/core_plugins/interpreter/public/functions/regionmap.js +++ b/src/core_plugins/interpreter/public/functions/regionmap.js @@ -27,7 +27,7 @@ export default () => ({ 'kibana_table' ], }, - help: i18n('common.core_plugins.interpreter.public.functions.regionmap.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.regionmap.help', { defaultMessage: 'Regionmap visualization' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/table.js b/src/core_plugins/interpreter/public/functions/table.js index 3e01409aef19c..78a4bc62ccd82 100644 --- a/src/core_plugins/interpreter/public/functions/table.js +++ b/src/core_plugins/interpreter/public/functions/table.js @@ -31,7 +31,7 @@ export default () => ({ 'kibana_table' ], }, - help: i18n('common.core_plugins.interpreter.public.functions.table.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.table.help', { defaultMessage: 'Table visualization' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/tagcloud.js b/src/core_plugins/interpreter/public/functions/tagcloud.js index add4d8b632da5..9ce00c806c0d2 100644 --- a/src/core_plugins/interpreter/public/functions/tagcloud.js +++ b/src/core_plugins/interpreter/public/functions/tagcloud.js @@ -27,7 +27,7 @@ export default () => ({ 'kibana_table' ], }, - help: i18n('common.core_plugins.interpreter.public.functions.tagcloud.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.tagcloud.help', { defaultMessage: 'Tagcloud visualization' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/tilemap.js b/src/core_plugins/interpreter/public/functions/tilemap.js index b8c71b9c3d217..59e51d26a69c4 100644 --- a/src/core_plugins/interpreter/public/functions/tilemap.js +++ b/src/core_plugins/interpreter/public/functions/tilemap.js @@ -30,7 +30,7 @@ export default () => ({ 'kibana_table' ], }, - help: i18n('common.core_plugins.interpreter.public.functions.tilemap.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.tilemap.help', { defaultMessage: 'Tilemap visualization' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/timelion_vis.js b/src/core_plugins/interpreter/public/functions/timelion_vis.js index f7626f2d0ea50..a6216381166f6 100644 --- a/src/core_plugins/interpreter/public/functions/timelion_vis.js +++ b/src/core_plugins/interpreter/public/functions/timelion_vis.js @@ -33,7 +33,7 @@ export default () => ({ 'null', ], }, - help: i18n('common.core_plugins.interpreter.public.functions.timelion.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.timelion.help', { defaultMessage: 'Timelion visualization' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/tsvb.js b/src/core_plugins/interpreter/public/functions/tsvb.js index d49647441effd..bb4bd87e62369 100644 --- a/src/core_plugins/interpreter/public/functions/tsvb.js +++ b/src/core_plugins/interpreter/public/functions/tsvb.js @@ -34,7 +34,7 @@ export default () => ({ 'null', ], }, - help: i18n('common.core_plugins.interpreter.public.functions.tsvb.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.tsvb.help', { defaultMessage: 'TSVB visualization' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/vega.js b/src/core_plugins/interpreter/public/functions/vega.js index 434fe772b5804..b4b2f5dba0d3e 100644 --- a/src/core_plugins/interpreter/public/functions/vega.js +++ b/src/core_plugins/interpreter/public/functions/vega.js @@ -31,7 +31,7 @@ export default () => ({ 'null', ], }, - help: i18n('common.core_plugins.interpreter.public.functions.vega.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.vega.help', { defaultMessage: 'Vega visualization' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/vislib.js b/src/core_plugins/interpreter/public/functions/vislib.js index bd81cde46a67e..7f96c2cfd6cb8 100644 --- a/src/core_plugins/interpreter/public/functions/vislib.js +++ b/src/core_plugins/interpreter/public/functions/vislib.js @@ -30,7 +30,7 @@ export default () => ({ 'kibana_table', 'null' ], }, - help: i18n('common.core_plugins.interpreter.public.functions.vislib.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.vislib.help', { defaultMessage: 'Vislib visualization' }), args: { diff --git a/src/core_plugins/interpreter/public/functions/visualization.js b/src/core_plugins/interpreter/public/functions/visualization.js index 25ba5f2393792..befc51b77b8ee 100644 --- a/src/core_plugins/interpreter/public/functions/visualization.js +++ b/src/core_plugins/interpreter/public/functions/visualization.js @@ -25,7 +25,7 @@ export default () => ({ context: { types: [], }, - help: i18n('common.core_plugins.interpreter.public.functions.visualization.help', { + help: i18n.translate('common.core_plugins.interpreter.public.functions.visualization.help', { defaultMessage: 'A simple visualization' }), args: { From 7f7ece61b05da58e55005c084ea1e66b644eebb0 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 28 Nov 2018 08:16:56 +0100 Subject: [PATCH 10/32] fix broken merge --- src/core_plugins/interpreter/public/load_browser_plugins.js | 2 +- x-pack/plugins/canvas/public/components/app/index.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core_plugins/interpreter/public/load_browser_plugins.js b/src/core_plugins/interpreter/public/load_browser_plugins.js index 909b35b6c6490..1025d283bf515 100644 --- a/src/core_plugins/interpreter/public/load_browser_plugins.js +++ b/src/core_plugins/interpreter/public/load_browser_plugins.js @@ -37,6 +37,6 @@ function addFunction(fnDef) { functions.forEach(addFunction); createSocket(basePath).then(async () => { - await populateBrowserRegistries(types); + await populateBrowserRegistries(types, basePath); await initializeInterpreter(); }); diff --git a/x-pack/plugins/canvas/public/components/app/index.js b/x-pack/plugins/canvas/public/components/app/index.js index 2024746e27755..48373e8ad1a8c 100644 --- a/x-pack/plugins/canvas/public/components/app/index.js +++ b/x-pack/plugins/canvas/public/components/app/index.js @@ -44,11 +44,11 @@ const types = { const mapDispatchToProps = dispatch => ({ // TODO: the correct socket path should come from upstream, using the constant here is not ideal - setAppReady: () => async () => { + setAppReady: basePath => async () => { try { // initialize the socket and interpreter loadPrivateBrowserFunctions(); - await populateBrowserRegistries(types); + await populateBrowserRegistries(types, basePath); // set app state to ready dispatch(appReady()); From 134321c7ad983238e4f1cd9d1779bb58468e9a9a Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 28 Nov 2018 08:50:28 +0100 Subject: [PATCH 11/32] review feedback --- .../src/plugin/types/kibana_table.js | 7 +- .../visualize/loader/pipeline_helpers.js | 106 ++++++++++-------- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/packages/kbn-interpreter/src/plugin/types/kibana_table.js b/packages/kbn-interpreter/src/plugin/types/kibana_table.js index 8e8750e88c0aa..1a133720b5286 100644 --- a/packages/kbn-interpreter/src/plugin/types/kibana_table.js +++ b/packages/kbn-interpreter/src/plugin/types/kibana_table.js @@ -17,8 +17,6 @@ * under the License. */ -import { map, each } from 'lodash'; - export const kibanaTable = () => ({ name: 'kibana_table', serialize: context => { @@ -76,7 +74,8 @@ export const kibanaTable = () => ({ pointseries: context => { const converted = { tables: [{ - columns: map(context.columns, (column, name) => { + columns: Object.getKeys(context.columns).map(name => { + const column = context.columns[name]; return { title: column.name || name, ...column @@ -84,7 +83,7 @@ export const kibanaTable = () => ({ }), rows: context.rows.map(row => { const crow = []; - each(context.columns, (column, i) => { + Object.getKeys(context.columns).forEach((column, i) => { crow.push(row[i]); }); return crow; diff --git a/src/ui/public/visualize/loader/pipeline_helpers.js b/src/ui/public/visualize/loader/pipeline_helpers.js index 1d5a8d7bbfde4..89cd820b254fd 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers.js +++ b/src/ui/public/visualize/loader/pipeline_helpers.js @@ -57,6 +57,62 @@ const prepareString = (variable, data) => { const vislibCharts = ['histogram', 'line', 'area', 'gauge', 'goal', 'heatmap', 'horizontal_bar']; +const buildPipelineVisFunction = { + vega: visState => { + return `vega ${prepareString('spec', visState.params.spec)}`; + }, + input_control_vis: visState => { + return `input_control_vis ${prepareJson('visConfig', visState.params)}`; + }, + metrics: visState => { + return `tsvb ${prepareJson('params', visState.params)}`; + }, + timelion: visState => { + return `timelion_vis + ${prepareString('expression', visState.params.expression)} interval='${visState.params.interval}'`; + }, + markdown: visState => { + return `markdown + ${prepareString('md', visState.params.markdown)} ${prepareJson('visConfig', visState.params)}`; + }, + table: (visState, schemas) => { + let pipeline = `kibana_table ${prepareJson('visConfig', visState.params)} `; + if (schemas.split) schemas.split.forEach(split => pipeline += `split='${split}' `); + if (schemas.bucket) schemas.bucket.forEach(bucket => pipeline += `bucket='${bucket}' `); + schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + return pipeline; + }, + metric: (visState, schemas) => { + let pipeline = `kibana_metric ${prepareJson('visConfig', visState.params)} `; + if (schemas.bucket) schemas.bucket.forEach(bucket => pipeline += `bucket='${bucket}' `); + schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + return pipeline; + }, + tagcloud: (visState, schemas) => { + let pipeline = `tagcloud ${prepareJson('visConfig', visState.params)} `; + schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); + schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + return pipeline; + }, + region_map: (visState, schemas) => { + let pipeline = `regionmap ${prepareJson('visConfig', visState.params)} `; + schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); + schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + return pipeline; + }, + tile_map: (visState, schemas) => { + let pipeline = `tilemap ${prepareJson('visConfig', visState.params)} `; + if (schemas.segment) schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); + schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + return pipeline; + }, + pie: (visState, schemas) => { + return `kibana_pie + ${prepareJson('visConfig', visState.params)} + ${prepareJson('schemas', schemas)}`; + } +}; + export const buildPipeline = (vis, params) => { const { searchSource } = params; const { indexPattern } = vis; @@ -86,55 +142,13 @@ export const buildPipeline = (vis, params) => { ${prepareJson('aggConfigs', visState.aggs)} | `; } - // response handler/visualization - if (vis.type.name === 'vega') { - pipeline += `vega ${prepareString('spec', visState.params.spec)}`; - } else if (vis.type.name === 'input_control_vis') { - pipeline += `input_control_vis ${prepareJson('visConfig', visState.params)}`; - } else if (vis.type.name === 'metrics') { - pipeline += `tsvb ${prepareJson('params', visState.params)}`; - } else if (vis.type.name === 'timelion') { - pipeline += `timelion_vis - ${prepareString('expression', visState.params.expression)} - interval='${visState.params.interval}'`; - } else if (vis.type.name === 'markdown') { - pipeline += `markdown - ${prepareString('md', visState.params.markdown)} - ${prepareJson('visConfig', visState.params)}`; - } else if (vis.type.name === 'table') { - const schemas = getSchemas(vis); - pipeline += `kibana_table ${prepareJson('visConfig', visState.params)} `; - if (schemas.split) schemas.split.forEach(split => pipeline += `split='${split}' `); - if (schemas.bucket) schemas.bucket.forEach(bucket => pipeline += `bucket='${bucket}' `); - schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); - } else if (vis.type.name === 'metric') { - const schemas = getSchemas(vis); - pipeline += `kibana_metric ${prepareJson('visConfig', visState.params)} `; - if (schemas.bucket) schemas.bucket.forEach(bucket => pipeline += `bucket='${bucket}' `); - schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); - } else if (vis.type.name === 'tagcloud') { - const schemas = getSchemas(vis); - pipeline += `tagcloud ${prepareJson('visConfig', visState.params)} `; - schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); - schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); - } else if (vis.type.name === 'region_map') { - const schemas = getSchemas(vis); - pipeline += `regionmap ${prepareJson('visConfig', visState.params)} `; - schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); - schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); - } else if (vis.type.name === 'pie') { - pipeline += `kibana_pie - ${prepareJson('visConfig', visState.params)} - ${prepareJson('schemas', getSchemas(vis))}`; - } else if (vis.type.name === 'tile_map') { - const schemas = getSchemas(vis); - pipeline += `tilemap ${prepareJson('visConfig', visState.params)} `; - if (schemas.segment) schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); - schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + const schemas = getSchemas(vis); + if (buildPipelineVisFunction[vis.type.name]) { + pipeline += buildPipelineVisFunction[vis.type.name](visState, schemas); } else if (vislibCharts.includes(vis.type.name)) { pipeline += `vislib type='${vis.type.name}' ${prepareJson('visConfig', visState.params)} - ${prepareJson('schemas', getSchemas(vis))}`; + ${prepareJson('schemas', schemas)}`; } else { pipeline += `visualization type='${vis.type.name}' ${prepareJson('visConfig', visState.params)}`; } From 04f3c3a6622dd9413cd565b2f77770ef172d1bb6 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 28 Nov 2018 16:07:24 +0100 Subject: [PATCH 12/32] support for custom request and response handlers --- .../public/functions/visualization.js | 108 ++++++++++++++++-- .../visualize/loader/pipeline_helpers.js | 7 +- 2 files changed, 103 insertions(+), 12 deletions(-) diff --git a/src/core_plugins/interpreter/public/functions/visualization.js b/src/core_plugins/interpreter/public/functions/visualization.js index befc51b77b8ee..8b34400f31d30 100644 --- a/src/core_plugins/interpreter/public/functions/visualization.js +++ b/src/core_plugins/interpreter/public/functions/visualization.js @@ -17,7 +17,29 @@ * under the License. */ +import { get } from 'lodash'; import { i18n } from '@kbn/i18n'; +import chrome from 'ui/chrome'; +import { VisRequestHandlersRegistryProvider as RequestHandlersProvider } from 'ui/registry/vis_request_handlers'; +import { VisResponseHandlersRegistryProvider as ResponseHandlerProvider } from 'ui/registry/vis_response_handlers'; +import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; +import { IndexPatternsProvider } from 'ui/index_patterns'; +import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; +import { PersistedState } from 'ui/persisted_state'; + +function getHandler(from, type) { + if (typeof type === 'function') { + return type; + } + if (type === 'courier') { + return null; + } + const handlerDesc = from.find(handler => handler.name === type); + if (!handlerDesc) { + throw new Error(`Could not find handler "${type}".`); + } + return handlerDesc.handler; +} export default () => ({ name: 'visualization', @@ -29,6 +51,18 @@ export default () => ({ defaultMessage: 'A simple visualization' }), args: { + index: { + types: ['string', 'null'], + default: null, + }, + metricsAtAllLevels: { + types: ['boolean'], + default: false, + }, + partialRows: { + types: ['boolean'], + default: false, + }, type: { types: ['string'], default: '', @@ -40,17 +74,69 @@ export default () => ({ multi: false, } }, - fn(context, args) { - const params = args.params ? JSON.parse(args.params) : {}; - return { - type: 'render', - as: 'visualization', - value: { - visConfig: { - type: args.type, - params: params - }, + fn(context, args, handlers) { + return chrome.dangerouslyGetActiveInjector().then(async $injector => { + const Private = $injector.get('Private'); + const requestHandlers = Private(RequestHandlersProvider); + const responseHandlers = Private(ResponseHandlerProvider); + const visTypes = Private(VisTypesRegistryProvider); + const indexPatterns = Private(IndexPatternsProvider); + const queryFilter = Private(FilterBarQueryFilterProvider); + + const visConfigParams = JSON.parse(args.visConfig || {}); + const schemas = JSON.parse(args.schemas); + const visType = visTypes.byName[args.type || 'histogram']; + const requestHandler = getHandler(requestHandlers, visType.requestHandler); + const responseHandler = getHandler(responseHandlers, visType.responseHandler); + const indexPattern = args.index ? await indexPatterns.get(args.index) : null; + + const uiStateParams = args.uiState ? JSON.parse(args.uiState) : {}; + const uiState = new PersistedState(uiStateParams); + + if (requestHandler) { + context = await requestHandler({ + partialRows: args.partialRows, + metricsAtAllLevels: args.metricsAtAllLevels, + index: indexPattern, + visParams: visConfigParams, + timeRange: get(context, 'timeRange', null), + query: get(context, 'query', null), + filters: get(context, 'filters', null), + uiState: uiState, + inspectorAdapters: handlers.inspectorAdapters, + queryFilter, + forceFetch: true, + }); } - }; + + if (responseHandler) { + if (context.columns) { + // assign schemas to aggConfigs + context.columns.forEach(column => { + column.aggConfig.aggConfigs.schemas = visType.schemas.all; + }); + + Object.keys(schemas).forEach(key => { + schemas[key].forEach(i => { + context.columns[i].aggConfig.schema = key; + }); + }); + } + + context = await responseHandler(context); + } + + return { + type: 'render', + as: 'visualization', + value: { + visData: context, + visConfig: { + type: args.type, + params: visConfigParams + }, + } + }; + }); } }); diff --git a/src/ui/public/visualize/loader/pipeline_helpers.js b/src/ui/public/visualize/loader/pipeline_helpers.js index 89cd820b254fd..18c56d5090b2c 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers.js +++ b/src/ui/public/visualize/loader/pipeline_helpers.js @@ -150,7 +150,12 @@ export const buildPipeline = (vis, params) => { ${prepareJson('visConfig', visState.params)} ${prepareJson('schemas', schemas)}`; } else { - pipeline += `visualization type='${vis.type.name}' ${prepareJson('visConfig', visState.params)}`; + pipeline += `visualization type='${vis.type.name}' + ${prepareJson('visConfig', visState.params)} + ${prepareString('index', indexPattern.id)} + metricsAtAllLevels=${vis.isHierarchical()} + partialRows=${vis.params.showPartialRows || vis.type.name === 'tile_map'} + `; } return pipeline; From 338f08be8bdae738b6af00f03908b96a586d4977 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 28 Nov 2018 16:22:44 +0100 Subject: [PATCH 13/32] fixing markdown --- src/core_plugins/interpreter/public/functions/markdown.js | 8 ++++---- src/ui/public/visualize/loader/pipeline_helpers.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core_plugins/interpreter/public/functions/markdown.js b/src/core_plugins/interpreter/public/functions/markdown.js index 7d3fda98c5d33..8fa486db610a7 100644 --- a/src/core_plugins/interpreter/public/functions/markdown.js +++ b/src/core_plugins/interpreter/public/functions/markdown.js @@ -20,7 +20,7 @@ import { i18n } from '@kbn/i18n'; export default () => ({ - name: 'markdown', + name: 'kibana_markdown', type: 'render', context: { types: [], @@ -29,21 +29,21 @@ export default () => ({ defaultMessage: 'Markdown visualization' }), args: { - md: { + expression: { types: ['string'], aliases: [ '_' ], default: '', help: 'markdown', multi: false, }, - params: { + visConfig: { types: ['string'], default: '"{}"', multi: false, } }, fn(context, args) { - const params = args.params ? JSON.parse(args.params) : {}; + const params = args.visConfig ? JSON.parse(args.visConfig) : {}; return { type: 'render', as: 'visualization', diff --git a/src/ui/public/visualize/loader/pipeline_helpers.js b/src/ui/public/visualize/loader/pipeline_helpers.js index 18c56d5090b2c..06ecb099e2fe4 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers.js +++ b/src/ui/public/visualize/loader/pipeline_helpers.js @@ -72,8 +72,8 @@ const buildPipelineVisFunction = { ${prepareString('expression', visState.params.expression)} interval='${visState.params.interval}'`; }, markdown: visState => { - return `markdown - ${prepareString('md', visState.params.markdown)} ${prepareJson('visConfig', visState.params)}`; + return `kibana_markdown + ${prepareString('expression', visState.params.markdown)} ${prepareJson('visConfig', visState.params)}`; }, table: (visState, schemas) => { let pipeline = `kibana_table ${prepareJson('visConfig', visState.params)} `; From b00c64ad07fa2f6d26633f0c6cf2b87bd13d4fb5 Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Wed, 28 Nov 2018 23:31:05 -0700 Subject: [PATCH 14/32] Rewrite pipeline helpers in ts, add WIP unit tests. --- src/ui/public/vis/index.d.ts | 2 +- src/ui/public/vis/vis.d.ts | 7 ++ .../__tests__/build_pipeline.js | 85 ++++++++++++++ .../build_pipeline.ts} | 106 +++++++++++------- .../loader/pipeline_helpers/index.ts | 21 ++++ .../loader/pipeline_helpers/run_pipeline.ts | 27 +++++ 6 files changed, 206 insertions(+), 42 deletions(-) create mode 100644 src/ui/public/visualize/loader/pipeline_helpers/__tests__/build_pipeline.js rename src/ui/public/visualize/loader/{pipeline_helpers.js => pipeline_helpers/build_pipeline.ts} (61%) create mode 100644 src/ui/public/visualize/loader/pipeline_helpers/index.ts create mode 100644 src/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts diff --git a/src/ui/public/vis/index.d.ts b/src/ui/public/vis/index.d.ts index a16588c89e708..4b8295367a322 100644 --- a/src/ui/public/vis/index.d.ts +++ b/src/ui/public/vis/index.d.ts @@ -18,7 +18,7 @@ */ export { AggConfig } from './agg_config'; -export { Vis, VisProvider } from './vis'; +export { Vis, VisProvider, VisState } from './vis'; export { VisualizationController, VisType } from './vis_types/vis_type'; export * from './request_handlers'; export * from './response_handlers'; diff --git a/src/ui/public/vis/vis.d.ts b/src/ui/public/vis/vis.d.ts index ef2ac096f27f0..b5fb5390bf86c 100644 --- a/src/ui/public/vis/vis.d.ts +++ b/src/ui/public/vis/vis.d.ts @@ -30,3 +30,10 @@ export interface Vis { } export type VisProvider = (...dependencies: any[]) => Vis; + +export interface VisState { + title: string; + type: VisType; + params: any; + aggs: any[]; +} diff --git a/src/ui/public/visualize/loader/pipeline_helpers/__tests__/build_pipeline.js b/src/ui/public/visualize/loader/pipeline_helpers/__tests__/build_pipeline.js new file mode 100644 index 0000000000000..4ddb14c7baf43 --- /dev/null +++ b/src/ui/public/visualize/loader/pipeline_helpers/__tests__/build_pipeline.js @@ -0,0 +1,85 @@ +/* + * 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 expect from 'expect.js'; +import { buildPipelineVisFunction } from '../build_pipeline'; + +describe('visualize loader pipeline helpers: build pipeline', () => { + describe('buildPipelineVisFunction', () => { + it('handles vega function', () => { + const type = 'vega'; + const visState = { + params: { + spec: 'this is a test' + } + }; + const actual = buildPipelineVisFunction[type](visState); + expect(actual).to.be(`vega spec='this is a test' `); + }); + + it('handles input_control_vis function', () => { + const type = 'input_control_vis'; + const visState = { + params: { + some: 'nested', + data: { + here: true + } + } + }; + const actual = buildPipelineVisFunction[type](visState); + expect(actual).to.be(`input_control_vis visConfig='{"some":"nested","data":{"here":true}}' `); + }); + + it('handles metrics function', () => { + const type = 'metrics'; + const visState = { + params: { + foo: 'bar', + } + }; + const actual = buildPipelineVisFunction[type](visState); + expect(actual).to.be(`tsvb params='{"foo":"bar"}' `); + }); + + it('handles timelion function', () => { + const type = 'timelion'; + const visState = { + params: { + expression: 'foo', + interval: 'bar', + } + }; + const actual = buildPipelineVisFunction[type](visState); + expect(actual).to.be(`timelion_vis expression='foo' interval='bar' `); + }); + + it('handles markdown function', () => { + const type = 'markdown'; + const visState = { + params: { + markdown: '## hello _markdown_', + foo: 'bar', + } + }; + const actual = buildPipelineVisFunction[type](visState); + expect(actual).to.be(`kibana_markdown expression='## hello _markdown_' visConfig='{"markdown":"## hello _markdown_","foo":"bar"}' `); + }); + }); +}); diff --git a/src/ui/public/visualize/loader/pipeline_helpers.js b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts similarity index 61% rename from src/ui/public/visualize/loader/pipeline_helpers.js rename to src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts index 06ecb099e2fe4..87470862b8667 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers.js +++ b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts @@ -17,24 +17,46 @@ * under the License. */ +import { AggConfig, Vis, VisState } from 'ui/vis'; -import { fromExpression } from '@kbn/interpreter/common'; -import { interpretAst } from '@kbn/interpreter/public'; +type buildVisFunction = (visState: VisState, schemas?: any) => string; -const getSchemas = (vis) => { +interface BuildPipelineVisFunction { + [key: string]: buildVisFunction; +} + +const vislibCharts: string[] = [ + 'area', + 'gauge', + 'goal', + 'heatmap', + 'histogram', + 'horizontal_bar', + 'line', +]; + +export const getSchemas = (vis: Vis) => { let cnt = 0; - const schemas = { + const schemas: any = { metric: [], }; const responseAggs = vis.aggs.getResponseAggs(); const isHierarchical = vis.isHierarchical(); - const metrics = responseAggs.filter(agg => agg.type.type === 'metrics'); - responseAggs.forEach((agg) => { - if (!agg.enabled) return; + const metrics = responseAggs.filter((agg: AggConfig) => agg.type.type === 'metrics'); + responseAggs.forEach((agg: AggConfig) => { + if (!agg.enabled) { + return; + } let schemaName = agg.schema ? agg.schema.name || agg.schema : null; - if (typeof schemaName === 'object') schemaName = null; - if (!schemaName) return; - if (!schemas[schemaName]) schemas[schemaName] = []; + if (typeof schemaName === 'object') { + schemaName = null; + } + if (!schemaName) { + return; + } + if (!schemas[schemaName]) { + schemas[schemaName] = []; + } if (!isHierarchical || agg.type.type !== 'metrics') { schemas[schemaName].push(cnt++); } @@ -47,17 +69,15 @@ const getSchemas = (vis) => { return schemas; }; -const prepareJson = (variable, data) => { +export const prepareJson = (variable: string, data: object): string => { return `${variable}='${JSON.stringify(data).replace(/'/g, `\\'`)}' `; }; -const prepareString = (variable, data) => { +export const prepareString = (variable: string, data: string): string => { return `${variable}='${data.replace(/'/g, `\\'`)}' `; }; -const vislibCharts = ['histogram', 'line', 'area', 'gauge', 'goal', 'heatmap', 'horizontal_bar']; - -const buildPipelineVisFunction = { +export const buildPipelineVisFunction: BuildPipelineVisFunction = { vega: visState => { return `vega ${prepareString('spec', visState.params.spec)}`; }, @@ -68,52 +88,62 @@ const buildPipelineVisFunction = { return `tsvb ${prepareJson('params', visState.params)}`; }, timelion: visState => { - return `timelion_vis - ${prepareString('expression', visState.params.expression)} interval='${visState.params.interval}'`; + const expression = prepareString('expression', visState.params.expression); + const interval = prepareString('interval', visState.params.interval); + return `timelion_vis ${expression}${interval}`; }, markdown: visState => { - return `kibana_markdown - ${prepareString('expression', visState.params.markdown)} ${prepareJson('visConfig', visState.params)}`; + const expression = prepareString('expression', visState.params.markdown); + const visConfig = prepareJson('visConfig', visState.params); + return `kibana_markdown ${expression}${visConfig}`; }, table: (visState, schemas) => { let pipeline = `kibana_table ${prepareJson('visConfig', visState.params)} `; - if (schemas.split) schemas.split.forEach(split => pipeline += `split='${split}' `); - if (schemas.bucket) schemas.bucket.forEach(bucket => pipeline += `bucket='${bucket}' `); - schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + if (schemas.split) { + schemas.split.forEach(split => (pipeline += `split='${split}' `)); + } + if (schemas.bucket) { + schemas.bucket.forEach(bucket => (pipeline += `bucket='${bucket}' `)); + } + schemas.metric.forEach(metric => (pipeline += `metric='${metric}' `)); return pipeline; }, metric: (visState, schemas) => { let pipeline = `kibana_metric ${prepareJson('visConfig', visState.params)} `; - if (schemas.bucket) schemas.bucket.forEach(bucket => pipeline += `bucket='${bucket}' `); - schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + if (schemas.bucket) { + schemas.bucket.forEach(bucket => (pipeline += `bucket='${bucket}' `)); + } + schemas.metric.forEach(metric => (pipeline += `metric='${metric}' `)); return pipeline; }, tagcloud: (visState, schemas) => { let pipeline = `tagcloud ${prepareJson('visConfig', visState.params)} `; - schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); - schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + schemas.segment.forEach(bucket => (pipeline += `bucket='${bucket}' `)); + schemas.metric.forEach(metric => (pipeline += `metric='${metric}' `)); return pipeline; }, region_map: (visState, schemas) => { let pipeline = `regionmap ${prepareJson('visConfig', visState.params)} `; - schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); - schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + schemas.segment.forEach(bucket => (pipeline += `bucket='${bucket}' `)); + schemas.metric.forEach(metric => (pipeline += `metric='${metric}' `)); return pipeline; }, tile_map: (visState, schemas) => { let pipeline = `tilemap ${prepareJson('visConfig', visState.params)} `; - if (schemas.segment) schemas.segment.forEach(bucket => pipeline += `bucket='${bucket}' `); - schemas.metric.forEach(metric => pipeline += `metric='${metric}' `); + if (schemas.segment) { + schemas.segment.forEach(bucket => (pipeline += `bucket='${bucket}' `)); + } + schemas.metric.forEach(metric => (pipeline += `metric='${metric}' `)); return pipeline; }, pie: (visState, schemas) => { - return `kibana_pie - ${prepareJson('visConfig', visState.params)} - ${prepareJson('schemas', schemas)}`; - } + const visConfig = prepareJson('visConfig', visState.params); + const schemas = prepareJson('schemas', schemas); + return `kibana_pie ${visConfig}${schemas}`; + }, }; -export const buildPipeline = (vis, params) => { +export const buildPipeline = (vis: Vis, params) => { const { searchSource } = params; const { indexPattern } = vis; const query = searchSource.getField('query'); @@ -160,9 +190,3 @@ export const buildPipeline = (vis, params) => { return pipeline; }; - -export const runPipeline = async (pipeline, context, handlers) => { - const ast = fromExpression(pipeline); - const pipelineResponse = await interpretAst(ast, context, handlers); - return pipelineResponse; -}; diff --git a/src/ui/public/visualize/loader/pipeline_helpers/index.ts b/src/ui/public/visualize/loader/pipeline_helpers/index.ts new file mode 100644 index 0000000000000..69c29339a8713 --- /dev/null +++ b/src/ui/public/visualize/loader/pipeline_helpers/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { buildPipeline } from './build_pipeline'; +export { runPipeline } from './run_pipeline'; diff --git a/src/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts b/src/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts new file mode 100644 index 0000000000000..4a0c1555884cd --- /dev/null +++ b/src/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts @@ -0,0 +1,27 @@ +/* + * 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 { fromExpression } from '@kbn/interpreter/common'; +import { interpretAst } from '@kbn/interpreter/public'; + +export const runPipeline = async (pipeline: string, context, handlers) => { + const ast = fromExpression(pipeline); + const pipelineResponse = await interpretAst(ast, context, handlers); + return pipelineResponse; +}; From 1d9d35b70495417890a3e7c196e77f1adeee60e4 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 29 Nov 2018 10:21:39 +0100 Subject: [PATCH 15/32] changing the syntax for passing multiple metrics/buckets --- .../interpreter/public/functions/metric.js | 11 +++++--- .../interpreter/public/functions/table.js | 12 ++++---- .../loader/pipeline_helpers/build_pipeline.ts | 28 +++++++++---------- .../loader/pipeline_helpers/run_pipeline.ts | 6 ++-- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/core_plugins/interpreter/public/functions/metric.js b/src/core_plugins/interpreter/public/functions/metric.js index 96f71ee84b3f0..f3963ec758519 100644 --- a/src/core_plugins/interpreter/public/functions/metric.js +++ b/src/core_plugins/interpreter/public/functions/metric.js @@ -39,7 +39,7 @@ export default () => ({ metric: { types: ['string'], default: '1', - multi: true, + multi: false, }, visConfig: { types: ['string', 'null'], @@ -49,9 +49,12 @@ export default () => ({ }, fn(context, args) { const visConfigParams = JSON.parse(args.visConfig || {}); - const metricColumn = context.columns.find((column, i) => - column.id === args.metric || column.name === args.metric || i === parseInt(args.metric)); - metricColumn.aggConfig.schema = 'metric'; + const metrics = args.metric.split(','); + metrics.forEach(metric => { + const metricColumn = context.columns.find((column, i) => + column.id === metric || column.name === metric || i === parseInt(metric)); + metricColumn.aggConfig.schema = 'metric'; + }); if (args.bucket) { const bucketColumn = context.columns.find((column, i) => column.id === args.bucket || column.name === args.bucket || i === parseInt(args.bucket)); diff --git a/src/core_plugins/interpreter/public/functions/table.js b/src/core_plugins/interpreter/public/functions/table.js index 78a4bc62ccd82..9232c5296d5da 100644 --- a/src/core_plugins/interpreter/public/functions/table.js +++ b/src/core_plugins/interpreter/public/functions/table.js @@ -37,16 +37,16 @@ export default () => ({ args: { bucket: { types: ['string'], - multi: true, + multi: false, }, split: { types: ['string'], - multi: true, + multi: false, }, metric: { types: ['string'], default: '1', - multi: true, + multi: false, }, visConfig: { types: ['string', 'null'], @@ -56,20 +56,20 @@ export default () => ({ }, async fn(context, args) { const visConfigParams = JSON.parse(args.visConfig || {}); - args.metric.forEach(metric => { + args.metric.split(',').forEach(metric => { const metricColumn = context.columns.find((column, i) => column.id === metric || column.name === metric || i === parseInt(metric)); metricColumn.aggConfig.schema = 'metric'; }); if (args.bucket) { - args.bucket.forEach(bucket => { + args.bucket.split(',').forEach(bucket => { const bucketColumn = context.columns.find((column, i) => column.id === bucket || column.name === bucket || i === parseInt(bucket)); bucketColumn.aggConfig.schema = 'bucket'; }); } if (args.split) { - args.split.forEach(split => { + args.split.split(',').forEach(split => { const splitColumn = context.columns.find((column, i) => column.id === split || column.name === split || i === parseInt(split)); splitColumn.aggConfig.schema = 'split'; diff --git a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts index 87470862b8667..10ec25d8b0e42 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts +++ b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts @@ -100,50 +100,50 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { table: (visState, schemas) => { let pipeline = `kibana_table ${prepareJson('visConfig', visState.params)} `; if (schemas.split) { - schemas.split.forEach(split => (pipeline += `split='${split}' `)); + pipeline += `split='${schemas.split.join(',')}' `; } if (schemas.bucket) { - schemas.bucket.forEach(bucket => (pipeline += `bucket='${bucket}' `)); + pipeline += `bucket='${schemas.bucket.join(',')}' `; } - schemas.metric.forEach(metric => (pipeline += `metric='${metric}' `)); + pipeline += `metric='${schemas.metric.join(',')}' `; return pipeline; }, metric: (visState, schemas) => { let pipeline = `kibana_metric ${prepareJson('visConfig', visState.params)} `; if (schemas.bucket) { - schemas.bucket.forEach(bucket => (pipeline += `bucket='${bucket}' `)); + pipeline += `bucket='${schemas.bucket.join(',')}' `; } - schemas.metric.forEach(metric => (pipeline += `metric='${metric}' `)); + pipeline += `metric='${schemas.metric.join(',')}' `; return pipeline; }, tagcloud: (visState, schemas) => { let pipeline = `tagcloud ${prepareJson('visConfig', visState.params)} `; - schemas.segment.forEach(bucket => (pipeline += `bucket='${bucket}' `)); - schemas.metric.forEach(metric => (pipeline += `metric='${metric}' `)); + pipeline += `bucket='${schemas.segment.join(',')}' `; + pipeline += `metric='${schemas.metric.join(',')}' `; return pipeline; }, region_map: (visState, schemas) => { let pipeline = `regionmap ${prepareJson('visConfig', visState.params)} `; - schemas.segment.forEach(bucket => (pipeline += `bucket='${bucket}' `)); - schemas.metric.forEach(metric => (pipeline += `metric='${metric}' `)); + pipeline += `bucket='${schemas.segment.join(',')}' `; + pipeline += `metric='${schemas.metric.join(',')}' `; return pipeline; }, tile_map: (visState, schemas) => { let pipeline = `tilemap ${prepareJson('visConfig', visState.params)} `; if (schemas.segment) { - schemas.segment.forEach(bucket => (pipeline += `bucket='${bucket}' `)); + pipeline += `bucket='${schemas.segment.join(',')}' `; } - schemas.metric.forEach(metric => (pipeline += `metric='${metric}' `)); + pipeline += `metric='${schemas.metric.join(',')}' `; return pipeline; }, pie: (visState, schemas) => { const visConfig = prepareJson('visConfig', visState.params); - const schemas = prepareJson('schemas', schemas); - return `kibana_pie ${visConfig}${schemas}`; + const visSchemas = prepareJson('schemas', schemas); + return `kibana_pie ${visConfig} ${visSchemas}`; }, }; -export const buildPipeline = (vis: Vis, params) => { +export const buildPipeline = (vis: Vis, params: any) => { const { searchSource } = params; const { indexPattern } = vis; const query = searchSource.getField('query'); diff --git a/src/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts b/src/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts index 4a0c1555884cd..a3b98570c870f 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts +++ b/src/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts @@ -17,11 +17,13 @@ * under the License. */ +// @ts-ignore import { fromExpression } from '@kbn/interpreter/common'; +// @ts-ignore import { interpretAst } from '@kbn/interpreter/public'; -export const runPipeline = async (pipeline: string, context, handlers) => { - const ast = fromExpression(pipeline); +export const runPipeline = async (expression: string, context: any, handlers: any) => { + const ast = fromExpression(expression); const pipelineResponse = await interpretAst(ast, context, handlers); return pipelineResponse; }; From b43de6f1c4341dccd04ba52f8a6d3d2e0aea339d Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 29 Nov 2018 11:08:00 +0100 Subject: [PATCH 16/32] initialContext handler function --- .../interpreter/public/functions/kibana.js | 23 +++++++++++++++---- .../visualize/loader/pipeline_data_loader.ts | 15 ++++++------ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/core_plugins/interpreter/public/functions/kibana.js b/src/core_plugins/interpreter/public/functions/kibana.js index a408285d1c5f6..de75eba6e78a1 100644 --- a/src/core_plugins/interpreter/public/functions/kibana.js +++ b/src/core_plugins/interpreter/public/functions/kibana.js @@ -27,12 +27,27 @@ export default () => ({ defaultMessage: 'Gets kibana global context' }), args: {}, - fn(context) { + fn(context, args, handlers) { + const initialContext = handlers.getInitialContext ? handlers.getInitialContext() : {}; + + if (context.query) { + const contextQueries = Array.isArray(context.query) ? context.query : [context.query]; + initialContext.query = initialContext.query.concat(contextQueries); + } + + if (context.filters) { + // merge filters + initialContext.filters = initialContext.filters.concat(context.filters); + } + + const timeRange = initialContext.timeRange ? JSON.parse(initialContext.timeRange) : context.timeRange; + return { + ...context, type: 'kibana_context', - query: context.query, - filters: context.filters, - timeRange: context.timeRange, + query: initialContext.query, + filters: initialContext.filters, + timeRange: timeRange, }; }, }); diff --git a/src/ui/public/visualize/loader/pipeline_data_loader.ts b/src/ui/public/visualize/loader/pipeline_data_loader.ts index ad45aa80bad7d..c0dd9ed345996 100644 --- a/src/ui/public/visualize/loader/pipeline_data_loader.ts +++ b/src/ui/public/visualize/loader/pipeline_data_loader.ts @@ -34,14 +34,15 @@ export class PipelineDataLoader { try { return await runPipeline( this.vis.pipelineExpression, + {}, { - query: params.query, - timeRange: params.timeRange, - filters: params.filters - ? params.filters.filter(filter => !filter.meta.disabled) - : undefined, - }, - { + getInitialContext: () => ({ + query: params.query, + timeRange: params.timeRange, + filters: params.filters + ? params.filters.filter(filter => !filter.meta.disabled) + : undefined, + }), inspectorAdapters: params.inspectorAdapters, } ); From e1f911935fc30708cd98a01b738ba5ad34ec53b3 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 29 Nov 2018 11:12:20 +0100 Subject: [PATCH 17/32] cleaning up pipeline_data_loader --- .../visualize/loader/pipeline_data_loader.ts | 45 ++++++------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/src/ui/public/visualize/loader/pipeline_data_loader.ts b/src/ui/public/visualize/loader/pipeline_data_loader.ts index c0dd9ed345996..2933297ec8af0 100644 --- a/src/ui/public/visualize/loader/pipeline_data_loader.ts +++ b/src/ui/public/visualize/loader/pipeline_data_loader.ts @@ -17,7 +17,6 @@ * under the License. */ -import { toastNotifications } from 'ui/notify'; import { RequestHandlerParams, Vis } from '../../vis'; // @ts-ignore No typing present @@ -31,35 +30,19 @@ export class PipelineDataLoader { this.vis.showRequestError = false; this.vis.pipelineExpression = buildPipeline(this.vis, params); - try { - return await runPipeline( - this.vis.pipelineExpression, - {}, - { - getInitialContext: () => ({ - query: params.query, - timeRange: params.timeRange, - filters: params.filters - ? params.filters.filter(filter => !filter.meta.disabled) - : undefined, - }), - inspectorAdapters: params.inspectorAdapters, - } - ); - } catch (error) { - params.searchSource.cancelQueued(); - - this.vis.requestError = error; - this.vis.showRequestError = - error.type && ['NO_OP_SEARCH_STRATEGY', 'UNSUPPORTED_QUERY'].includes(error.type); - - // tslint:disable-next-line - console.error(error); - - toastNotifications.addDanger({ - title: 'Error in visualization', - text: error.message, - }); - } + return await runPipeline( + this.vis.pipelineExpression, + {}, + { + getInitialContext: () => ({ + query: params.query, + timeRange: params.timeRange, + filters: params.filters + ? params.filters.filter(filter => !filter.meta.disabled) + : undefined, + }), + inspectorAdapters: params.inspectorAdapters, + } + ); } } From 6d5b8a55cf204bd8ec46c5681c5c66a190eaf0af Mon Sep 17 00:00:00 2001 From: Tim Roes Date: Thu, 29 Nov 2018 13:36:02 +0100 Subject: [PATCH 18/32] Improve TS and autofix trailing spaces --- .../visualize/loader/pipeline_data_loader.ts | 2 -- .../loader/pipeline_helpers/build_pipeline.ts | 19 ++++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/ui/public/visualize/loader/pipeline_data_loader.ts b/src/ui/public/visualize/loader/pipeline_data_loader.ts index 2933297ec8af0..ac5c7c0a09bbb 100644 --- a/src/ui/public/visualize/loader/pipeline_data_loader.ts +++ b/src/ui/public/visualize/loader/pipeline_data_loader.ts @@ -18,8 +18,6 @@ */ import { RequestHandlerParams, Vis } from '../../vis'; - -// @ts-ignore No typing present import { buildPipeline, runPipeline } from './pipeline_helpers'; export class PipelineDataLoader { diff --git a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts index 10ec25d8b0e42..54f89985d31f1 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts +++ b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts @@ -17,6 +17,7 @@ * under the License. */ +import { SearchSource } from 'ui/courier'; import { AggConfig, Vis, VisState } from 'ui/vis'; type buildVisFunction = (visState: VisState, schemas?: any) => string; @@ -143,7 +144,7 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { }, }; -export const buildPipeline = (vis: Vis, params: any) => { +export const buildPipeline = (vis: Vis, params: { searchSource: SearchSource }) => { const { searchSource } = params; const { indexPattern } = vis; const query = searchSource.getField('query'); @@ -165,9 +166,9 @@ export const buildPipeline = (vis: Vis, params: any) => { // request handler if (vis.type.requestHandler === 'courier') { - pipeline += `esaggs - ${prepareString('index', indexPattern.id)} - metricsAtAllLevels=${vis.isHierarchical()} + pipeline += `esaggs + ${prepareString('index', indexPattern.id)} + metricsAtAllLevels=${vis.isHierarchical()} partialRows=${vis.params.showPartialRows || vis.type.name === 'tile_map'} ${prepareJson('aggConfigs', visState.aggs)} | `; } @@ -176,14 +177,14 @@ export const buildPipeline = (vis: Vis, params: any) => { if (buildPipelineVisFunction[vis.type.name]) { pipeline += buildPipelineVisFunction[vis.type.name](visState, schemas); } else if (vislibCharts.includes(vis.type.name)) { - pipeline += `vislib type='${vis.type.name}' - ${prepareJson('visConfig', visState.params)} + pipeline += `vislib type='${vis.type.name}' + ${prepareJson('visConfig', visState.params)} ${prepareJson('schemas', schemas)}`; } else { - pipeline += `visualization type='${vis.type.name}' + pipeline += `visualization type='${vis.type.name}' ${prepareJson('visConfig', visState.params)} - ${prepareString('index', indexPattern.id)} - metricsAtAllLevels=${vis.isHierarchical()} + ${prepareString('index', indexPattern.id)} + metricsAtAllLevels=${vis.isHierarchical()} partialRows=${vis.params.showPartialRows || vis.type.name === 'tile_map'} `; } From 41fb6814f6be8e29814ef12d255f7359d41d824a Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 29 Nov 2018 14:44:09 +0100 Subject: [PATCH 19/32] applying tim's feedback --- .../interpreter/public/functions/esaggs.js | 60 +++++---- .../public/functions/input_control.js | 2 +- .../interpreter/public/functions/kibana.js | 2 +- .../public/functions/kibana_context.js | 57 +++++---- .../interpreter/public/functions/markdown.js | 2 +- .../interpreter/public/functions/metric.js | 2 +- .../interpreter/public/functions/pie.js | 63 +++++----- .../interpreter/public/functions/regionmap.js | 2 +- .../interpreter/public/functions/table.js | 2 +- .../interpreter/public/functions/tagcloud.js | 2 +- .../interpreter/public/functions/tilemap.js | 2 +- .../public/functions/timelion_vis.js | 34 +++-- .../interpreter/public/functions/tsvb.js | 44 ++++--- .../interpreter/public/functions/vega.js | 51 ++++---- .../interpreter/public/functions/vislib.js | 65 +++++----- .../public/functions/visualization.js | 119 ++++++++++-------- 16 files changed, 254 insertions(+), 255 deletions(-) diff --git a/src/core_plugins/interpreter/public/functions/esaggs.js b/src/core_plugins/interpreter/public/functions/esaggs.js index c537118c2c18c..e73dd1f761917 100644 --- a/src/core_plugins/interpreter/public/functions/esaggs.js +++ b/src/core_plugins/interpreter/public/functions/esaggs.js @@ -61,40 +61,38 @@ export default () => ({ multi: false, }, }, - fn(context, args, handlers) { - return chrome.dangerouslyGetActiveInjector().then(async $injector => { - const Private = $injector.get('Private'); - const indexPatterns = Private(IndexPatternsProvider); - const SearchSource = Private(SearchSourceProvider); - const queryFilter = Private(FilterBarQueryFilterProvider); + async fn(context, args, handlers) { + const $injector = await chrome.dangerouslyGetActiveInjector(); + const Private = $injector.get('Private'); + const indexPatterns = Private(IndexPatternsProvider); + const SearchSource = Private(SearchSourceProvider); + const queryFilter = Private(FilterBarQueryFilterProvider); - const aggConfigsState = JSON.parse(args.aggConfigs); - const indexPattern = await indexPatterns.get(args.index); - const aggs = new AggConfigs(indexPattern, aggConfigsState); + const aggConfigsState = JSON.parse(args.aggConfigs); + const indexPattern = await indexPatterns.get(args.index); + const aggs = new AggConfigs(indexPattern, aggConfigsState); - // we should move searchSource creation inside courier request handler - const searchSource = new SearchSource(); - searchSource.setField('index', indexPattern); - - const response = await courierRequestHandler({ - searchSource: searchSource, - aggs: aggs, - timeRange: get(context, 'timeRange', null), - query: get(context, 'query', null), - filters: get(context, 'filters', null), - forceFetch: true, - isHierarchical: args.metricsAtAllLevels, - partialRows: args.partialRows, - inspectorAdapters: handlers.inspectorAdapters, - queryFilter, - }); - - return { - type: 'kibana_table', - index: args.index, - ...response, - }; + // we should move searchSource creation inside courier request handler + const searchSource = new SearchSource(); + searchSource.setField('index', indexPattern); + const response = await courierRequestHandler({ + searchSource: searchSource, + aggs: aggs, + timeRange: get(context, 'timeRange', null), + query: get(context, 'query', null), + filters: get(context, 'filters', null), + forceFetch: true, + isHierarchical: args.metricsAtAllLevels, + partialRows: args.partialRows, + inspectorAdapters: handlers.inspectorAdapters, + queryFilter, }); + + return { + type: 'kibana_table', + index: args.index, + ...response, + }; }, }); diff --git a/src/core_plugins/interpreter/public/functions/input_control.js b/src/core_plugins/interpreter/public/functions/input_control.js index cc111cb5e2200..ce2b54b5e98e7 100644 --- a/src/core_plugins/interpreter/public/functions/input_control.js +++ b/src/core_plugins/interpreter/public/functions/input_control.js @@ -36,7 +36,7 @@ export default () => ({ } }, fn(context, args) { - const params = args.visConfig ? JSON.parse(args.visConfig) : {}; + const params = JSON.parse(args.visConfig); return { type: 'render', as: 'visualization', diff --git a/src/core_plugins/interpreter/public/functions/kibana.js b/src/core_plugins/interpreter/public/functions/kibana.js index de75eba6e78a1..7946c06bb149b 100644 --- a/src/core_plugins/interpreter/public/functions/kibana.js +++ b/src/core_plugins/interpreter/public/functions/kibana.js @@ -40,7 +40,7 @@ export default () => ({ initialContext.filters = initialContext.filters.concat(context.filters); } - const timeRange = initialContext.timeRange ? JSON.parse(initialContext.timeRange) : context.timeRange; + const timeRange = initialContext.timeRange || context.timeRange; return { ...context, diff --git a/src/core_plugins/interpreter/public/functions/kibana_context.js b/src/core_plugins/interpreter/public/functions/kibana_context.js index 2d0d7cdf060ed..519c40ac93998 100644 --- a/src/core_plugins/interpreter/public/functions/kibana_context.js +++ b/src/core_plugins/interpreter/public/functions/kibana_context.js @@ -51,39 +51,38 @@ export default () => ({ default: null, } }, - fn(context, args) { - return chrome.dangerouslyGetActiveInjector().then(async $injector => { - const savedSearches = $injector.get('savedSearches'); - const queryArg = args.q ? JSON.parse(args.q) : []; - let queries = Array.isArray(queryArg) ? queryArg : [queryArg]; - let filters = args.filters ? JSON.parse(args.filters) : []; + async fn(context, args) { + const $injector = await chrome.dangerouslyGetActiveInjector(); + const savedSearches = $injector.get('savedSearches'); + const queryArg = args.q ? JSON.parse(args.q) : []; + let queries = Array.isArray(queryArg) ? queryArg : [queryArg]; + let filters = args.filters ? JSON.parse(args.filters) : []; - if (args.savedSearchId) { - const savedSearch = await savedSearches.get(args.savedSearchId); - const searchQuery = savedSearch.searchSource.getField('query'); - const searchFilters = savedSearch.searchSource.getField('filter'); - queries = queries.concat(searchQuery); - filters = filters.concat(searchFilters); - } + if (args.savedSearchId) { + const savedSearch = await savedSearches.get(args.savedSearchId); + const searchQuery = savedSearch.searchSource.getField('query'); + const searchFilters = savedSearch.searchSource.getField('filter'); + queries = queries.concat(searchQuery); + filters = filters.concat(searchFilters); + } - if (context.query) { - const contextQueries = Array.isArray(context.query) ? context.query : [context.query]; - queries = queries.concat(contextQueries); - } + if (context.query) { + const contextQueries = Array.isArray(context.query) ? context.query : [context.query]; + queries = queries.concat(contextQueries); + } - if (context.filters) { - // merge filters - filters = filters.concat(context.filters); - } + if (context.filters) { + // merge filters + filters = filters.concat(context.filters); + } - const timeRange = args.timeRange ? JSON.parse(args.timeRange) : context.timeRange; + const timeRange = args.timeRange ? JSON.parse(args.timeRange) : context.timeRange; - return { - type: 'kibana_context', - query: queries, - filters: filters, - timeRange: timeRange, - }; - }); + return { + type: 'kibana_context', + query: queries, + filters: filters, + timeRange: timeRange, + }; }, }); diff --git a/src/core_plugins/interpreter/public/functions/markdown.js b/src/core_plugins/interpreter/public/functions/markdown.js index 8fa486db610a7..691a5110abdfb 100644 --- a/src/core_plugins/interpreter/public/functions/markdown.js +++ b/src/core_plugins/interpreter/public/functions/markdown.js @@ -43,7 +43,7 @@ export default () => ({ } }, fn(context, args) { - const params = args.visConfig ? JSON.parse(args.visConfig) : {}; + const params = JSON.parse(args.visConfig); return { type: 'render', as: 'visualization', diff --git a/src/core_plugins/interpreter/public/functions/metric.js b/src/core_plugins/interpreter/public/functions/metric.js index f3963ec758519..7778e28b80dfa 100644 --- a/src/core_plugins/interpreter/public/functions/metric.js +++ b/src/core_plugins/interpreter/public/functions/metric.js @@ -48,7 +48,7 @@ export default () => ({ }, }, fn(context, args) { - const visConfigParams = JSON.parse(args.visConfig || {}); + const visConfigParams = JSON.parse(args.visConfig); const metrics = args.metric.split(','); metrics.forEach(metric => { const metricColumn = context.columns.find((column, i) => diff --git a/src/core_plugins/interpreter/public/functions/pie.js b/src/core_plugins/interpreter/public/functions/pie.js index 76c871115c893..177d8c7ed8534 100644 --- a/src/core_plugins/interpreter/public/functions/pie.js +++ b/src/core_plugins/interpreter/public/functions/pie.js @@ -45,43 +45,42 @@ export default () => ({ multi: false, }, }, - fn(context, args) { - return chrome.dangerouslyGetActiveInjector().then(async $injector => { - const Private = $injector.get('Private'); - const responseHandler = Private(VislibSlicesResponseHandlerProvider).handler; - const visTypes = Private(VisTypesRegistryProvider); - const visConfigParams = JSON.parse(args.visConfig || {}); - const visType = visTypes.byName.pie; - const schemas = JSON.parse(args.schemas); + async fn(context, args) { + const $injector = await chrome.dangerouslyGetActiveInjector(); + const Private = $injector.get('Private'); + const responseHandler = Private(VislibSlicesResponseHandlerProvider).handler; + const visTypes = Private(VisTypesRegistryProvider); + const visConfigParams = JSON.parse(args.visConfig); + const visType = visTypes.byName.pie; + const schemas = JSON.parse(args.schemas); - if (context.columns) { - context.columns.forEach(column => { - column.aggConfig.aggConfigs.schemas = visType.schemas.all; - }); + if (context.columns) { + context.columns.forEach(column => { + column.aggConfig.aggConfigs.schemas = visType.schemas.all; + }); - Object.keys(schemas).forEach(key => { - schemas[key].forEach(i => { - context.columns[i].aggConfig.schema = key; - }); + Object.keys(schemas).forEach(key => { + schemas[key].forEach(i => { + context.columns[i].aggConfig.schema = key; }); - } + }); + } - const convertedData = await responseHandler(context); + const convertedData = await responseHandler(context); - return { - type: 'render', - as: 'visualization', - value: { - visData: convertedData, - visConfig: { - type: args.type, - params: visConfigParams, - }, - params: { - listenOnChange: true, - } + return { + type: 'render', + as: 'visualization', + value: { + visData: convertedData, + visConfig: { + type: args.type, + params: visConfigParams, }, - }; - }); + params: { + listenOnChange: true, + } + }, + }; }, }); diff --git a/src/core_plugins/interpreter/public/functions/regionmap.js b/src/core_plugins/interpreter/public/functions/regionmap.js index 4b8f7717c5f82..f04167bed7e32 100644 --- a/src/core_plugins/interpreter/public/functions/regionmap.js +++ b/src/core_plugins/interpreter/public/functions/regionmap.js @@ -48,7 +48,7 @@ export default () => ({ }, }, fn(context, args) { - const visConfigParams = JSON.parse(args.visConfig || {}); + const visConfigParams = JSON.parse(args.visConfig); const metricColumn = context.columns.find((column, i) => column.id === args.metric || column.name === args.metric || i === parseInt(args.metric) ); diff --git a/src/core_plugins/interpreter/public/functions/table.js b/src/core_plugins/interpreter/public/functions/table.js index 9232c5296d5da..ce2b08b134504 100644 --- a/src/core_plugins/interpreter/public/functions/table.js +++ b/src/core_plugins/interpreter/public/functions/table.js @@ -55,7 +55,7 @@ export default () => ({ }, }, async fn(context, args) { - const visConfigParams = JSON.parse(args.visConfig || {}); + const visConfigParams = JSON.parse(args.visConfig); args.metric.split(',').forEach(metric => { const metricColumn = context.columns.find((column, i) => column.id === metric || column.name === metric || i === parseInt(metric)); diff --git a/src/core_plugins/interpreter/public/functions/tagcloud.js b/src/core_plugins/interpreter/public/functions/tagcloud.js index 9ce00c806c0d2..cb502cae722bf 100644 --- a/src/core_plugins/interpreter/public/functions/tagcloud.js +++ b/src/core_plugins/interpreter/public/functions/tagcloud.js @@ -48,7 +48,7 @@ export default () => ({ }, }, fn(context, args) { - const visConfigParams = JSON.parse(args.visConfig || {}); + const visConfigParams = JSON.parse(args.visConfig); const metricColumn = context.columns.find((column, i) => column.id === args.metric || column.name === args.metric || i === parseInt(args.metric) ); diff --git a/src/core_plugins/interpreter/public/functions/tilemap.js b/src/core_plugins/interpreter/public/functions/tilemap.js index 59e51d26a69c4..0fe81d0aad0b4 100644 --- a/src/core_plugins/interpreter/public/functions/tilemap.js +++ b/src/core_plugins/interpreter/public/functions/tilemap.js @@ -51,7 +51,7 @@ export default () => ({ }, }, fn(context, args) { - const visConfigParams = JSON.parse(args.visConfig || {}); + const visConfigParams = JSON.parse(args.visConfig); const metricColumn = context.columns.find((column, i) => column.id === args.metric || column.name === args.metric || i === parseInt(args.metric) ); diff --git a/src/core_plugins/interpreter/public/functions/timelion_vis.js b/src/core_plugins/interpreter/public/functions/timelion_vis.js index a6216381166f6..6752768a47143 100644 --- a/src/core_plugins/interpreter/public/functions/timelion_vis.js +++ b/src/core_plugins/interpreter/public/functions/timelion_vis.js @@ -49,25 +49,23 @@ export default () => ({ multi: false, } }, - fn(context, args) { - return chrome.dangerouslyGetActiveInjector().then(async $injector => { - const Private = $injector.get('Private'); - const timelionRequestHandler = Private(TimelionRequestHandlerProvider).handler; - - const response = await timelionRequestHandler({ - timeRange: get(context, 'timeRange', null), - query: get(context, 'query', null), - filters: get(context, 'filters', null), - forceFetch: true, - visParams: { expression: args.expression, interval: args.interval } - }); - - return { - type: 'render', - as: 'visualization', - value: response, - }; + async fn(context, args) { + const $injector = await chrome.dangerouslyGetActiveInjector(); + const Private = $injector.get('Private'); + const timelionRequestHandler = Private(TimelionRequestHandlerProvider).handler; + const response = await timelionRequestHandler({ + timeRange: get(context, 'timeRange', null), + query: get(context, 'query', null), + filters: get(context, 'filters', null), + forceFetch: true, + visParams: { expression: args.expression, interval: args.interval } }); + + return { + type: 'render', + as: 'visualization', + value: response, + }; }, }); diff --git a/src/core_plugins/interpreter/public/functions/tsvb.js b/src/core_plugins/interpreter/public/functions/tsvb.js index bb4bd87e62369..c828551b6d449 100644 --- a/src/core_plugins/interpreter/public/functions/tsvb.js +++ b/src/core_plugins/interpreter/public/functions/tsvb.js @@ -40,38 +40,36 @@ export default () => ({ args: { params: { types: ['string'], - default: '""', + default: '"{}"', multi: false, }, uiState: { types: ['string'], - default: '""', + default: '"{}"', multi: false } }, - fn(context, args) { - return chrome.dangerouslyGetActiveInjector().then(async $injector => { - const Private = $injector.get('Private'); - const metricsRequestHandler = Private(MetricsRequestHandlerProvider).handler; + async fn(context, args) { + const $injector = await chrome.dangerouslyGetActiveInjector(); + const Private = $injector.get('Private'); + const metricsRequestHandler = Private(MetricsRequestHandlerProvider).handler; - const params = JSON.parse(args.params); - const uiStateParams = args.uiState ? JSON.parse(args.uiState) : {}; - const uiState = new PersistedState(uiStateParams); - - const response = await metricsRequestHandler({ - timeRange: get(context, 'timeRange', null), - query: get(context, 'query', null), - filters: get(context, 'filters', null), - visParams: params, - uiState: uiState, - }); - - return { - type: 'render', - as: 'visualization', - value: response, - }; + const params = JSON.parse(args.params); + const uiStateParams = JSON.parse(args.uiState); + const uiState = new PersistedState(uiStateParams); + const response = await metricsRequestHandler({ + timeRange: get(context, 'timeRange', null), + query: get(context, 'query', null), + filters: get(context, 'filters', null), + visParams: params, + uiState: uiState, }); + + return { + type: 'render', + as: 'visualization', + value: response, + }; }, }); diff --git a/src/core_plugins/interpreter/public/functions/vega.js b/src/core_plugins/interpreter/public/functions/vega.js index b4b2f5dba0d3e..a1d4b34a2e941 100644 --- a/src/core_plugins/interpreter/public/functions/vega.js +++ b/src/core_plugins/interpreter/public/functions/vega.js @@ -37,36 +37,35 @@ export default () => ({ args: { spec: { types: ['string'], - default: '{}', + default: '', multi: false, }, }, - fn(context, args) { - return chrome.dangerouslyGetActiveInjector().then(async $injector => { - const Private = $injector.get('Private'); - const vegaRequestHandler = Private(VegaRequestHandlerProvider).handler; + async fn(context, args) { + const $injector = await chrome.dangerouslyGetActiveInjector(); + const Private = $injector.get('Private'); + const vegaRequestHandler = Private(VegaRequestHandlerProvider).handler; - const response = await vegaRequestHandler({ - timeRange: get(context, 'timeRange', null), - query: get(context, 'q', null), - filters: get(context, 'filters', null), - visParams: { spec: args.spec }, - forceFetch: true - }); - - return { - type: 'render', - as: 'visualization', - value: { - visData: response, - visConfig: { - type: 'vega', - params: { - spec: args.spec - } - }, - } - }; + const response = await vegaRequestHandler({ + timeRange: get(context, 'timeRange', null), + query: get(context, 'q', null), + filters: get(context, 'filters', null), + visParams: { spec: args.spec }, + forceFetch: true }); + + return { + type: 'render', + as: 'visualization', + value: { + visData: response, + visConfig: { + type: 'vega', + params: { + spec: args.spec + } + }, + } + }; } }); diff --git a/src/core_plugins/interpreter/public/functions/vislib.js b/src/core_plugins/interpreter/public/functions/vislib.js index 7f96c2cfd6cb8..437d458d4d901 100644 --- a/src/core_plugins/interpreter/public/functions/vislib.js +++ b/src/core_plugins/interpreter/public/functions/vislib.js @@ -50,44 +50,43 @@ export default () => ({ multi: false, }, }, - fn(context, args) { - return chrome.dangerouslyGetActiveInjector().then(async $injector => { - const Private = $injector.get('Private'); - const responseHandler = Private(VislibSeriesResponseHandlerProvider).handler; - const visTypes = Private(VisTypesRegistryProvider); - const visConfigParams = JSON.parse(args.visConfig || {}); - const schemas = JSON.parse(args.schemas); - const visType = visTypes.byName[args.type || 'histogram']; + async fn(context, args) { + const $injector = await chrome.dangerouslyGetActiveInjector(); + const Private = $injector.get('Private'); + const responseHandler = Private(VislibSeriesResponseHandlerProvider).handler; + const visTypes = Private(VisTypesRegistryProvider); + const visConfigParams = JSON.parse(args.visConfig); + const schemas = JSON.parse(args.schemas); + const visType = visTypes.byName[args.type || 'histogram']; - if (context.columns) { - // assign schemas to aggConfigs - context.columns.forEach(column => { - column.aggConfig.aggConfigs.schemas = visType.schemas.all; - }); + if (context.columns) { + // assign schemas to aggConfigs + context.columns.forEach(column => { + column.aggConfig.aggConfigs.schemas = visType.schemas.all; + }); - Object.keys(schemas).forEach(key => { - schemas[key].forEach(i => { - context.columns[i].aggConfig.schema = key; - }); + Object.keys(schemas).forEach(key => { + schemas[key].forEach(i => { + context.columns[i].aggConfig.schema = key; }); - } + }); + } - const convertedData = await responseHandler(context); + const convertedData = await responseHandler(context); - return { - type: 'render', - as: 'visualization', - value: { - visData: convertedData, - visConfig: { - type: args.type, - params: visConfigParams, - }, - params: { - listenOnChange: true, - } + return { + type: 'render', + as: 'visualization', + value: { + visData: convertedData, + visConfig: { + type: args.type, + params: visConfigParams, }, - }; - }); + params: { + listenOnChange: true, + } + }, + }; }, }); diff --git a/src/core_plugins/interpreter/public/functions/visualization.js b/src/core_plugins/interpreter/public/functions/visualization.js index 8b34400f31d30..bd048622b9ef3 100644 --- a/src/core_plugins/interpreter/public/functions/visualization.js +++ b/src/core_plugins/interpreter/public/functions/visualization.js @@ -68,75 +68,84 @@ export default () => ({ default: '', multi: false, }, + schemas: { + types: ['string'], + default: '"{}"', + multi: false, + }, visConfig: { types: ['string'], default: '"{}"', multi: false, + }, + uiState: { + types: ['string'], + default: '"{}"', + multi: false } }, - fn(context, args, handlers) { - return chrome.dangerouslyGetActiveInjector().then(async $injector => { - const Private = $injector.get('Private'); - const requestHandlers = Private(RequestHandlersProvider); - const responseHandlers = Private(ResponseHandlerProvider); - const visTypes = Private(VisTypesRegistryProvider); - const indexPatterns = Private(IndexPatternsProvider); - const queryFilter = Private(FilterBarQueryFilterProvider); + async fn(context, args, handlers) { + const $injector = await chrome.dangerouslyGetActiveInjector(); + const Private = $injector.get('Private'); + const requestHandlers = Private(RequestHandlersProvider); + const responseHandlers = Private(ResponseHandlerProvider); + const visTypes = Private(VisTypesRegistryProvider); + const indexPatterns = Private(IndexPatternsProvider); + const queryFilter = Private(FilterBarQueryFilterProvider); - const visConfigParams = JSON.parse(args.visConfig || {}); - const schemas = JSON.parse(args.schemas); - const visType = visTypes.byName[args.type || 'histogram']; - const requestHandler = getHandler(requestHandlers, visType.requestHandler); - const responseHandler = getHandler(responseHandlers, visType.responseHandler); - const indexPattern = args.index ? await indexPatterns.get(args.index) : null; + const visConfigParams = JSON.parse(args.visConfig); + const schemas = JSON.parse(args.schemas); + const visType = visTypes.byName[args.type || 'histogram']; + const requestHandler = getHandler(requestHandlers, visType.requestHandler); + const responseHandler = getHandler(responseHandlers, visType.responseHandler); + const indexPattern = args.index ? await indexPatterns.get(args.index) : null; - const uiStateParams = args.uiState ? JSON.parse(args.uiState) : {}; - const uiState = new PersistedState(uiStateParams); + const uiStateParams = JSON.parse(args.uiState); + const uiState = new PersistedState(uiStateParams); - if (requestHandler) { - context = await requestHandler({ - partialRows: args.partialRows, - metricsAtAllLevels: args.metricsAtAllLevels, - index: indexPattern, - visParams: visConfigParams, - timeRange: get(context, 'timeRange', null), - query: get(context, 'query', null), - filters: get(context, 'filters', null), - uiState: uiState, - inspectorAdapters: handlers.inspectorAdapters, - queryFilter, - forceFetch: true, + if (requestHandler) { + context = await requestHandler({ + partialRows: args.partialRows, + metricsAtAllLevels: args.metricsAtAllLevels, + index: indexPattern, + visParams: visConfigParams, + timeRange: get(context, 'timeRange', null), + query: get(context, 'query', null), + filters: get(context, 'filters', null), + uiState: uiState, + inspectorAdapters: handlers.inspectorAdapters, + queryFilter, + forceFetch: true, + }); + } + + if (responseHandler) { + if (context.columns) { + // assign schemas to aggConfigs + context.columns.forEach(column => { + column.aggConfig.aggConfigs.schemas = visType.schemas.all; }); - } - if (responseHandler) { - if (context.columns) { - // assign schemas to aggConfigs - context.columns.forEach(column => { - column.aggConfig.aggConfigs.schemas = visType.schemas.all; + Object.keys(schemas).forEach(key => { + schemas[key].forEach(i => { + context.columns[i].aggConfig.schema = key; }); + }); + } - Object.keys(schemas).forEach(key => { - schemas[key].forEach(i => { - context.columns[i].aggConfig.schema = key; - }); - }); - } + context = await responseHandler(context); + } - context = await responseHandler(context); + return { + type: 'render', + as: 'visualization', + value: { + visData: context, + visConfig: { + type: args.type, + params: visConfigParams + }, } - - return { - type: 'render', - as: 'visualization', - value: { - visData: context, - visConfig: { - type: args.type, - params: visConfigParams - }, - } - }; - }); + }; } }); From 631c748da29f0dd556b624ec259fcd74244b75d8 Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Thu, 29 Nov 2018 12:55:12 -0700 Subject: [PATCH 20/32] Add Schemas interface, finish buildVisPipeline tests. --- .../__snapshots__/build_pipeline.test.js.snap | 31 ++++ .../__tests__/build_pipeline.js | 85 --------- .../pipeline_helpers/build_pipeline.test.js | 168 ++++++++++++++++++ .../loader/pipeline_helpers/build_pipeline.ts | 23 ++- 4 files changed, 213 insertions(+), 94 deletions(-) create mode 100644 src/ui/public/visualize/loader/pipeline_helpers/__snapshots__/build_pipeline.test.js.snap delete mode 100644 src/ui/public/visualize/loader/pipeline_helpers/__tests__/build_pipeline.js create mode 100644 src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.js diff --git a/src/ui/public/visualize/loader/pipeline_helpers/__snapshots__/build_pipeline.test.js.snap b/src/ui/public/visualize/loader/pipeline_helpers/__snapshots__/build_pipeline.test.js.snap new file mode 100644 index 0000000000000..2d396f74439d7 --- /dev/null +++ b/src/ui/public/visualize/loader/pipeline_helpers/__snapshots__/build_pipeline.test.js.snap @@ -0,0 +1,31 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles input_control_vis function 1`] = `"input_control_vis visConfig='{\\"some\\":\\"nested\\",\\"data\\":{\\"here\\":true}}' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles markdown function 1`] = `"kibana_markdown expression='## hello _markdown_' visConfig='{\\"markdown\\":\\"## hello _markdown_\\",\\"foo\\":\\"bar\\"}' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles metric function with buckets 1`] = `"kibana_metric visConfig='{\\"foo\\":\\"bar\\"}' bucket='2' metric='0,1' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles metric function without buckets 1`] = `"kibana_metric visConfig='{\\"foo\\":\\"bar\\"}' metric='0,1' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles metrics/tsvb function 1`] = `"tsvb params='{\\"foo\\":\\"bar\\"}' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles pie function 1`] = `"kibana_pie visConfig='{\\"foo\\":\\"bar\\"}' schemas='{\\"baz\\":\\"qux\\"}' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles region_map function with metrics and buckets 1`] = `"regionmap visConfig='{\\"foo\\":\\"bar\\"}' bucket='1,2' metric='0' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function with splits 1`] = `"kibana_table visConfig='{\\"foo\\":\\"bar\\"}' split='1,2' metric='0' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function with splits and buckets 1`] = `"kibana_table visConfig='{\\"foo\\":\\"bar\\"}' split='2,4' bucket='3' metric='0,1' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function without splits or buckets 1`] = `"kibana_table visConfig='{\\"foo\\":\\"bar\\"}' metric='0,1' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles tagcloud function with metrics and buckets 1`] = `"tagcloud visConfig='{\\"foo\\":\\"bar\\"}' bucket='1,2' metric='0' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles tile_map function with metrics and buckets 1`] = `"tilemap visConfig='{\\"foo\\":\\"bar\\"}' bucket='1,2' metric='0' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles tile_map function without buckets 1`] = `"tilemap visConfig='{\\"foo\\":\\"bar\\"}' metric='0' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles timelion function 1`] = `"timelion_vis expression='foo' interval='bar' "`; + +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles vega function 1`] = `"vega spec='this is a test' "`; diff --git a/src/ui/public/visualize/loader/pipeline_helpers/__tests__/build_pipeline.js b/src/ui/public/visualize/loader/pipeline_helpers/__tests__/build_pipeline.js deleted file mode 100644 index 4ddb14c7baf43..0000000000000 --- a/src/ui/public/visualize/loader/pipeline_helpers/__tests__/build_pipeline.js +++ /dev/null @@ -1,85 +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 expect from 'expect.js'; -import { buildPipelineVisFunction } from '../build_pipeline'; - -describe('visualize loader pipeline helpers: build pipeline', () => { - describe('buildPipelineVisFunction', () => { - it('handles vega function', () => { - const type = 'vega'; - const visState = { - params: { - spec: 'this is a test' - } - }; - const actual = buildPipelineVisFunction[type](visState); - expect(actual).to.be(`vega spec='this is a test' `); - }); - - it('handles input_control_vis function', () => { - const type = 'input_control_vis'; - const visState = { - params: { - some: 'nested', - data: { - here: true - } - } - }; - const actual = buildPipelineVisFunction[type](visState); - expect(actual).to.be(`input_control_vis visConfig='{"some":"nested","data":{"here":true}}' `); - }); - - it('handles metrics function', () => { - const type = 'metrics'; - const visState = { - params: { - foo: 'bar', - } - }; - const actual = buildPipelineVisFunction[type](visState); - expect(actual).to.be(`tsvb params='{"foo":"bar"}' `); - }); - - it('handles timelion function', () => { - const type = 'timelion'; - const visState = { - params: { - expression: 'foo', - interval: 'bar', - } - }; - const actual = buildPipelineVisFunction[type](visState); - expect(actual).to.be(`timelion_vis expression='foo' interval='bar' `); - }); - - it('handles markdown function', () => { - const type = 'markdown'; - const visState = { - params: { - markdown: '## hello _markdown_', - foo: 'bar', - } - }; - const actual = buildPipelineVisFunction[type](visState); - expect(actual).to.be(`kibana_markdown expression='## hello _markdown_' visConfig='{"markdown":"## hello _markdown_","foo":"bar"}' `); - }); - }); -}); diff --git a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.js b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.js new file mode 100644 index 0000000000000..a6a9d438386fb --- /dev/null +++ b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.js @@ -0,0 +1,168 @@ +/* + * 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 { buildPipelineVisFunction } from './build_pipeline'; + +describe('visualize loader pipeline helpers: build pipeline', () => { + describe('buildPipelineVisFunction', () => { + it('handles vega function', () => { + const params = { spec: 'this is a test' }; + const actual = buildPipelineVisFunction.vega({ params }); + expect(actual).toMatchSnapshot(); + }); + + it('handles input_control_vis function', () => { + const params = { + some: 'nested', + data: { + here: true + } + }; + const actual = buildPipelineVisFunction.input_control_vis({ params }); + expect(actual).toMatchSnapshot(); + }); + + it('handles metrics/tsvb function', () => { + const params = { foo: 'bar' }; + const actual = buildPipelineVisFunction.metrics({ params }); + expect(actual).toMatchSnapshot(); + }); + + it('handles timelion function', () => { + const params = { expression: 'foo', interval: 'bar' }; + const actual = buildPipelineVisFunction.timelion({ params }); + expect(actual).toMatchSnapshot(); + }); + + it('handles markdown function', () => { + const params = { markdown: '## hello _markdown_', foo: 'bar' }; + const actual = buildPipelineVisFunction.markdown({ params }); + expect(actual).toMatchSnapshot(); + }); + + describe('handles table function', () => { + const params = { foo: 'bar' }; + it('without splits or buckets', () => { + const schemas = { metric: [0, 1] }; + const actual = buildPipelineVisFunction.table({ params }, schemas); + expect(actual).toMatchSnapshot(); + }); + + it('with splits', () => { + const schemas = { + metric: [0], + split: [1, 2], + }; + const actual = buildPipelineVisFunction.table({ params }, schemas); + expect(actual).toMatchSnapshot(); + }); + + it('with splits and buckets', () => { + const schemas = { + metric: [0, 1], + split: [2, 4], + bucket: [3] + }; + const actual = buildPipelineVisFunction.table({ params }, schemas); + expect(actual).toMatchSnapshot(); + }); + }); + + describe('handles metric function', () => { + const params = { foo: 'bar' }; + it('without buckets', () => { + const schemas = { metric: [0, 1] }; + const actual = buildPipelineVisFunction.metric({ params }, schemas); + expect(actual).toMatchSnapshot(); + }); + + it('with buckets', () => { + const schemas = { + metric: [0, 1], + bucket: [2] + }; + const actual = buildPipelineVisFunction.metric({ params }, schemas); + expect(actual).toMatchSnapshot(); + }); + }); + + describe('handles tagcloud function', () => { + const params = { foo: 'bar' }; + it('with metrics and buckets', () => { + const schemas = { + metric: [0], + segment: [1, 2] + }; + const actual = buildPipelineVisFunction.tagcloud({ params }, schemas); + expect(actual).toMatchSnapshot(); + }); + + it('throws without bucket', () => { + const schemas = { metric: [0] }; + expect(() => { + buildPipelineVisFunction.tagcloud({ params }, schemas); + }).toThrow(TypeError); + }); + }); + + describe('handles region_map function', () => { + const params = { foo: 'bar' }; + it('with metrics and buckets', () => { + const schemas = { + metric: [0], + segment: [1, 2] + }; + const actual = buildPipelineVisFunction.region_map({ params }, schemas); + expect(actual).toMatchSnapshot(); + }); + + it('throws without bucket', () => { + const schemas = { metric: [0] }; + expect(() => { + buildPipelineVisFunction.region_map({ params }, schemas); + }).toThrow(TypeError); + }); + }); + + describe('handles tile_map function', () => { + const params = { foo: 'bar' }; + it('with metrics and buckets', () => { + const schemas = { + metric: [0], + segment: [1, 2] + }; + const actual = buildPipelineVisFunction.tile_map({ params }, schemas); + expect(actual).toMatchSnapshot(); + }); + + it('without buckets', () => { + const schemas = { metric: [0] }; + const actual = buildPipelineVisFunction.tile_map({ params }, schemas); + expect(actual).toMatchSnapshot(); + }); + }); + + it('handles pie function', () => { + const params = { foo: 'bar' }; + const schemas = { baz: 'qux' }; + const actual = buildPipelineVisFunction.pie({ params }, schemas); + expect(actual).toMatchSnapshot(); + }); + }); +}); diff --git a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts index 54f89985d31f1..06f6809f87329 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts +++ b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts @@ -20,7 +20,12 @@ import { SearchSource } from 'ui/courier'; import { AggConfig, Vis, VisState } from 'ui/vis'; -type buildVisFunction = (visState: VisState, schemas?: any) => string; +interface Schemas { + metric: number[]; + [key: string]: number[]; +} + +type buildVisFunction = (visState: VisState, schemas: Schemas) => string; interface BuildPipelineVisFunction { [key: string]: buildVisFunction; @@ -36,9 +41,9 @@ const vislibCharts: string[] = [ 'line', ]; -export const getSchemas = (vis: Vis) => { +export const getSchemas = (vis: Vis): Schemas => { let cnt = 0; - const schemas: any = { + const schemas: Schemas = { metric: [], }; const responseAggs = vis.aggs.getResponseAggs(); @@ -99,7 +104,7 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { return `kibana_markdown ${expression}${visConfig}`; }, table: (visState, schemas) => { - let pipeline = `kibana_table ${prepareJson('visConfig', visState.params)} `; + let pipeline = `kibana_table ${prepareJson('visConfig', visState.params)}`; if (schemas.split) { pipeline += `split='${schemas.split.join(',')}' `; } @@ -110,7 +115,7 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { return pipeline; }, metric: (visState, schemas) => { - let pipeline = `kibana_metric ${prepareJson('visConfig', visState.params)} `; + let pipeline = `kibana_metric ${prepareJson('visConfig', visState.params)}`; if (schemas.bucket) { pipeline += `bucket='${schemas.bucket.join(',')}' `; } @@ -118,19 +123,19 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { return pipeline; }, tagcloud: (visState, schemas) => { - let pipeline = `tagcloud ${prepareJson('visConfig', visState.params)} `; + let pipeline = `tagcloud ${prepareJson('visConfig', visState.params)}`; pipeline += `bucket='${schemas.segment.join(',')}' `; pipeline += `metric='${schemas.metric.join(',')}' `; return pipeline; }, region_map: (visState, schemas) => { - let pipeline = `regionmap ${prepareJson('visConfig', visState.params)} `; + let pipeline = `regionmap ${prepareJson('visConfig', visState.params)}`; pipeline += `bucket='${schemas.segment.join(',')}' `; pipeline += `metric='${schemas.metric.join(',')}' `; return pipeline; }, tile_map: (visState, schemas) => { - let pipeline = `tilemap ${prepareJson('visConfig', visState.params)} `; + let pipeline = `tilemap ${prepareJson('visConfig', visState.params)}`; if (schemas.segment) { pipeline += `bucket='${schemas.segment.join(',')}' `; } @@ -140,7 +145,7 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { pie: (visState, schemas) => { const visConfig = prepareJson('visConfig', visState.params); const visSchemas = prepareJson('schemas', schemas); - return `kibana_pie ${visConfig} ${visSchemas}`; + return `kibana_pie ${visConfig}${visSchemas}`; }, }; From 79eca457eeab36809a81b9dd1f131a8884c7e680 Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Thu, 29 Nov 2018 14:20:56 -0700 Subject: [PATCH 21/32] Add remaining tests for build pipeline helper. --- .../pipeline_helpers/build_pipeline.test.js | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.js b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.js index a6a9d438386fb..577ad96d8c150 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.js +++ b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.js @@ -17,9 +17,43 @@ * under the License. */ -import { buildPipelineVisFunction } from './build_pipeline'; +import { prepareJson, prepareString, buildPipelineVisFunction } from './build_pipeline'; describe('visualize loader pipeline helpers: build pipeline', () => { + describe('prepareJson', () => { + it('returns a correctly formatted key/value string', () => { + const expected = `foo='{}' `; // trailing space is expected + const actual = prepareJson('foo', {}); + expect(actual).toBe(expected); + }); + + it('stringifies provided data', () => { + const expected = `foo='{\"well\":\"hello\",\"there\":{\"friend\":true}}' `; + const actual = prepareJson('foo', { well: 'hello', there: { friend: true } }); + expect(actual).toBe(expected); + }); + + it('escapes single quotes', () => { + const expected = `foo='{\"well\":\"hello \\'hi\\'\",\"there\":{\"friend\":true}}' `; + const actual = prepareJson('foo', { well: `hello 'hi'`, there: { friend: true } }); + expect(actual).toBe(expected); + }); + }); + + describe('prepareString', () => { + it('returns a correctly formatted key/value string', () => { + const expected = `foo='bar' `; // trailing space is expected + const actual = prepareString('foo', 'bar'); + expect(actual).toBe(expected); + }); + + it('escapes single quotes', () => { + const expected = `foo='\\'bar\\'' `; + const actual = prepareString('foo', `'bar'`); + expect(actual).toBe(expected); + }); + }); + describe('buildPipelineVisFunction', () => { it('handles vega function', () => { const params = { spec: 'this is a test' }; From e8dbf0721dbc598a528948da1665baabcede8f76 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 30 Nov 2018 12:45:11 +0100 Subject: [PATCH 22/32] fixing --- .../interpreter/public/functions/visualization.js | 2 +- .../visualize/loader/pipeline_helpers/build_pipeline.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core_plugins/interpreter/public/functions/visualization.js b/src/core_plugins/interpreter/public/functions/visualization.js index bd048622b9ef3..c935e8fd0ae9e 100644 --- a/src/core_plugins/interpreter/public/functions/visualization.js +++ b/src/core_plugins/interpreter/public/functions/visualization.js @@ -31,7 +31,7 @@ function getHandler(from, type) { if (typeof type === 'function') { return type; } - if (type === 'courier') { + if (type === 'courier' || type === 'none') { return null; } const handlerDesc = from.find(handler => handler.name === type); diff --git a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts index 06f6809f87329..b440f7091bcbd 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts +++ b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts @@ -188,10 +188,11 @@ export const buildPipeline = (vis: Vis, params: { searchSource: SearchSource }) } else { pipeline += `visualization type='${vis.type.name}' ${prepareJson('visConfig', visState.params)} - ${prepareString('index', indexPattern.id)} metricsAtAllLevels=${vis.isHierarchical()} - partialRows=${vis.params.showPartialRows || vis.type.name === 'tile_map'} - `; + partialRows=${vis.params.showPartialRows || vis.type.name === 'tile_map'} `; + if (indexPattern) { + pipeline += `${prepareString('index', indexPattern.id)}`; + } } return pipeline; From 9c00335f13ed65be818b0a0b3b30c9ada845649f Mon Sep 17 00:00:00 2001 From: ppisljar Date: Sat, 1 Dec 2018 11:41:13 +0100 Subject: [PATCH 23/32] review feedback --- .../public/visualize/loader/pipeline_helpers/build_pipeline.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts index b440f7091bcbd..219dc7cf171eb 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts +++ b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts @@ -174,7 +174,7 @@ export const buildPipeline = (vis: Vis, params: { searchSource: SearchSource }) pipeline += `esaggs ${prepareString('index', indexPattern.id)} metricsAtAllLevels=${vis.isHierarchical()} - partialRows=${vis.params.showPartialRows || vis.type.name === 'tile_map'} + partialRows=${vis.params.showPartialRows || vis.type.requiresPartialRows || false} ${prepareJson('aggConfigs', visState.aggs)} | `; } From af839d38319410dd09c9d8addf3977f3073a9245 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 3 Dec 2018 15:53:24 +0100 Subject: [PATCH 24/32] fixing merge master --- .../core_plugins/interpreter/public/functions/esaggs.js | 0 .../core_plugins/interpreter/public/functions/index.js | 0 .../core_plugins/interpreter/public/functions/input_control.js | 0 .../core_plugins/interpreter/public/functions/kibana.js | 0 .../core_plugins/interpreter/public/functions/kibana_context.js | 0 .../core_plugins/interpreter/public/functions/markdown.js | 0 .../core_plugins/interpreter/public/functions/metric.js | 0 src/{ => legacy}/core_plugins/interpreter/public/functions/pie.js | 0 .../core_plugins/interpreter/public/functions/regionmap.js | 0 .../core_plugins/interpreter/public/functions/table.js | 0 .../core_plugins/interpreter/public/functions/tagcloud.js | 0 .../core_plugins/interpreter/public/functions/tilemap.js | 0 .../core_plugins/interpreter/public/functions/timelion_vis.js | 0 .../core_plugins/interpreter/public/functions/tsvb.js | 0 .../core_plugins/interpreter/public/functions/vega.js | 0 .../core_plugins/interpreter/public/functions/vislib.js | 0 .../core_plugins/interpreter/public/functions/visualization.js | 0 17 files changed, 0 insertions(+), 0 deletions(-) rename src/{ => legacy}/core_plugins/interpreter/public/functions/esaggs.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/index.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/input_control.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/kibana.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/kibana_context.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/markdown.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/metric.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/pie.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/regionmap.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/table.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/tagcloud.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/tilemap.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/timelion_vis.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/tsvb.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/vega.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/vislib.js (100%) rename src/{ => legacy}/core_plugins/interpreter/public/functions/visualization.js (100%) diff --git a/src/core_plugins/interpreter/public/functions/esaggs.js b/src/legacy/core_plugins/interpreter/public/functions/esaggs.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/esaggs.js rename to src/legacy/core_plugins/interpreter/public/functions/esaggs.js diff --git a/src/core_plugins/interpreter/public/functions/index.js b/src/legacy/core_plugins/interpreter/public/functions/index.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/index.js rename to src/legacy/core_plugins/interpreter/public/functions/index.js diff --git a/src/core_plugins/interpreter/public/functions/input_control.js b/src/legacy/core_plugins/interpreter/public/functions/input_control.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/input_control.js rename to src/legacy/core_plugins/interpreter/public/functions/input_control.js diff --git a/src/core_plugins/interpreter/public/functions/kibana.js b/src/legacy/core_plugins/interpreter/public/functions/kibana.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/kibana.js rename to src/legacy/core_plugins/interpreter/public/functions/kibana.js diff --git a/src/core_plugins/interpreter/public/functions/kibana_context.js b/src/legacy/core_plugins/interpreter/public/functions/kibana_context.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/kibana_context.js rename to src/legacy/core_plugins/interpreter/public/functions/kibana_context.js diff --git a/src/core_plugins/interpreter/public/functions/markdown.js b/src/legacy/core_plugins/interpreter/public/functions/markdown.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/markdown.js rename to src/legacy/core_plugins/interpreter/public/functions/markdown.js diff --git a/src/core_plugins/interpreter/public/functions/metric.js b/src/legacy/core_plugins/interpreter/public/functions/metric.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/metric.js rename to src/legacy/core_plugins/interpreter/public/functions/metric.js diff --git a/src/core_plugins/interpreter/public/functions/pie.js b/src/legacy/core_plugins/interpreter/public/functions/pie.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/pie.js rename to src/legacy/core_plugins/interpreter/public/functions/pie.js diff --git a/src/core_plugins/interpreter/public/functions/regionmap.js b/src/legacy/core_plugins/interpreter/public/functions/regionmap.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/regionmap.js rename to src/legacy/core_plugins/interpreter/public/functions/regionmap.js diff --git a/src/core_plugins/interpreter/public/functions/table.js b/src/legacy/core_plugins/interpreter/public/functions/table.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/table.js rename to src/legacy/core_plugins/interpreter/public/functions/table.js diff --git a/src/core_plugins/interpreter/public/functions/tagcloud.js b/src/legacy/core_plugins/interpreter/public/functions/tagcloud.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/tagcloud.js rename to src/legacy/core_plugins/interpreter/public/functions/tagcloud.js diff --git a/src/core_plugins/interpreter/public/functions/tilemap.js b/src/legacy/core_plugins/interpreter/public/functions/tilemap.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/tilemap.js rename to src/legacy/core_plugins/interpreter/public/functions/tilemap.js diff --git a/src/core_plugins/interpreter/public/functions/timelion_vis.js b/src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/timelion_vis.js rename to src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js diff --git a/src/core_plugins/interpreter/public/functions/tsvb.js b/src/legacy/core_plugins/interpreter/public/functions/tsvb.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/tsvb.js rename to src/legacy/core_plugins/interpreter/public/functions/tsvb.js diff --git a/src/core_plugins/interpreter/public/functions/vega.js b/src/legacy/core_plugins/interpreter/public/functions/vega.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/vega.js rename to src/legacy/core_plugins/interpreter/public/functions/vega.js diff --git a/src/core_plugins/interpreter/public/functions/vislib.js b/src/legacy/core_plugins/interpreter/public/functions/vislib.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/vislib.js rename to src/legacy/core_plugins/interpreter/public/functions/vislib.js diff --git a/src/core_plugins/interpreter/public/functions/visualization.js b/src/legacy/core_plugins/interpreter/public/functions/visualization.js similarity index 100% rename from src/core_plugins/interpreter/public/functions/visualization.js rename to src/legacy/core_plugins/interpreter/public/functions/visualization.js From 1b5bdce46aa104124885798fbb6cebae6a7363df Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 5 Dec 2018 07:21:17 +0100 Subject: [PATCH 25/32] fixing merge master --- .../kibana/public/discover/controllers/discover.js | 2 +- .../visualize/loader/embedded_visualize_handler.ts | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js index e8b16737af445..aceed75ee15cb 100644 --- a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js @@ -756,7 +756,7 @@ function discoverController( Promise .resolve(responseHandler(tabifiedData)) .then(resp => { - visualizeHandler.render(resp); + visualizeHandler.render({ value: resp }); }); } diff --git a/src/ui/public/visualize/loader/embedded_visualize_handler.ts b/src/ui/public/visualize/loader/embedded_visualize_handler.ts index faa37ea0ed56c..3adca32f0bf8e 100644 --- a/src/ui/public/visualize/loader/embedded_visualize_handler.ts +++ b/src/ui/public/visualize/loader/embedded_visualize_handler.ts @@ -94,15 +94,7 @@ export class EmbeddedVisualizeHandler { ) { const { searchSource, vis } = savedObject; - const { - appState, - uiState, - queryFilter, - timeRange, - filters, - query, - autoFetch, - } = params; + const { appState, uiState, queryFilter, timeRange, filters, query, autoFetch } = params; this.dataLoaderParams = { searchSource, @@ -250,7 +242,9 @@ export class EmbeddedVisualizeHandler { .then(() => { if (!this.loaded) { this.loaded = true; - this.fetchAndRender(); + if (this.autoFetch) { + this.fetchAndRender(); + } } }); }; From 851ef3531483330438d2115a65b7455eefbd0f9e Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 5 Dec 2018 10:59:41 +0100 Subject: [PATCH 26/32] split table row/column --- .../interpreter/public/functions/table.js | 18 +++++++++++++++--- .../interpreter/public/functions/vislib.js | 6 +++++- .../loader/pipeline_helpers/build_pipeline.ts | 10 ++++++++-- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/legacy/core_plugins/interpreter/public/functions/table.js b/src/legacy/core_plugins/interpreter/public/functions/table.js index ce2b08b134504..4355bfa77bf8e 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/table.js +++ b/src/legacy/core_plugins/interpreter/public/functions/table.js @@ -39,7 +39,11 @@ export default () => ({ types: ['string'], multi: false, }, - split: { + splitRow: { + types: ['string'], + multi: false, + }, + splitColumn: { types: ['string'], multi: false, }, @@ -68,11 +72,19 @@ export default () => ({ bucketColumn.aggConfig.schema = 'bucket'; }); } - if (args.split) { - args.split.split(',').forEach(split => { + if (args.splitColumn) { + args.splitColumn.split(',').forEach(split => { + const splitColumn = context.columns.find((column, i) => + column.id === split || column.name === split || i === parseInt(split)); + splitColumn.aggConfig.schema = 'split'; + }); + } + if (args.splitRow) { + args.splitRow.split(',').forEach(split => { const splitColumn = context.columns.find((column, i) => column.id === split || column.name === split || i === parseInt(split)); splitColumn.aggConfig.schema = 'split'; + splitColumn.aggConfig.params.row = true; }); } diff --git a/src/legacy/core_plugins/interpreter/public/functions/vislib.js b/src/legacy/core_plugins/interpreter/public/functions/vislib.js index 437d458d4d901..f3ce6004fb029 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/vislib.js +++ b/src/legacy/core_plugins/interpreter/public/functions/vislib.js @@ -67,7 +67,11 @@ export default () => ({ Object.keys(schemas).forEach(key => { schemas[key].forEach(i => { - context.columns[i].aggConfig.schema = key; + const schema = key.split('_'); + context.columns[i].aggConfig.schema = schema[0]; + if (schema[1] === 'row') { + context.columns[i].aggConfig.params.row = true; + } }); }); } diff --git a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts index 219dc7cf171eb..582bd545a64eb 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts +++ b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts @@ -60,6 +60,9 @@ export const getSchemas = (vis: Vis): Schemas => { if (!schemaName) { return; } + if (schemaName === 'split') { + schemaName = `split_${agg.params.row ? 'row' : 'column'}`; + } if (!schemas[schemaName]) { schemas[schemaName] = []; } @@ -105,8 +108,11 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { }, table: (visState, schemas) => { let pipeline = `kibana_table ${prepareJson('visConfig', visState.params)}`; - if (schemas.split) { - pipeline += `split='${schemas.split.join(',')}' `; + if (schemas.split_row) { + pipeline += `splitRow='${schemas.split_row.join(',')}' `; + } + if (schemas.split_column) { + pipeline += `splitColumn='${schemas.split_column.join(',')}' `; } if (schemas.bucket) { pipeline += `bucket='${schemas.bucket.join(',')}' `; From e7c63f1066df3aaa17ba7f0fcc8a7055384a47ce Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 5 Dec 2018 15:23:10 +0100 Subject: [PATCH 27/32] updating based on tim's review --- .../src/plugin/types/kibana_table.js | 96 ------------------- .../interpreter/public/functions/kibana.js | 4 +- .../public/functions/kibana_context.js | 4 +- 3 files changed, 2 insertions(+), 102 deletions(-) diff --git a/packages/kbn-interpreter/src/plugin/types/kibana_table.js b/packages/kbn-interpreter/src/plugin/types/kibana_table.js index 1a133720b5286..67cedbded50ae 100644 --- a/packages/kbn-interpreter/src/plugin/types/kibana_table.js +++ b/packages/kbn-interpreter/src/plugin/types/kibana_table.js @@ -25,11 +25,6 @@ export const kibanaTable = () => ({ }); return context; }, - deserialize: () => { - // config.visData.columns.forEach(column => { - // column.aggConfig = new AggConfig(a, column.aggConfig); - // }); - }, validate: tabify => { if (!tabify.columns) { throw new Error('tabify must have a columns array, even if it is empty'); @@ -42,96 +37,5 @@ export const kibanaTable = () => ({ columns: [], }; }, - datatable: context => { - const converted = { - columns: context.columns.map(column => { - return { - id: column.name, - title: column.name, - ...column - }; - }), - rows: context.rows.map(row => { - const crow = {}; - context.columns.forEach(column => { - crow[column.name] = (row[column.name]); - }); - return crow; - }) - }; - return { - type: 'kibana_table', - ...converted, - }; - }, - number: context => { - return { - type: 'kibana_table', - columns: [{ id: 'col-0', title: 'Count' }], - rows: [{ 'col-0': context }] - }; - }, - pointseries: context => { - const converted = { - tables: [{ - columns: Object.getKeys(context.columns).map(name => { - const column = context.columns[name]; - return { - title: column.name || name, - ...column - }; - }), - rows: context.rows.map(row => { - const crow = []; - Object.getKeys(context.columns).forEach((column, i) => { - crow.push(row[i]); - }); - return crow; - }) - }] - }; - return { - type: 'kibana_table', - value: converted, - }; - } }, - to: { - datatable: context => { - const columns = context.columns.map(column => { - return { name: column.title, ...column }; - }); - const rows = context.rows.map(row => { - const converted = {}; - columns.forEach((column) => { - converted[column.name] = row[column.id]; - }); - return converted; - }); - - return { - type: 'datatable', - columns: columns, - rows: rows, - }; - }, - pointseries: context => { - const columns = context.value.tables[0].columns.map(column => { - return { name: column.title, ...column }; - }); - const rows = context.value.tables[0].rows.map(row => { - const converted = {}; - columns.forEach((column, i) => { - converted[column.name] = row[i]; - }); - return converted; - }); - - return { - type: 'pointseries', - columns: columns, - rows: rows, - }; - } - } }); diff --git a/src/legacy/core_plugins/interpreter/public/functions/kibana.js b/src/legacy/core_plugins/interpreter/public/functions/kibana.js index 7946c06bb149b..622f689e23ec2 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/kibana.js +++ b/src/legacy/core_plugins/interpreter/public/functions/kibana.js @@ -31,12 +31,10 @@ export default () => ({ const initialContext = handlers.getInitialContext ? handlers.getInitialContext() : {}; if (context.query) { - const contextQueries = Array.isArray(context.query) ? context.query : [context.query]; - initialContext.query = initialContext.query.concat(contextQueries); + initialContext.query = initialContext.query.concat(context.query); } if (context.filters) { - // merge filters initialContext.filters = initialContext.filters.concat(context.filters); } diff --git a/src/legacy/core_plugins/interpreter/public/functions/kibana_context.js b/src/legacy/core_plugins/interpreter/public/functions/kibana_context.js index 519c40ac93998..f1d1540ad4d4e 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/kibana_context.js +++ b/src/legacy/core_plugins/interpreter/public/functions/kibana_context.js @@ -67,12 +67,10 @@ export default () => ({ } if (context.query) { - const contextQueries = Array.isArray(context.query) ? context.query : [context.query]; - queries = queries.concat(contextQueries); + queries = queries.concat(context.query); } if (context.filters) { - // merge filters filters = filters.concat(context.filters); } From 995e241a59570315d5eb3eaa2d6beaf56f34f01b Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 6 Dec 2018 08:40:47 +0100 Subject: [PATCH 28/32] fixing escaping issue --- .../__snapshots__/build_pipeline.test.js.snap | 4 ++-- .../loader/pipeline_helpers/build_pipeline.test.js | 4 ++-- .../visualize/loader/pipeline_helpers/build_pipeline.ts | 6 ++++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/ui/public/visualize/loader/pipeline_helpers/__snapshots__/build_pipeline.test.js.snap b/src/ui/public/visualize/loader/pipeline_helpers/__snapshots__/build_pipeline.test.js.snap index 2d396f74439d7..41998b84691b6 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers/__snapshots__/build_pipeline.test.js.snap +++ b/src/ui/public/visualize/loader/pipeline_helpers/__snapshots__/build_pipeline.test.js.snap @@ -14,9 +14,9 @@ exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunct exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles region_map function with metrics and buckets 1`] = `"regionmap visConfig='{\\"foo\\":\\"bar\\"}' bucket='1,2' metric='0' "`; -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function with splits 1`] = `"kibana_table visConfig='{\\"foo\\":\\"bar\\"}' split='1,2' metric='0' "`; +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function with splits 1`] = `"kibana_table visConfig='{\\"foo\\":\\"bar\\"}' splitRow='1,2' metric='0' "`; -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function with splits and buckets 1`] = `"kibana_table visConfig='{\\"foo\\":\\"bar\\"}' split='2,4' bucket='3' metric='0,1' "`; +exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function with splits and buckets 1`] = `"kibana_table visConfig='{\\"foo\\":\\"bar\\"}' splitRow='2,4' bucket='3' metric='0,1' "`; exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function without splits or buckets 1`] = `"kibana_table visConfig='{\\"foo\\":\\"bar\\"}' metric='0,1' "`; diff --git a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.js b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.js index 577ad96d8c150..9290706545d99 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.js +++ b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.js @@ -101,7 +101,7 @@ describe('visualize loader pipeline helpers: build pipeline', () => { it('with splits', () => { const schemas = { metric: [0], - split: [1, 2], + split_row: [1, 2], }; const actual = buildPipelineVisFunction.table({ params }, schemas); expect(actual).toMatchSnapshot(); @@ -110,7 +110,7 @@ describe('visualize loader pipeline helpers: build pipeline', () => { it('with splits and buckets', () => { const schemas = { metric: [0, 1], - split: [2, 4], + split_row: [2, 4], bucket: [3] }; const actual = buildPipelineVisFunction.table({ params }, schemas); diff --git a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts index 582bd545a64eb..20a6b27febec4 100644 --- a/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts +++ b/src/ui/public/visualize/loader/pipeline_helpers/build_pipeline.ts @@ -79,11 +79,13 @@ export const getSchemas = (vis: Vis): Schemas => { }; export const prepareJson = (variable: string, data: object): string => { - return `${variable}='${JSON.stringify(data).replace(/'/g, `\\'`)}' `; + return `${variable}='${JSON.stringify(data) + .replace(/\\/g, `\\\\`) + .replace(/'/g, `\\'`)}' `; }; export const prepareString = (variable: string, data: string): string => { - return `${variable}='${data.replace(/'/g, `\\'`)}' `; + return `${variable}='${data.replace(/\\/g, `\\\\`).replace(/'/g, `\\'`)}' `; }; export const buildPipelineVisFunction: BuildPipelineVisFunction = { From c50ead2f080533081c0b38217e330488cf0ec079 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 6 Dec 2018 13:22:55 +0100 Subject: [PATCH 29/32] updating canvas setAppReady --- packages/kbn-interpreter/src/public/index.js | 2 +- packages/kbn-interpreter/src/public/interpreter.js | 4 ++++ x-pack/plugins/canvas/public/components/app/index.js | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/kbn-interpreter/src/public/index.js b/packages/kbn-interpreter/src/public/index.js index de8caad1dbc5b..736e6917f2cb2 100644 --- a/packages/kbn-interpreter/src/public/index.js +++ b/packages/kbn-interpreter/src/public/index.js @@ -19,4 +19,4 @@ export { populateBrowserRegistries, getBrowserRegistries } from './browser_registries'; export { createSocket } from './socket'; -export { initializeInterpreter, interpretAst } from './interpreter'; +export { initializeInterpreter, interpretAst, isInterpreterInitialized } from './interpreter'; diff --git a/packages/kbn-interpreter/src/public/interpreter.js b/packages/kbn-interpreter/src/public/interpreter.js index 5747eafcd274c..0f88184d52e56 100644 --- a/packages/kbn-interpreter/src/public/interpreter.js +++ b/packages/kbn-interpreter/src/public/interpreter.js @@ -47,6 +47,10 @@ export async function initializeInterpreter() { return functionList; } +export async function isInterpreterInitialized() { + return functionList; +} + // Use the above promise to seed the interpreter with the functions it can defer to export async function interpretAst(ast, context, handlers) { // Load plugins before attempting to get functions, otherwise this gets racey diff --git a/x-pack/plugins/canvas/public/components/app/index.js b/x-pack/plugins/canvas/public/components/app/index.js index 48373e8ad1a8c..1417a5b90ba56 100644 --- a/x-pack/plugins/canvas/public/components/app/index.js +++ b/x-pack/plugins/canvas/public/components/app/index.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { populateBrowserRegistries } from '@kbn/interpreter/public'; +import { populateBrowserRegistries, isInterpreterInitialized } from '@kbn/interpreter/public'; import { connect } from 'react-redux'; import { compose, withProps } from 'recompose'; import { getAppReady, getBasePath } from '../../state/selectors/app'; @@ -49,6 +49,7 @@ const mapDispatchToProps = dispatch => ({ // initialize the socket and interpreter loadPrivateBrowserFunctions(); await populateBrowserRegistries(types, basePath); + await isInterpreterInitialized(); // set app state to ready dispatch(appReady()); From 01fbb847829e9769c6123279a4b84140d81b5bd4 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 6 Dec 2018 15:18:20 +0100 Subject: [PATCH 30/32] removing multi: false from args --- .../core_plugins/interpreter/public/functions/esaggs.js | 1 - .../interpreter/public/functions/input_control.js | 1 - .../core_plugins/interpreter/public/functions/markdown.js | 2 -- .../core_plugins/interpreter/public/functions/metric.js | 3 --- src/legacy/core_plugins/interpreter/public/functions/pie.js | 2 -- .../core_plugins/interpreter/public/functions/regionmap.js | 3 --- .../core_plugins/interpreter/public/functions/table.js | 5 ----- .../core_plugins/interpreter/public/functions/tagcloud.js | 3 --- .../core_plugins/interpreter/public/functions/tilemap.js | 3 --- .../interpreter/public/functions/timelion_vis.js | 2 -- src/legacy/core_plugins/interpreter/public/functions/tsvb.js | 2 -- src/legacy/core_plugins/interpreter/public/functions/vega.js | 1 - .../core_plugins/interpreter/public/functions/vislib.js | 3 --- .../interpreter/public/functions/visualization.js | 4 ---- 14 files changed, 35 deletions(-) diff --git a/src/legacy/core_plugins/interpreter/public/functions/esaggs.js b/src/legacy/core_plugins/interpreter/public/functions/esaggs.js index e73dd1f761917..a2c0069330f28 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/esaggs.js +++ b/src/legacy/core_plugins/interpreter/public/functions/esaggs.js @@ -58,7 +58,6 @@ export default () => ({ aggConfigs: { types: ['string'], default: '""', - multi: false, }, }, async fn(context, args, handlers) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/input_control.js b/src/legacy/core_plugins/interpreter/public/functions/input_control.js index ce2b54b5e98e7..b081fce09d136 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/input_control.js +++ b/src/legacy/core_plugins/interpreter/public/functions/input_control.js @@ -32,7 +32,6 @@ export default () => ({ visConfig: { types: ['string'], default: '"{}"', - multi: false, } }, fn(context, args) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/markdown.js b/src/legacy/core_plugins/interpreter/public/functions/markdown.js index 691a5110abdfb..ec901e0553765 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/markdown.js +++ b/src/legacy/core_plugins/interpreter/public/functions/markdown.js @@ -34,12 +34,10 @@ export default () => ({ aliases: [ '_' ], default: '', help: 'markdown', - multi: false, }, visConfig: { types: ['string'], default: '"{}"', - multi: false, } }, fn(context, args) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/metric.js b/src/legacy/core_plugins/interpreter/public/functions/metric.js index 7778e28b80dfa..97171cb557bb2 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/metric.js +++ b/src/legacy/core_plugins/interpreter/public/functions/metric.js @@ -34,17 +34,14 @@ export default () => ({ bucket: { types: ['string', 'null'], default: null, - multi: false, }, metric: { types: ['string'], default: '1', - multi: false, }, visConfig: { types: ['string', 'null'], default: '"{}"', - multi: false, }, }, fn(context, args) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/pie.js b/src/legacy/core_plugins/interpreter/public/functions/pie.js index 177d8c7ed8534..ae78defffc5ca 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/pie.js +++ b/src/legacy/core_plugins/interpreter/public/functions/pie.js @@ -37,12 +37,10 @@ export default () => ({ schemas: { types: ['string'], default: '"{}"', - multi: false, }, visConfig: { types: ['string', 'null'], default: '"{}"', - multi: false, }, }, async fn(context, args) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/regionmap.js b/src/legacy/core_plugins/interpreter/public/functions/regionmap.js index f04167bed7e32..91970f3b8a008 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/regionmap.js +++ b/src/legacy/core_plugins/interpreter/public/functions/regionmap.js @@ -34,17 +34,14 @@ export default () => ({ bucket: { types: ['string'], default: '0', - multi: false, }, metric: { types: ['string'], default: '1', - multi: false, }, visConfig: { types: ['string', 'null'], default: '"{}"', - multi: false, }, }, fn(context, args) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/table.js b/src/legacy/core_plugins/interpreter/public/functions/table.js index 4355bfa77bf8e..5514de529cdf1 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/table.js +++ b/src/legacy/core_plugins/interpreter/public/functions/table.js @@ -37,25 +37,20 @@ export default () => ({ args: { bucket: { types: ['string'], - multi: false, }, splitRow: { types: ['string'], - multi: false, }, splitColumn: { types: ['string'], - multi: false, }, metric: { types: ['string'], default: '1', - multi: false, }, visConfig: { types: ['string', 'null'], default: '"{}"', - multi: false, }, }, async fn(context, args) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/tagcloud.js b/src/legacy/core_plugins/interpreter/public/functions/tagcloud.js index cb502cae722bf..3193d07dedd27 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/tagcloud.js +++ b/src/legacy/core_plugins/interpreter/public/functions/tagcloud.js @@ -34,17 +34,14 @@ export default () => ({ bucket: { types: ['string'], default: '0', - multi: false, }, metric: { types: ['string'], default: '1', - multi: false, }, visConfig: { types: ['string', 'null'], default: '"{}"', - multi: false, }, }, fn(context, args) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/tilemap.js b/src/legacy/core_plugins/interpreter/public/functions/tilemap.js index 0fe81d0aad0b4..ae1e1cc0325c7 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/tilemap.js +++ b/src/legacy/core_plugins/interpreter/public/functions/tilemap.js @@ -37,17 +37,14 @@ export default () => ({ bucket: { types: ['string'], default: '0', - multi: false, }, metric: { types: ['string'], default: '1', - multi: false, }, visConfig: { types: ['string', 'null'], default: '"{}"', - multi: false, }, }, fn(context, args) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js b/src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js index 6752768a47143..5085832a76025 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js +++ b/src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js @@ -41,12 +41,10 @@ export default () => ({ types: ['string'], aliases: ['_'], default: '".es(*)"', - multi: false, }, interval: { types: ['string', 'null'], default: 'auto', - multi: false, } }, async fn(context, args) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/tsvb.js b/src/legacy/core_plugins/interpreter/public/functions/tsvb.js index c828551b6d449..fa5367528f53b 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/tsvb.js +++ b/src/legacy/core_plugins/interpreter/public/functions/tsvb.js @@ -41,12 +41,10 @@ export default () => ({ params: { types: ['string'], default: '"{}"', - multi: false, }, uiState: { types: ['string'], default: '"{}"', - multi: false } }, async fn(context, args) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/vega.js b/src/legacy/core_plugins/interpreter/public/functions/vega.js index a1d4b34a2e941..393eac7ef43b6 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/vega.js +++ b/src/legacy/core_plugins/interpreter/public/functions/vega.js @@ -38,7 +38,6 @@ export default () => ({ spec: { types: ['string'], default: '', - multi: false, }, }, async fn(context, args) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/vislib.js b/src/legacy/core_plugins/interpreter/public/functions/vislib.js index f3ce6004fb029..bbd61d2ef56b6 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/vislib.js +++ b/src/legacy/core_plugins/interpreter/public/functions/vislib.js @@ -37,17 +37,14 @@ export default () => ({ type: { types: ['string'], default: 'metric', - multi: false, }, schemas: { types: ['string'], default: '"{}"', - multi: false, }, visConfig: { types: ['string', 'null'], default: '"{}"', - multi: false, }, }, async fn(context, args) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/visualization.js b/src/legacy/core_plugins/interpreter/public/functions/visualization.js index c935e8fd0ae9e..386a94c488eb1 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/visualization.js +++ b/src/legacy/core_plugins/interpreter/public/functions/visualization.js @@ -66,22 +66,18 @@ export default () => ({ type: { types: ['string'], default: '', - multi: false, }, schemas: { types: ['string'], default: '"{}"', - multi: false, }, visConfig: { types: ['string'], default: '"{}"', - multi: false, }, uiState: { types: ['string'], default: '"{}"', - multi: false } }, async fn(context, args, handlers) { From fcd0f6afd95e2b012b0cd673c78ef4047659c979 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Sun, 9 Dec 2018 08:36:38 +0100 Subject: [PATCH 31/32] named functions --- .../interpreter/public/functions/esaggs.js | 2 +- .../interpreter/public/functions/index.js | 36 +++++++++---------- .../public/functions/input_control.js | 2 +- .../interpreter/public/functions/kibana.js | 2 +- .../public/functions/kibana_context.js | 2 +- .../interpreter/public/functions/markdown.js | 2 +- .../interpreter/public/functions/metric.js | 2 +- .../interpreter/public/functions/pie.js | 2 +- .../interpreter/public/functions/regionmap.js | 2 +- .../interpreter/public/functions/table.js | 2 +- .../interpreter/public/functions/tagcloud.js | 2 +- .../interpreter/public/functions/tilemap.js | 2 +- .../public/functions/timelion_vis.js | 2 +- .../interpreter/public/functions/tsvb.js | 2 +- .../interpreter/public/functions/vega.js | 2 +- .../interpreter/public/functions/vislib.js | 2 +- .../public/functions/visualization.js | 2 +- 17 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/legacy/core_plugins/interpreter/public/functions/esaggs.js b/src/legacy/core_plugins/interpreter/public/functions/esaggs.js index a2c0069330f28..ba5b6c009701f 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/esaggs.js +++ b/src/legacy/core_plugins/interpreter/public/functions/esaggs.js @@ -32,7 +32,7 @@ import chrome from 'ui/chrome'; const courierRequestHandlerProvider = CourierRequestHandlerProvider; const courierRequestHandler = courierRequestHandlerProvider().handler; -export default () => ({ +export const esaggs = () => ({ name: 'esaggs', type: 'kibana_table', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/index.js b/src/legacy/core_plugins/interpreter/public/functions/index.js index 89b96ed92283d..27605bf9e69c5 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/index.js +++ b/src/legacy/core_plugins/interpreter/public/functions/index.js @@ -17,24 +17,24 @@ * under the License. */ -import esaggs from './esaggs'; -import kibana from './kibana'; -import kibanaContext from './kibana_context'; -import vega from './vega'; -import timelion from './timelion_vis'; -import tsvb from './tsvb'; -import markdown from './markdown'; -import inputControl from './input_control'; -import metric from './metric'; -import pie from './pie'; -import regionMap from './regionmap'; -import tileMap from './tilemap'; -import table from './table'; -import tagCloud from './tagcloud'; -import vislib from './vislib'; -import visualization from './visualization'; +import { esaggs } from './esaggs'; +import { kibana } from './kibana'; +import { kibanaContext } from './kibana_context'; +import { vega } from './vega'; +import { timelionVis } from './timelion_vis'; +import { tsvb } from './tsvb'; +import { kibanaMarkdown } from './markdown'; +import { inputControlVis } from './input_control'; +import { metric } from './metric'; +import { kibanaPie } from './pie'; +import { regionmap } from './regionmap'; +import { tilemap } from './tilemap'; +import { kibanaTable } from './table'; +import { tagcloud } from './tagcloud'; +import { vislib } from './vislib'; +import { visualization } from './visualization'; export const functions = [ - esaggs, kibana, kibanaContext, vega, timelion, tsvb, markdown, inputControl, - metric, pie, regionMap, tileMap, table, tagCloud, vislib, visualization + esaggs, kibana, kibanaContext, vega, timelionVis, tsvb, kibanaMarkdown, inputControlVis, + metric, kibanaPie, regionmap, tilemap, kibanaTable, tagcloud, vislib, visualization ]; diff --git a/src/legacy/core_plugins/interpreter/public/functions/input_control.js b/src/legacy/core_plugins/interpreter/public/functions/input_control.js index b081fce09d136..db0f5dfe27af6 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/input_control.js +++ b/src/legacy/core_plugins/interpreter/public/functions/input_control.js @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; -export default () => ({ +export const inputControlVis = () => ({ name: 'input_control_vis', type: 'render', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/kibana.js b/src/legacy/core_plugins/interpreter/public/functions/kibana.js index 622f689e23ec2..faef6a660c063 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/kibana.js +++ b/src/legacy/core_plugins/interpreter/public/functions/kibana.js @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; -export default () => ({ +export const kibana = () => ({ name: 'kibana', type: 'kibana_context', context: {}, diff --git a/src/legacy/core_plugins/interpreter/public/functions/kibana_context.js b/src/legacy/core_plugins/interpreter/public/functions/kibana_context.js index f1d1540ad4d4e..9b6cccb773df9 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/kibana_context.js +++ b/src/legacy/core_plugins/interpreter/public/functions/kibana_context.js @@ -20,7 +20,7 @@ import chrome from 'ui/chrome'; import { i18n } from '@kbn/i18n'; -export default () => ({ +export const kibanaContext = () => ({ name: 'kibana_context', type: 'kibana_context', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/markdown.js b/src/legacy/core_plugins/interpreter/public/functions/markdown.js index ec901e0553765..0b1afda450bd6 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/markdown.js +++ b/src/legacy/core_plugins/interpreter/public/functions/markdown.js @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; -export default () => ({ +export const kibanaMarkdown = () => ({ name: 'kibana_markdown', type: 'render', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/metric.js b/src/legacy/core_plugins/interpreter/public/functions/metric.js index 97171cb557bb2..defa432f65314 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/metric.js +++ b/src/legacy/core_plugins/interpreter/public/functions/metric.js @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; -export default () => ({ +export const metric = () => ({ name: 'kibana_metric', type: 'render', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/pie.js b/src/legacy/core_plugins/interpreter/public/functions/pie.js index ae78defffc5ca..e828164e18ee2 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/pie.js +++ b/src/legacy/core_plugins/interpreter/public/functions/pie.js @@ -22,7 +22,7 @@ import { VislibSlicesResponseHandlerProvider } from 'ui/vis/response_handlers/vi import chrome from 'ui/chrome'; import { i18n } from '@kbn/i18n'; -export default () => ({ +export const kibanaPie = () => ({ name: 'kibana_pie', type: 'render', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/regionmap.js b/src/legacy/core_plugins/interpreter/public/functions/regionmap.js index 91970f3b8a008..b92122a726905 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/regionmap.js +++ b/src/legacy/core_plugins/interpreter/public/functions/regionmap.js @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; -export default () => ({ +export const regionmap = () => ({ name: 'regionmap', type: 'render', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/table.js b/src/legacy/core_plugins/interpreter/public/functions/table.js index 5514de529cdf1..d35e81d6b1a74 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/table.js +++ b/src/legacy/core_plugins/interpreter/public/functions/table.js @@ -23,7 +23,7 @@ import { i18n } from '@kbn/i18n'; // eslint-disable-next-line new-cap const responseHandler = LegacyResponseHandlerProvider().handler; -export default () => ({ +export const kibanaTable = () => ({ name: 'kibana_table', type: 'render', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/tagcloud.js b/src/legacy/core_plugins/interpreter/public/functions/tagcloud.js index 3193d07dedd27..fbad1dd39acc4 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/tagcloud.js +++ b/src/legacy/core_plugins/interpreter/public/functions/tagcloud.js @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; -export default () => ({ +export const tagcloud = () => ({ name: 'tagcloud', type: 'render', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/tilemap.js b/src/legacy/core_plugins/interpreter/public/functions/tilemap.js index ae1e1cc0325c7..6015a8e2626e7 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/tilemap.js +++ b/src/legacy/core_plugins/interpreter/public/functions/tilemap.js @@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n'; const responseHandler = makeGeoJsonResponseHandler(); -export default () => ({ +export const tilemap = () => ({ name: 'tilemap', type: 'render', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js b/src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js index 5085832a76025..f45f7038cbb22 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js +++ b/src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js @@ -24,7 +24,7 @@ import { TimelionRequestHandlerProvider } from 'plugins/timelion/vis/timelion_re import chrome from 'ui/chrome'; -export default () => ({ +export const timelionVis = () => ({ name: 'timelion_vis', type: 'render', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/tsvb.js b/src/legacy/core_plugins/interpreter/public/functions/tsvb.js index fa5367528f53b..ce83dfcadb62d 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/tsvb.js +++ b/src/legacy/core_plugins/interpreter/public/functions/tsvb.js @@ -25,7 +25,7 @@ import { PersistedState } from 'ui/persisted_state'; import chrome from 'ui/chrome'; -export default () => ({ +export const tsvb = () => ({ name: 'tsvb', type: 'render', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/vega.js b/src/legacy/core_plugins/interpreter/public/functions/vega.js index 393eac7ef43b6..52439e607c89e 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/vega.js +++ b/src/legacy/core_plugins/interpreter/public/functions/vega.js @@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n'; import chrome from 'ui/chrome'; import { VegaRequestHandlerProvider } from 'plugins/vega/vega_request_handler'; -export default () => ({ +export const vega = () => ({ name: 'vega', type: 'render', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/vislib.js b/src/legacy/core_plugins/interpreter/public/functions/vislib.js index bbd61d2ef56b6..3ff0c6f0389d1 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/vislib.js +++ b/src/legacy/core_plugins/interpreter/public/functions/vislib.js @@ -22,7 +22,7 @@ import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import { VislibSeriesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib'; import chrome from 'ui/chrome'; -export default () => ({ +export const vislib = () => ({ name: 'vislib', type: 'render', context: { diff --git a/src/legacy/core_plugins/interpreter/public/functions/visualization.js b/src/legacy/core_plugins/interpreter/public/functions/visualization.js index 386a94c488eb1..2e37871c9750e 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/visualization.js +++ b/src/legacy/core_plugins/interpreter/public/functions/visualization.js @@ -41,7 +41,7 @@ function getHandler(from, type) { return handlerDesc.handler; } -export default () => ({ +export const visualization = () => ({ name: 'visualization', type: 'render', context: { From 319d7c16dad729dbf997df4e1e66acbeb6807621 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Sun, 9 Dec 2018 08:39:23 +0100 Subject: [PATCH 32/32] renaming getInitializedFunctions --- packages/kbn-interpreter/src/public/index.js | 2 +- packages/kbn-interpreter/src/public/interpreter.js | 2 +- x-pack/plugins/canvas/public/components/app/index.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/kbn-interpreter/src/public/index.js b/packages/kbn-interpreter/src/public/index.js index 736e6917f2cb2..8c50c66ff2f2e 100644 --- a/packages/kbn-interpreter/src/public/index.js +++ b/packages/kbn-interpreter/src/public/index.js @@ -19,4 +19,4 @@ export { populateBrowserRegistries, getBrowserRegistries } from './browser_registries'; export { createSocket } from './socket'; -export { initializeInterpreter, interpretAst, isInterpreterInitialized } from './interpreter'; +export { initializeInterpreter, interpretAst, getInitializedFunctions } from './interpreter'; diff --git a/packages/kbn-interpreter/src/public/interpreter.js b/packages/kbn-interpreter/src/public/interpreter.js index 0f88184d52e56..99bf6814deb65 100644 --- a/packages/kbn-interpreter/src/public/interpreter.js +++ b/packages/kbn-interpreter/src/public/interpreter.js @@ -47,7 +47,7 @@ export async function initializeInterpreter() { return functionList; } -export async function isInterpreterInitialized() { +export async function getInitializedFunctions() { return functionList; } diff --git a/x-pack/plugins/canvas/public/components/app/index.js b/x-pack/plugins/canvas/public/components/app/index.js index 1417a5b90ba56..b3a9fcc79036e 100644 --- a/x-pack/plugins/canvas/public/components/app/index.js +++ b/x-pack/plugins/canvas/public/components/app/index.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { populateBrowserRegistries, isInterpreterInitialized } from '@kbn/interpreter/public'; +import { populateBrowserRegistries, getInitializedFunctions } from '@kbn/interpreter/public'; import { connect } from 'react-redux'; import { compose, withProps } from 'recompose'; import { getAppReady, getBasePath } from '../../state/selectors/app'; @@ -49,7 +49,7 @@ const mapDispatchToProps = dispatch => ({ // initialize the socket and interpreter loadPrivateBrowserFunctions(); await populateBrowserRegistries(types, basePath); - await isInterpreterInitialized(); + await getInitializedFunctions(); // set app state to ready dispatch(appReady());