diff --git a/.ci/Jenkinsfile_flaky b/.ci/Jenkinsfile_flaky index e1cbac0528b1f..8ad02b7162b6a 100644 --- a/.ci/Jenkinsfile_flaky +++ b/.ci/Jenkinsfile_flaky @@ -34,7 +34,7 @@ stage("Kibana Pipeline") { if (!IS_XPACK) { kibanaPipeline.buildOss() if (CI_GROUP == '1') { - runbld "./test/scripts/jenkins_build_kbn_tp_sample_panel_action.sh" + runbld("./test/scripts/jenkins_build_kbn_tp_sample_panel_action.sh", "Build kbn tp sample panel action for ciGroup1") } } else { kibanaPipeline.buildXpack() @@ -62,18 +62,18 @@ stage("Kibana Pipeline") { def getWorkerFromParams(isXpack, job, ciGroup) { if (!isXpack) { if (job == 'firefoxSmoke') { - return kibanaPipeline.getPostBuildWorker('firefoxSmoke', { runbld './test/scripts/jenkins_firefox_smoke.sh' }) + return kibanaPipeline.getPostBuildWorker('firefoxSmoke', { runbld('./test/scripts/jenkins_firefox_smoke.sh', 'Execute kibana-firefoxSmoke') }) } else if(job == 'visualRegression') { - return kibanaPipeline.getPostBuildWorker('visualRegression', { runbld './test/scripts/jenkins_visual_regression.sh' }) + return kibanaPipeline.getPostBuildWorker('visualRegression', { runbld('./test/scripts/jenkins_visual_regression.sh', 'Execute kibana-visualRegression') }) } else { return kibanaPipeline.getOssCiGroupWorker(ciGroup) } } if (job == 'firefoxSmoke') { - return kibanaPipeline.getPostBuildWorker('xpack-firefoxSmoke', { runbld './test/scripts/jenkins_xpack_firefox_smoke.sh' }) + return kibanaPipeline.getPostBuildWorker('xpack-firefoxSmoke', { runbld('./test/scripts/jenkins_xpack_firefox_smoke.sh', 'Execute xpack-firefoxSmoke') }) } else if(job == 'visualRegression') { - return kibanaPipeline.getPostBuildWorker('xpack-visualRegression', { runbld './test/scripts/jenkins_xpack_visual_regression.sh' }) + return kibanaPipeline.getPostBuildWorker('xpack-visualRegression', { runbld('./test/scripts/jenkins_xpack_visual_regression.sh', 'Execute xpack-visualRegression') }) } else { return kibanaPipeline.getXpackCiGroupWorker(ciGroup) } diff --git a/Jenkinsfile b/Jenkinsfile index 8d8579736f639..c002832d4d51a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -24,9 +24,9 @@ stage("Kibana Pipeline") { // This stage is just here to help the BlueOcean UI a 'oss-ciGroup10': kibanaPipeline.getOssCiGroupWorker(10), 'oss-ciGroup11': kibanaPipeline.getOssCiGroupWorker(11), 'oss-ciGroup12': kibanaPipeline.getOssCiGroupWorker(12), - 'oss-firefoxSmoke': kibanaPipeline.getPostBuildWorker('firefoxSmoke', { runbld './test/scripts/jenkins_firefox_smoke.sh' }), - 'oss-accessibility': kibanaPipeline.getPostBuildWorker('accessibility', { runbld './test/scripts/jenkins_accessibility.sh' }), - 'oss-visualRegression': kibanaPipeline.getPostBuildWorker('visualRegression', { runbld './test/scripts/jenkins_visual_regression.sh' }), + 'oss-firefoxSmoke': kibanaPipeline.getPostBuildWorker('firefoxSmoke', { runbld('./test/scripts/jenkins_firefox_smoke.sh', 'Execute kibana-firefoxSmoke') }), + 'oss-accessibility': kibanaPipeline.getPostBuildWorker('accessibility', { runbld('./test/scripts/jenkins_accessibility.sh', 'Execute kibana-accessibility') }), + 'oss-visualRegression': kibanaPipeline.getPostBuildWorker('visualRegression', { runbld('./test/scripts/jenkins_visual_regression.sh', 'Execute kibana-visualRegression') }), ]), 'kibana-xpack-agent': kibanaPipeline.withWorkers('kibana-xpack-tests', { kibanaPipeline.buildXpack() }, [ 'xpack-ciGroup1': kibanaPipeline.getXpackCiGroupWorker(1), @@ -39,9 +39,9 @@ stage("Kibana Pipeline") { // This stage is just here to help the BlueOcean UI a 'xpack-ciGroup8': kibanaPipeline.getXpackCiGroupWorker(8), 'xpack-ciGroup9': kibanaPipeline.getXpackCiGroupWorker(9), 'xpack-ciGroup10': kibanaPipeline.getXpackCiGroupWorker(10), - 'xpack-firefoxSmoke': kibanaPipeline.getPostBuildWorker('xpack-firefoxSmoke', { runbld './test/scripts/jenkins_xpack_firefox_smoke.sh' }), - 'xpack-accessibility': kibanaPipeline.getPostBuildWorker('xpack-accessibility', { runbld './test/scripts/jenkins_xpack_accessibility.sh' }), - 'xpack-visualRegression': kibanaPipeline.getPostBuildWorker('xpack-visualRegression', { runbld './test/scripts/jenkins_xpack_visual_regression.sh' }), + 'xpack-firefoxSmoke': kibanaPipeline.getPostBuildWorker('xpack-firefoxSmoke', { runbld('./test/scripts/jenkins_xpack_firefox_smoke.sh', 'Execute xpack-firefoxSmoke') }), + 'xpack-accessibility': kibanaPipeline.getPostBuildWorker('xpack-accessibility', { runbld('./test/scripts/jenkins_xpack_accessibility.sh', 'Execute xpack-accessibility') }), + 'xpack-visualRegression': kibanaPipeline.getPostBuildWorker('xpack-visualRegression', { runbld('./test/scripts/jenkins_xpack_visual_regression.sh', 'Execute xpack-visualRegression') }), ]), ]) } diff --git a/packages/kbn-babel-preset/common_preset.js b/packages/kbn-babel-preset/common_preset.js index d2bad41e8de86..d1b7bc20dd9f9 100644 --- a/packages/kbn-babel-preset/common_preset.js +++ b/packages/kbn-babel-preset/common_preset.js @@ -27,6 +27,13 @@ const plugins = [ // // See https://github.com/babel/proposals/issues/12 for progress require.resolve('@babel/plugin-proposal-class-properties'), + + // Optional Chaining proposal is stage 3 (https://github.com/tc39/proposal-optional-chaining) + // Need this since we are using TypeScript 3.7+ + require.resolve('@babel/plugin-proposal-optional-chaining'), + // Nullish coalescing proposal is stage 3 (https://github.com/tc39/proposal-nullish-coalescing) + // Need this since we are using TypeScript 3.7+ + require.resolve('@babel/plugin-proposal-nullish-coalescing-operator'), ]; const isTestEnv = process.env.BABEL_ENV === 'test' || process.env.NODE_ENV === 'test'; diff --git a/packages/kbn-babel-preset/package.json b/packages/kbn-babel-preset/package.json index c22cf175b29e5..1913301e21a76 100644 --- a/packages/kbn-babel-preset/package.json +++ b/packages/kbn-babel-preset/package.json @@ -5,6 +5,8 @@ "license": "Apache-2.0", "dependencies": { "@babel/plugin-proposal-class-properties": "^7.5.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.4.4", + "@babel/plugin-proposal-optional-chaining": "^7.6.0", "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-transform-modules-commonjs": "^7.5.0", "@babel/preset-env": "^7.5.5", diff --git a/packages/kbn-es-query/src/es_query/__tests__/_migrate_filter.js b/packages/kbn-es-query/src/es_query/__tests__/_migrate_filter.js deleted file mode 100644 index d9f559987f58b..0000000000000 --- a/packages/kbn-es-query/src/es_query/__tests__/_migrate_filter.js +++ /dev/null @@ -1,64 +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 '@kbn/expect'; -import _ from 'lodash'; -import { migrateFilter } from '../migrate_filter'; - -describe('migrateFilter', function () { - - const oldMatchPhraseFilter = { - match: { - fieldFoo: { - query: 'foobar', - type: 'phrase' - } - } - }; - - const newMatchPhraseFilter = { - match_phrase: { - fieldFoo: { - query: 'foobar' - } - } - }; - - // https://github.com/elastic/elasticsearch/pull/17508 - it('should migrate match filters of type phrase', function () { - const migratedFilter = migrateFilter(oldMatchPhraseFilter); - expect(_.isEqual(migratedFilter, newMatchPhraseFilter)).to.be(true); - }); - - it('should not modify the original filter', function () { - const oldMatchPhraseFilterCopy = _.clone(oldMatchPhraseFilter, true); - migrateFilter(oldMatchPhraseFilter); - expect(_.isEqual(oldMatchPhraseFilter, oldMatchPhraseFilterCopy)).to.be(true); - }); - - it('should return the original filter if no migration is necessary', function () { - const originalFilter = { - match_all: {} - }; - const migratedFilter = migrateFilter(originalFilter); - expect(migratedFilter).to.be(originalFilter); - expect(_.isEqual(migratedFilter, originalFilter)).to.be(true); - }); - -}); diff --git a/packages/kbn-es-query/src/es_query/__tests__/from_filters.js b/packages/kbn-es-query/src/es_query/__tests__/from_filters.js deleted file mode 100644 index 676992e4dddc8..0000000000000 --- a/packages/kbn-es-query/src/es_query/__tests__/from_filters.js +++ /dev/null @@ -1,151 +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 '@kbn/expect'; -import { buildQueryFromFilters } from '../from_filters'; - -describe('build query', function () { - describe('buildQueryFromFilters', function () { - it('should return the parameters of an Elasticsearch bool query', function () { - const result = buildQueryFromFilters([]); - const expected = { - must: [], - filter: [], - should: [], - must_not: [], - }; - expect(result).to.eql(expected); - }); - - it('should transform an array of kibana filters into ES queries combined in the bool clauses', function () { - const filters = [ - { - match_all: {}, - meta: { type: 'match_all' }, - }, - { - exists: { field: 'foo' }, - meta: { type: 'exists' }, - }, - ]; - - const expectedESQueries = [ - { match_all: {} }, - { exists: { field: 'foo' } }, - ]; - - const result = buildQueryFromFilters(filters); - - expect(result.filter).to.eql(expectedESQueries); - }); - - it('should remove disabled filters', function () { - const filters = [ - { - match_all: {}, - meta: { type: 'match_all', negate: true, disabled: true }, - }, - ]; - - const expectedESQueries = []; - - const result = buildQueryFromFilters(filters); - - expect(result.must_not).to.eql(expectedESQueries); - }); - - it('should remove falsy filters', function () { - const filters = [null, undefined]; - - const expectedESQueries = []; - - const result = buildQueryFromFilters(filters); - - expect(result.must_not).to.eql(expectedESQueries); - expect(result.must).to.eql(expectedESQueries); - }); - - it('should place negated filters in the must_not clause', function () { - const filters = [ - { - match_all: {}, - meta: { type: 'match_all', negate: true }, - }, - ]; - - const expectedESQueries = [{ match_all: {} }]; - - const result = buildQueryFromFilters(filters); - - expect(result.must_not).to.eql(expectedESQueries); - }); - - it('should translate old ES filter syntax into ES 5+ query objects', function () { - const filters = [ - { - query: { exists: { field: 'foo' } }, - meta: { type: 'exists' }, - }, - ]; - - const expectedESQueries = [ - { - exists: { field: 'foo' }, - }, - ]; - - const result = buildQueryFromFilters(filters); - - expect(result.filter).to.eql(expectedESQueries); - }); - - it('should migrate deprecated match syntax', function () { - const filters = [ - { - query: { match: { extension: { query: 'foo', type: 'phrase' } } }, - meta: { type: 'phrase' }, - }, - ]; - - const expectedESQueries = [ - { - match_phrase: { extension: { query: 'foo' } }, - }, - ]; - - const result = buildQueryFromFilters(filters); - - expect(result.filter).to.eql(expectedESQueries); - }); - - it('should not add query:queryString:options to query_string filters', function () { - const filters = [ - { - query: { query_string: { query: 'foo' } }, - meta: { type: 'query_string' }, - }, - ]; - const expectedESQueries = [{ query_string: { query: 'foo' } }]; - - const result = buildQueryFromFilters(filters); - - expect(result.filter).to.eql(expectedESQueries); - }); - }); -}); diff --git a/packages/kbn-es-query/src/es_query/__tests__/from_lucene.js b/packages/kbn-es-query/src/es_query/__tests__/from_lucene.js deleted file mode 100644 index 4361659021bd5..0000000000000 --- a/packages/kbn-es-query/src/es_query/__tests__/from_lucene.js +++ /dev/null @@ -1,87 +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 '@kbn/expect'; -import { buildQueryFromLucene } from '../from_lucene'; -import { decorateQuery } from '../decorate_query'; -import { luceneStringToDsl } from '../lucene_string_to_dsl'; - -describe('build query', function () { - - describe('buildQueryFromLucene', function () { - - it('should return the parameters of an Elasticsearch bool query', function () { - const result = buildQueryFromLucene(); - const expected = { - must: [], - filter: [], - should: [], - must_not: [], - }; - expect(result).to.eql(expected); - }); - - it('should transform an array of lucene queries into ES queries combined in the bool\'s must clause', function () { - const queries = [ - { query: 'foo:bar', language: 'lucene' }, - { query: 'bar:baz', language: 'lucene' }, - ]; - - const expectedESQueries = queries.map( - (query) => { - return decorateQuery(luceneStringToDsl(query.query), {}); - } - ); - - const result = buildQueryFromLucene(queries, {}); - - expect(result.must).to.eql(expectedESQueries); - }); - - it('should also accept queries in ES query DSL format, simply passing them through', function () { - const queries = [ - { query: { match_all: {} }, language: 'lucene' }, - ]; - - const result = buildQueryFromLucene(queries, {}); - - expect(result.must).to.eql([queries[0].query]); - }); - - }); - - it('should accept a date format in the decorated queries and combine that into the bool\'s must clause', function () { - const queries = [ - { query: 'foo:bar', language: 'lucene' }, - { query: 'bar:baz', language: 'lucene' }, - ]; - const dateFormatTZ = 'America/Phoenix'; - - const expectedESQueries = queries.map( - (query) => { - return decorateQuery(luceneStringToDsl(query.query), {}, dateFormatTZ); - } - ); - - const result = buildQueryFromLucene(queries, {}, dateFormatTZ); - - expect(result.must).to.eql(expectedESQueries); - }); - -}); diff --git a/packages/kbn-es-query/src/es_query/index.d.ts b/packages/kbn-es-query/src/es_query/index.d.ts deleted file mode 100644 index 9510a18441e53..0000000000000 --- a/packages/kbn-es-query/src/es_query/index.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export function buildQueryFromFilters(filters: unknown[], indexPattern: unknown): unknown; -export function buildEsQuery( - indexPattern: unknown, - queries: unknown, - filters: unknown, - config?: { - allowLeadingWildcards: boolean; - queryStringOptions: unknown; - ignoreFilterIfFieldNotInIndex: boolean; - dateFormatTZ?: string | null; - } -): unknown; -export function getEsQueryConfig(config: { - get: (name: string) => unknown; -}): { - allowLeadingWildcards: boolean; - queryStringOptions: unknown; - ignoreFilterIfFieldNotInIndex: boolean; - dateFormatTZ?: string | null; -}; diff --git a/packages/kbn-es-query/src/es_query/migrate_filter.js b/packages/kbn-es-query/src/es_query/migrate_filter.js deleted file mode 100644 index b74fc485a6184..0000000000000 --- a/packages/kbn-es-query/src/es_query/migrate_filter.js +++ /dev/null @@ -1,49 +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 _ from 'lodash'; -import { getConvertedValueForField } from '../utils/filters'; - -export function migrateFilter(filter, indexPattern) { - if (filter.match) { - const fieldName = Object.keys(filter.match)[0]; - - - if (isMatchPhraseFilter(filter, fieldName)) { - const params = _.get(filter, ['match', fieldName]); - if (indexPattern) { - const field = indexPattern.fields.find(f => f.name === fieldName); - if (field) { - params.query = getConvertedValueForField(field, params.query); - } - } - return { - match_phrase: { - [fieldName]: _.omit(params, 'type'), - }, - }; - } - } - - return filter; -} - -function isMatchPhraseFilter(filter, fieldName) { - return _.get(filter, ['match', fieldName, 'type']) === 'phrase'; -} diff --git a/packages/kbn-es-query/src/index.d.ts b/packages/kbn-es-query/src/index.d.ts index c06cef6367fe7..79e6903b18644 100644 --- a/packages/kbn-es-query/src/index.d.ts +++ b/packages/kbn-es-query/src/index.d.ts @@ -17,5 +17,4 @@ * under the License. */ -export * from './es_query'; export * from './kuery'; diff --git a/packages/kbn-es-query/src/index.js b/packages/kbn-es-query/src/index.js index 963999bd0999b..79e6903b18644 100644 --- a/packages/kbn-es-query/src/index.js +++ b/packages/kbn-es-query/src/index.js @@ -18,4 +18,3 @@ */ export * from './kuery'; -export * from './es_query'; diff --git a/packages/kbn-es-query/src/kuery/ast/ast.d.ts b/packages/kbn-es-query/src/kuery/ast/ast.d.ts index 06f4940e8ed3b..ef3d0ee828874 100644 --- a/packages/kbn-es-query/src/kuery/ast/ast.d.ts +++ b/packages/kbn-es-query/src/kuery/ast/ast.d.ts @@ -25,18 +25,26 @@ import { JsonObject } from '..'; export type KueryNode = any; +export type DslQuery = any; + export interface KueryParseOptions { helpers: { [key: string]: any; }; startRule: string; + allowLeadingWildcards: boolean; } export function fromKueryExpression( - expression: string, - parseOptions?: KueryParseOptions + expression: string | DslQuery, + parseOptions?: Partial ): KueryNode; -export function toElasticsearchQuery(node: KueryNode, indexPattern?: any): JsonObject; +export function toElasticsearchQuery( + node: KueryNode, + indexPattern?: any, + config?: Record, + context?: Record +): JsonObject; export function doesKueryExpressionHaveLuceneSyntaxError(expression: string): boolean; diff --git a/src/core/server/http/base_path_proxy_server.ts b/src/core/server/http/base_path_proxy_server.ts index ff7fee0198f68..cde35f3cbe995 100644 --- a/src/core/server/http/base_path_proxy_server.ts +++ b/src/core/server/http/base_path_proxy_server.ts @@ -143,6 +143,7 @@ export class BasePathProxyServer { return responseToolkit.continue; }, ], + validate: { payload: true }, }, path: `${this.httpConfig.basePath}/{kbnPath*}`, }); @@ -175,6 +176,7 @@ export class BasePathProxyServer { return responseToolkit.continue; }, ], + validate: { payload: true }, }, path: `/__UNSAFE_bypassBasePath/{kbnPath*}`, }); diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index 3354324c12407..da97ab535516c 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -128,6 +128,8 @@ export class HttpServer { for (const route of router.getRoutes()) { this.log.debug(`registering route handler for [${route.path}]`); const { authRequired = true, tags } = route.options; + // Hapi does not allow payload validation to be specified for 'head' or 'get' requests + const validate = ['head', 'get'].includes(route.method) ? undefined : { payload: true }; this.server.route({ handler: route.handler, method: route.method, @@ -135,6 +137,11 @@ export class HttpServer { options: { auth: authRequired ? undefined : false, tags: tags ? Array.from(tags) : undefined, + // TODO: This 'validate' section can be removed once the legacy platform is completely removed. + // We are telling Hapi that NP routes can accept any payload, so that it can bypass the default + // validation applied in ./http_tools#getServerOptions + // (All NP routes are already required to specify their own validation in order to access the payload) + validate, }, }); } diff --git a/src/core/server/http/http_tools.ts b/src/core/server/http/http_tools.ts index 88164a76c66f0..22468a5b252f4 100644 --- a/src/core/server/http/http_tools.ts +++ b/src/core/server/http/http_tools.ts @@ -23,6 +23,7 @@ import Hoek from 'hoek'; import { ServerOptions as TLSOptions } from 'https'; import { ValidationError } from 'joi'; import { HttpConfig } from './http_config'; +import { validateObject } from './prototype_pollution'; /** * Converts Kibana `HttpConfig` into `ServerOptions` that are accepted by the Hapi server. @@ -45,6 +46,11 @@ export function getServerOptions(config: HttpConfig, { configureTLS = true } = { options: { abortEarly: false, }, + // TODO: This payload validation can be removed once the legacy platform is completely removed. + // This is a default payload validation which applies to all LP routes which do not specify their own + // `validate.payload` handler, in order to reduce the likelyhood of prototype pollution vulnerabilities. + // (All NP routes are already required to specify their own validation in order to access the payload) + payload: value => Promise.resolve(validateObject(value)), }, }, state: { diff --git a/src/core/server/http/prototype_pollution/__snapshots__/validate_object.test.ts.snap b/src/core/server/http/prototype_pollution/__snapshots__/validate_object.test.ts.snap new file mode 100644 index 0000000000000..937e040c771ee --- /dev/null +++ b/src/core/server/http/prototype_pollution/__snapshots__/validate_object.test.ts.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`can't submit {"__proto__":null} 1`] = `"'__proto__' is an invalid key"`; + +exports[`can't submit {"constructor":{"prototype":null}} 1`] = `"'constructor.prototype' is an invalid key"`; + +exports[`can't submit {"foo":{"__proto__":true}} 1`] = `"'__proto__' is an invalid key"`; + +exports[`can't submit {"foo":{"bar":{"__proto__":{}}}} 1`] = `"'__proto__' is an invalid key"`; + +exports[`can't submit {"foo":{"bar":{"constructor":{"prototype":null}}}} 1`] = `"'constructor.prototype' is an invalid key"`; + +exports[`can't submit {"foo":{"constructor":{"prototype":null}}} 1`] = `"'constructor.prototype' is an invalid key"`; diff --git a/src/core/server/http/prototype_pollution/index.ts b/src/core/server/http/prototype_pollution/index.ts new file mode 100644 index 0000000000000..e1a33ffba155e --- /dev/null +++ b/src/core/server/http/prototype_pollution/index.ts @@ -0,0 +1,20 @@ +/* + * 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 { validateObject } from './validate_object'; diff --git a/src/core/server/http/prototype_pollution/validate_object.test.ts b/src/core/server/http/prototype_pollution/validate_object.test.ts new file mode 100644 index 0000000000000..9e23d6cec6444 --- /dev/null +++ b/src/core/server/http/prototype_pollution/validate_object.test.ts @@ -0,0 +1,79 @@ +/* + * 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 { validateObject } from './validate_object'; + +test(`fails on circular references`, () => { + const foo: Record = {}; + foo.myself = foo; + + expect(() => + validateObject({ + payload: foo, + }) + ).toThrowErrorMatchingInlineSnapshot(`"circular reference detected"`); +}); + +[ + { + foo: true, + bar: '__proto__', + baz: 1.1, + qux: undefined, + quux: () => null, + quuz: Object.create(null), + }, + { + foo: { + foo: true, + bar: '__proto__', + baz: 1.1, + qux: undefined, + quux: () => null, + quuz: Object.create(null), + }, + }, + { constructor: { foo: { prototype: null } } }, + { prototype: { foo: { constructor: null } } }, +].forEach(value => { + ['headers', 'payload', 'query', 'params'].forEach(property => { + const obj = { + [property]: value, + }; + test(`can submit ${JSON.stringify(obj)}`, () => { + expect(() => validateObject(obj)).not.toThrowError(); + }); + }); +}); + +// if we use the object literal syntax to create the following values, we end up +// actually reassigning the __proto__ which makes it be a non-enumerable not-own property +// which isn't what we want to test here +[ + JSON.parse(`{ "__proto__": null }`), + JSON.parse(`{ "foo": { "__proto__": true } }`), + JSON.parse(`{ "foo": { "bar": { "__proto__": {} } } }`), + JSON.parse(`{ "constructor": { "prototype" : null } }`), + JSON.parse(`{ "foo": { "constructor": { "prototype" : null } } }`), + JSON.parse(`{ "foo": { "bar": { "constructor": { "prototype" : null } } } }`), +].forEach(value => { + test(`can't submit ${JSON.stringify(value)}`, () => { + expect(() => validateObject(value)).toThrowErrorMatchingSnapshot(); + }); +}); diff --git a/src/core/server/http/prototype_pollution/validate_object.ts b/src/core/server/http/prototype_pollution/validate_object.ts new file mode 100644 index 0000000000000..cab6ce295ce92 --- /dev/null +++ b/src/core/server/http/prototype_pollution/validate_object.ts @@ -0,0 +1,80 @@ +/* + * 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. + */ + +interface StackItem { + value: any; + previousKey: string | null; +} + +// we have to do Object.prototype.hasOwnProperty because when you create an object using +// Object.create(null), and I assume other methods, you get an object without a prototype, +// so you can't use current.hasOwnProperty +const hasOwnProperty = (obj: any, property: string) => + Object.prototype.hasOwnProperty.call(obj, property); + +const isObject = (obj: any) => typeof obj === 'object' && obj !== null; + +// we're using a stack instead of recursion so we aren't limited by the call stack +export function validateObject(obj: any) { + if (!isObject(obj)) { + return; + } + + const stack: StackItem[] = [ + { + value: obj, + previousKey: null, + }, + ]; + const seen = new WeakSet([obj]); + + while (stack.length > 0) { + const { value, previousKey } = stack.pop()!; + + if (!isObject(value)) { + continue; + } + + if (hasOwnProperty(value, '__proto__')) { + throw new Error(`'__proto__' is an invalid key`); + } + + if (hasOwnProperty(value, 'prototype') && previousKey === 'constructor') { + throw new Error(`'constructor.prototype' is an invalid key`); + } + + // iterating backwards through an array is reportedly more performant + const entries = Object.entries(value); + for (let i = entries.length - 1; i >= 0; --i) { + const [key, childValue] = entries[i]; + if (isObject(childValue)) { + if (seen.has(childValue)) { + throw new Error('circular reference detected'); + } + + seen.add(childValue); + } + + stack.push({ + value: childValue, + previousKey: key, + }); + } + } +} diff --git a/src/dev/i18n/extractors/code.js b/src/dev/i18n/extractors/code.js index fa0d834824e97..6439f8ceff332 100644 --- a/src/dev/i18n/extractors/code.js +++ b/src/dev/i18n/extractors/code.js @@ -67,7 +67,16 @@ export function* extractCodeMessages(buffer, reporter) { try { ast = parse(buffer.toString(), { sourceType: 'module', - plugins: ['jsx', 'typescript', 'objectRestSpread', 'classProperties', 'asyncGenerators', 'dynamicImport'], + plugins: [ + 'jsx', + 'typescript', + 'objectRestSpread', + 'classProperties', + 'asyncGenerators', + 'dynamicImport', + 'nullishCoalescingOperator', + 'optionalChaining', + ], }); } catch (error) { if (error instanceof SyntaxError) { diff --git a/src/es_archiver/lib/indices/delete_index.js b/src/es_archiver/lib/indices/delete_index.js index 44a83be741063..b732989f02cb6 100644 --- a/src/es_archiver/lib/indices/delete_index.js +++ b/src/es_archiver/lib/indices/delete_index.js @@ -32,7 +32,7 @@ export async function deleteIndex(options) { stats, index, log, - retryIfSnapshottingCount = 3 + retryIfSnapshottingCount = 10 } = options; const getIndicesToDelete = async () => { diff --git a/src/fixtures/logstash_fields.js b/src/fixtures/logstash_fields.js index ab96b69851b71..f054c4d53fd8d 100644 --- a/src/fixtures/logstash_fields.js +++ b/src/fixtures/logstash_fields.js @@ -17,9 +17,10 @@ * under the License. */ -import { castEsToKbnFieldTypeName } from '../plugins/data/common'; -// eslint-disable-next-line max-len -import { shouldReadFieldFromDocValues } from '../plugins/data/server'; +import { + shouldReadFieldFromDocValues, + castEsToKbnFieldTypeName, +} from '../plugins/data/server'; function stubbedLogstashFields() { return [ diff --git a/src/legacy/core_plugins/console/server/proxy_route.js b/src/legacy/core_plugins/console/server/proxy_route.js index 8ce828879a677..856128f3d4c03 100644 --- a/src/legacy/core_plugins/console/server/proxy_route.js +++ b/src/legacy/core_plugins/console/server/proxy_route.js @@ -71,6 +71,7 @@ export const createProxyRoute = ({ parse: false, }, validate: { + payload: true, query: Joi.object() .keys({ method: Joi.string() diff --git a/src/legacy/core_plugins/data/public/filter/filter_bar/filter_bar.tsx b/src/legacy/core_plugins/data/public/filter/filter_bar/filter_bar.tsx index 333e1e328651d..5b389f5b98aba 100644 --- a/src/legacy/core_plugins/data/public/filter/filter_bar/filter_bar.tsx +++ b/src/legacy/core_plugins/data/public/filter/filter_bar/filter_bar.tsx @@ -22,13 +22,12 @@ import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import classNames from 'classnames'; import React, { useState } from 'react'; import { CoreStart } from 'src/core/public'; -import { DataPublicPluginStart } from 'src/plugins/data/public'; import { IndexPattern } from '../../index_patterns'; import { FilterEditor } from './filter_editor'; import { FilterItem } from './filter_item'; import { FilterOptions } from './filter_options'; import { useKibana, KibanaContextProvider } from '../../../../../../plugins/kibana_react/public'; -import { esFilters } from '../../../../../../plugins/data/public'; +import { DataPublicPluginStart, esFilters } from '../../../../../../plugins/data/public'; interface Props { filters: esFilters.Filter[]; diff --git a/src/legacy/core_plugins/data/public/index_patterns/fields/field.ts b/src/legacy/core_plugins/data/public/index_patterns/fields/field.ts index dc5023795bf19..6084b4c106452 100644 --- a/src/legacy/core_plugins/data/public/index_patterns/fields/field.ts +++ b/src/legacy/core_plugins/data/public/index_patterns/fields/field.ts @@ -22,40 +22,24 @@ import { fieldFormats } from 'ui/registry/field_formats'; import { i18n } from '@kbn/i18n'; // @ts-ignore import { ObjDefine } from './obj_define'; -import { FieldFormat } from '../../../../../../plugins/data/common/field_formats'; // @ts-ignore import { shortenDottedString } from '../../../../../core_plugins/kibana/common/utils/shorten_dotted_string'; import { IndexPattern } from '../index_patterns'; import { getNotifications } from '../services'; -import { getKbnFieldType } from '../../../../../../plugins/data/public'; - -interface FieldSubType { - multi?: { parent: string }; - nested?: { path: string }; -} +import { + FieldFormat, + getKbnFieldType, + IFieldType, + IFieldSubType, +} from '../../../../../../plugins/data/public'; export type FieldSpec = Record; -export interface FieldType { - name: string; - type: string; - script?: string; - lang?: string; - count?: number; - // esTypes might be undefined on old index patterns that have not been refreshed since we added - // this prop. It is also undefined on scripted fields. - esTypes?: string[]; - aggregatable?: boolean; - filterable?: boolean; - searchable?: boolean; - sortable?: boolean; - visualizable?: boolean; - readFromDocValues?: boolean; - scripted?: boolean; - subType?: FieldSubType; - displayName?: string; - format?: any; -} + +/** @deprecated + * Please use IFieldType instead + * */ +export type FieldType = IFieldType; export class Field implements FieldType { name: string; @@ -72,7 +56,7 @@ export class Field implements FieldType { sortable?: boolean; visualizable?: boolean; scripted?: boolean; - subType?: FieldSubType; + subType?: IFieldSubType; displayName?: string; format: any; routes: Record = { diff --git a/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.ts b/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.ts index bf0d79e960d9b..12aa3c2fb0d51 100644 --- a/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.ts +++ b/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.ts @@ -37,21 +37,18 @@ import { createFieldsFetcher } from './_fields_fetcher'; import { formatHitProvider } from './format_hit'; import { flattenHitWrapper } from './flatten_hit'; import { IIndexPatternsApiClient } from './index_patterns_api_client'; -import { ES_FIELD_TYPES } from '../../../../../../plugins/data/common'; +import { ES_FIELD_TYPES, IIndexPattern } from '../../../../../../plugins/data/public'; import { getNotifications } from '../services'; const MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS = 3; const type = 'index-pattern'; -export interface StaticIndexPattern { - fields: FieldType[]; - title: string; - id?: string; - type?: string; - timeFieldName?: string; -} +/** @deprecated + * Please use IIndexPattern instead + * */ +export type StaticIndexPattern = IIndexPattern; -export class IndexPattern implements StaticIndexPattern { +export class IndexPattern implements IIndexPattern { [key: string]: any; public id?: string; diff --git a/src/legacy/core_plugins/data/public/search/search_bar/components/create_search_bar.tsx b/src/legacy/core_plugins/data/public/search/search_bar/components/create_search_bar.tsx index 4485b74ca0901..125c6b8dad006 100644 --- a/src/legacy/core_plugins/data/public/search/search_bar/components/create_search_bar.tsx +++ b/src/legacy/core_plugins/data/public/search/search_bar/components/create_search_bar.tsx @@ -20,12 +20,11 @@ import React, { useState, useEffect } from 'react'; import { Subscription } from 'rxjs'; import { CoreStart } from 'src/core/public'; -import { DataPublicPluginStart } from 'src/plugins/data/public'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public'; import { SearchBar } from '../../../'; import { SearchBarOwnProps } from '.'; -import { esFilters } from '../../../../../../../plugins/data/public'; +import { DataPublicPluginStart, esFilters } from '../../../../../../../plugins/data/public'; interface StatefulSearchBarDeps { core: CoreStart; diff --git a/src/legacy/core_plugins/data/public/search/search_bar/components/search_bar.tsx b/src/legacy/core_plugins/data/public/search/search_bar/components/search_bar.tsx index d713139366eef..e97c06ace1579 100644 --- a/src/legacy/core_plugins/data/public/search/search_bar/components/search_bar.tsx +++ b/src/legacy/core_plugins/data/public/search/search_bar/components/search_bar.tsx @@ -24,7 +24,6 @@ import React, { Component } from 'react'; import ResizeObserver from 'resize-observer-polyfill'; import { get, isEqual } from 'lodash'; -import { TimeRange, Query, TimeHistoryContract } from 'src/plugins/data/public'; import { IndexPattern, FilterBar } from '../../../../../data/public'; import { QueryBarTopRow } from '../../../query'; import { SavedQuery, SavedQueryAttributes } from '../index'; @@ -37,7 +36,12 @@ import { KibanaReactContextValue, } from '../../../../../../../plugins/kibana_react/public'; import { IDataPluginServices } from '../../../types'; -import { esFilters } from '../../../../../../../plugins/data/public'; +import { + TimeRange, + Query, + esFilters, + TimeHistoryContract, +} from '../../../../../../../plugins/data/public'; interface SearchBarInjectedDeps { kibana: KibanaReactContextValue; diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/types.ts b/src/legacy/core_plugins/expressions/public/np_ready/public/types.ts index 9d7b4fb6d0480..c8870b9f97957 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/types.ts +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/types.ts @@ -17,9 +17,8 @@ * under the License. */ -import { TimeRange } from '../../../../../../plugins/data/public'; import { Adapters } from '../../../../../../plugins/inspector/public'; -import { Query } from '../../../../../../plugins/data/public'; +import { TimeRange, Query } from '../../../../../../plugins/data/public'; export { TimeRange, Adapters, Query }; export * from '../../../../../../plugins/expressions/public'; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.tsx index 656b54040ad99..d5da4ba51e55b 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.tsx @@ -32,7 +32,6 @@ import { } from 'ui/state_management/app_state'; import { KbnUrl } from 'ui/url/kbn_url'; -import { TimeRange, Query } from 'src/plugins/data/public'; import { IndexPattern } from 'ui/index_patterns'; import { IPrivate } from 'ui/private'; import { StaticIndexPattern, SavedQuery } from 'plugins/data'; @@ -42,7 +41,7 @@ import { Subscription } from 'rxjs'; import { ViewMode } from '../../../embeddable_api/public/np_ready/public'; import { SavedObjectDashboard } from './saved_dashboard/saved_dashboard'; import { DashboardAppState, SavedDashboardPanel, ConfirmModalFn } from './types'; -import { esFilters } from '../../../../../../src/plugins/data/public'; +import { TimeRange, Query, esFilters } from '../../../../../../src/plugins/data/public'; import { DashboardAppController } from './dashboard_app_controller'; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.ts b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.ts index 1a42ed837a9de..d5af4c93d0e0c 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.ts @@ -27,9 +27,8 @@ import { migrateLegacyQuery } from 'ui/utils/migrate_legacy_query'; import { Moment } from 'moment'; import { DashboardContainer } from 'src/legacy/core_plugins/dashboard_embeddable_container/public/np_ready/public'; -import { Query } from 'src/plugins/data/public'; import { ViewMode } from '../../../../../../src/plugins/embeddable/public'; -import { esFilters } from '../../../../../../src/plugins/data/public'; +import { Query, esFilters } from '../../../../../../src/plugins/data/public'; import { getAppStateDefaults, migrateAppState } from './lib'; import { convertPanelStateToSavedDashboardPanel } from './lib/embeddable_saved_object_converters'; diff --git a/src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable.ts b/src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable.ts index c575465a377e2..ef79cda476e51 100644 --- a/src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable.ts +++ b/src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable.ts @@ -30,6 +30,7 @@ import { generateFilters, getTime, Query, + IFieldType, } from '../../../../../../plugins/data/public'; import { APPLY_FILTER_TRIGGER, @@ -66,7 +67,7 @@ interface SearchScope extends ng.IScope { removeColumn?: (column: string) => void; addColumn?: (column: string) => void; moveColumn?: (column: string, index: number) => void; - filter?: (field: { name: string; scripted: boolean }, value: string[], operator: string) => void; + filter?: (field: IFieldType, value: string[], operator: string) => void; hits?: any[]; indexPattern?: IndexPattern; totalHitCount?: number; diff --git a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_conformance.js b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_conformance.js index bc27e1a0ac2a1..1c63d2efc7e0b 100644 --- a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_conformance.js +++ b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_conformance.js @@ -20,8 +20,8 @@ import _ from 'lodash'; import expect from '@kbn/expect'; import { fieldFormats } from 'ui/registry/field_formats'; -import { FieldFormat } from '../../../../../../plugins/data/common/field_formats'; import { npStart } from 'ui/new_platform'; +import { FieldFormat } from '../../../../../../plugins/data/public'; const config = npStart.core.uiSettings; diff --git a/src/legacy/core_plugins/kibana/server/field_formats/register.js b/src/legacy/core_plugins/kibana/server/field_formats/register.js index 95818f22b397e..bade66ce2c881 100644 --- a/src/legacy/core_plugins/kibana/server/field_formats/register.js +++ b/src/legacy/core_plugins/kibana/server/field_formats/register.js @@ -33,7 +33,7 @@ import { BoolFormat, SourceFormat, StaticLookupFormat -} from '../../../../../plugins/data/common'; +} from '../../../../../plugins/data/server'; export function registerFieldFormats(server) { server.registerFieldFormat(UrlFormat); diff --git a/src/legacy/core_plugins/timelion/public/vis/timelion_request_handler.ts b/src/legacy/core_plugins/timelion/public/vis/timelion_request_handler.ts index 35dea4a0deb9b..74111bf794877 100644 --- a/src/legacy/core_plugins/timelion/public/vis/timelion_request_handler.ts +++ b/src/legacy/core_plugins/timelion/public/vis/timelion_request_handler.ts @@ -17,15 +17,13 @@ * under the License. */ -// @ts-ignore -import { buildEsQuery, getEsQueryConfig } from '@kbn/es-query'; // @ts-ignore import { timezoneProvider } from 'ui/vis/lib/timezone'; import { KIBANA_CONTEXT_NAME } from 'src/plugins/expressions/public'; -import { Query, TimeRange, esFilters } from 'src/plugins/data/public'; import { VisParams } from 'ui/vis'; import { i18n } from '@kbn/i18n'; import { TimelionVisualizationDependencies } from '../plugin'; +import { TimeRange, esFilters, esQuery, Query } from '../../../../../plugins/data/public'; interface Stats { cacheCount: number; @@ -74,7 +72,7 @@ export function getTimelionRequestHandler(dependencies: TimelionVisualizationDep ); } - const esQueryConfigs = getEsQueryConfig(uiSettings); + const esQueryConfigs = esQuery.getEsQueryConfig(uiSettings); // parse the time range client side to make sure it behaves like other charts const timeRangeBounds = timefilter.calculateBounds(timeRange); @@ -85,7 +83,7 @@ export function getTimelionRequestHandler(dependencies: TimelionVisualizationDep sheet: [expression], extended: { es: { - filter: buildEsQuery(undefined, query, filters, esQueryConfigs), + filter: esQuery.buildEsQuery(null, query, filters, esQueryConfigs), }, }, time: { diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/filter_ratio.js b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/filter_ratio.js index 92558559845be..6974389897812 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/filter_ratio.js +++ b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/filter_ratio.js @@ -35,7 +35,7 @@ import { EuiFormRow, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public'; import { METRIC_TYPES } from '../../../common/metric_types'; export const FilterRatioAgg = props => { diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile.js b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile.js index fafb2621aafe0..ec16a0f2eb3ee 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile.js +++ b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile.js @@ -34,7 +34,7 @@ import { EuiFormRow, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public'; import { Percentiles, newPercentile } from './percentile_ui'; const RESTRICT_FIELDS = [KBN_FIELD_TYPES.NUMBER]; diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/percentile_rank.js b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/percentile_rank.js index 85aded0ca248b..069ea9706e927 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/percentile_rank.js +++ b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/percentile_rank.js @@ -36,7 +36,7 @@ import { EuiSpacer, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { KBN_FIELD_TYPES } from '../../../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../../../plugins/data/public'; const RESTRICT_FIELDS = [KBN_FIELD_TYPES.NUMBER]; diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_agg.js b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_agg.js index 4b8b356f2af48..67fe9403e402b 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_agg.js +++ b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_agg.js @@ -33,7 +33,7 @@ import { EuiSpacer, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public'; import { METRIC_TYPES } from '../../../common/metric_types'; export function StandardAgg(props) { diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_deviation.js b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_deviation.js index c078bac8d7f9c..1f0347b210886 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_deviation.js +++ b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_deviation.js @@ -36,7 +36,7 @@ import { EuiSpacer, } from '@elastic/eui'; import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; -import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public'; const RESTRICT_FIELDS = [KBN_FIELD_TYPES.NUMBER]; diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/top_hit.js b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/top_hit.js index 1439768b95643..fa92713046aca 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/top_hit.js +++ b/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/top_hit.js @@ -35,7 +35,7 @@ import { EuiFormRow, } from '@elastic/eui'; import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; -import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public'; import { PANEL_TYPES } from '../../../common/panel_types'; const isFieldTypeEnabled = (fieldRestrictions, fieldType) => diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/query.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/query.js index e91c182ad1d5a..19bf807f1b315 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/query.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/query.js @@ -19,7 +19,7 @@ import { getBucketSize } from '../../helpers/get_bucket_size'; import { getTimerange } from '../../helpers/get_timerange'; -import { buildEsQuery } from '@kbn/es-query'; +import { esQuery } from '../../../../../../../../plugins/data/server'; export function query(req, panel, annotation, esQueryConfig, indexPattern, capabilities) { return next => doc => { @@ -30,7 +30,7 @@ export function query(req, panel, annotation, esQueryConfig, indexPattern, capab doc.size = 0; const queries = !annotation.ignore_global_filters ? req.payload.query : []; const filters = !annotation.ignore_global_filters ? req.payload.filters : []; - doc.query = buildEsQuery(indexPattern, queries, filters, esQueryConfig); + doc.query = esQuery.buildEsQuery(indexPattern, queries, filters, esQueryConfig); const timerange = { range: { [timeField]: { @@ -44,12 +44,12 @@ export function query(req, panel, annotation, esQueryConfig, indexPattern, capab if (annotation.query_string) { doc.query.bool.must.push( - buildEsQuery(indexPattern, [annotation.query_string], [], esQueryConfig) + esQuery.buildEsQuery(indexPattern, [annotation.query_string], [], esQueryConfig) ); } if (!annotation.ignore_panel_filters && panel.filter) { - doc.query.bool.must.push(buildEsQuery(indexPattern, [panel.filter], [], esQueryConfig)); + doc.query.bool.must.push(esQuery.buildEsQuery(indexPattern, [panel.filter], [], esQueryConfig)); } if (annotation.fields) { diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/query.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/query.js index 75de84ae33462..a287b394422e1 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/query.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/query.js @@ -19,7 +19,7 @@ import { offsetTime } from '../../offset_time'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; -import { buildEsQuery } from '@kbn/es-query'; +import { esQuery } from '../../../../../../../../plugins/data/server'; export function query(req, panel, series, esQueryConfig, indexPatternObject) { return next => doc => { @@ -29,7 +29,7 @@ export function query(req, panel, series, esQueryConfig, indexPatternObject) { doc.size = 0; const queries = !panel.ignore_global_filter ? req.payload.query : []; const filters = !panel.ignore_global_filter ? req.payload.filters : []; - doc.query = buildEsQuery(indexPatternObject, queries, filters, esQueryConfig); + doc.query = esQuery.buildEsQuery(indexPatternObject, queries, filters, esQueryConfig); const timerange = { range: { @@ -43,12 +43,12 @@ export function query(req, panel, series, esQueryConfig, indexPatternObject) { doc.query.bool.must.push(timerange); if (panel.filter) { - doc.query.bool.must.push(buildEsQuery(indexPatternObject, [panel.filter], [], esQueryConfig)); + doc.query.bool.must.push(esQuery.buildEsQuery(indexPatternObject, [panel.filter], [], esQueryConfig)); } if (series.filter) { doc.query.bool.must.push( - buildEsQuery(indexPatternObject, [series.filter], [], esQueryConfig) + esQuery.buildEsQuery(indexPatternObject, [series.filter], [], esQueryConfig) ); } diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filter.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filter.js index 8b9ebf9319efe..1548c9e17c2e1 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filter.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filter.js @@ -17,17 +17,21 @@ * under the License. */ -import _ from 'lodash'; -import { buildEsQuery } from '@kbn/es-query'; +import { set } from 'lodash'; +import { esQuery } from '../../../../../../../../plugins/data/server'; export function splitByFilter(req, panel, series, esQueryConfig, indexPattern) { return next => doc => { - if (series.split_mode !== 'filter') return next(doc); - _.set( + if (series.split_mode !== 'filter') { + return next(doc); + } + + set( doc, `aggs.${series.id}.filter`, - buildEsQuery(indexPattern, [series.filter], [], esQueryConfig) + esQuery.buildEsQuery(indexPattern, [series.filter], [], esQueryConfig) ); + return next(doc); }; } diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filters.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filters.js index 60b29141aaa3e..4295bceed43cc 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filters.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filters.js @@ -17,14 +17,16 @@ * under the License. */ -import _ from 'lodash'; -import { buildEsQuery } from '@kbn/es-query'; +import { set } from 'lodash'; +import { esQuery } from '../../../../../../../../plugins/data/server'; + export function splitByFilters(req, panel, series, esQueryConfig, indexPattern) { return next => doc => { if (series.split_mode === 'filters' && series.split_filters) { series.split_filters.forEach(filter => { - const builtEsQuery = buildEsQuery(indexPattern, [filter.filter], [], esQueryConfig); - _.set(doc, `aggs.${series.id}.filters.filters.${filter.id}`, builtEsQuery); + const builtEsQuery = esQuery.buildEsQuery(indexPattern, [filter.filter], [], esQueryConfig); + + set(doc, `aggs.${series.id}.filters.filters.${filter.id}`, builtEsQuery); }); } return next(doc); diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/query.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/query.js index 212e7a615dcad..f3b5413c63d79 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/query.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/query.js @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -import { buildEsQuery } from '@kbn/es-query'; import { getTimerange } from '../../helpers/get_timerange'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; +import { esQuery } from '../../../../../../../../plugins/data/server'; export function query(req, panel, esQueryConfig, indexPatternObject) { return next => doc => { @@ -29,7 +29,7 @@ export function query(req, panel, esQueryConfig, indexPatternObject) { const queries = !panel.ignore_global_filter ? req.payload.query : []; const filters = !panel.ignore_global_filter ? req.payload.filters : []; - doc.query = buildEsQuery(indexPatternObject, queries, filters, esQueryConfig); + doc.query = esQuery.buildEsQuery(indexPatternObject, queries, filters, esQueryConfig); const timerange = { range: { @@ -42,7 +42,7 @@ export function query(req, panel, esQueryConfig, indexPatternObject) { }; doc.query.bool.must.push(timerange); if (panel.filter) { - doc.query.bool.must.push(buildEsQuery(indexPatternObject, [panel.filter], [], esQueryConfig)); + doc.query.bool.must.push(esQuery.buildEsQuery(indexPatternObject, [panel.filter], [], esQueryConfig)); } return next(doc); diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_everything.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_everything.js index 01d33ca86e6d1..17f99ea431fd3 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_everything.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_everything.js @@ -17,21 +17,22 @@ * under the License. */ -import _ from 'lodash'; -import { buildEsQuery } from '@kbn/es-query'; +import { set } from 'lodash'; +import { esQuery } from '../../../../../../../../plugins/data/server'; + export function splitByEverything(req, panel, esQueryConfig, indexPattern) { return next => doc => { panel.series .filter(c => !(c.aggregate_by && c.aggregate_function)) .forEach(column => { if (column.filter) { - _.set( + set( doc, `aggs.pivot.aggs.${column.id}.filter`, - buildEsQuery(indexPattern, [column.filter], [], esQueryConfig) + esQuery.buildEsQuery(indexPattern, [column.filter], [], esQueryConfig) ); } else { - _.set(doc, `aggs.pivot.aggs.${column.id}.filter.match_all`, {}); + set(doc, `aggs.pivot.aggs.${column.id}.filter.match_all`, {}); } }); return next(doc); diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_terms.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_terms.js index 829f7d8c5a0de..042e4d98e2767 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_terms.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_terms.js @@ -17,20 +17,22 @@ * under the License. */ -import _ from 'lodash'; -import { buildEsQuery } from '@kbn/es-query'; +import { set } from 'lodash'; +import { esQuery } from '../../../../../../../../plugins/data/server'; + export function splitByTerms(req, panel, esQueryConfig, indexPattern) { return next => doc => { panel.series .filter(c => c.aggregate_by && c.aggregate_function) .forEach(column => { - _.set(doc, `aggs.pivot.aggs.${column.id}.terms.field`, column.aggregate_by); - _.set(doc, `aggs.pivot.aggs.${column.id}.terms.size`, 100); + set(doc, `aggs.pivot.aggs.${column.id}.terms.field`, column.aggregate_by); + set(doc, `aggs.pivot.aggs.${column.id}.terms.size`, 100); + if (column.filter) { - _.set( + set( doc, `aggs.pivot.aggs.${column.id}.column_filter.filter`, - buildEsQuery(indexPattern, [column.filter], [], esQueryConfig) + esQuery.buildEsQuery(indexPattern, [column.filter], [], esQueryConfig) ); } }); diff --git a/src/legacy/core_plugins/vis_type_vega/public/vega_request_handler.ts b/src/legacy/core_plugins/vis_type_vega/public/vega_request_handler.ts index accc52c1e5a14..83ae31bf87400 100644 --- a/src/legacy/core_plugins/vis_type_vega/public/vega_request_handler.ts +++ b/src/legacy/core_plugins/vis_type_vega/public/vega_request_handler.ts @@ -18,9 +18,7 @@ */ import { timefilter } from 'ui/timefilter'; - -import { buildEsQuery, getEsQueryConfig } from '@kbn/es-query'; -import { esFilters, TimeRange, Query } from '../../../../plugins/data/public'; +import { esFilters, esQuery, TimeRange, Query } from '../../../../plugins/data/public'; // @ts-ignore import { VegaParser } from './data_model/vega_parser'; @@ -50,8 +48,8 @@ export function createVegaRequestHandler({ return ({ timeRange, filters, query, visParams }: VegaRequestHandlerParams) => { timeCache.setTimeRange(timeRange); - const esQueryConfigs = getEsQueryConfig(uiSettings); - const filtersDsl = buildEsQuery(undefined, query, filters, esQueryConfigs); + const esQueryConfigs = esQuery.getEsQueryConfig(uiSettings); + const filtersDsl = esQuery.buildEsQuery(null, query, filters, esQueryConfigs); const vp = new VegaParser(visParams.spec, searchCache, timeCache, filtersDsl, serviceSettings); return vp.parseAsync(); diff --git a/src/legacy/server/http/integration_tests/xsrf.test.js b/src/legacy/server/http/integration_tests/xsrf.test.js index 562a94e198631..baeb61bff6113 100644 --- a/src/legacy/server/http/integration_tests/xsrf.test.js +++ b/src/legacy/server/http/integration_tests/xsrf.test.js @@ -57,7 +57,8 @@ describe('xsrf request filter', () => { // Disable payload parsing to make HapiJS server accept any content-type header. payload: { parse: false - } + }, + validate: { payload: null } }, handler: async function () { return 'ok'; @@ -71,7 +72,8 @@ describe('xsrf request filter', () => { // Disable payload parsing to make HapiJS server accept any content-type header. payload: { parse: false - } + }, + validate: { payload: null } }, handler: async function () { return 'ok'; diff --git a/src/legacy/server/http/version_check.js b/src/legacy/server/http/version_check.js index 8bd2bb6e22df1..12666c9a0f3f6 100644 --- a/src/legacy/server/http/version_check.js +++ b/src/legacy/server/http/version_check.js @@ -27,10 +27,11 @@ export function setupVersionCheck(server, config) { const versionRequested = req.headers[versionHeader]; if (versionRequested && versionRequested !== actualVersion) { - throw badRequest('Browser client is out of date, please refresh the page', { - expected: actualVersion, - got: versionRequested - }); + throw badRequest( + `Browser client is out of date, \ + please refresh the page ("${versionHeader}" header was "${versionRequested}" but should be "${actualVersion}")`, + { expected: actualVersion, got: versionRequested } + ); } return h.continue; diff --git a/src/legacy/ui/public/agg_types/agg_config.ts b/src/legacy/ui/public/agg_types/agg_config.ts index eedfc1cc05a84..becfaf8c89e27 100644 --- a/src/legacy/ui/public/agg_types/agg_config.ts +++ b/src/legacy/ui/public/agg_types/agg_config.ts @@ -32,7 +32,7 @@ import { AggGroupNames } from '../vis/editors/default/agg_groups'; import { writeParams } from './agg_params'; import { AggConfigs } from './agg_configs'; import { Schema } from '../vis/editors/default/schemas'; -import { ContentType } from '../../../../plugins/data/common'; +import { ContentType } from '../../../../plugins/data/public'; // @ts-ignore import { fieldFormats } from '../registry/field_formats'; diff --git a/src/legacy/ui/public/agg_types/buckets/_bucket_agg_type.ts b/src/legacy/ui/public/agg_types/buckets/_bucket_agg_type.ts index 74e4017b28728..c151f9101d090 100644 --- a/src/legacy/ui/public/agg_types/buckets/_bucket_agg_type.ts +++ b/src/legacy/ui/public/agg_types/buckets/_bucket_agg_type.ts @@ -19,7 +19,7 @@ import { AggParamType } from '../param_types/agg'; import { AggConfig } from '../../vis'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; import { AggType, AggTypeConfig } from '../agg_type'; export type IBucketAggConfig = AggConfig; diff --git a/src/legacy/ui/public/agg_types/buckets/_terms_other_bucket_helper.js b/src/legacy/ui/public/agg_types/buckets/_terms_other_bucket_helper.js index 70bca2e40ae3f..d0d712704964b 100644 --- a/src/legacy/ui/public/agg_types/buckets/_terms_other_bucket_helper.js +++ b/src/legacy/ui/public/agg_types/buckets/_terms_other_bucket_helper.js @@ -18,9 +18,8 @@ */ import _ from 'lodash'; -import { buildQueryFromFilters } from '@kbn/es-query'; import { AggGroupNames } from '../../vis/editors/default/agg_groups'; -import { esFilters } from '../../../../../plugins/data/public'; +import { esFilters, esQuery } from '../../../../../plugins/data/public'; /** * walks the aggregation DSL and returns DSL starting at aggregation with id of startFromAggId @@ -197,7 +196,7 @@ export const buildOtherBucketAgg = (aggConfigs, aggWithOtherBucket, response) => }); resultAgg.filters.filters[key] = { - bool: buildQueryFromFilters(filters, indexPattern), + bool: esQuery.buildQueryFromFilters(filters, indexPattern), }; }; walkBucketTree(0, response.aggregations, bucketAggs[0].id, [], ''); diff --git a/src/legacy/ui/public/agg_types/buckets/create_filter/date_range.test.ts b/src/legacy/ui/public/agg_types/buckets/create_filter/date_range.test.ts index 35b6c38bad799..0399e8d382320 100644 --- a/src/legacy/ui/public/agg_types/buckets/create_filter/date_range.test.ts +++ b/src/legacy/ui/public/agg_types/buckets/create_filter/date_range.test.ts @@ -19,7 +19,7 @@ import moment from 'moment'; import { createFilterDateRange } from './date_range'; -import { DateFormat } from '../../../../../../plugins/data/common'; +import { DateFormat } from '../../../../../../plugins/data/public'; import { AggConfigs } from '../../agg_configs'; import { BUCKET_TYPES } from '../bucket_agg_types'; diff --git a/src/legacy/ui/public/agg_types/buckets/create_filter/histogram.test.ts b/src/legacy/ui/public/agg_types/buckets/create_filter/histogram.test.ts index 0095df75b8914..ac8e55f096fb4 100644 --- a/src/legacy/ui/public/agg_types/buckets/create_filter/histogram.test.ts +++ b/src/legacy/ui/public/agg_types/buckets/create_filter/histogram.test.ts @@ -19,7 +19,7 @@ import { createFilterHistogram } from './histogram'; import { AggConfigs } from '../../agg_configs'; import { BUCKET_TYPES } from '../bucket_agg_types'; -import { BytesFormat } from '../../../../../../plugins/data/common'; +import { BytesFormat } from '../../../../../../plugins/data/public'; jest.mock('ui/new_platform'); diff --git a/src/legacy/ui/public/agg_types/buckets/create_filter/ip_range.test.ts b/src/legacy/ui/public/agg_types/buckets/create_filter/ip_range.test.ts index 2e030d820b396..569735a60298d 100644 --- a/src/legacy/ui/public/agg_types/buckets/create_filter/ip_range.test.ts +++ b/src/legacy/ui/public/agg_types/buckets/create_filter/ip_range.test.ts @@ -19,7 +19,7 @@ import { createFilterIpRange } from './ip_range'; import { AggConfigs } from '../../agg_configs'; -import { IpFormat } from '../../../../../../plugins/data/common'; +import { IpFormat } from '../../../../../../plugins/data/public'; import { BUCKET_TYPES } from '../bucket_agg_types'; jest.mock('ui/new_platform'); diff --git a/src/legacy/ui/public/agg_types/buckets/create_filter/range.test.ts b/src/legacy/ui/public/agg_types/buckets/create_filter/range.test.ts index 04476ba62ccd5..e7344f16ba0b1 100644 --- a/src/legacy/ui/public/agg_types/buckets/create_filter/range.test.ts +++ b/src/legacy/ui/public/agg_types/buckets/create_filter/range.test.ts @@ -18,7 +18,7 @@ */ import { createFilterRange } from './range'; -import { BytesFormat } from '../../../../../../plugins/data/common'; +import { BytesFormat } from '../../../../../../plugins/data/public'; import { AggConfigs } from '../../agg_configs'; import { BUCKET_TYPES } from '../bucket_agg_types'; diff --git a/src/legacy/ui/public/agg_types/buckets/date_histogram.ts b/src/legacy/ui/public/agg_types/buckets/date_histogram.ts index e86d561a1c79b..03e358af5f1f0 100644 --- a/src/legacy/ui/public/agg_types/buckets/date_histogram.ts +++ b/src/legacy/ui/public/agg_types/buckets/date_histogram.ts @@ -34,7 +34,7 @@ import { writeParams } from '../agg_params'; import { AggConfigs } from '../agg_configs'; import { isMetricAggType } from '../metrics/metric_agg_type'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; // @ts-ignore import { TimeBuckets } from '../../time_buckets'; diff --git a/src/legacy/ui/public/agg_types/buckets/date_range.ts b/src/legacy/ui/public/agg_types/buckets/date_range.ts index 4de6002e2e374..908d921d12313 100644 --- a/src/legacy/ui/public/agg_types/buckets/date_range.ts +++ b/src/legacy/ui/public/agg_types/buckets/date_range.ts @@ -23,14 +23,13 @@ import { npStart } from 'ui/new_platform'; import { BUCKET_TYPES } from './bucket_agg_types'; import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type'; import { createFilterDateRange } from './create_filter/date_range'; -import { FieldFormat } from '../../../../../plugins/data/common/field_formats'; +import { FieldFormat, KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; import { DateRangesParamEditor } from '../../vis/editors/default/controls/date_ranges'; // @ts-ignore import { fieldFormats } from '../../registry/field_formats'; // @ts-ignore import { dateRange } from '../../utils/date_range'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; const dateRangeTitle = i18n.translate('common.ui.aggTypes.buckets.dateRangeTitle', { defaultMessage: 'Date Range', diff --git a/src/legacy/ui/public/agg_types/buckets/filters.ts b/src/legacy/ui/public/agg_types/buckets/filters.ts index a8d509d507c6b..caebf2d7d974e 100644 --- a/src/legacy/ui/public/agg_types/buckets/filters.ts +++ b/src/legacy/ui/public/agg_types/buckets/filters.ts @@ -23,12 +23,11 @@ import angular from 'angular'; import { i18n } from '@kbn/i18n'; import chrome from 'ui/chrome'; -import { buildEsQuery } from '@kbn/es-query'; import { FiltersParamEditor, FilterValue } from '../../vis/editors/default/controls/filters'; import { createFilterFilters } from './create_filter/filters'; import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type'; import { Storage } from '../../../../../plugins/kibana_utils/public'; -import { getQueryLog } from '../../../../../plugins/data/public'; +import { getQueryLog, esQuery } from '../../../../../plugins/data/public'; const config = chrome.getUiSettingsClient(); const storage = new Storage(window.localStorage); @@ -68,7 +67,7 @@ export const filtersBucketAgg = new BucketAggType({ return; } - const query = buildEsQuery(aggConfig.getIndexPattern(), [input], [], config); + const query = esQuery.buildEsQuery(aggConfig.getIndexPattern(), [input], [], config); if (!query) { console.log('malformed filter agg params, missing "query" on input'); // eslint-disable-line no-console diff --git a/src/legacy/ui/public/agg_types/buckets/geo_hash.ts b/src/legacy/ui/public/agg_types/buckets/geo_hash.ts index 1716891231b83..700f5a048fce2 100644 --- a/src/legacy/ui/public/agg_types/buckets/geo_hash.ts +++ b/src/legacy/ui/public/agg_types/buckets/geo_hash.ts @@ -26,7 +26,7 @@ import { IsFilteredByCollarParamEditor } from '../../vis/editors/default/control import { PrecisionParamEditor } from '../../vis/editors/default/controls/precision'; import { geohashColumns } from '../../utils/decode_geo_hash'; import { AggGroupNames } from '../../vis/editors/default/agg_groups'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; // @ts-ignore import { geoContains, scaleBounds } from '../../utils/geo_utils'; diff --git a/src/legacy/ui/public/agg_types/buckets/geo_tile.ts b/src/legacy/ui/public/agg_types/buckets/geo_tile.ts index 87373a064086f..3afb35a035690 100644 --- a/src/legacy/ui/public/agg_types/buckets/geo_tile.ts +++ b/src/legacy/ui/public/agg_types/buckets/geo_tile.ts @@ -24,7 +24,7 @@ import { AggConfigOptions } from 'ui/agg_types/agg_config'; import { BucketAggType } from './_bucket_agg_type'; import { BUCKET_TYPES } from './bucket_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; const geotileGridTitle = i18n.translate('common.ui.aggTypes.buckets.geotileGridTitle', { defaultMessage: 'Geotile', diff --git a/src/legacy/ui/public/agg_types/buckets/histogram.ts b/src/legacy/ui/public/agg_types/buckets/histogram.ts index fba2f47010c34..7bd3d565003be 100644 --- a/src/legacy/ui/public/agg_types/buckets/histogram.ts +++ b/src/legacy/ui/public/agg_types/buckets/histogram.ts @@ -28,7 +28,7 @@ import { NumberIntervalParamEditor } from '../../vis/editors/default/controls/nu import { MinDocCountParamEditor } from '../../vis/editors/default/controls/min_doc_count'; import { HasExtendedBoundsParamEditor } from '../../vis/editors/default/controls/has_extended_bounds'; import { ExtendedBoundsParamEditor } from '../../vis/editors/default/controls/extended_bounds'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; import { BUCKET_TYPES } from './bucket_agg_types'; export interface AutoBounds { diff --git a/src/legacy/ui/public/agg_types/buckets/ip_range.ts b/src/legacy/ui/public/agg_types/buckets/ip_range.ts index bbc91b0768f6b..7ef415ff8d0c4 100644 --- a/src/legacy/ui/public/agg_types/buckets/ip_range.ts +++ b/src/legacy/ui/public/agg_types/buckets/ip_range.ts @@ -24,13 +24,12 @@ import { IpRangeTypeParamEditor } from '../../vis/editors/default/controls/ip_ra import { IpRangesParamEditor } from '../../vis/editors/default/controls/ip_ranges'; // @ts-ignore import { fieldFormats } from '../../registry/field_formats'; -import { FieldFormat } from '../../../../../plugins/data/common/field_formats'; +import { FieldFormat, KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; import { ipRange } from '../../utils/ip_range'; import { BUCKET_TYPES } from './bucket_agg_types'; // @ts-ignore import { createFilterIpRange } from './create_filter/ip_range'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; const ipRangeTitle = i18n.translate('common.ui.aggTypes.buckets.ipRangeTitle', { defaultMessage: 'IPv4 Range', diff --git a/src/legacy/ui/public/agg_types/buckets/range.test.ts b/src/legacy/ui/public/agg_types/buckets/range.test.ts index 1b423e64c48ae..5db7eb3c2d8e9 100644 --- a/src/legacy/ui/public/agg_types/buckets/range.test.ts +++ b/src/legacy/ui/public/agg_types/buckets/range.test.ts @@ -19,7 +19,7 @@ import { AggConfigs } from '../agg_configs'; import { BUCKET_TYPES } from './bucket_agg_types'; -import { NumberFormat } from '../../../../../plugins/data/common/'; +import { NumberFormat } from '../../../../../plugins/data/public'; jest.mock('ui/new_platform'); diff --git a/src/legacy/ui/public/agg_types/buckets/range.ts b/src/legacy/ui/public/agg_types/buckets/range.ts index 230675ab487ad..89529442b24a6 100644 --- a/src/legacy/ui/public/agg_types/buckets/range.ts +++ b/src/legacy/ui/public/agg_types/buckets/range.ts @@ -20,14 +20,13 @@ import { i18n } from '@kbn/i18n'; import { IBucketAggConfig } from './_bucket_agg_type'; import { BucketAggType } from './_bucket_agg_type'; -import { FieldFormat } from '../../../../../plugins/data/common/field_formats'; +import { FieldFormat, KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; import { RangeKey } from './range_key'; import { RangesEditor } from './range_editor'; // @ts-ignore import { createFilterRange } from './create_filter/range'; import { BUCKET_TYPES } from './bucket_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; const keyCaches = new WeakMap(); const formats = new WeakMap(); diff --git a/src/legacy/ui/public/agg_types/buckets/significant_terms.ts b/src/legacy/ui/public/agg_types/buckets/significant_terms.ts index 865ede2b1bd23..65c73e5f9b7dd 100644 --- a/src/legacy/ui/public/agg_types/buckets/significant_terms.ts +++ b/src/legacy/ui/public/agg_types/buckets/significant_terms.ts @@ -23,7 +23,7 @@ import { BucketAggType, BucketAggParam } from './_bucket_agg_type'; import { createFilterTerms } from './create_filter/terms'; import { isStringType, migrateIncludeExcludeFormat } from './migrate_include_exclude_format'; import { BUCKET_TYPES } from './bucket_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; const significantTermsTitle = i18n.translate('common.ui.aggTypes.buckets.significantTermsTitle', { defaultMessage: 'Significant Terms', diff --git a/src/legacy/ui/public/agg_types/buckets/terms.ts b/src/legacy/ui/public/agg_types/buckets/terms.ts index bc6dd4860561e..c0f870c27f10d 100644 --- a/src/legacy/ui/public/agg_types/buckets/terms.ts +++ b/src/legacy/ui/public/agg_types/buckets/terms.ts @@ -23,7 +23,6 @@ import { SearchSource } from 'ui/courier'; import { i18n } from '@kbn/i18n'; import { BucketAggType, BucketAggParam } from './_bucket_agg_type'; import { BUCKET_TYPES } from './bucket_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; import { AggConfigOptions } from '../agg_config'; import { IBucketAggConfig } from './_bucket_agg_type'; import { @@ -39,10 +38,10 @@ import { OrderByParamEditor, aggFilter } from '../../vis/editors/default/control import { SizeParamEditor } from '../../vis/editors/default/controls/size'; import { MissingBucketParamEditor } from '../../vis/editors/default/controls/missing_bucket'; import { OtherBucketParamEditor } from '../../vis/editors/default/controls/other_bucket'; -import { ContentType } from '../../../../../plugins/data/common'; import { AggConfigs } from '../agg_configs'; import { Adapters } from '../../../../../plugins/inspector/public'; +import { ContentType, KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; // @ts-ignore import { Schemas } from '../../vis/editors/default/schemas'; diff --git a/src/legacy/ui/public/agg_types/metrics/avg.ts b/src/legacy/ui/public/agg_types/metrics/avg.ts index cd069f3133af1..0222a8e543223 100644 --- a/src/legacy/ui/public/agg_types/metrics/avg.ts +++ b/src/legacy/ui/public/agg_types/metrics/avg.ts @@ -20,7 +20,7 @@ import { i18n } from '@kbn/i18n'; import { MetricAggType } from './metric_agg_type'; import { METRIC_TYPES } from './metric_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; const averageTitle = i18n.translate('common.ui.aggTypes.metrics.averageTitle', { defaultMessage: 'Average', diff --git a/src/legacy/ui/public/agg_types/metrics/geo_bounds.ts b/src/legacy/ui/public/agg_types/metrics/geo_bounds.ts index b5c479bde5cb0..b8ce03cdf11ec 100644 --- a/src/legacy/ui/public/agg_types/metrics/geo_bounds.ts +++ b/src/legacy/ui/public/agg_types/metrics/geo_bounds.ts @@ -20,7 +20,7 @@ import { i18n } from '@kbn/i18n'; import { MetricAggType } from './metric_agg_type'; import { METRIC_TYPES } from './metric_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; const geoBoundsTitle = i18n.translate('common.ui.aggTypes.metrics.geoBoundsTitle', { defaultMessage: 'Geo Bounds', diff --git a/src/legacy/ui/public/agg_types/metrics/geo_centroid.ts b/src/legacy/ui/public/agg_types/metrics/geo_centroid.ts index 25b45ff7d6b1c..5313e31796a5b 100644 --- a/src/legacy/ui/public/agg_types/metrics/geo_centroid.ts +++ b/src/legacy/ui/public/agg_types/metrics/geo_centroid.ts @@ -20,7 +20,7 @@ import { i18n } from '@kbn/i18n'; import { MetricAggType } from './metric_agg_type'; import { METRIC_TYPES } from './metric_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; const geoCentroidTitle = i18n.translate('common.ui.aggTypes.metrics.geoCentroidTitle', { defaultMessage: 'Geo Centroid', diff --git a/src/legacy/ui/public/agg_types/metrics/max.ts b/src/legacy/ui/public/agg_types/metrics/max.ts index f6e460be9e624..5c43511acee72 100644 --- a/src/legacy/ui/public/agg_types/metrics/max.ts +++ b/src/legacy/ui/public/agg_types/metrics/max.ts @@ -20,7 +20,7 @@ import { i18n } from '@kbn/i18n'; import { MetricAggType } from './metric_agg_type'; import { METRIC_TYPES } from './metric_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; const maxTitle = i18n.translate('common.ui.aggTypes.metrics.maxTitle', { defaultMessage: 'Max', diff --git a/src/legacy/ui/public/agg_types/metrics/median.ts b/src/legacy/ui/public/agg_types/metrics/median.ts index 1a3d6cf4b8d23..8797bed5105c5 100644 --- a/src/legacy/ui/public/agg_types/metrics/median.ts +++ b/src/legacy/ui/public/agg_types/metrics/median.ts @@ -22,7 +22,7 @@ import { METRIC_TYPES } from './metric_agg_types'; // @ts-ignore import { percentilesMetricAgg } from './percentiles'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; const medianTitle = i18n.translate('common.ui.aggTypes.metrics.medianTitle', { defaultMessage: 'Median', diff --git a/src/legacy/ui/public/agg_types/metrics/metric_agg_type.ts b/src/legacy/ui/public/agg_types/metrics/metric_agg_type.ts index c1f5528825bcc..7428bd6caa22d 100644 --- a/src/legacy/ui/public/agg_types/metrics/metric_agg_type.ts +++ b/src/legacy/ui/public/agg_types/metrics/metric_agg_type.ts @@ -25,7 +25,7 @@ import { METRIC_TYPES } from './metric_agg_types'; // @ts-ignore import { fieldFormats } from '../../registry/field_formats'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; export type IMetricAggConfig = AggConfig; diff --git a/src/legacy/ui/public/agg_types/metrics/min.ts b/src/legacy/ui/public/agg_types/metrics/min.ts index 4761985c75a43..5f8ca72954cc2 100644 --- a/src/legacy/ui/public/agg_types/metrics/min.ts +++ b/src/legacy/ui/public/agg_types/metrics/min.ts @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; import { MetricAggType } from './metric_agg_type'; import { METRIC_TYPES } from './metric_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; const minTitle = i18n.translate('common.ui.aggTypes.metrics.minTitle', { defaultMessage: 'Min', diff --git a/src/legacy/ui/public/agg_types/metrics/percentile_ranks.ts b/src/legacy/ui/public/agg_types/metrics/percentile_ranks.ts index 8b923092772db..4fabe137f1bc8 100644 --- a/src/legacy/ui/public/agg_types/metrics/percentile_ranks.ts +++ b/src/legacy/ui/public/agg_types/metrics/percentile_ranks.ts @@ -26,7 +26,7 @@ import { getPercentileValue } from './percentiles_get_value'; import { METRIC_TYPES } from './metric_agg_types'; // @ts-ignore import { fieldFormats } from '../../registry/field_formats'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; // required by the values editor diff --git a/src/legacy/ui/public/agg_types/metrics/percentiles.ts b/src/legacy/ui/public/agg_types/metrics/percentiles.ts index 0ac0455468472..1a3606d677951 100644 --- a/src/legacy/ui/public/agg_types/metrics/percentiles.ts +++ b/src/legacy/ui/public/agg_types/metrics/percentiles.ts @@ -21,7 +21,7 @@ import { i18n } from '@kbn/i18n'; import { IMetricAggConfig, MetricAggType } from './metric_agg_type'; import { METRIC_TYPES } from './metric_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; import { getResponseAggConfigClass, IResponseAggConfig } from './lib/get_response_agg_config_class'; import { getPercentileValue } from './percentiles_get_value'; diff --git a/src/legacy/ui/public/agg_types/metrics/std_deviation.ts b/src/legacy/ui/public/agg_types/metrics/std_deviation.ts index ebd5fceb9c751..b2e6d3b3ca4d0 100644 --- a/src/legacy/ui/public/agg_types/metrics/std_deviation.ts +++ b/src/legacy/ui/public/agg_types/metrics/std_deviation.ts @@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n'; import { MetricAggType } from './metric_agg_type'; import { METRIC_TYPES } from './metric_agg_types'; import { getResponseAggConfigClass, IResponseAggConfig } from './lib/get_response_agg_config_class'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; interface ValProp { valProp: string[]; diff --git a/src/legacy/ui/public/agg_types/metrics/sum.ts b/src/legacy/ui/public/agg_types/metrics/sum.ts index 4e428a35a5383..ce79c761ce799 100644 --- a/src/legacy/ui/public/agg_types/metrics/sum.ts +++ b/src/legacy/ui/public/agg_types/metrics/sum.ts @@ -20,7 +20,7 @@ import { i18n } from '@kbn/i18n'; import { MetricAggType } from './metric_agg_type'; import { METRIC_TYPES } from './metric_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; const sumTitle = i18n.translate('common.ui.aggTypes.metrics.sumTitle', { defaultMessage: 'Sum', diff --git a/src/legacy/ui/public/agg_types/metrics/top_hit.test.ts b/src/legacy/ui/public/agg_types/metrics/top_hit.test.ts index e9d1ebb93d3ba..051174c388c1b 100644 --- a/src/legacy/ui/public/agg_types/metrics/top_hit.test.ts +++ b/src/legacy/ui/public/agg_types/metrics/top_hit.test.ts @@ -21,7 +21,7 @@ import { dropRight, last } from 'lodash'; import { topHitMetricAgg } from './top_hit'; import { AggConfigs } from '../agg_configs'; import { IMetricAggConfig } from './metric_agg_type'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; jest.mock('ui/new_platform'); diff --git a/src/legacy/ui/public/agg_types/metrics/top_hit.ts b/src/legacy/ui/public/agg_types/metrics/top_hit.ts index 7ff83e326fc8f..49c4a7951fab9 100644 --- a/src/legacy/ui/public/agg_types/metrics/top_hit.ts +++ b/src/legacy/ui/public/agg_types/metrics/top_hit.ts @@ -27,7 +27,7 @@ import { TopSizeParamEditor } from '../../vis/editors/default/controls/top_size' import { TopAggregateParamEditor } from '../../vis/editors/default/controls/top_aggregate'; import { aggTypeFieldFilters } from '../param_types/filter'; import { METRIC_TYPES } from './metric_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; // @ts-ignore import { wrapWithInlineComp } from '../buckets/inline_comp_wrapper'; diff --git a/src/legacy/ui/public/agg_types/param_types/field.test.ts b/src/legacy/ui/public/agg_types/param_types/field.test.ts index 2434f95056b78..9cea2934d7459 100644 --- a/src/legacy/ui/public/agg_types/param_types/field.test.ts +++ b/src/legacy/ui/public/agg_types/param_types/field.test.ts @@ -19,7 +19,7 @@ import { BaseParamType } from './base'; import { FieldParamType } from './field'; -import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../../../../plugins/data/common'; +import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../../../../plugins/data/public'; jest.mock('ui/new_platform'); diff --git a/src/legacy/ui/public/agg_types/utils.ts b/src/legacy/ui/public/agg_types/utils.ts index 6721262d265f4..fd405d49625ed 100644 --- a/src/legacy/ui/public/agg_types/utils.ts +++ b/src/legacy/ui/public/agg_types/utils.ts @@ -17,7 +17,7 @@ * under the License. */ -import { isValidEsInterval } from '../../../core_plugins/data/common'; +import { isValidEsInterval } from '../../../core_plugins/data/public'; import { leastCommonInterval } from '../vis/lib/least_common_interval'; /** diff --git a/src/legacy/ui/public/courier/search_source/search_source.js b/src/legacy/ui/public/courier/search_source/search_source.js index 729de41ed77db..bc69e862fea48 100644 --- a/src/legacy/ui/public/courier/search_source/search_source.js +++ b/src/legacy/ui/public/courier/search_source/search_source.js @@ -71,13 +71,12 @@ import _ from 'lodash'; import angular from 'angular'; -import { getEsQueryConfig, buildEsQuery } from '@kbn/es-query'; import { normalizeSortRequest } from './_normalize_sort_request'; import { fetchSoon } from '../fetch'; import { fieldWildcardFilter } from '../../field_wildcard'; -import { getHighlightRequest } from '../../../../../plugins/data/public'; +import { getHighlightRequest, esQuery } from '../../../../../plugins/data/public'; import { npSetup } from 'ui/new_platform'; import chrome from '../../chrome'; import { RequestFailure } from '../fetch/errors'; @@ -491,8 +490,8 @@ export class SearchSource { _.set(flatData.body, '_source.includes', remainingFields); } - const esQueryConfigs = getEsQueryConfig(config); - flatData.body.query = buildEsQuery(flatData.index, flatData.query, flatData.filters, esQueryConfigs); + const esQueryConfigs = esQuery.getEsQueryConfig(config); + flatData.body.query = esQuery.buildEsQuery(flatData.index, flatData.query, flatData.filters, esQueryConfigs); if (flatData.highlightAll != null) { if (flatData.highlightAll && flatData.body.query) { diff --git a/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts b/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts index c5ebc75973d0c..6598da76f60ba 100644 --- a/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts +++ b/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts @@ -22,7 +22,7 @@ import { identity } from 'lodash'; import { AggConfig, Vis } from 'ui/vis'; import { SerializedFieldFormat } from 'src/plugins/expressions/public'; -import { FieldFormat } from '../../../../../../plugins/data/common/field_formats'; +import { FieldFormat } from '../../../../../../plugins/data/public'; import { tabifyGetColumns } from '../../../agg_response/tabify/_get_columns'; import chrome from '../../../chrome'; diff --git a/packages/kbn-es-query/src/es_query/__tests__/build_es_query.js b/src/plugins/data/common/es_query/es_query/build_es_query.test.ts similarity index 61% rename from packages/kbn-es-query/src/es_query/__tests__/build_es_query.js rename to src/plugins/data/common/es_query/es_query/build_es_query.test.ts index fde3d063caaa6..3db23051b6ced 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/build_es_query.js +++ b/src/plugins/data/common/es_query/es_query/build_es_query.test.ts @@ -17,99 +17,100 @@ * under the License. */ -import expect from '@kbn/expect'; -import { buildEsQuery } from '../build_es_query'; -import indexPattern from '../../__fixtures__/index_pattern_response.json'; -import { fromKueryExpression, toElasticsearchQuery } from '../../kuery'; -import { luceneStringToDsl } from '../lucene_string_to_dsl'; -import { decorateQuery } from '../decorate_query'; +import { buildEsQuery } from './build_es_query'; +import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; +import { luceneStringToDsl } from './lucene_string_to_dsl'; +import { decorateQuery } from './decorate_query'; +import { IIndexPattern } from '../../index_patterns'; +import { MatchAllFilter } from '../filters'; +import { fields } from '../../index_patterns/mocks'; +import { Query } from '../../query/types'; -describe('build query', function () { - describe('buildEsQuery', function () { +describe('build query', () => { + const indexPattern: IIndexPattern = ({ + fields, + } as unknown) as IIndexPattern; - it('should return the parameters of an Elasticsearch bool query', function () { - const result = buildEsQuery(); + describe('buildEsQuery', () => { + it('should return the parameters of an Elasticsearch bool query', () => { + const result = buildEsQuery(indexPattern, [], []); const expected = { bool: { must: [], filter: [], should: [], must_not: [], - } + }, }; - expect(result).to.eql(expected); + expect(result).toEqual(expected); }); - it('should combine queries and filters from multiple query languages into a single ES bool query', function () { + it('should combine queries and filters from multiple query languages into a single ES bool query', () => { const queries = [ { query: 'extension:jpg', language: 'kuery' }, { query: 'bar:baz', language: 'lucene' }, - ]; + ] as Query[]; const filters = [ { match_all: {}, meta: { type: 'match_all' }, - }, + } as MatchAllFilter, ]; const config = { allowLeadingWildcards: true, queryStringOptions: {}, + ignoreFilterIfFieldNotInIndex: false, }; const expectedResult = { bool: { - must: [ - decorateQuery(luceneStringToDsl('bar:baz'), config.queryStringOptions), - ], + must: [decorateQuery(luceneStringToDsl('bar:baz'), config.queryStringOptions)], filter: [ toElasticsearchQuery(fromKueryExpression('extension:jpg'), indexPattern), { match_all: {} }, ], should: [], must_not: [], - } + }, }; const result = buildEsQuery(indexPattern, queries, filters, config); - expect(result).to.eql(expectedResult); + expect(result).toEqual(expectedResult); }); - it('should accept queries and filters as either single objects or arrays', function () { - const queries = { query: 'extension:jpg', language: 'lucene' }; + it('should accept queries and filters as either single objects or arrays', () => { + const queries = { query: 'extension:jpg', language: 'lucene' } as Query; const filters = { match_all: {}, meta: { type: 'match_all' }, - }; + } as MatchAllFilter; const config = { allowLeadingWildcards: true, queryStringOptions: {}, + ignoreFilterIfFieldNotInIndex: false, }; const expectedResult = { bool: { - must: [ - decorateQuery(luceneStringToDsl('extension:jpg'), config.queryStringOptions), - ], + must: [decorateQuery(luceneStringToDsl('extension:jpg'), config.queryStringOptions)], filter: [{ match_all: {} }], should: [], must_not: [], - } + }, }; const result = buildEsQuery(indexPattern, queries, filters, config); - expect(result).to.eql(expectedResult); + expect(result).toEqual(expectedResult); }); - it('should use the default time zone set in the Advanced Settings in queries and filters', function () { + it('should use the default time zone set in the Advanced Settings in queries and filters', () => { const queries = [ { query: '@timestamp:"2019-03-23T13:18:00"', language: 'kuery' }, - { query: '@timestamp:"2019-03-23T13:18:00"', language: 'lucene' } - ]; - const filters = [ - { match_all: {}, meta: { type: 'match_all' } } - ]; + { query: '@timestamp:"2019-03-23T13:18:00"', language: 'lucene' }, + ] as Query[]; + const filters = [{ match_all: {}, meta: { type: 'match_all' } } as MatchAllFilter]; const config = { allowLeadingWildcards: true, queryStringOptions: {}, @@ -120,20 +121,27 @@ describe('build query', function () { const expectedResult = { bool: { must: [ - decorateQuery(luceneStringToDsl('@timestamp:"2019-03-23T13:18:00"'), config.queryStringOptions, config.dateFormatTZ), + decorateQuery( + luceneStringToDsl('@timestamp:"2019-03-23T13:18:00"'), + config.queryStringOptions, + config.dateFormatTZ + ), ], filter: [ - toElasticsearchQuery(fromKueryExpression('@timestamp:"2019-03-23T13:18:00"'), indexPattern, config), - { match_all: {} } + toElasticsearchQuery( + fromKueryExpression('@timestamp:"2019-03-23T13:18:00"'), + indexPattern, + config + ), + { match_all: {} }, ], should: [], must_not: [], - } + }, }; const result = buildEsQuery(indexPattern, queries, filters, config); - expect(result).to.eql(expectedResult); - }); + expect(result).toEqual(expectedResult); + }); }); - }); diff --git a/packages/kbn-es-query/src/es_query/build_es_query.js b/src/plugins/data/common/es_query/es_query/build_es_query.ts similarity index 58% rename from packages/kbn-es-query/src/es_query/build_es_query.js rename to src/plugins/data/common/es_query/es_query/build_es_query.ts index d17147761d8bc..b754496793660 100644 --- a/packages/kbn-es-query/src/es_query/build_es_query.js +++ b/src/plugins/data/common/es_query/es_query/build_es_query.ts @@ -21,6 +21,16 @@ import { groupBy, has } from 'lodash'; import { buildQueryFromKuery } from './from_kuery'; import { buildQueryFromFilters } from './from_filters'; import { buildQueryFromLucene } from './from_lucene'; +import { IIndexPattern } from '../../index_patterns'; +import { Filter } from '../filters'; +import { Query } from '../../query/types'; + +export interface EsQueryConfig { + allowLeadingWildcards: boolean; + queryStringOptions: Record; + ignoreFilterIfFieldNotInIndex: boolean; + dateFormatTZ?: string; +} /** * @param indexPattern @@ -31,30 +41,43 @@ import { buildQueryFromLucene } from './from_lucene'; * config contains dateformat:tz */ export function buildEsQuery( - indexPattern, - queries = [], - filters = [], - config = { + indexPattern: IIndexPattern | null, + queries: Query | Query[], + filters: Filter | Filter[], + config: EsQueryConfig = { allowLeadingWildcards: false, queryStringOptions: {}, ignoreFilterIfFieldNotInIndex: false, - dateFormatTZ: null, - }) { + } +) { queries = Array.isArray(queries) ? queries : [queries]; filters = Array.isArray(filters) ? filters : [filters]; - const validQueries = queries.filter((query) => has(query, 'query')); + const validQueries = queries.filter(query => has(query, 'query')); const queriesByLanguage = groupBy(validQueries, 'language'); - const kueryQuery = buildQueryFromKuery(indexPattern, queriesByLanguage.kuery, config.allowLeadingWildcards, config.dateFormatTZ); - const luceneQuery = buildQueryFromLucene(queriesByLanguage.lucene, config.queryStringOptions, config.dateFormatTZ); - const filterQuery = buildQueryFromFilters(filters, indexPattern, config.ignoreFilterIfFieldNotInIndex); + const kueryQuery = buildQueryFromKuery( + indexPattern, + queriesByLanguage.kuery, + config.allowLeadingWildcards, + config.dateFormatTZ + ); + const luceneQuery = buildQueryFromLucene( + queriesByLanguage.lucene, + config.queryStringOptions, + config.dateFormatTZ + ); + const filterQuery = buildQueryFromFilters( + filters, + indexPattern, + config.ignoreFilterIfFieldNotInIndex + ); return { bool: { - must: [].concat(kueryQuery.must, luceneQuery.must, filterQuery.must), - filter: [].concat(kueryQuery.filter, luceneQuery.filter, filterQuery.filter), - should: [].concat(kueryQuery.should, luceneQuery.should, filterQuery.should), - must_not: [].concat(kueryQuery.must_not, luceneQuery.must_not, filterQuery.must_not), - } + must: [...kueryQuery.must, ...luceneQuery.must, ...filterQuery.must], + filter: [...kueryQuery.filter, ...luceneQuery.filter, ...filterQuery.filter], + should: [...kueryQuery.should, ...luceneQuery.should, ...filterQuery.should], + must_not: [...kueryQuery.must_not, ...luceneQuery.must_not, ...filterQuery.must_not], + }, }; } diff --git a/packages/kbn-es-query/src/es_query/__tests__/decorate_query.js b/src/plugins/data/common/es_query/es_query/decorate_query.test.ts similarity index 50% rename from packages/kbn-es-query/src/es_query/__tests__/decorate_query.js rename to src/plugins/data/common/es_query/es_query/decorate_query.test.ts index d5978716dac9e..d7cd82eb7108a 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/decorate_query.js +++ b/src/plugins/data/common/es_query/es_query/decorate_query.test.ts @@ -17,21 +17,30 @@ * under the License. */ -import expect from '@kbn/expect'; -import { decorateQuery } from '../decorate_query'; +import { decorateQuery } from './decorate_query'; -describe('Query decorator', function () { - it('should be a function', function () { - expect(decorateQuery).to.be.a(Function); +describe('Query decorator', () => { + test('should be a function', () => { + expect(typeof decorateQuery).toBe('function'); }); - it('should merge in the query string options', function () { - const decoratedQuery = decorateQuery({ query_string: { query: '*' } }, { analyze_wildcard: true }); - expect(decoratedQuery).to.eql({ query_string: { query: '*', analyze_wildcard: true } }); + test('should merge in the query string options', () => { + const decoratedQuery = decorateQuery( + { query_string: { query: '*' } }, + { analyze_wildcard: true } + ); + + expect(decoratedQuery).toEqual({ query_string: { query: '*', analyze_wildcard: true } }); }); - it('should add a default of a time_zone parameter if one is provided', function () { - const decoratedQuery = decorateQuery({ query_string: { query: '*' } }, { analyze_wildcard: true }, 'America/Phoenix'); - expect(decoratedQuery).to.eql({ query_string: { query: '*', analyze_wildcard: true, time_zone: 'America/Phoenix' } }); + test('should add a default of a time_zone parameter if one is provided', () => { + const decoratedQuery = decorateQuery( + { query_string: { query: '*' } }, + { analyze_wildcard: true }, + 'America/Phoenix' + ); + expect(decoratedQuery).toEqual({ + query_string: { query: '*', analyze_wildcard: true, time_zone: 'America/Phoenix' }, + }); }); }); diff --git a/packages/kbn-es-query/src/es_query/decorate_query.js b/src/plugins/data/common/es_query/es_query/decorate_query.ts similarity index 69% rename from packages/kbn-es-query/src/es_query/decorate_query.js rename to src/plugins/data/common/es_query/es_query/decorate_query.ts index 8104707e0298a..891712d057886 100644 --- a/packages/kbn-es-query/src/es_query/decorate_query.js +++ b/src/plugins/data/common/es_query/es_query/decorate_query.ts @@ -17,8 +17,9 @@ * under the License. */ -import _ from 'lodash'; -import { getTimeZoneFromSettings } from '../utils/get_time_zone_from_settings'; +import { extend, defaults } from 'lodash'; +import { getTimeZoneFromSettings } from '../utils'; +import { DslQuery, isEsQueryString } from './es_query_dsl'; /** * Decorate queries with default parameters @@ -28,11 +29,17 @@ import { getTimeZoneFromSettings } from '../utils/get_time_zone_from_settings'; * @returns {object} */ -export function decorateQuery(query, queryStringOptions, dateFormatTZ = null) { - if (_.has(query, 'query_string.query')) { - _.extend(query.query_string, queryStringOptions); +export function decorateQuery( + query: DslQuery, + queryStringOptions: Record, + dateFormatTZ?: string +) { + if (isEsQueryString(query)) { + extend(query.query_string, queryStringOptions); if (dateFormatTZ) { - _.defaults(query.query_string, { time_zone: getTimeZoneFromSettings(dateFormatTZ) }); + defaults(query.query_string, { + time_zone: getTimeZoneFromSettings(dateFormatTZ), + }); } } diff --git a/src/plugins/data/common/es_query/es_query/es_query_dsl.ts b/src/plugins/data/common/es_query/es_query/es_query_dsl.ts new file mode 100644 index 0000000000000..d906ae5359ec2 --- /dev/null +++ b/src/plugins/data/common/es_query/es_query/es_query_dsl.ts @@ -0,0 +1,65 @@ +/* + * 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 { has } from 'lodash'; + +export interface DslRangeQuery { + range: { + [name: string]: { + gte: number; + lte: number; + format: string; + }; + }; +} + +export interface DslMatchQuery { + match: { + [name: string]: { + query: string; + operator: string; + zero_terms_query: string; + }; + }; +} + +export interface DslQueryStringQuery { + query_string: { + query: string; + analyze_wildcard?: boolean; + }; +} + +export interface DslMatchAllQuery { + match_all: Record; +} + +export interface DslTermQuery { + term: Record; +} + +export type DslQuery = + | DslRangeQuery + | DslMatchQuery + | DslQueryStringQuery + | DslMatchAllQuery + | DslTermQuery; + +export const isEsQueryString = (query: any): query is DslQueryStringQuery => + has(query, 'query_string.query'); diff --git a/packages/kbn-es-query/src/es_query/__tests__/filter_matches_index.js b/src/plugins/data/common/es_query/es_query/filter_matches_index.test.ts similarity index 62% rename from packages/kbn-es-query/src/es_query/__tests__/filter_matches_index.js rename to src/plugins/data/common/es_query/es_query/filter_matches_index.test.ts index 1c43230aeea30..6a5c7bdf8eea3 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/filter_matches_index.js +++ b/src/plugins/data/common/es_query/es_query/filter_matches_index.test.ts @@ -17,31 +17,36 @@ * under the License. */ -import expect from '@kbn/expect'; -import { filterMatchesIndex } from '../filter_matches_index'; +import { Filter } from '../filters'; +import { filterMatchesIndex } from './filter_matches_index'; +import { IIndexPattern } from '../../index_patterns'; -describe('filterMatchesIndex', function () { +describe('filterMatchesIndex', () => { it('should return true if the filter has no meta', () => { - const filter = {}; - const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] }; - expect(filterMatchesIndex(filter, indexPattern)).to.be(true); + const filter = {} as Filter; + const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] } as IIndexPattern; + + expect(filterMatchesIndex(filter, indexPattern)).toBe(true); }); it('should return true if no index pattern is passed', () => { - const filter = { meta: { index: 'foo', key: 'bar' } }; - const indexPattern = undefined; - expect(filterMatchesIndex(filter, indexPattern)).to.be(true); + const filter = { meta: { index: 'foo', key: 'bar' } } as Filter; + const indexPattern = null; + + expect(filterMatchesIndex(filter, indexPattern)).toBe(true); }); it('should return true if the filter key matches a field name', () => { - const filter = { meta: { index: 'foo', key: 'bar' } }; - const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] }; - expect(filterMatchesIndex(filter, indexPattern)).to.be(true); + const filter = { meta: { index: 'foo', key: 'bar' } } as Filter; + const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] } as IIndexPattern; + + expect(filterMatchesIndex(filter, indexPattern)).toBe(true); }); it('should return false if the filter key does not match a field name', () => { - const filter = { meta: { index: 'foo', key: 'baz' } }; - const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] }; - expect(filterMatchesIndex(filter, indexPattern)).to.be(false); + const filter = { meta: { index: 'foo', key: 'baz' } } as Filter; + const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] } as IIndexPattern; + + expect(filterMatchesIndex(filter, indexPattern)).toBe(false); }); }); diff --git a/packages/kbn-es-query/src/es_query/filter_matches_index.js b/src/plugins/data/common/es_query/es_query/filter_matches_index.ts similarity index 68% rename from packages/kbn-es-query/src/es_query/filter_matches_index.js rename to src/plugins/data/common/es_query/es_query/filter_matches_index.ts index 602a9bbfbc925..496aab3ea585f 100644 --- a/packages/kbn-es-query/src/es_query/filter_matches_index.js +++ b/src/plugins/data/common/es_query/es_query/filter_matches_index.ts @@ -17,12 +17,17 @@ * under the License. */ -// TODO: We should base this on something better than `filter.meta.key`. We should probably modify -// this to check if `filter.meta.index` matches `indexPattern.id` instead, but that's a breaking -// change. -export function filterMatchesIndex(filter, indexPattern) { +import { IIndexPattern, IFieldType } from '../../index_patterns'; +import { Filter } from '../filters'; + +/* + * TODO: We should base this on something better than `filter.meta.key`. We should probably modify + * this to check if `filter.meta.index` matches `indexPattern.id` instead, but that's a breaking + * change. + */ +export function filterMatchesIndex(filter: Filter, indexPattern: IIndexPattern | null) { if (!filter.meta || !indexPattern) { return true; } - return indexPattern.fields.some(field => field.name === filter.meta.key); + return indexPattern.fields.some((field: IFieldType) => field.name === filter.meta.key); } diff --git a/src/plugins/data/common/es_query/es_query/from_filters.test.ts b/src/plugins/data/common/es_query/es_query/from_filters.test.ts new file mode 100644 index 0000000000000..8c1d990c389b8 --- /dev/null +++ b/src/plugins/data/common/es_query/es_query/from_filters.test.ts @@ -0,0 +1,148 @@ +/* + * 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 { buildQueryFromFilters } from './from_filters'; +import { IIndexPattern } from '../../index_patterns'; +import { ExistsFilter, Filter, MatchAllFilter } from '../filters'; +import { fields } from '../../index_patterns/mocks'; + +describe('build query', () => { + const indexPattern: IIndexPattern = ({ + fields, + } as unknown) as IIndexPattern; + + describe('buildQueryFromFilters', () => { + test('should return the parameters of an Elasticsearch bool query', () => { + const result = buildQueryFromFilters([], indexPattern, false); + const expected = { + must: [], + filter: [], + should: [], + must_not: [], + }; + expect(result).toEqual(expected); + }); + + test('should transform an array of kibana filters into ES queries combined in the bool clauses', () => { + const filters = [ + { + match_all: {}, + meta: { type: 'match_all' }, + } as MatchAllFilter, + { + exists: { field: 'foo' }, + meta: { type: 'exists' }, + } as ExistsFilter, + ] as Filter[]; + + const expectedESQueries = [{ match_all: {} }, { exists: { field: 'foo' } }]; + + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.filter).toEqual(expectedESQueries); + }); + + test('should remove disabled filters', () => { + const filters = [ + { + match_all: {}, + meta: { type: 'match_all', negate: true, disabled: true }, + } as MatchAllFilter, + ] as Filter[]; + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.must_not).toEqual([]); + }); + + test('should remove falsy filters', () => { + const filters = ([null, undefined] as unknown) as Filter[]; + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.must_not).toEqual([]); + expect(result.must).toEqual([]); + }); + + test('should place negated filters in the must_not clause', () => { + const filters = [ + { + match_all: {}, + meta: { type: 'match_all', negate: true }, + } as MatchAllFilter, + ] as Filter[]; + + const expectedESQueries = [{ match_all: {} }]; + + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.must_not).toEqual(expectedESQueries); + }); + + test('should translate old ES filter syntax into ES 5+ query objects', () => { + const filters = [ + { + query: { exists: { field: 'foo' } }, + meta: { type: 'exists' }, + }, + ] as Filter[]; + + const expectedESQueries = [ + { + exists: { field: 'foo' }, + }, + ]; + + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.filter).toEqual(expectedESQueries); + }); + + test('should migrate deprecated match syntax', () => { + const filters = [ + { + query: { match: { extension: { query: 'foo', type: 'phrase' } } }, + meta: { type: 'phrase' }, + }, + ] as Filter[]; + + const expectedESQueries = [ + { + match_phrase: { extension: { query: 'foo' } }, + }, + ]; + + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.filter).toEqual(expectedESQueries); + }); + + test('should not add query:queryString:options to query_string filters', () => { + const filters = [ + { + query: { query_string: { query: 'foo' } }, + meta: { type: 'query_string' }, + }, + ] as Filter[]; + + const expectedESQueries = [{ query_string: { query: 'foo' } }]; + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.filter).toEqual(expectedESQueries); + }); + }); +}); diff --git a/packages/kbn-es-query/src/es_query/from_filters.js b/src/plugins/data/common/es_query/es_query/from_filters.ts similarity index 69% rename from packages/kbn-es-query/src/es_query/from_filters.js rename to src/plugins/data/common/es_query/es_query/from_filters.ts index 10f9cf82fc972..1e0957d816590 100644 --- a/packages/kbn-es-query/src/es_query/from_filters.js +++ b/src/plugins/data/common/es_query/es_query/from_filters.ts @@ -16,10 +16,11 @@ * specific language governing permissions and limitations * under the License. */ - -import _ from 'lodash'; +import { isUndefined } from 'lodash'; import { migrateFilter } from './migrate_filter'; import { filterMatchesIndex } from './filter_matches_index'; +import { Filter, cleanFilter, isFilterDisabled } from '../filters'; +import { IIndexPattern } from '../../index_patterns'; /** * Create a filter that can be reversed for filters with negate set @@ -28,11 +29,12 @@ import { filterMatchesIndex } from './filter_matches_index'; * through otherwise it will filter out * @returns {function} */ -const filterNegate = function (reverse) { - return function (filter) { - if (_.isUndefined(filter.meta) || _.isUndefined(filter.meta.negate)) return !reverse; - return filter.meta && filter.meta.negate === reverse; - }; +const filterNegate = (reverse: boolean) => (filter: Filter) => { + if (isUndefined(filter.meta) || isUndefined(filter.meta.negate)) { + return !reverse; + } + + return filter.meta && filter.meta.negate === reverse; }; /** @@ -40,7 +42,7 @@ const filterNegate = function (reverse) { * @param {Object} filter - The filter to translate * @return {Object} the query version of that filter */ -const translateToQuery = function (filter) { +const translateToQuery = (filter: Filter) => { if (!filter) return; if (filter.query) { @@ -50,17 +52,13 @@ const translateToQuery = function (filter) { return filter; }; -/** - * Clean out any invalid attributes from the filters - * @param {object} filter The filter to clean - * @returns {object} - */ -const cleanFilter = function (filter) { - return _.omit(filter, ['meta', '$state']); -}; +export const buildQueryFromFilters = ( + filters: Filter[] = [], + indexPattern: IIndexPattern | null, + ignoreFilterIfFieldNotInIndex: boolean = false +) => { + filters = filters.filter(filter => filter && !isFilterDisabled(filter)); -export function buildQueryFromFilters(filters = [], indexPattern, ignoreFilterIfFieldNotInIndex) { - filters = filters.filter(filter => filter && !_.get(filter, ['meta', 'disabled'])); return { must: [], filter: filters @@ -68,17 +66,13 @@ export function buildQueryFromFilters(filters = [], indexPattern, ignoreFilterIf .filter(filter => !ignoreFilterIfFieldNotInIndex || filterMatchesIndex(filter, indexPattern)) .map(translateToQuery) .map(cleanFilter) - .map(filter => { - return migrateFilter(filter, indexPattern); - }), + .map(filter => migrateFilter(filter, indexPattern)), should: [], must_not: filters .filter(filterNegate(true)) .filter(filter => !ignoreFilterIfFieldNotInIndex || filterMatchesIndex(filter, indexPattern)) .map(translateToQuery) .map(cleanFilter) - .map(filter => { - return migrateFilter(filter, indexPattern); - }), + .map(filter => migrateFilter(filter, indexPattern)), }; -} +}; diff --git a/packages/kbn-es-query/src/es_query/__tests__/from_kuery.js b/src/plugins/data/common/es_query/es_query/from_kuery.test.ts similarity index 54% rename from packages/kbn-es-query/src/es_query/__tests__/from_kuery.js rename to src/plugins/data/common/es_query/es_query/from_kuery.test.ts index 18738b05ea69d..000815b51f620 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/from_kuery.js +++ b/src/plugins/data/common/es_query/es_query/from_kuery.test.ts @@ -17,14 +17,19 @@ * under the License. */ -import { buildQueryFromKuery } from '../from_kuery'; -import indexPattern from '../../__fixtures__/index_pattern_response.json'; -import expect from '@kbn/expect'; -import { fromKueryExpression, toElasticsearchQuery } from '../../kuery'; - -describe('build query', function () { - describe('buildQueryFromKuery', function () { - it('should return the parameters of an Elasticsearch bool query', function () { +import { buildQueryFromKuery } from './from_kuery'; +import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; +import { IIndexPattern } from '../../index_patterns'; +import { fields } from '../../index_patterns/mocks'; +import { Query } from '../../query/types'; + +describe('build query', () => { + const indexPattern: IIndexPattern = ({ + fields, + } as unknown) as IIndexPattern; + + describe('buildQueryFromKuery', () => { + test('should return the parameters of an Elasticsearch bool query', () => { const result = buildQueryFromKuery(null, [], true); const expected = { must: [], @@ -32,50 +37,48 @@ describe('build query', function () { should: [], must_not: [], }; - expect(result).to.eql(expected); + expect(result).toEqual(expected); }); - it('should transform an array of kuery queries into ES queries combined in the bool\'s filter clause', function () { + test("should transform an array of kuery queries into ES queries combined in the bool's filter clause", () => { const queries = [ { query: 'extension:jpg', language: 'kuery' }, { query: 'machine.os:osx', language: 'kuery' }, - ]; + ] as Query[]; - const expectedESQueries = queries.map( - (query) => { - return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern); - } - ); + const expectedESQueries = queries.map(query => { + return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern); + }); const result = buildQueryFromKuery(indexPattern, queries, true); - expect(result.filter).to.eql(expectedESQueries); + expect(result.filter).toEqual(expectedESQueries); }); - it('should accept a specific date format for a kuery query into an ES query in the bool\'s filter clause', function () { - const queries = [{ query: '@timestamp:"2018-04-03T19:04:17"', language: 'kuery' }]; - + test("should accept a specific date format for a kuery query into an ES query in the bool's filter clause", () => { + const queries = [{ query: '@timestamp:"2018-04-03T19:04:17"', language: 'kuery' }] as Query[]; const expectedESQueries = queries.map(query => { - return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern, { dateFormatTZ: 'America/Phoenix' }); + return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern, { + dateFormatTZ: 'America/Phoenix', + }); }); const result = buildQueryFromKuery(indexPattern, queries, true, 'America/Phoenix'); - expect(result.filter).to.eql(expectedESQueries); + expect(result.filter).toEqual(expectedESQueries); }); - it('should gracefully handle date queries when no date format is provided', function () { - const queries = [{ query: '@timestamp:"2018-04-03T19:04:17Z"', language: 'kuery' }]; - + test('should gracefully handle date queries when no date format is provided', () => { + const queries = [ + { query: '@timestamp:"2018-04-03T19:04:17Z"', language: 'kuery' }, + ] as Query[]; const expectedESQueries = queries.map(query => { return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern); }); const result = buildQueryFromKuery(indexPattern, queries, true); - expect(result.filter).to.eql(expectedESQueries); + expect(result.filter).toEqual(expectedESQueries); }); - }); - }); diff --git a/packages/kbn-es-query/src/es_query/from_kuery.js b/src/plugins/data/common/es_query/es_query/from_kuery.ts similarity index 59% rename from packages/kbn-es-query/src/es_query/from_kuery.js rename to src/plugins/data/common/es_query/es_query/from_kuery.ts index 8e6e64b4c984e..f91c3d97b95b4 100644 --- a/packages/kbn-es-query/src/es_query/from_kuery.js +++ b/src/plugins/data/common/es_query/es_query/from_kuery.ts @@ -17,27 +17,40 @@ * under the License. */ -import { - fromKueryExpression, - toElasticsearchQuery, - nodeTypes, -} from '../kuery'; +import { fromKueryExpression, toElasticsearchQuery, nodeTypes, KueryNode } from '@kbn/es-query'; +import { IIndexPattern } from '../../index_patterns'; +import { Query } from '../../query/types'; -export function buildQueryFromKuery(indexPattern, queries = [], allowLeadingWildcards, dateFormatTZ = null) { +export function buildQueryFromKuery( + indexPattern: IIndexPattern | null, + queries: Query[] = [], + allowLeadingWildcards: boolean = false, + dateFormatTZ?: string +) { const queryASTs = queries.map(query => { return fromKueryExpression(query.query, { allowLeadingWildcards }); }); + return buildQuery(indexPattern, queryASTs, { dateFormatTZ }); } -function buildQuery(indexPattern, queryASTs, config = null) { - const compoundQueryAST = nodeTypes.function.buildNode('and', queryASTs); - const kueryQuery = toElasticsearchQuery(compoundQueryAST, indexPattern, config); +function buildQuery( + indexPattern: IIndexPattern | null, + queryASTs: KueryNode[], + config: Record = {} +) { + const compoundQueryAST: KueryNode = nodeTypes.function.buildNode('and', queryASTs); + const kueryQuery: Record = toElasticsearchQuery( + compoundQueryAST, + indexPattern, + config + ); + return { must: [], filter: [], should: [], must_not: [], - ...kueryQuery.bool + ...kueryQuery.bool, }; } diff --git a/src/plugins/data/common/es_query/es_query/from_lucene.test.ts b/src/plugins/data/common/es_query/es_query/from_lucene.test.ts new file mode 100644 index 0000000000000..fc85404a5060c --- /dev/null +++ b/src/plugins/data/common/es_query/es_query/from_lucene.test.ts @@ -0,0 +1,74 @@ +/* + * 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 { buildQueryFromLucene } from './from_lucene'; +import { decorateQuery } from './decorate_query'; +import { luceneStringToDsl } from './lucene_string_to_dsl'; +import { Query } from '../../query/types'; + +describe('build query', () => { + describe('buildQueryFromLucene', () => { + test('should return the parameters of an Elasticsearch bool query', () => { + const result = buildQueryFromLucene([], {}); + const expected = { + must: [], + filter: [], + should: [], + must_not: [], + }; + + expect(result).toEqual(expected); + }); + + test("should transform an array of lucene queries into ES queries combined in the bool's must clause", () => { + const queries = ([ + { query: 'foo:bar', language: 'lucene' }, + { query: 'bar:baz', language: 'lucene' }, + ] as unknown) as Query[]; + const expectedESQueries = queries.map(query => { + return decorateQuery(luceneStringToDsl(query.query), {}); + }); + + const result = buildQueryFromLucene(queries, {}); + + expect(result.must).toEqual(expectedESQueries); + }); + + test('should also accept queries in ES query DSL format, simply passing them through', () => { + const queries = ([{ query: { match_all: {} }, language: 'lucene' }] as unknown) as Query[]; + const result = buildQueryFromLucene(queries, {}); + + expect(result.must).toEqual([queries[0].query]); + }); + }); + + test("should accept a date format in the decorated queries and combine that into the bool's must clause", () => { + const queries = ([ + { query: 'foo:bar', language: 'lucene' }, + { query: 'bar:baz', language: 'lucene' }, + ] as unknown) as Query[]; + const dateFormatTZ = 'America/Phoenix'; + const expectedESQueries = queries.map(query => { + return decorateQuery(luceneStringToDsl(query.query), {}, dateFormatTZ); + }); + const result = buildQueryFromLucene(queries, {}, dateFormatTZ); + + expect(result.must).toEqual(expectedESQueries); + }); +}); diff --git a/packages/kbn-es-query/src/es_query/from_lucene.js b/src/plugins/data/common/es_query/es_query/from_lucene.ts similarity index 81% rename from packages/kbn-es-query/src/es_query/from_lucene.js rename to src/plugins/data/common/es_query/es_query/from_lucene.ts index 8845fd68efb4d..8babb6df4fba5 100644 --- a/packages/kbn-es-query/src/es_query/from_lucene.js +++ b/src/plugins/data/common/es_query/es_query/from_lucene.ts @@ -16,19 +16,23 @@ * specific language governing permissions and limitations * under the License. */ - -import _ from 'lodash'; import { decorateQuery } from './decorate_query'; import { luceneStringToDsl } from './lucene_string_to_dsl'; +import { Query } from '../../query/types'; -export function buildQueryFromLucene(queries, queryStringOptions, dateFormatTZ = null) { - const combinedQueries = _.map(queries, (query) => { +export function buildQueryFromLucene( + queries: Query[], + queryStringOptions: Record, + dateFormatTZ?: string +) { + const combinedQueries = (queries || []).map(query => { const queryDsl = luceneStringToDsl(query.query); + return decorateQuery(queryDsl, queryStringOptions, dateFormatTZ); }); return { - must: [].concat(combinedQueries), + must: combinedQueries, filter: [], should: [], must_not: [], diff --git a/packages/kbn-es-query/src/es_query/__tests__/get_es_query_config.js b/src/plugins/data/common/es_query/es_query/get_es_query_config.test.ts similarity index 69% rename from packages/kbn-es-query/src/es_query/__tests__/get_es_query_config.js rename to src/plugins/data/common/es_query/es_query/get_es_query_config.test.ts index 8ccb04dd4b25a..a4ab03687f92e 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/get_es_query_config.js +++ b/src/plugins/data/common/es_query/es_query/get_es_query_config.test.ts @@ -16,13 +16,13 @@ * specific language governing permissions and limitations * under the License. */ +import { get } from 'lodash'; +import { getEsQueryConfig } from './get_es_query_config'; +import { UiSettingsClientContract } from 'kibana/public'; -import expect from '@kbn/expect'; -import { getEsQueryConfig } from '../get_es_query_config'; - -const config = { - get(item) { - return config[item]; +const config = ({ + get(item: string) { + return get(config, item); }, 'query:allowLeadingWildcards': { allowLeadingWildcards: true, @@ -36,10 +36,10 @@ const config = { 'dateFormat:tz': { dateFormatTZ: 'Browser', }, -}; +} as unknown) as UiSettingsClientContract; -describe('getEsQueryConfig', function () { - it('should return the parameters of an Elasticsearch query config requested', function () { +describe('getEsQueryConfig', () => { + test('should return the parameters of an Elasticsearch query config requested', () => { const result = getEsQueryConfig(config); const expected = { allowLeadingWildcards: { @@ -55,12 +55,12 @@ describe('getEsQueryConfig', function () { queryStringOptions: {}, }, }; - expect(result).to.eql(expected); - expect(result).to.have.keys( - 'allowLeadingWildcards', - 'dateFormatTZ', - 'ignoreFilterIfFieldNotInIndex', - 'queryStringOptions' - ); + + expect(result).toEqual(expected); + + expect(result).toHaveProperty('allowLeadingWildcards'); + expect(result).toHaveProperty('dateFormatTZ'); + expect(result).toHaveProperty('ignoreFilterIfFieldNotInIndex'); + expect(result).toHaveProperty('queryStringOptions'); }); }); diff --git a/packages/kbn-es-query/src/es_query/get_es_query_config.js b/src/plugins/data/common/es_query/es_query/get_es_query_config.ts similarity index 78% rename from packages/kbn-es-query/src/es_query/get_es_query_config.js rename to src/plugins/data/common/es_query/es_query/get_es_query_config.ts index 2518b1077462d..0a82cf03bdb44 100644 --- a/packages/kbn-es-query/src/es_query/get_es_query_config.js +++ b/src/plugins/data/common/es_query/es_query/get_es_query_config.ts @@ -17,10 +17,22 @@ * under the License. */ -export function getEsQueryConfig(config) { +import { EsQueryConfig } from './build_es_query'; + +interface KibanaConfig { + get(key: string): T; +} + +export function getEsQueryConfig(config: KibanaConfig) { const allowLeadingWildcards = config.get('query:allowLeadingWildcards'); const queryStringOptions = config.get('query:queryString:options'); const ignoreFilterIfFieldNotInIndex = config.get('courier:ignoreFilterIfFieldNotInIndex'); const dateFormatTZ = config.get('dateFormat:tz'); - return { allowLeadingWildcards, queryStringOptions, ignoreFilterIfFieldNotInIndex, dateFormatTZ }; + + return { + allowLeadingWildcards, + queryStringOptions, + ignoreFilterIfFieldNotInIndex, + dateFormatTZ, + } as EsQueryConfig; } diff --git a/packages/kbn-es-query/src/es_query/index.js b/src/plugins/data/common/es_query/es_query/index.ts similarity index 94% rename from packages/kbn-es-query/src/es_query/index.js rename to src/plugins/data/common/es_query/es_query/index.ts index 57dc31fd9fb6f..82cbc543e19db 100644 --- a/packages/kbn-es-query/src/es_query/index.js +++ b/src/plugins/data/common/es_query/es_query/index.ts @@ -17,7 +17,7 @@ * under the License. */ -export { buildEsQuery } from './build_es_query'; +export { buildEsQuery, EsQueryConfig } from './build_es_query'; export { buildQueryFromFilters } from './from_filters'; export { luceneStringToDsl } from './lucene_string_to_dsl'; export { migrateFilter } from './migrate_filter'; diff --git a/packages/kbn-es-query/src/es_query/__tests__/lucene_string_to_dsl.js b/src/plugins/data/common/es_query/es_query/lucene_string_to_dsl.test.ts similarity index 58% rename from packages/kbn-es-query/src/es_query/__tests__/lucene_string_to_dsl.js rename to src/plugins/data/common/es_query/es_query/lucene_string_to_dsl.test.ts index 04f6209ce6665..a0e94f2c46dcc 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/lucene_string_to_dsl.js +++ b/src/plugins/data/common/es_query/es_query/lucene_string_to_dsl.test.ts @@ -17,37 +17,34 @@ * under the License. */ -import { luceneStringToDsl } from '../lucene_string_to_dsl'; -import expect from '@kbn/expect'; +import { luceneStringToDsl } from './lucene_string_to_dsl'; -describe('build query', function () { - - describe('luceneStringToDsl', function () { - - it('should wrap strings with an ES query_string query', function () { +describe('build query', () => { + describe('luceneStringToDsl', () => { + test('should wrap strings with an ES query_string query', () => { const result = luceneStringToDsl('foo:bar'); const expectedResult = { - query_string: { query: 'foo:bar' } + query_string: { query: 'foo:bar' }, }; - expect(result).to.eql(expectedResult); + + expect(result).toEqual(expectedResult); }); - it('should return a match_all query for empty strings and whitespace', function () { + test('should return a match_all query for empty strings and whitespace', () => { const expectedResult = { - match_all: {} + match_all: {}, }; - expect(luceneStringToDsl('')).to.eql(expectedResult); - expect(luceneStringToDsl(' ')).to.eql(expectedResult); + expect(luceneStringToDsl('')).toEqual(expectedResult); + expect(luceneStringToDsl(' ')).toEqual(expectedResult); }); - it('should return non-string arguments without modification', function () { + test('should return non-string arguments without modification', () => { const expectedResult = {}; const result = luceneStringToDsl(expectedResult); - expect(result).to.be(expectedResult); - expect(result).to.eql(expectedResult); - }); + expect(result).toBe(expectedResult); + expect(result).toEqual(expectedResult); + }); }); - }); diff --git a/src/plugins/data/common/es_query/es_query/lucene_string_to_dsl.ts b/src/plugins/data/common/es_query/es_query/lucene_string_to_dsl.ts new file mode 100644 index 0000000000000..6e8d519ec0ce2 --- /dev/null +++ b/src/plugins/data/common/es_query/es_query/lucene_string_to_dsl.ts @@ -0,0 +1,33 @@ +/* + * 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 { isString } from 'lodash'; +import { DslQuery } from './es_query_dsl'; + +export function luceneStringToDsl(query: string | any): DslQuery { + if (isString(query)) { + if (query.trim() === '') { + return { match_all: {} }; + } + + return { query_string: { query } }; + } + + return query; +} diff --git a/src/plugins/data/common/es_query/es_query/migrate_filter.test.ts b/src/plugins/data/common/es_query/es_query/migrate_filter.test.ts new file mode 100644 index 0000000000000..4617ee1a1c43d --- /dev/null +++ b/src/plugins/data/common/es_query/es_query/migrate_filter.test.ts @@ -0,0 +1,65 @@ +/* + * 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 { isEqual, clone } from 'lodash'; +import { migrateFilter, DeprecatedMatchPhraseFilter } from './migrate_filter'; +import { PhraseFilter, MatchAllFilter } from '../filters'; + +describe('migrateFilter', function() { + const oldMatchPhraseFilter = ({ + match: { + fieldFoo: { + query: 'foobar', + type: 'phrase', + }, + }, + } as unknown) as DeprecatedMatchPhraseFilter; + + const newMatchPhraseFilter = ({ + match_phrase: { + fieldFoo: { + query: 'foobar', + }, + }, + } as unknown) as PhraseFilter; + + it('should migrate match filters of type phrase', function() { + const migratedFilter = migrateFilter(oldMatchPhraseFilter, null); + + expect(isEqual(migratedFilter, newMatchPhraseFilter)).toBe(true); + }); + + it('should not modify the original filter', function() { + const oldMatchPhraseFilterCopy = clone(oldMatchPhraseFilter, true); + + migrateFilter(oldMatchPhraseFilter, null); + + expect(isEqual(oldMatchPhraseFilter, oldMatchPhraseFilterCopy)).toBe(true); + }); + + it('should return the original filter if no migration is necessary', function() { + const originalFilter = { + match_all: {}, + } as MatchAllFilter; + const migratedFilter = migrateFilter(originalFilter, null); + + expect(migratedFilter).toBe(originalFilter); + expect(isEqual(migratedFilter, originalFilter)).toBe(true); + }); +}); diff --git a/src/plugins/data/common/es_query/es_query/migrate_filter.ts b/src/plugins/data/common/es_query/es_query/migrate_filter.ts new file mode 100644 index 0000000000000..258ab9e703131 --- /dev/null +++ b/src/plugins/data/common/es_query/es_query/migrate_filter.ts @@ -0,0 +1,65 @@ +/* + * 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 { get, omit } from 'lodash'; +import { getConvertedValueForField } from '../filters'; +import { Filter } from '../filters'; +import { IIndexPattern } from '../../index_patterns'; + +/** @deprecated + * see https://github.com/elastic/elasticsearch/pull/17508 + * */ +export interface DeprecatedMatchPhraseFilter extends Filter { + match: { + [field: string]: { + query: any; + type: 'phrase'; + }; + }; +} + +/** @deprecated + * see https://github.com/elastic/elasticsearch/pull/17508 + * */ +function isMatchPhraseFilter(filter: any): filter is DeprecatedMatchPhraseFilter { + const fieldName = filter.match && Object.keys(filter.match)[0]; + + return Boolean(fieldName && get(filter, ['match', fieldName, 'type']) === 'phrase'); +} + +export function migrateFilter(filter: Filter, indexPattern: IIndexPattern | null) { + if (isMatchPhraseFilter(filter)) { + const fieldName = Object.keys(filter.match)[0]; + const params: Record = get(filter, ['match', fieldName]); + if (indexPattern) { + const field = indexPattern.fields.find(f => f.name === fieldName); + + if (field) { + params.query = getConvertedValueForField(field, params.query); + } + } + return { + match_phrase: { + [fieldName]: omit(params, 'type'), + }, + }; + } + + return filter; +} diff --git a/src/plugins/data/common/es_query/filters/exists_filter.ts b/src/plugins/data/common/es_query/filters/exists_filter.ts index 1a404ca415117..a20a4f0634766 100644 --- a/src/plugins/data/common/es_query/filters/exists_filter.ts +++ b/src/plugins/data/common/es_query/filters/exists_filter.ts @@ -18,7 +18,7 @@ */ import { Filter, FilterMeta } from './meta_filter'; -import { IndexPattern, Field } from '../../types'; +import { IIndexPattern, IFieldType } from '../../index_patterns'; export type ExistsFilterMeta = FilterMeta; @@ -33,7 +33,7 @@ export type ExistsFilter = Filter & { export const isExistsFilter = (filter: any): filter is ExistsFilter => filter && filter.exists; -export const buildExistsFilter = (field: Field, indexPattern: IndexPattern) => { +export const buildExistsFilter = (field: IFieldType, indexPattern: IIndexPattern) => { return { meta: { index: indexPattern.id, diff --git a/src/plugins/data/common/es_query/filters/index.ts b/src/plugins/data/common/es_query/filters/index.ts index e28ce9ba74975..c19545eb83a06 100644 --- a/src/plugins/data/common/es_query/filters/index.ts +++ b/src/plugins/data/common/es_query/filters/index.ts @@ -17,6 +17,9 @@ * under the License. */ +import { omit, get } from 'lodash'; +import { Filter } from './meta_filter'; + export * from './custom_filter'; export * from './exists_filter'; export * from './geo_bounding_box_filter'; @@ -30,3 +33,12 @@ export * from './query_string_filter'; export * from './range_filter'; export * from './types'; + +/** + * Clean out any invalid attributes from the filters + * @param {object} filter The filter to clean + * @returns {object} + */ +export const cleanFilter = (filter: Filter): Filter => omit(filter, ['meta', '$state']); + +export const isFilterDisabled = (filter: Filter): boolean => get(filter, 'meta.disabled', false); diff --git a/src/plugins/data/common/es_query/filters/phrase_filter.test.ts b/src/plugins/data/common/es_query/filters/phrase_filter.test.ts index 250ec792fbb57..3c7d00a80fecf 100644 --- a/src/plugins/data/common/es_query/filters/phrase_filter.test.ts +++ b/src/plugins/data/common/es_query/filters/phrase_filter.test.ts @@ -18,16 +18,16 @@ */ import { buildInlineScriptForPhraseFilter, buildPhraseFilter } from './phrase_filter'; -import { IndexPattern } from '../../types'; -import { getField } from '../__tests__/fields_mock'; +import { getField } from '../../index_patterns/mocks'; +import { IIndexPattern } from '../../index_patterns'; describe('Phrase filter builder', () => { - let indexPattern: IndexPattern; + let indexPattern: IIndexPattern; beforeEach(() => { indexPattern = { id: 'id', - }; + } as IIndexPattern; }); it('should be a function', () => { diff --git a/src/plugins/data/common/es_query/filters/phrase_filter.ts b/src/plugins/data/common/es_query/filters/phrase_filter.ts index 35110c924fe61..8b8c5f8915269 100644 --- a/src/plugins/data/common/es_query/filters/phrase_filter.ts +++ b/src/plugins/data/common/es_query/filters/phrase_filter.ts @@ -19,7 +19,7 @@ import { get, isPlainObject } from 'lodash'; import { Filter, FilterMeta } from './meta_filter'; -import { IndexPattern, Field } from '../../types'; +import { IIndexPattern, IFieldType } from '../../index_patterns'; export type PhraseFilterMeta = FilterMeta & { params?: { @@ -51,7 +51,7 @@ export const isPhraseFilter = (filter: any): filter is PhraseFilter => { filter.query.match && Object.values(filter.query.match).find((params: any) => params.type === 'phrase'); - return !!(isMatchPhraseQuery || isDeprecatedMatchPhraseQuery); + return Boolean(isMatchPhraseQuery || isDeprecatedMatchPhraseQuery); }; export const isScriptedPhraseFilter = (filter: any): filter is PhraseFilter => @@ -69,9 +69,9 @@ export const getPhraseFilterValue = (filter: PhraseFilter): PhraseFilterValue => }; export const buildPhraseFilter = ( - field: Field, + field: IFieldType, value: any, - indexPattern: IndexPattern + indexPattern: IIndexPattern ): PhraseFilter => { const convertedValue = getConvertedValueForField(field, value); @@ -92,7 +92,7 @@ export const buildPhraseFilter = ( } }; -export const getPhraseScript = (field: Field, value: string) => { +export const getPhraseScript = (field: IFieldType, value: string) => { const convertedValue = getConvertedValueForField(field, value); const script = buildInlineScriptForPhraseFilter(field); @@ -110,7 +110,7 @@ export const getPhraseScript = (field: Field, value: string) => { // See https://github.com/elastic/elasticsearch/issues/20941 and https://github.com/elastic/kibana/issues/8677 // and https://github.com/elastic/elasticsearch/pull/22201 // for the reason behind this change. Aggs now return boolean buckets with a key of 1 or 0. -export const getConvertedValueForField = (field: Field, value: any) => { +export const getConvertedValueForField = (field: IFieldType, value: any) => { if (typeof value !== 'boolean' && field.type === 'boolean') { if ([1, 'true'].includes(value)) { return true; diff --git a/src/plugins/data/common/es_query/filters/phrases_filter.ts b/src/plugins/data/common/es_query/filters/phrases_filter.ts index e207a3ff5961b..f7164f0ad3c83 100644 --- a/src/plugins/data/common/es_query/filters/phrases_filter.ts +++ b/src/plugins/data/common/es_query/filters/phrases_filter.ts @@ -18,8 +18,9 @@ */ import { Filter, FilterMeta } from './meta_filter'; -import { Field, IndexPattern } from '../../types'; import { getPhraseScript } from './phrase_filter'; +import { FILTERS } from './index'; +import { IIndexPattern, IFieldType } from '../../index_patterns'; export type PhrasesFilterMeta = FilterMeta & { params: string[]; // The unformatted values @@ -31,16 +32,16 @@ export type PhrasesFilter = Filter & { }; export const isPhrasesFilter = (filter: any): filter is PhrasesFilter => - filter && filter.meta.type === 'phrases'; + filter && filter.meta.type === FILTERS.PHRASES; // Creates a filter where the given field matches one or more of the given values // params should be an array of values -export const buildPhrasesFilter = (field: Field, params: any, indexPattern: IndexPattern) => { +export const buildPhrasesFilter = (field: IFieldType, params: any, indexPattern: IIndexPattern) => { const index = indexPattern.id; - const type = 'phrases'; + const type = FILTERS.PHRASES; const key = field.name; - const format = (f: Field, value: any) => + const format = (f: IFieldType, value: any) => f && f.format && f.format.convert ? f.format.convert(value) : value; const value = params.map((v: any) => format(field, v)).join(', '); diff --git a/src/plugins/data/common/es_query/filters/query_string_filter.test.ts b/src/plugins/data/common/es_query/filters/query_string_filter.test.ts index 5a580db0c57b8..4fcb15ccac44a 100644 --- a/src/plugins/data/common/es_query/filters/query_string_filter.test.ts +++ b/src/plugins/data/common/es_query/filters/query_string_filter.test.ts @@ -18,26 +18,17 @@ */ import { buildQueryFilter } from './query_string_filter'; -import { IndexPattern } from '../../types'; describe('Phrase filter builder', () => { - let indexPattern: IndexPattern; - - beforeEach(() => { - indexPattern = { - id: 'id', - }; - }); - it('should be a function', () => { expect(typeof buildQueryFilter).toBe('function'); }); it('should return a query filter when passed a standard field', () => { - expect(buildQueryFilter({ foo: 'bar' }, indexPattern.id, '')).toEqual({ + expect(buildQueryFilter({ foo: 'bar' }, 'index', '')).toEqual({ meta: { alias: '', - index: 'id', + index: 'index', }, query: { foo: 'bar', diff --git a/src/plugins/data/common/es_query/filters/query_string_filter.ts b/src/plugins/data/common/es_query/filters/query_string_filter.ts index d2374162b195f..a0e563eca6334 100644 --- a/src/plugins/data/common/es_query/filters/query_string_filter.ts +++ b/src/plugins/data/common/es_query/filters/query_string_filter.ts @@ -18,7 +18,6 @@ */ import { Filter, FilterMeta } from './meta_filter'; -import { IndexPattern } from '../../types'; export type QueryStringFilterMeta = FilterMeta; @@ -35,11 +34,7 @@ export const isQueryStringFilter = (filter: any): filter is QueryStringFilter => filter && filter.query && filter.query.query_string; // Creates a filter corresponding to a raw Elasticsearch query DSL object -export const buildQueryFilter = ( - query: QueryStringFilter['query'], - index: IndexPattern, - alias: string -) => +export const buildQueryFilter = (query: QueryStringFilter['query'], index: string, alias: string) => ({ query, meta: { diff --git a/src/plugins/data/common/es_query/filters/range_filter.test.ts b/src/plugins/data/common/es_query/filters/range_filter.test.ts index 017bb8e9cb7c5..56b63018b5153 100644 --- a/src/plugins/data/common/es_query/filters/range_filter.test.ts +++ b/src/plugins/data/common/es_query/filters/range_filter.test.ts @@ -19,16 +19,16 @@ import { each } from 'lodash'; import { buildRangeFilter, RangeFilter } from './range_filter'; -import { IndexPattern, Field } from '../../types'; -import { getField } from '../__tests__/fields_mock'; +import { getField } from '../../index_patterns/mocks'; +import { IIndexPattern, IFieldType } from '../../index_patterns'; describe('Range filter builder', () => { - let indexPattern: IndexPattern; + let indexPattern: IIndexPattern; beforeEach(() => { indexPattern = { id: 'id', - }; + } as IIndexPattern; }); it('should be a function', () => { @@ -118,7 +118,7 @@ describe('Range filter builder', () => { }); describe('when given params where one side is infinite', () => { - let field: Field; + let field: IFieldType; let filter: RangeFilter; beforeEach(() => { @@ -148,7 +148,7 @@ describe('Range filter builder', () => { }); describe('when given params where both sides are infinite', () => { - let field: Field; + let field: IFieldType; let filter: RangeFilter; beforeEach(() => { diff --git a/src/plugins/data/common/es_query/filters/range_filter.ts b/src/plugins/data/common/es_query/filters/range_filter.ts index c2513a9dc0c5e..fa07b3e611fa7 100644 --- a/src/plugins/data/common/es_query/filters/range_filter.ts +++ b/src/plugins/data/common/es_query/filters/range_filter.ts @@ -18,7 +18,7 @@ */ import { map, reduce, mapValues, get, keys, pick } from 'lodash'; import { Filter, FilterMeta } from './meta_filter'; -import { Field, IndexPattern } from '../../types'; +import { IIndexPattern, IFieldType } from '../../index_patterns'; const OPERANDS_IN_RANGE = 2; @@ -84,18 +84,18 @@ export const isScriptedRangeFilter = (filter: any): filter is RangeFilter => { return hasRangeKeys(params); }; -const formatValue = (field: Field, params: any[]) => +const formatValue = (field: IFieldType, params: any[]) => map(params, (val: any, key: string) => get(operators, key) + format(field, val)).join(' '); -const format = (field: Field, value: any) => +const format = (field: IFieldType, value: any) => field && field.format && field.format.convert ? field.format.convert(value) : value; // Creates a filter where the value for the given field is in the given range // params should be an object containing `lt`, `lte`, `gt`, and/or `gte` export const buildRangeFilter = ( - field: Field, + field: IFieldType, params: RangeFilterParams, - indexPattern: IndexPattern, + indexPattern: IIndexPattern, formattedValue?: string ): RangeFilter => { const filter: any = { meta: { index: indexPattern.id, params: {} } }; @@ -139,7 +139,7 @@ export const buildRangeFilter = ( return filter as RangeFilter; }; -export const getRangeScript = (field: IndexPattern, params: RangeFilterParams) => { +export const getRangeScript = (field: IFieldType, params: RangeFilterParams) => { const knownParams = pick(params, (val, key: any) => key in operators); let script = map( knownParams, diff --git a/src/plugins/data/common/es_query/index.ts b/src/plugins/data/common/es_query/index.ts index 88e14a43cfaae..56eb45c4b1dca 100644 --- a/src/plugins/data/common/es_query/index.ts +++ b/src/plugins/data/common/es_query/index.ts @@ -16,6 +16,8 @@ * specific language governing permissions and limitations * under the License. */ +import * as esQuery from './es_query'; import * as esFilters from './filters'; +import * as utils from './utils'; -export { esFilters }; +export { esFilters, esQuery, utils }; diff --git a/packages/kbn-es-query/src/es_query/lucene_string_to_dsl.js b/src/plugins/data/common/es_query/utils/get_time_zone_from_settings.ts similarity index 78% rename from packages/kbn-es-query/src/es_query/lucene_string_to_dsl.js rename to src/plugins/data/common/es_query/utils/get_time_zone_from_settings.ts index 36ff621e8a694..303bd3547f2ff 100644 --- a/packages/kbn-es-query/src/es_query/lucene_string_to_dsl.js +++ b/src/plugins/data/common/es_query/utils/get_time_zone_from_settings.ts @@ -17,16 +17,10 @@ * under the License. */ -import _ from 'lodash'; +import moment from 'moment-timezone'; -export function luceneStringToDsl(query) { - if (!_.isString(query)) { - return query; - } +export function getTimeZoneFromSettings(dateFormatTZ: string) { + const detectedTimezone = moment.tz.guess(); - if (query.trim() === '') { - return { match_all: {} }; - } - - return { query_string: { query } }; + return dateFormatTZ === 'Browser' ? detectedTimezone : dateFormatTZ; } diff --git a/src/plugins/data/common/es_query/utils/index.ts b/src/plugins/data/common/es_query/utils/index.ts new file mode 100644 index 0000000000000..27f51c1f44cf2 --- /dev/null +++ b/src/plugins/data/common/es_query/utils/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './get_time_zone_from_settings'; diff --git a/src/plugins/data/common/field_formats/converters/color.test.ts b/src/plugins/data/common/field_formats/converters/color.test.ts index d3e1054f3db1f..b7fcbf61227eb 100644 --- a/src/plugins/data/common/field_formats/converters/color.test.ts +++ b/src/plugins/data/common/field_formats/converters/color.test.ts @@ -18,7 +18,7 @@ */ import { ColorFormat } from './color'; -import { HTML_CONTEXT_TYPE } from '../../index'; +import { HTML_CONTEXT_TYPE } from '../content_types'; describe('Color Format', () => { describe('field is a number', () => { diff --git a/src/plugins/data/common/field_formats/converters/url.test.ts b/src/plugins/data/common/field_formats/converters/url.test.ts index a194b499744a9..66307cefe08f7 100644 --- a/src/plugins/data/common/field_formats/converters/url.test.ts +++ b/src/plugins/data/common/field_formats/converters/url.test.ts @@ -18,7 +18,7 @@ */ import { UrlFormat } from './url'; -import { TEXT_CONTEXT_TYPE, HTML_CONTEXT_TYPE } from '../../index'; +import { TEXT_CONTEXT_TYPE, HTML_CONTEXT_TYPE } from '../content_types'; describe('UrlFormat', () => { test('outputs a simple tag by default', () => { diff --git a/src/plugins/data/common/index.ts b/src/plugins/data/common/index.ts index 42b5a03fcc926..f9bbeb5f4b3f3 100644 --- a/src/plugins/data/common/index.ts +++ b/src/plugins/data/common/index.ts @@ -20,6 +20,7 @@ export * from './query'; export * from './field_formats'; export * from './kbn_field_types'; +export * from './index_patterns'; export * from './es_query'; export * from './types'; diff --git a/src/plugins/data/common/es_query/__tests__/fields_mock.ts b/src/plugins/data/common/index_patterns/fields/fields.mocks.ts.ts similarity index 98% rename from src/plugins/data/common/es_query/__tests__/fields_mock.ts rename to src/plugins/data/common/index_patterns/fields/fields.mocks.ts.ts index 83fdf588af00c..c27ff42b1e9d2 100644 --- a/src/plugins/data/common/es_query/__tests__/fields_mock.ts +++ b/src/plugins/data/common/index_patterns/fields/fields.mocks.ts.ts @@ -16,8 +16,9 @@ * specific language governing permissions and limitations * under the License. */ +import { IFieldType } from './types'; -export const fields = [ +export const fields: IFieldType[] = [ { name: 'bytes', type: 'number', @@ -317,4 +318,4 @@ export const fields = [ }, ]; -export const getField = (name: string) => fields.find(field => field.name === name); +export const getField = (name: string) => fields.find(field => field.name === name) as IFieldType; diff --git a/src/plugins/data/common/index_patterns/fields/index.ts b/src/plugins/data/common/index_patterns/fields/index.ts new file mode 100644 index 0000000000000..d8f7b5091eb8f --- /dev/null +++ b/src/plugins/data/common/index_patterns/fields/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './types'; diff --git a/src/plugins/data/common/index_patterns/fields/types.ts b/src/plugins/data/common/index_patterns/fields/types.ts new file mode 100644 index 0000000000000..c336472a1e7d6 --- /dev/null +++ b/src/plugins/data/common/index_patterns/fields/types.ts @@ -0,0 +1,44 @@ +/* + * 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 interface IFieldSubType { + multi?: { parent: string }; + nested?: { path: string }; +} + +export interface IFieldType { + name: string; + type: string; + script?: string; + lang?: string; + count?: number; + // esTypes might be undefined on old index patterns that have not been refreshed since we added + // this prop. It is also undefined on scripted fields. + esTypes?: string[]; + aggregatable?: boolean; + filterable?: boolean; + searchable?: boolean; + sortable?: boolean; + visualizable?: boolean; + readFromDocValues?: boolean; + scripted?: boolean; + subType?: IFieldSubType; + displayName?: string; + format?: any; +} diff --git a/src/plugins/data/common/index_patterns/index.ts b/src/plugins/data/common/index_patterns/index.ts new file mode 100644 index 0000000000000..d26587efccc0f --- /dev/null +++ b/src/plugins/data/common/index_patterns/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 * from './fields'; +export * from './types'; diff --git a/src/plugins/data/common/index_patterns/mocks.ts b/src/plugins/data/common/index_patterns/mocks.ts new file mode 100644 index 0000000000000..6036c08fa2b10 --- /dev/null +++ b/src/plugins/data/common/index_patterns/mocks.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './fields/fields.mocks.ts'; diff --git a/src/plugins/data/common/index_patterns/types.ts b/src/plugins/data/common/index_patterns/types.ts new file mode 100644 index 0000000000000..0a1ba48342244 --- /dev/null +++ b/src/plugins/data/common/index_patterns/types.ts @@ -0,0 +1,35 @@ +/* + * 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 { IFieldType } from './fields'; + +export interface IIndexPattern { + fields: IFieldType[]; + title: string; + id?: string; + type?: string; + timeFieldName?: string; + fieldFormatMap?: Record< + string, + { + id: string; + params: unknown; + } + >; +} diff --git a/src/plugins/data/common/types.ts b/src/plugins/data/common/types.ts index ec8d8b006317f..bc0d0c323bafa 100644 --- a/src/plugins/data/common/types.ts +++ b/src/plugins/data/common/types.ts @@ -21,10 +21,4 @@ export * from './field_formats/types'; export * from './timefilter/types'; export * from './query/types'; export * from './kbn_field_types/types'; - -// We can't import the real types from the data plugin, so need to either duplicate -// them here or figure out another solution, perhaps housing them in this package -// will be replaces after Fieds / IndexPattern will be moved into new platform -export type Field = any; -export type IndexPattern = any; -export type StaticIndexPattern = any; +export * from './index_patterns/types'; diff --git a/src/plugins/data/public/autocomplete_provider/types.ts b/src/plugins/data/public/autocomplete_provider/types.ts index d838e54e9ead4..3d34b1bc4a2d2 100644 --- a/src/plugins/data/public/autocomplete_provider/types.ts +++ b/src/plugins/data/public/autocomplete_provider/types.ts @@ -18,7 +18,7 @@ */ import { AutocompleteProviderRegister } from '.'; -import { Field, StaticIndexPattern } from '..'; +import { IIndexPattern, IFieldType } from '../../common'; export type AutocompletePublicPluginSetup = Pick< AutocompleteProviderRegister, @@ -31,7 +31,7 @@ export type AutocompleteProvider = (args: { config: { get(configKey: string): any; }; - indexPatterns: StaticIndexPattern[]; + indexPatterns: IIndexPattern[]; boolFilter?: any; }) => GetSuggestions; @@ -67,5 +67,5 @@ interface BasicAutocompleteSuggestion { export type FieldAutocompleteSuggestion = BasicAutocompleteSuggestion & { type: 'field'; - field: Field; + field: IFieldType; }; diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index 32153df69f367..4477c6defbc81 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -25,11 +25,10 @@ export function plugin(initializerContext: PluginInitializerContext) { } export { DataPublicPlugin as Plugin }; -export { DataPublicPluginSetup, DataPublicPluginStart } from './types'; export * from '../common'; -export * from './autocomplete_provider'; +export * from './autocomplete_provider'; export * from './types'; export { IRequestTypesMap, IResponseTypesMap } from './search'; diff --git a/src/plugins/data/public/index_patterns/field.stub.ts b/src/plugins/data/public/index_patterns/field.stub.ts index 315894cd212c4..2e94f4b45f400 100644 --- a/src/plugins/data/public/index_patterns/field.stub.ts +++ b/src/plugins/data/public/index_patterns/field.stub.ts @@ -17,9 +17,9 @@ * under the License. */ -import { Field } from '../../common'; +import { IFieldType } from '../../../../plugins/data/public'; -export const stubFields: Field[] = [ +export const stubFields: IFieldType[] = [ { name: 'machine.os', esTypes: ['text'], diff --git a/src/plugins/data/public/index_patterns/index_pattern.stub.ts b/src/plugins/data/public/index_patterns/index_pattern.stub.ts index 444e65cd0cd4b..3d5151752a080 100644 --- a/src/plugins/data/public/index_patterns/index_pattern.stub.ts +++ b/src/plugins/data/public/index_patterns/index_pattern.stub.ts @@ -17,10 +17,10 @@ * under the License. */ -import { IndexPattern } from '../../common'; +import { IIndexPattern } from '../../common'; import { stubFields } from './field.stub'; -export const stubIndexPattern: IndexPattern = { +export const stubIndexPattern: IIndexPattern = { id: 'logstash-*', fields: stubFields, title: 'logstash-*', diff --git a/src/plugins/data/public/query/filter_manager/filter_manager.test.ts b/src/plugins/data/public/query/filter_manager/filter_manager.test.ts index 33f9c4ccd795d..7857e2989bda6 100644 --- a/src/plugins/data/public/query/filter_manager/filter_manager.test.ts +++ b/src/plugins/data/public/query/filter_manager/filter_manager.test.ts @@ -24,7 +24,7 @@ import { Subscription } from 'rxjs'; import { FilterManager } from './filter_manager'; import { getFilter } from './test_helpers/get_stub_filter'; import { getFiltersArray } from './test_helpers/get_filters_array'; -import { esFilters } from '../../../common/es_query'; +import { esFilters } from '../../../common'; import { coreMock } from '../../../../../core/public/mocks'; const setupMock = coreMock.createSetup(); diff --git a/src/plugins/data/public/query/filter_manager/filter_manager.ts b/src/plugins/data/public/query/filter_manager/filter_manager.ts index 06e2b77dca238..feab75ed7457f 100644 --- a/src/plugins/data/public/query/filter_manager/filter_manager.ts +++ b/src/plugins/data/public/query/filter_manager/filter_manager.ts @@ -27,7 +27,7 @@ import { mapAndFlattenFilters } from './lib/map_and_flatten_filters'; import { uniqFilters } from './lib/uniq_filters'; import { onlyDisabledFiltersChanged } from './lib/only_disabled'; import { PartitionedFilters } from './types'; -import { esFilters } from '../../../common/es_query'; +import { esFilters } from '../../../common'; export class FilterManager { private filters: esFilters.Filter[] = []; diff --git a/src/plugins/data/public/query/filter_manager/lib/compare_filters.test.ts b/src/plugins/data/public/query/filter_manager/lib/compare_filters.test.ts index 6bde6b528d07b..34fd662c4ba46 100644 --- a/src/plugins/data/public/query/filter_manager/lib/compare_filters.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/compare_filters.test.ts @@ -18,7 +18,7 @@ */ import { compareFilters } from './compare_filters'; -import { esFilters } from '../../../../common/es_query'; +import { esFilters } from '../../../../common'; describe('filter manager utilities', () => { describe('compare filters', () => { diff --git a/src/plugins/data/public/query/filter_manager/lib/compare_filters.ts b/src/plugins/data/public/query/filter_manager/lib/compare_filters.ts index 2a7cbe6e3303b..9b171ab0aacb2 100644 --- a/src/plugins/data/public/query/filter_manager/lib/compare_filters.ts +++ b/src/plugins/data/public/query/filter_manager/lib/compare_filters.ts @@ -18,7 +18,7 @@ */ import { defaults, isEqual, omit } from 'lodash'; -import { esFilters } from '../../../../common/es_query'; +import { esFilters } from '../../../../common'; /** * Compare two filters to see if they match diff --git a/src/plugins/data/public/query/filter_manager/lib/dedup_filters.test.ts b/src/plugins/data/public/query/filter_manager/lib/dedup_filters.test.ts index 9b493add0886c..ebad5ad6b02c5 100644 --- a/src/plugins/data/public/query/filter_manager/lib/dedup_filters.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/dedup_filters.test.ts @@ -18,13 +18,26 @@ */ import { dedupFilters } from './dedup_filters'; -import { esFilters } from '../../../../common/es_query'; +import { esFilters, IIndexPattern, IFieldType } from '../../../../common'; describe('filter manager utilities', () => { + let indexPattern: IIndexPattern; + + beforeEach(() => { + indexPattern = { + id: 'index', + } as IIndexPattern; + }); + describe('dedupFilters(existing, filters)', () => { test('should return only filters which are not in the existing', () => { const existing: esFilters.Filter[] = [ - esFilters.buildRangeFilter({ name: 'bytes' }, { from: 0, to: 1024 }, 'index', ''), + esFilters.buildRangeFilter( + { name: 'bytes' } as IFieldType, + { from: 0, to: 1024 }, + indexPattern, + '' + ), esFilters.buildQueryFilter( { match: { _term: { query: 'apache', type: 'phrase' } } }, 'index', @@ -32,7 +45,12 @@ describe('filter manager utilities', () => { ), ]; const filters: esFilters.Filter[] = [ - esFilters.buildRangeFilter({ name: 'bytes' }, { from: 1024, to: 2048 }, 'index', ''), + esFilters.buildRangeFilter( + { name: 'bytes' } as IFieldType, + { from: 1024, to: 2048 }, + indexPattern, + '' + ), esFilters.buildQueryFilter( { match: { _term: { query: 'apache', type: 'phrase' } } }, 'index', @@ -47,7 +65,12 @@ describe('filter manager utilities', () => { test('should ignore the disabled attribute when comparing ', () => { const existing: esFilters.Filter[] = [ - esFilters.buildRangeFilter({ name: 'bytes' }, { from: 0, to: 1024 }, 'index', ''), + esFilters.buildRangeFilter( + { name: 'bytes' } as IFieldType, + { from: 0, to: 1024 }, + indexPattern, + '' + ), { ...esFilters.buildQueryFilter( { match: { _term: { query: 'apache', type: 'phrase' } } }, @@ -58,7 +81,12 @@ describe('filter manager utilities', () => { }, ]; const filters: esFilters.Filter[] = [ - esFilters.buildRangeFilter({ name: 'bytes' }, { from: 1024, to: 2048 }, 'index', ''), + esFilters.buildRangeFilter( + { name: 'bytes' } as IFieldType, + { from: 1024, to: 2048 }, + indexPattern, + '' + ), esFilters.buildQueryFilter( { match: { _term: { query: 'apache', type: 'phrase' } } }, 'index1', @@ -73,7 +101,12 @@ describe('filter manager utilities', () => { test('should ignore $state attribute', () => { const existing: esFilters.Filter[] = [ - esFilters.buildRangeFilter({ name: 'bytes' }, { from: 0, to: 1024 }, 'index', ''), + esFilters.buildRangeFilter( + { name: 'bytes' } as IFieldType, + { from: 0, to: 1024 }, + indexPattern, + '' + ), { ...esFilters.buildQueryFilter( { match: { _term: { query: 'apache', type: 'phrase' } } }, @@ -84,7 +117,12 @@ describe('filter manager utilities', () => { }, ]; const filters: esFilters.Filter[] = [ - esFilters.buildRangeFilter({ name: 'bytes' }, { from: 1024, to: 2048 }, 'index', ''), + esFilters.buildRangeFilter( + { name: 'bytes' } as IFieldType, + { from: 1024, to: 2048 }, + indexPattern, + '' + ), { ...esFilters.buildQueryFilter( { match: { _term: { query: 'apache', type: 'phrase' } } }, diff --git a/src/plugins/data/public/query/filter_manager/lib/dedup_filters.ts b/src/plugins/data/public/query/filter_manager/lib/dedup_filters.ts index 6d6f49cb5e833..6dae14f480b4f 100644 --- a/src/plugins/data/public/query/filter_manager/lib/dedup_filters.ts +++ b/src/plugins/data/public/query/filter_manager/lib/dedup_filters.ts @@ -19,7 +19,7 @@ import { filter, find } from 'lodash'; import { compareFilters } from './compare_filters'; -import { esFilters } from '../../../../../../plugins/data/public'; +import { esFilters } from '../../../../common'; /** * Combine 2 filter collections, removing duplicates diff --git a/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts b/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts index 46cf0fd9c111e..b8de08fc3a610 100644 --- a/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts @@ -19,13 +19,14 @@ import { generateFilters } from './generate_filters'; import { FilterManager } from '../filter_manager'; -import { esFilters } from '../../..'; + +import { esFilters, IFieldType, IIndexPattern } from '../../../../common'; const INDEX_NAME = 'my-index'; const EXISTS_FIELD_NAME = '_exists_'; const FIELD = { name: 'my-field', -}; +} as IFieldType; const PHRASE_VALUE = 'my-value'; describe('Generate filters', () => { @@ -70,7 +71,7 @@ describe('Generate filters', () => { }); it('should update and re-enable EXISTING exists filter', () => { - const filter = esFilters.buildExistsFilter(FIELD, { id: INDEX_NAME }); + const filter = esFilters.buildExistsFilter(FIELD, { id: INDEX_NAME } as IIndexPattern); filter.meta.disabled = true; filtersArray.push(filter); diff --git a/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts b/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts index 5c4cdc2717338..42607843df3ba 100644 --- a/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts +++ b/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts @@ -18,7 +18,8 @@ */ import _ from 'lodash'; -import { FilterManager, esFilters, Field } from '../../..'; +import { esFilters, IFieldType, IIndexPattern } from '../../../../common'; +import { FilterManager } from '../filter_manager'; function getExistingFilter( appFilters: esFilters.Filter[], @@ -67,17 +68,17 @@ function updateExistingFilter(existingFilter: esFilters.Filter, negate: boolean) */ export function generateFilters( filterManager: FilterManager, - field: Field | string, + field: IFieldType | string, values: any, operation: string, index: string ): esFilters.Filter[] { values = Array.isArray(values) ? values : [values]; - const fieldObj = _.isObject(field) + const fieldObj = (_.isObject(field) ? field : { name: field, - }; + }) as IFieldType; const fieldName = fieldObj.name; const newFilters: esFilters.Filter[] = []; const appFilters = filterManager.getAppFilters(); @@ -92,7 +93,8 @@ export function generateFilters( updateExistingFilter(existing, negate); filter = existing; } else { - const tmpIndexPattern = { id: index }; + const tmpIndexPattern = { id: index } as IIndexPattern; + switch (fieldName) { case '_exists_': filter = esFilters.buildExistsFilter(fieldObj, tmpIndexPattern); diff --git a/src/plugins/data/public/query/filter_manager/lib/generate_mapping_chain.test.ts b/src/plugins/data/public/query/filter_manager/lib/generate_mapping_chain.test.ts index dfe3a093c6614..9e386bdc7c80d 100644 --- a/src/plugins/data/public/query/filter_manager/lib/generate_mapping_chain.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/generate_mapping_chain.test.ts @@ -19,7 +19,7 @@ import sinon from 'sinon'; import { generateMappingChain } from './generate_mapping_chain'; -import { esFilters } from '../../../../../../plugins/data/public'; +import { esFilters } from '../../../../common'; describe('filter manager utilities', () => { let mapping: any; diff --git a/src/plugins/data/public/query/filter_manager/lib/generate_mapping_chain.ts b/src/plugins/data/public/query/filter_manager/lib/generate_mapping_chain.ts index b6764389e0db9..1af8482a96e0f 100644 --- a/src/plugins/data/public/query/filter_manager/lib/generate_mapping_chain.ts +++ b/src/plugins/data/public/query/filter_manager/lib/generate_mapping_chain.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { esFilters } from '../../../../../../plugins/data/public'; +import { esFilters } from '../../../../common'; const noop = () => { throw new Error('No mappings have been found for filter.'); diff --git a/src/plugins/data/public/query/filter_manager/lib/map_and_flatten_filters.test.ts b/src/plugins/data/public/query/filter_manager/lib/map_and_flatten_filters.test.ts index 9a0d0d93698f6..3190b6777a9e1 100644 --- a/src/plugins/data/public/query/filter_manager/lib/map_and_flatten_filters.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/map_and_flatten_filters.test.ts @@ -18,7 +18,7 @@ */ import { mapAndFlattenFilters } from './map_and_flatten_filters'; -import { esFilters } from '../../../../../data/public'; +import { esFilters } from '../../../../common'; describe('filter manager utilities', () => { describe('mapAndFlattenFilters()', () => { diff --git a/src/plugins/data/public/query/filter_manager/lib/map_and_flatten_filters.ts b/src/plugins/data/public/query/filter_manager/lib/map_and_flatten_filters.ts index 5326d59f3e32b..28b5e8d151ff6 100644 --- a/src/plugins/data/public/query/filter_manager/lib/map_and_flatten_filters.ts +++ b/src/plugins/data/public/query/filter_manager/lib/map_and_flatten_filters.ts @@ -19,7 +19,7 @@ import { compact, flatten } from 'lodash'; import { mapFilter } from './map_filter'; -import { esFilters } from '../../../../../data/public'; +import { esFilters } from '../../../../common'; export const mapAndFlattenFilters = (filters: esFilters.Filter[]) => { return compact(flatten(filters)).map((item: esFilters.Filter) => mapFilter(item)); diff --git a/src/plugins/data/public/query/filter_manager/lib/map_filter.test.ts b/src/plugins/data/public/query/filter_manager/lib/map_filter.test.ts index 0d115125451ee..9df07718d5bcb 100644 --- a/src/plugins/data/public/query/filter_manager/lib/map_filter.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/map_filter.test.ts @@ -18,7 +18,7 @@ */ import { mapFilter } from './map_filter'; -import { esFilters } from '../../../../../data/public'; +import { esFilters } from '../../../../common'; describe('filter manager utilities', () => { function getDisplayName(filter: esFilters.Filter) { diff --git a/src/plugins/data/public/query/filter_manager/lib/map_filter.ts b/src/plugins/data/public/query/filter_manager/lib/map_filter.ts index 2dc855caabfd3..a68eafe6bf1c2 100644 --- a/src/plugins/data/public/query/filter_manager/lib/map_filter.ts +++ b/src/plugins/data/public/query/filter_manager/lib/map_filter.ts @@ -30,7 +30,7 @@ import { mapGeoBoundingBox } from './mappers/map_geo_bounding_box'; import { mapGeoPolygon } from './mappers/map_geo_polygon'; import { mapDefault } from './mappers/map_default'; import { generateMappingChain } from './generate_mapping_chain'; -import { esFilters } from '../../../../../data/public'; +import { esFilters } from '../../../../common'; export function mapFilter(filter: esFilters.Filter) { /** Mappers **/ diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_default.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_default.test.ts index f10766901e5b7..f6baaa9218d74 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_default.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_default.test.ts @@ -18,7 +18,7 @@ */ import { mapDefault } from './map_default'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; describe('filter manager utilities', () => { describe('mapDefault()', () => { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_default.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_default.ts index fd84c5c742589..3fee6a063be5a 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_default.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_default.ts @@ -18,7 +18,7 @@ */ import { find, keys, get } from 'lodash'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; export const mapDefault = (filter: esFilters.Filter) => { const metaProperty = /(^\$|meta)/; diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.test.ts index ff0ed4f4e4d94..2f0ab136bc59f 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.test.ts @@ -19,12 +19,20 @@ import { mapExists } from './map_exists'; import { mapQueryString } from './map_query_string'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters, IIndexPattern, IFieldType } from '../../../../../common'; describe('filter manager utilities', () => { describe('mapExists()', () => { + let indexPattern: IIndexPattern; + + beforeEach(() => { + indexPattern = { + id: 'index', + } as IIndexPattern; + }); + test('should return the key and value for matching filters', async () => { - const filter = esFilters.buildExistsFilter({ name: '_type' }, 'index'); + const filter = esFilters.buildExistsFilter({ name: '_type' } as IFieldType, indexPattern); const result = mapExists(filter); expect(result).toHaveProperty('key', '_type'); diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.ts index 63665bdd88ccb..38f9b1554c5c8 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.ts @@ -18,7 +18,7 @@ */ import { get } from 'lodash'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; export const mapExists = (filter: esFilters.Filter) => { if (esFilters.isExistsFilter(filter)) { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_bounding_box.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_bounding_box.test.ts index 5fca4a652bad8..322b086c2cf49 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_bounding_box.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_bounding_box.test.ts @@ -18,7 +18,7 @@ */ import { mapGeoBoundingBox } from './map_geo_bounding_box'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; describe('filter manager utilities', () => { describe('mapGeoBoundingBox()', () => { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_bounding_box.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_bounding_box.ts index 091e9a3f34000..be63d2de5b0df 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_bounding_box.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_bounding_box.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; const getFormattedValueFn = (params: any) => { return (formatter?: esFilters.FilterValueFormatter) => { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_polygon.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_polygon.test.ts index 1847296016c73..2713f0fd17734 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_polygon.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_polygon.test.ts @@ -18,7 +18,7 @@ */ import { mapGeoPolygon } from './map_geo_polygon'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; describe('filter manager utilities', () => { let filter: esFilters.GeoPolygonFilter; diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_polygon.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_polygon.ts index a7881b4a145a1..8cca92a81cb5f 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_polygon.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_polygon.ts @@ -17,7 +17,7 @@ * under the License. */ -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; const POINTS_SEPARATOR = ', '; diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_match_all.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_match_all.test.ts index 4fc6d0b492414..4d6bba6429b47 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_match_all.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_match_all.test.ts @@ -18,7 +18,7 @@ */ import { mapMatchAll } from './map_match_all'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; describe('filter_manager/lib', () => { describe('mapMatchAll()', () => { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_match_all.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_match_all.ts index 4e93b1d41e9a8..9a4ea8430a305 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_match_all.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_match_all.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; export const mapMatchAll = (filter: esFilters.Filter) => { if (esFilters.isMatchAllFilter(filter)) { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_missing.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_missing.test.ts index 1847eb37ca42f..faf4b54989e20 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_missing.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_missing.test.ts @@ -18,7 +18,7 @@ */ import { mapMissing } from './map_missing'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; describe('filter manager utilities', () => { describe('mapMissing()', () => { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_missing.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_missing.ts index 51dee89ad884b..a1b6474365f40 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_missing.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_missing.ts @@ -17,7 +17,7 @@ * under the License. */ -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; export const mapMissing = (filter: esFilters.Filter) => { if (esFilters.isMissingFilter(filter)) { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.test.ts index 05372d37264b0..5150b32f118ae 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.test.ts @@ -17,7 +17,7 @@ * under the License. */ import { mapPhrase } from './map_phrase'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; describe('filter manager utilities', () => { describe('mapPhrase()', () => { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts index b6e9c2007db97..ae7701bf3a501 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts @@ -18,7 +18,7 @@ */ import { get } from 'lodash'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; const getScriptedPhraseValue = (filter: esFilters.PhraseFilter) => get(filter, ['script', 'script', 'params', 'value']); diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrases.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrases.ts index 7240d87d02b5a..f8f2aba1309b7 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrases.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrases.ts @@ -17,7 +17,7 @@ * under the License. */ -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; export const mapPhrases = (filter: esFilters.Filter) => { if (!esFilters.isPhrasesFilter(filter)) { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_query_string.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_query_string.test.ts index c60e7d3454fe0..c65bc00b7df61 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_query_string.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_query_string.test.ts @@ -18,7 +18,7 @@ */ import { mapQueryString } from './map_query_string'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; describe('filter manager utilities', () => { describe('mapQueryString()', () => { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_query_string.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_query_string.ts index 20c3555639a3e..e8e4e68318973 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_query_string.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_query_string.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; export const mapQueryString = (filter: esFilters.Filter) => { if (esFilters.isQueryStringFilter(filter)) { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.test.ts index c0d5773d6f2c1..2d312351c0f31 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.test.ts @@ -18,7 +18,7 @@ */ import { mapRange } from './map_range'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; describe('filter manager utilities', () => { describe('mapRange()', () => { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.ts index 51fb970f5f03e..affc8e6343076 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.ts @@ -18,7 +18,7 @@ */ import { get, has } from 'lodash'; -import { esFilters } from '../../../../../common/es_query'; +import { esFilters } from '../../../../../common'; const getFormattedValueFn = (left: any, right: any) => { return (formatter?: esFilters.FilterValueFormatter) => { diff --git a/src/plugins/data/public/query/filter_manager/lib/only_disabled.test.ts b/src/plugins/data/public/query/filter_manager/lib/only_disabled.test.ts index b9731797c9ee3..a9863696d47cd 100644 --- a/src/plugins/data/public/query/filter_manager/lib/only_disabled.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/only_disabled.test.ts @@ -18,7 +18,7 @@ */ import { onlyDisabledFiltersChanged } from './only_disabled'; -import { esFilters } from '../../../../../data/public'; +import { esFilters } from '../../../../common'; describe('filter manager utilities', () => { describe('onlyDisabledFiltersChanged()', () => { diff --git a/src/plugins/data/public/query/filter_manager/lib/only_disabled.ts b/src/plugins/data/public/query/filter_manager/lib/only_disabled.ts index 0fb6894a297a1..c040d2f2960c7 100644 --- a/src/plugins/data/public/query/filter_manager/lib/only_disabled.ts +++ b/src/plugins/data/public/query/filter_manager/lib/only_disabled.ts @@ -18,7 +18,7 @@ */ import { filter, isEqual } from 'lodash'; -import { esFilters } from '../../../../../../plugins/data/public'; +import { esFilters } from '../../../../common'; const isEnabled = (f: esFilters.Filter) => f && f.meta && !f.meta.disabled; diff --git a/src/plugins/data/public/query/filter_manager/lib/uniq_filters.test.ts b/src/plugins/data/public/query/filter_manager/lib/uniq_filters.test.ts index 08eeabc1497e3..f71ac2940f32b 100644 --- a/src/plugins/data/public/query/filter_manager/lib/uniq_filters.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/uniq_filters.test.ts @@ -18,7 +18,7 @@ */ import { uniqFilters } from './uniq_filters'; -import { esFilters } from '../../../../../data/public'; +import { esFilters } from '../../../../common'; describe('filter manager utilities', () => { describe('niqFilter', () => { diff --git a/src/plugins/data/public/query/filter_manager/lib/uniq_filters.ts b/src/plugins/data/public/query/filter_manager/lib/uniq_filters.ts index e96c52e6db3de..b6001d698c5f1 100644 --- a/src/plugins/data/public/query/filter_manager/lib/uniq_filters.ts +++ b/src/plugins/data/public/query/filter_manager/lib/uniq_filters.ts @@ -18,7 +18,7 @@ */ import { each, union } from 'lodash'; import { dedupFilters } from './dedup_filters'; -import { esFilters } from '../../../../../data/public'; +import { esFilters } from '../../../../common'; /** * Remove duplicate filters from an array of filters diff --git a/src/plugins/data/public/query/filter_manager/test_helpers/get_filters_array.ts b/src/plugins/data/public/query/filter_manager/test_helpers/get_filters_array.ts index aa047647c5751..c5f0b11ce13f8 100644 --- a/src/plugins/data/public/query/filter_manager/test_helpers/get_filters_array.ts +++ b/src/plugins/data/public/query/filter_manager/test_helpers/get_filters_array.ts @@ -17,7 +17,7 @@ * under the License. */ -import { esFilters } from '../../../../../../plugins/data/public'; +import { esFilters } from '../../../../common'; export function getFiltersArray(): esFilters.Filter[] { return [ diff --git a/src/plugins/data/public/query/filter_manager/test_helpers/get_stub_filter.ts b/src/plugins/data/public/query/filter_manager/test_helpers/get_stub_filter.ts index adc72c961b08b..a531ce7e03984 100644 --- a/src/plugins/data/public/query/filter_manager/test_helpers/get_stub_filter.ts +++ b/src/plugins/data/public/query/filter_manager/test_helpers/get_stub_filter.ts @@ -17,7 +17,7 @@ * under the License. */ -import { esFilters } from '../../../../../../plugins/data/public'; +import { esFilters } from '../../../../common'; export function getFilter( store: esFilters.FilterStateStore, diff --git a/src/plugins/data/public/query/filter_manager/types.ts b/src/plugins/data/public/query/filter_manager/types.ts index 0b3dbca2d6e0a..0f74a243ca91a 100644 --- a/src/plugins/data/public/query/filter_manager/types.ts +++ b/src/plugins/data/public/query/filter_manager/types.ts @@ -17,7 +17,7 @@ * under the License. */ -import { esFilters } from '../../../../../plugins/data/public'; +import { esFilters } from '../../../common'; export interface PartitionedFilters { globalFilters: esFilters.Filter[]; diff --git a/src/plugins/data/public/query/timefilter/get_time.ts b/src/plugins/data/public/query/timefilter/get_time.ts index 55ee6527fbb1a..41ad1a49af0ff 100644 --- a/src/plugins/data/public/query/timefilter/get_time.ts +++ b/src/plugins/data/public/query/timefilter/get_time.ts @@ -18,7 +18,7 @@ */ import dateMath from '@elastic/datemath'; -import { TimeRange } from 'src/plugins/data/public'; +import { TimeRange } from '../../../common'; // TODO: remove this import { IndexPattern, Field } from '../../../../../legacy/core_plugins/data/public/index_patterns'; diff --git a/src/plugins/data/public/query/timefilter/lib/change_time_filter.test.ts b/src/plugins/data/public/query/timefilter/lib/change_time_filter.test.ts index df3e33060b01f..62805cde15936 100644 --- a/src/plugins/data/public/query/timefilter/lib/change_time_filter.test.ts +++ b/src/plugins/data/public/query/timefilter/lib/change_time_filter.test.ts @@ -17,9 +17,8 @@ * under the License. */ import { changeTimeFilter } from './change_time_filter'; -import { TimeRange } from 'src/plugins/data/public'; import { timefilterServiceMock } from '../timefilter_service.mock'; -import { esFilters } from '../../../../../../plugins/data/public'; +import { TimeRange, esFilters } from '../../../../common'; const timefilterMock = timefilterServiceMock.createSetupContract(); const timefilter = timefilterMock.timefilter; diff --git a/src/plugins/data/public/query/timefilter/lib/change_time_filter.ts b/src/plugins/data/public/query/timefilter/lib/change_time_filter.ts index 7943aab3c151f..cae464f1449bc 100644 --- a/src/plugins/data/public/query/timefilter/lib/change_time_filter.ts +++ b/src/plugins/data/public/query/timefilter/lib/change_time_filter.ts @@ -19,8 +19,8 @@ import moment from 'moment'; import { keys } from 'lodash'; -import { TimefilterContract } from '../timefilter'; -import { esFilters } from '../../../../../../plugins/data/public'; +import { TimefilterContract } from '../../timefilter'; +import { esFilters } from '../../../../common'; export function convertRangeFilterToTimeRange(filter: esFilters.RangeFilter) { const key = keys(filter.range)[0]; diff --git a/src/plugins/data/public/query/timefilter/lib/diff_time_picker_vals.ts b/src/plugins/data/public/query/timefilter/lib/diff_time_picker_vals.ts index 27da80661dbce..850c87635be9c 100644 --- a/src/plugins/data/public/query/timefilter/lib/diff_time_picker_vals.ts +++ b/src/plugins/data/public/query/timefilter/lib/diff_time_picker_vals.ts @@ -19,7 +19,7 @@ import _ from 'lodash'; -import { RefreshInterval } from 'src/plugins/data/public'; +import { RefreshInterval } from '../../../../common'; import { InputTimeRange } from '../types'; const valueOf = function(o: any) { diff --git a/src/plugins/data/public/query/timefilter/lib/extract_time_filter.test.ts b/src/plugins/data/public/query/timefilter/lib/extract_time_filter.test.ts index 981c50844c4f3..d371f4587d2b8 100644 --- a/src/plugins/data/public/query/timefilter/lib/extract_time_filter.test.ts +++ b/src/plugins/data/public/query/timefilter/lib/extract_time_filter.test.ts @@ -18,9 +18,17 @@ */ import { extractTimeFilter } from './extract_time_filter'; -import { esFilters } from '../../../../../../plugins/data/public'; +import { esFilters, IIndexPattern, IFieldType } from '../../../../common'; describe('filter manager utilities', () => { + let indexPattern: IIndexPattern; + + beforeEach(() => { + indexPattern = { + id: 'logstash-*', + } as IIndexPattern; + }); + describe('extractTimeFilter()', () => { test('should detect timeFilter', async () => { const filters: esFilters.Filter[] = [ @@ -30,9 +38,9 @@ describe('filter manager utilities', () => { '' ), esFilters.buildRangeFilter( - { name: 'time' }, + { name: 'time' } as IFieldType, { gt: 1388559600000, lt: 1388646000000 }, - 'logstash-*' + indexPattern ), ]; const result = await extractTimeFilter('time', filters); @@ -48,7 +56,12 @@ describe('filter manager utilities', () => { 'logstash-*', '' ), - esFilters.buildRangeFilter({ name: '@timestamp' }, { from: 1, to: 2 }, 'logstash-*', ''), + esFilters.buildRangeFilter( + { name: '@timestamp' } as IFieldType, + { from: 1, to: 2 }, + indexPattern, + '' + ), ]; const result = await extractTimeFilter('time', filters); @@ -63,7 +76,7 @@ describe('filter manager utilities', () => { 'logstash-*', '' ), - esFilters.buildPhraseFilter({ name: 'time' }, 'banana', 'logstash-*'), + esFilters.buildPhraseFilter({ name: 'time' } as IFieldType, 'banana', indexPattern), ]; const result = await extractTimeFilter('time', filters); diff --git a/src/plugins/data/public/query/timefilter/lib/extract_time_filter.ts b/src/plugins/data/public/query/timefilter/lib/extract_time_filter.ts index 4281610cb63e4..af2e8be65fb62 100644 --- a/src/plugins/data/public/query/timefilter/lib/extract_time_filter.ts +++ b/src/plugins/data/public/query/timefilter/lib/extract_time_filter.ts @@ -18,7 +18,7 @@ */ import { keys, partition } from 'lodash'; -import { esFilters } from '../../../../../../plugins/data/public'; +import { esFilters } from '../../../../common'; export function extractTimeFilter(timeFieldName: string, filters: esFilters.Filter[]) { const [timeRangeFilter, restOfFilters] = partition(filters, (obj: esFilters.Filter) => { diff --git a/src/plugins/data/public/query/timefilter/time_history.ts b/src/plugins/data/public/query/timefilter/time_history.ts index e14c9ac0bc7ca..4dabbb557e9db 100644 --- a/src/plugins/data/public/query/timefilter/time_history.ts +++ b/src/plugins/data/public/query/timefilter/time_history.ts @@ -18,9 +18,9 @@ */ import moment from 'moment'; -import { TimeRange } from 'src/plugins/data/public'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; import { PersistedLog } from '../persisted_log'; +import { TimeRange } from '../../../common'; export class TimeHistory { private history: PersistedLog; diff --git a/src/plugins/data/public/query/timefilter/timefilter.test.ts b/src/plugins/data/public/query/timefilter/timefilter.test.ts index cca646508b539..cd904c76ac4d9 100644 --- a/src/plugins/data/public/query/timefilter/timefilter.test.ts +++ b/src/plugins/data/public/query/timefilter/timefilter.test.ts @@ -34,7 +34,7 @@ import expect from '@kbn/expect'; import moment from 'moment'; import { Timefilter } from './timefilter'; import { Subscription } from 'rxjs'; -import { TimeRange, RefreshInterval } from 'src/plugins/data/public'; +import { TimeRange, RefreshInterval } from '../../../common'; import { timefilterServiceMock } from './timefilter_service.mock'; const timefilterSetupMock = timefilterServiceMock.createSetupContract(); diff --git a/src/plugins/data/public/query/timefilter/timefilter.ts b/src/plugins/data/public/query/timefilter/timefilter.ts index 137e5100aa20e..639f3f4a66f18 100644 --- a/src/plugins/data/public/query/timefilter/timefilter.ts +++ b/src/plugins/data/public/query/timefilter/timefilter.ts @@ -20,12 +20,13 @@ import _ from 'lodash'; import { Subject, BehaviorSubject } from 'rxjs'; import moment from 'moment'; -import { RefreshInterval, TimeRange, TimeHistoryContract } from 'src/plugins/data/public'; import { IndexPattern } from 'src/legacy/core_plugins/data/public'; import { areRefreshIntervalsDifferent, areTimeRangesDifferent } from './lib/diff_time_picker_vals'; import { parseQueryString } from './lib/parse_querystring'; import { calculateBounds, getTime } from './get_time'; import { TimefilterConfig, InputTimeRange, TimeRangeBounds } from './types'; +import { RefreshInterval, TimeRange } from '../../../common'; +import { TimeHistoryContract } from './time_history'; // TODO: remove! diff --git a/src/plugins/data/public/query/timefilter/types.ts b/src/plugins/data/public/query/timefilter/types.ts index 879776cee178e..8b8deea43f808 100644 --- a/src/plugins/data/public/query/timefilter/types.ts +++ b/src/plugins/data/public/query/timefilter/types.ts @@ -17,7 +17,7 @@ * under the License. */ import { Moment } from 'moment'; -import { RefreshInterval, TimeRange } from 'src/plugins/data/public'; +import { TimeRange, RefreshInterval } from '../../../common'; export interface TimefilterConfig { timeDefaults: TimeRange; diff --git a/src/plugins/data/public/suggestions_provider/types.ts b/src/plugins/data/public/suggestions_provider/types.ts index 988b5fcd43fa8..a13ecfb10143f 100644 --- a/src/plugins/data/public/suggestions_provider/types.ts +++ b/src/plugins/data/public/suggestions_provider/types.ts @@ -16,6 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -import { Field } from '..'; +import { IFieldType } from '../../common'; -export type IGetSuggestions = (index: string, field: Field, query: string, boolFilter?: any) => any; +export type IGetSuggestions = ( + index: string, + field: IFieldType, + query: string, + boolFilter?: any +) => any; diff --git a/src/plugins/data/public/suggestions_provider/value_suggestions.ts b/src/plugins/data/public/suggestions_provider/value_suggestions.ts index c769f64025b0e..3bc1b45d87395 100644 --- a/src/plugins/data/public/suggestions_provider/value_suggestions.ts +++ b/src/plugins/data/public/suggestions_provider/value_suggestions.ts @@ -21,14 +21,14 @@ import { memoize } from 'lodash'; import { UiSettingsClientContract, HttpServiceBase } from 'src/core/public'; import { IGetSuggestions } from './types'; -import { Field } from '..'; +import { IFieldType } from '../../common'; export function getSuggestionsProvider( uiSettings: UiSettingsClientContract, http: HttpServiceBase ): IGetSuggestions { const requestSuggestions = memoize( - (index: string, field: Field, query: string, boolFilter: any = []) => { + (index: string, field: IFieldType, query: string, boolFilter: any = []) => { return http.fetch(`/api/kibana/suggestions/values/${index}`, { method: 'POST', body: JSON.stringify({ query, field: field.name, boolFilter }), @@ -37,7 +37,7 @@ export function getSuggestionsProvider( resolver ); - return async (index: string, field: Field, query: string, boolFilter?: any) => { + return async (index: string, field: IFieldType, query: string, boolFilter?: any) => { const shouldSuggestValues = uiSettings.get('filterEditor:suggestValues'); if (field.type === 'boolean') { return [true, false]; @@ -48,7 +48,7 @@ export function getSuggestionsProvider( }; } -function resolver(index: string, field: Field, query: string, boolFilter: any) { +function resolver(index: string, field: IFieldType, query: string, boolFilter: any) { // Only cache results for a minute const ttl = Math.floor(Date.now() / 1000 / 60); return [ttl, query, index, field.name, JSON.stringify(boolFilter)].join('|'); diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts index f0b6117b928cd..81906a63bd49d 100644 --- a/src/plugins/data/server/index.ts +++ b/src/plugins/data/server/index.ts @@ -32,5 +32,6 @@ export { } from './index_patterns'; export * from './search'; +export * from '../common'; export { IRequestTypesMap, IResponseTypesMap } from './search'; diff --git a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.test.js b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.test.js index cf4af615b9577..88d2d873521cb 100644 --- a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.test.js +++ b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.test.js @@ -24,7 +24,7 @@ import sinon from 'sinon'; import * as shouldReadFieldFromDocValuesNS from './should_read_field_from_doc_values'; import { shouldReadFieldFromDocValues } from './should_read_field_from_doc_values'; -import { getKbnFieldType } from '../../../../../../data/common'; +import { getKbnFieldType } from '../../../../../../data/server'; import { readFieldCapsResponse } from './field_caps_response'; import esResponse from './__fixtures__/es_field_caps_response.json'; diff --git a/src/plugins/data/server/search/index.ts b/src/plugins/data/server/search/index.ts index e160fd4026c58..298a665fd5b2c 100644 --- a/src/plugins/data/server/search/index.ts +++ b/src/plugins/data/server/search/index.ts @@ -18,7 +18,6 @@ */ export { ISearchSetup } from './i_search_setup'; -export * from '../../common'; export { ISearchContext } from './i_search_context'; diff --git a/src/plugins/es_ui_shared/public/request/np_ready_request.ts b/src/plugins/es_ui_shared/public/request/np_ready_request.ts new file mode 100644 index 0000000000000..48c7904661e51 --- /dev/null +++ b/src/plugins/es_ui_shared/public/request/np_ready_request.ts @@ -0,0 +1,166 @@ +/* + * 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 { useEffect, useState, useRef } from 'react'; + +import { HttpServiceBase } from '../../../../../src/core/public'; + +export interface SendRequestConfig { + path: string; + method: 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head'; + body?: any; +} + +export interface SendRequestResponse { + data: any; + error: Error | null; +} + +export interface UseRequestConfig extends SendRequestConfig { + pollIntervalMs?: number; + initialData?: any; + deserializer?: (data: any) => any; +} + +export interface UseRequestResponse { + isInitialRequest: boolean; + isLoading: boolean; + error: null | unknown; + data: any; + sendRequest: (...args: any[]) => Promise; +} + +export const sendRequest = async ( + httpClient: HttpServiceBase, + { path, method, body }: SendRequestConfig +): Promise => { + try { + const response = await httpClient[method](path, { body }); + + return { + data: response.data ? response.data : response, + error: null, + }; + } catch (e) { + return { + data: null, + error: e.response && e.response.data ? e.response.data : e.body, + }; + } +}; + +export const useRequest = ( + httpClient: HttpServiceBase, + { + path, + method, + body, + pollIntervalMs, + initialData, + deserializer = (data: any): any => data, + }: UseRequestConfig +): UseRequestResponse => { + // Main states for tracking request status and data + const [error, setError] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const [data, setData] = useState(initialData); + + // Consumers can use isInitialRequest to implement a polling UX. + const [isInitialRequest, setIsInitialRequest] = useState(true); + const pollInterval = useRef(null); + const pollIntervalId = useRef(null); + + // We always want to use the most recently-set interval in scheduleRequest. + pollInterval.current = pollIntervalMs; + + // Tied to every render and bound to each request. + let isOutdatedRequest = false; + + const scheduleRequest = () => { + // Clear current interval + if (pollIntervalId.current) { + clearTimeout(pollIntervalId.current); + } + + // Set new interval + if (pollInterval.current) { + pollIntervalId.current = setTimeout(_sendRequest, pollInterval.current); + } + }; + + const _sendRequest = async () => { + // We don't clear error or data, so it's up to the consumer to decide whether to display the + // "old" error/data or loading state when a new request is in-flight. + setIsLoading(true); + + const requestBody = { + path, + method, + body, + }; + + const response = await sendRequest(httpClient, requestBody); + const { data: serializedResponseData, error: responseError } = response; + const responseData = deserializer(serializedResponseData); + + // If an outdated request has resolved, DON'T update state, but DO allow the processData handler + // to execute side effects like update telemetry. + if (isOutdatedRequest) { + return { data: null, error: null }; + } + + setError(responseError); + setData(responseData); + setIsLoading(false); + setIsInitialRequest(false); + + // If we're on an interval, we need to schedule the next request. This also allows us to reset + // the interval if the user has manually requested the data, to avoid doubled-up requests. + scheduleRequest(); + + return { data: serializedResponseData, error: responseError }; + }; + + useEffect(() => { + _sendRequest(); + // To be functionally correct we'd send a new request if the method, path, or body changes. + // But it doesn't seem likely that the method will change and body is likely to be a new + // object even if its shape hasn't changed, so for now we're just watching the path. + }, [path]); + + useEffect(() => { + scheduleRequest(); + + // Clean up intervals and inflight requests and corresponding state changes + return () => { + isOutdatedRequest = true; + if (pollIntervalId.current) { + clearTimeout(pollIntervalId.current); + } + }; + }, [pollIntervalMs]); + + return { + isInitialRequest, + isLoading, + error, + data, + sendRequest: _sendRequest, // Gives the user the ability to manually request data + }; +}; diff --git a/src/plugins/inspector/public/adapters/request/request_adapter.ts b/src/plugins/inspector/public/adapters/request/request_adapter.ts index a1a1463b8f2f6..70af6b5b51d18 100644 --- a/src/plugins/inspector/public/adapters/request/request_adapter.ts +++ b/src/plugins/inspector/public/adapters/request/request_adapter.ts @@ -54,7 +54,7 @@ class RequestAdapter extends EventEmitter { name, startTime: Date.now(), status: RequestStatus.PENDING, - id: _.get(params, 'id', uuid()), + id: params.id ?? uuid(), }; this.requests.set(req.id, req); this._onChange(); diff --git a/src/plugins/kibana_utils/public/field_mapping/mapping_setup.test.ts b/src/plugins/kibana_utils/public/field_mapping/mapping_setup.test.ts index e57699e879a87..ca40685db0ebf 100644 --- a/src/plugins/kibana_utils/public/field_mapping/mapping_setup.test.ts +++ b/src/plugins/kibana_utils/public/field_mapping/mapping_setup.test.ts @@ -18,7 +18,7 @@ */ import { expandShorthand } from './mapping_setup'; -import { ES_FIELD_TYPES } from '../../../data/common'; +import { ES_FIELD_TYPES } from '../../../data/public'; describe('mapping_setup', () => { it('allows shortcuts for field types by just setting the value to the type name', () => { diff --git a/src/plugins/kibana_utils/public/field_mapping/mapping_setup.ts b/src/plugins/kibana_utils/public/field_mapping/mapping_setup.ts index 495338735337c..72f3716147efa 100644 --- a/src/plugins/kibana_utils/public/field_mapping/mapping_setup.ts +++ b/src/plugins/kibana_utils/public/field_mapping/mapping_setup.ts @@ -18,26 +18,25 @@ */ import { mapValues, isString } from 'lodash'; -import { ES_FIELD_TYPES } from '../../../../plugins/data/common'; import { FieldMappingSpec, MappingObject } from './types'; +import { ES_FIELD_TYPES } from '../../../data/public'; /** @private */ type ShorthandFieldMapObject = FieldMappingSpec | ES_FIELD_TYPES | 'json'; -const json: FieldMappingSpec = { - type: ES_FIELD_TYPES.TEXT, - _serialize(v) { - if (v) return JSON.stringify(v); - }, - _deserialize(v) { - if (v) return JSON.parse(v); - }, -}; - /** @public */ export const expandShorthand = (sh: Record): MappingObject => { return mapValues>(sh, (val: ShorthandFieldMapObject) => { const fieldMap = isString(val) ? { type: val } : val; + const json: FieldMappingSpec = { + type: ES_FIELD_TYPES.TEXT, + _serialize(v) { + if (v) return JSON.stringify(v); + }, + _deserialize(v) { + if (v) return JSON.parse(v); + }, + }; return fieldMap.type === 'json' ? json : fieldMap; }) as MappingObject; diff --git a/src/plugins/kibana_utils/public/field_mapping/types.ts b/src/plugins/kibana_utils/public/field_mapping/types.ts index 973a58d3baec4..f3fb9b000e45a 100644 --- a/src/plugins/kibana_utils/public/field_mapping/types.ts +++ b/src/plugins/kibana_utils/public/field_mapping/types.ts @@ -17,7 +17,7 @@ * under the License. */ -import { ES_FIELD_TYPES } from '../../../data/common'; +import { ES_FIELD_TYPES } from '../../../data/public'; /** @public */ export interface FieldMappingSpec { diff --git a/test/api_integration/apis/general/index.js b/test/api_integration/apis/general/index.js index 86b7565cba6de..f8daff1a6e8a8 100644 --- a/test/api_integration/apis/general/index.js +++ b/test/api_integration/apis/general/index.js @@ -21,5 +21,6 @@ export default function ({ loadTestFile }) { describe('general', () => { loadTestFile(require.resolve('./cookies')); loadTestFile(require.resolve('./csp')); + loadTestFile(require.resolve('./prototype_pollution')); }); } diff --git a/test/api_integration/apis/general/prototype_pollution.ts b/test/api_integration/apis/general/prototype_pollution.ts new file mode 100644 index 0000000000000..1b732dc81afa9 --- /dev/null +++ b/test/api_integration/apis/general/prototype_pollution.ts @@ -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. + */ + +import { FtrProviderContext } from 'test/api_integration/ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default function({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + + describe('prototype pollution smoke test', () => { + it('prevents payloads with the "constructor.prototype" pollution vector from being accepted', async () => { + await supertest + .post('/api/sample_data/some_data_id') + .send([ + { + constructor: { + prototype: 'foo', + }, + }, + ]) + .expect(400, { + statusCode: 400, + error: 'Bad Request', + message: "'constructor.prototype' is an invalid key", + validation: { source: 'payload', keys: [] }, + }); + }); + + it('prevents payloads with the "__proto__" pollution vector from being accepted', async () => { + await supertest + .post('/api/sample_data/some_data_id') + .send(JSON.parse(`{"foo": { "__proto__": {} } }`)) + .expect(400, { + statusCode: 400, + error: 'Bad Request', + message: "'__proto__' is an invalid key", + validation: { source: 'payload', keys: [] }, + }); + }); + }); +} diff --git a/test/api_integration/ftr_provider_context.d.ts b/test/api_integration/ftr_provider_context.d.ts new file mode 100644 index 0000000000000..60f4914a1d27e --- /dev/null +++ b/test/api_integration/ftr_provider_context.d.ts @@ -0,0 +1,24 @@ +/* + * 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 { GenericFtrProviderContext } from '@kbn/test/types/ftr'; + +import { services } from './services'; + +export type FtrProviderContext = GenericFtrProviderContext; diff --git a/test/plugin_functional/plugins/demo_search/common/index.ts b/test/plugin_functional/plugins/demo_search/common/index.ts index 0339e8fbda8c5..9254412ece291 100644 --- a/test/plugin_functional/plugins/demo_search/common/index.ts +++ b/test/plugin_functional/plugins/demo_search/common/index.ts @@ -20,7 +20,7 @@ import { IKibanaSearchRequest, IKibanaSearchResponse, -} from '../../../../../src/plugins/data/common/search'; +} from '../../../../../src/plugins/data/public'; export const DEMO_SEARCH_STRATEGY = 'DEMO_SEARCH_STRATEGY'; diff --git a/vars/kibanaPipeline.groovy b/vars/kibanaPipeline.groovy index e8d7cc03edad0..90df352e18a00 100644 --- a/vars/kibanaPipeline.groovy +++ b/vars/kibanaPipeline.groovy @@ -68,7 +68,7 @@ def getOssCiGroupWorker(ciGroup) { "CI_GROUP=${ciGroup}", "JOB=kibana-ciGroup${ciGroup}", ]) { - runbld "./test/scripts/jenkins_ci_group.sh" + runbld("./test/scripts/jenkins_ci_group.sh", "Execute kibana-ciGroup${ciGroup}") } }) } @@ -79,7 +79,7 @@ def getXpackCiGroupWorker(ciGroup) { "CI_GROUP=${ciGroup}", "JOB=xpack-kibana-ciGroup${ciGroup}", ]) { - runbld "./test/scripts/jenkins_xpack_ci_group.sh" + runbld("./test/scripts/jenkins_xpack_ci_group.sh", "Execute xpack-kibana-ciGroup${ciGroup}") } }) } @@ -93,7 +93,7 @@ def legacyJobRunner(name) { ]) { jobRunner('linux && immutable', false) { try { - runbld('.ci/run.sh', true) + runbld('.ci/run.sh', "Execute ${name}", true) } finally { catchError { uploadAllGcsArtifacts(name) @@ -118,16 +118,29 @@ def jobRunner(label, useRamDisk, closure) { // Move to a temporary workspace, so that we can symlink the real workspace into /dev/shm def originalWorkspace = env.WORKSPACE ws('/tmp/workspace') { - sh """ - mkdir -p /dev/shm/workspace - mkdir -p '${originalWorkspace}' # create all of the directories leading up to the workspace, if they don't exist - rm --preserve-root -rf '${originalWorkspace}' # then remove just the workspace, just in case there's stuff in it - ln -s /dev/shm/workspace '${originalWorkspace}' - """ + sh( + script: """ + mkdir -p /dev/shm/workspace + mkdir -p '${originalWorkspace}' # create all of the directories leading up to the workspace, if they don't exist + rm --preserve-root -rf '${originalWorkspace}' # then remove just the workspace, just in case there's stuff in it + ln -s /dev/shm/workspace '${originalWorkspace}' + """, + label: "Move workspace to RAM - /dev/shm/workspace" + ) } } - def scmVars = checkout scm + def scmVars + + // Try to clone from Github up to 8 times, waiting 15 secs between attempts + retry(8) { + try { + scmVars = checkout scm + } catch (ex) { + sleep 15 + throw ex + } + } withEnv([ "CI=true", @@ -225,27 +238,33 @@ def sendKibanaMail() { } } -def bash(script) { - sh "#!/bin/bash\n${script}" +def bash(script, label) { + sh( + script: "#!/bin/bash\n${script}", + label: label + ) } def doSetup() { - runbld "./test/scripts/jenkins_setup.sh" + runbld("./test/scripts/jenkins_setup.sh", "Setup Build Environment and Dependencies") } def buildOss() { - runbld "./test/scripts/jenkins_build_kibana.sh" + runbld("./test/scripts/jenkins_build_kibana.sh", "Build OSS/Default Kibana") } def buildXpack() { - runbld "./test/scripts/jenkins_xpack_build_kibana.sh" + runbld("./test/scripts/jenkins_xpack_build_kibana.sh", "Build X-Pack Kibana") } def runErrorReporter() { - bash """ - source src/dev/ci_setup/setup_env.sh - node scripts/report_failed_tests - """ + bash( + """ + source src/dev/ci_setup/setup_env.sh + node scripts/report_failed_tests + """, + "Report failed tests, if necessary" + ) } return this diff --git a/vars/runbld.groovy b/vars/runbld.groovy index 501e2421ca65b..e52bc244c65cb 100644 --- a/vars/runbld.groovy +++ b/vars/runbld.groovy @@ -1,11 +1,17 @@ -def call(script, enableJunitProcessing = false) { +def call(script, label, enableJunitProcessing = false) { def extraConfig = enableJunitProcessing ? "" : "--config ${env.WORKSPACE}/kibana/.ci/runbld_no_junit.yml" - sh "/usr/local/bin/runbld -d '${pwd()}' ${extraConfig} ${script}" + sh( + script: "/usr/local/bin/runbld -d '${pwd()}' ${extraConfig} ${script}", + label: label ?: script + ) } def junit() { - sh "/usr/local/bin/runbld -d '${pwd()}' ${env.WORKSPACE}/kibana/test/scripts/jenkins_runbld_junit.sh" + sh( + script: "/usr/local/bin/runbld -d '${pwd()}' ${env.WORKSPACE}/kibana/test/scripts/jenkins_runbld_junit.sh", + label: "Process JUnit reports with runbld" + ) } return this diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/extended_template.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/extended_template.examples.storyshot index 5efbbe0106505..ef301c08cdfe8 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/extended_template.examples.storyshot +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/extended_template.examples.storyshot @@ -11,7 +11,7 @@ exports[`Storyshots arguments/AxisConfig extended 1`] = ` } >
- The axis is disabled +

+ Switch on to view axis settings +

diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/extended_template.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/extended_template.tsx index 0ec722e370b40..832f953974af4 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/extended_template.tsx +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/extended_template.tsx @@ -71,7 +71,11 @@ export class ExtendedTemplate extends PureComponent { const isDisabled = typeof this.props.argValue === 'boolean' && this.props.argValue === false; if (isDisabled) { - return The axis is disabled; + return ( + +

{strings.getDisabledText()}

+
+ ); } const positions = { @@ -85,7 +89,7 @@ export class ExtendedTemplate extends PureComponent { return ( - + + { onChange={ev => setInputValue(ev.target.value)} /> - + - Set + {strings.getButtonSet()} setAddMode(!addMode)} flush="left"> - Cancel + {strings.getButtonCancel()} ); diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/image_upload/index.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/image_upload/index.js index e8c433fb8752d..a3c327da2e4dc 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/image_upload/index.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/image_upload/index.js @@ -130,6 +130,7 @@ class ImageUpload extends React.Component { idSelected={urlType} onChange={this.changeUrlType} isFullWidth + className="canvasSidebar__buttonGroup" /> ); diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/string.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/string.js index d8a7188dfab28..dc31497a7da78 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/string.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/string.js @@ -26,7 +26,7 @@ const StringArgInput = ({ updateValue, value, confirm, commit, argId }) => ( /> {confirm && ( - + commit(value)}> {confirm} diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/toggle.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/toggle.js index 462537e82b164..de19d3e29221b 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/toggle.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/toggle.js @@ -19,8 +19,14 @@ const ToggleArgInput = ({ onValueChange, argValue, argId, renderError }) => { return null; } return ( - - + + ); }; diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/demodata.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/demodata.js index ec492f52747c1..193d99e1c9533 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/demodata.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/demodata.js @@ -5,28 +5,15 @@ */ import React from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; import { EuiText } from '@elastic/eui'; import { templateFromReactComponent } from '../../../public/lib/template_from_react_component'; -import { ComponentStrings, CANVAS, DataSourceStrings } from '../../../i18n'; +import { DataSourceStrings } from '../../../i18n'; const { DemoData: strings } = DataSourceStrings; const DemodataDatasource = () => ( - -

{strings.getHeading()}

-

- {ComponentStrings.DatasourceDatasourceComponent.getChangeButtonLabel()} - ), - }} - /> -

+ +

{strings.getDescription()}

); @@ -34,7 +21,6 @@ export const demodata = () => ({ name: 'demodata', displayName: strings.getDisplayName(), help: strings.getHelp(), - // Replace this with a better icon when we have time. image: 'logoElasticStack', template: templateFromReactComponent(DemodataDatasource), }); diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/essql.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/essql.js index 43f2fa63aff70..707f2305e1368 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/essql.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/essql.js @@ -6,10 +6,10 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; -import { EuiFormRow, EuiTextArea } from '@elastic/eui'; +import { EuiFormRow, EuiTextArea, EuiLink, EuiText } from '@elastic/eui'; import { getSimpleArg, setSimpleArg } from '../../../public/lib/arg_helpers'; import { templateFromReactComponent } from '../../../public/lib/template_from_react_component'; -import { DataSourceStrings } from '../../../i18n'; +import { DataSourceStrings, SQL_URL } from '../../../i18n'; const { Essql: strings } = DataSourceStrings; @@ -59,13 +59,24 @@ class EssqlDatasource extends PureComponent { const { isInvalid } = this.props; return ( - + + + {strings.getLabelAppend()} + +
+ } + >
); diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/index.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/index.js index 107d4d241d2e7..13aa2a06306a0 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/index.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/index.js @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { timelion } from './timelion'; import { demodata } from './demodata'; import { essql } from './essql'; +import { timelion } from './timelion'; -export const datasourceSpecs = [timelion, demodata, essql]; +export const datasourceSpecs = [demodata, essql, timelion]; diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/timelion.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/timelion.js index 06efb6a791a2d..b30e43c1c3c57 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/timelion.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/timelion.js @@ -12,13 +12,13 @@ import { EuiCallOut, EuiSpacer, EuiCode, - EuiText, EuiTextArea, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { getSimpleArg, setSimpleArg } from '../../../public/lib/arg_helpers'; import { templateFromReactComponent } from '../../../public/lib/template_from_react_component'; import { DataSourceStrings, TIMELION, CANVAS } from '../../../i18n'; +import { TooltipIcon } from '../../../public/components/tooltip_icon'; const { Timelion: strings } = DataSourceStrings; @@ -57,43 +57,12 @@ const TimelionDatasource = ({ args, updateArgs, defaultIndex }) => { return (
- -

{TIMELION}

-

{strings.getAbout()}

-
- - - - - setArg(argName, e.target.value)} - /> - - { - // TODO: Time timelion interval picker should be a drop down - } - - setArg('interval', e.target.value)} - /> - - - - - +
  • {
  • {
+ + + + } + > + setArg(argName, e.target.value)} + rows={15} + /> + + { + // TODO: Time timelion interval picker should be a drop down + } + + setArg('interval', e.target.value)} + /> +
); }; diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/views/metric.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/views/metric.js index 213a2e0dd3b81..33cdb5541e172 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/views/metric.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/views/metric.js @@ -16,6 +16,13 @@ export const metric = () => ({ modelArgs: [['_', { label: strings.getNumberDisplayName() }]], requiresContext: false, args: [ + { + name: 'metricFormat', + displayName: strings.getMetricFormatDisplayName(), + help: strings.getMetricFormatHelp(), + argType: 'numberFormat', + default: `"${AdvancedSettings.get('format:number:defaultPattern')}"`, + }, { name: '_', displayName: strings.getLabelDisplayName(), @@ -23,13 +30,6 @@ export const metric = () => ({ argType: 'string', default: '""', }, - { - name: 'labelFont', - displayName: strings.getLabelFontDisplayName(), - help: strings.getLabelFontHelp(), - argType: 'font', - default: `{font size=18 family="${openSans.value}" color="#000000" align=center}`, - }, { name: 'metricFont', displayName: strings.getMetricFontDisplayName(), @@ -38,11 +38,11 @@ export const metric = () => ({ default: `{font size=48 family="${openSans.value}" color="#000000" align=center lHeight=48}`, }, { - name: 'metricFormat', - displayName: strings.getMetricFormatDisplayName(), - help: strings.getMetricFormatHelp(), - argType: 'numberFormat', - default: `"${AdvancedSettings.get('format:number:defaultPattern')}"`, + name: 'labelFont', + displayName: strings.getLabelFontDisplayName(), + help: strings.getLabelFontHelp(), + argType: 'font', + default: `{font size=18 family="${openSans.value}" color="#000000" align=center}`, }, ], }); diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/views/pie.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/views/pie.js index 4bb68973e80ea..783140b0c8b9e 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/views/pie.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/views/pie.js @@ -23,6 +23,16 @@ export const pie = () => ({ name: 'palette', argType: 'palette', }, + { + name: 'legend', + displayName: strings.getLegendDisplayName(), + help: strings.getLegendHelp(), + argType: 'select', + default: 'ne', + options: { + choices: legendOptions, + }, + }, { name: 'hole', displayName: strings.getHoleDisplayName(), @@ -34,13 +44,6 @@ export const pie = () => ({ max: 100, }, }, - { - name: 'labels', - displayName: strings.getLabelsDisplayName(), - help: strings.getLabelsHelp(), - argType: 'toggle', - default: true, - }, { name: 'labelRadius', displayName: strings.getLabelRadiusDisplayName(), @@ -52,16 +55,6 @@ export const pie = () => ({ max: 100, }, }, - { - name: 'legend', - displayName: strings.getLegendDisplayName(), - help: strings.getLegendHelp(), - argType: 'select', - default: 'ne', - options: { - choices: legendOptions, - }, - }, { name: 'radius', displayName: strings.getRadiusDisplayName(), @@ -69,6 +62,20 @@ export const pie = () => ({ argType: 'percentage', default: 1, }, + { + name: 'tilt', + displayName: strings.getTiltDisplayName(), + help: strings.getTiltHelp(), + argType: 'percentage', + default: 1, + }, + { + name: 'labels', + displayName: strings.getLabelsDisplayName(), + help: strings.getLabelsHelp(), + argType: 'toggle', + default: true, + }, { name: 'seriesStyle', argType: 'seriesStyle', @@ -78,13 +85,6 @@ export const pie = () => ({ name: 'font', argType: 'font', }, - { - name: 'tilt', - displayName: strings.getTiltDisplayName(), - help: strings.getTiltHelp(), - argType: 'percentage', - default: 1, - }, ], resolve({ context }) { if (getState(context) !== 'ready') { diff --git a/x-pack/legacy/plugins/canvas/i18n/components.ts b/x-pack/legacy/plugins/canvas/i18n/components.ts index 1e6da888abf58..5b9f6f00940f4 100644 --- a/x-pack/legacy/plugins/canvas/i18n/components.ts +++ b/x-pack/legacy/plugins/canvas/i18n/components.ts @@ -228,11 +228,11 @@ export const ComponentStrings = { DatasourceDatasourceComponent: { getChangeButtonLabel: () => i18n.translate('xpack.canvas.datasourceDatasourceComponent.changeButtonLabel', { - defaultMessage: 'Change your data source', + defaultMessage: 'Change element data source', }), getPreviewButtonLabel: () => i18n.translate('xpack.canvas.datasourceDatasourceComponent.previewButtonLabel', { - defaultMessage: 'Preview', + defaultMessage: 'Preview data', }), getSaveButtonLabel: () => i18n.translate('xpack.canvas.datasourceDatasourceComponent.saveButtonLabel', { @@ -294,7 +294,7 @@ export const ComponentStrings = { }), getTitle: () => i18n.translate('xpack.canvas.elementConfig.title', { - defaultMessage: 'Elements', + defaultMessage: 'Element status', description: '"Elements" refers to the individual text, images, or visualizations that you can add to a Canvas workpad', }), @@ -581,7 +581,7 @@ export const ComponentStrings = { }), getBackgroundColorLabel: () => i18n.translate('xpack.canvas.pageConfig.backgroundColorLabel', { - defaultMessage: 'Background Color', + defaultMessage: 'Background', }), getNoTransitionDropDownOptionLabel: () => i18n.translate('xpack.canvas.pageConfig.transitions.noneDropDownOptionLabel', { @@ -592,7 +592,7 @@ export const ComponentStrings = { }), getTitle: () => i18n.translate('xpack.canvas.pageConfig.title', { - defaultMessage: 'Page', + defaultMessage: 'Page styles', }), getTransitionLabel: () => i18n.translate('xpack.canvas.pageConfig.transitionLabel', { @@ -1002,7 +1002,7 @@ export const ComponentStrings = { }), getTitle: () => i18n.translate('xpack.canvas.workpadConfig.title', { - defaultMessage: 'Workpad', + defaultMessage: 'Workpad settings', }), getUSLetterButtonLabel: () => i18n.translate('xpack.canvas.workpadConfig.USLetterButtonLabel', { diff --git a/x-pack/legacy/plugins/canvas/i18n/constants.ts b/x-pack/legacy/plugins/canvas/i18n/constants.ts index 3659c369ba0b6..8aee6ca148681 100644 --- a/x-pack/legacy/plugins/canvas/i18n/constants.ts +++ b/x-pack/legacy/plugins/canvas/i18n/constants.ts @@ -15,6 +15,7 @@ export const CSV = 'CSV'; export const DATEMATH = '`datemath`'; export const DATATABLE = '`datatable`'; export const ELASTICSEARCH = 'Elasticsearch'; +export const ELASTICSEARCH_SHORT = 'ES'; export const FONT_FAMILY = '`font-family`'; export const FONT_WEIGHT = '`font-weight`'; export const HEX = 'HEX'; @@ -32,6 +33,8 @@ export const PDF = 'PDF'; export const POST = 'POST'; export const RGB = 'RGB'; export const SQL = 'SQL'; +export const SQL_URL = + 'https://www.elastic.co/guide/en/elasticsearch/reference/current/sql-spec.html'; export const SVG = 'SVG'; export const TIMELION = 'Timelion'; export const TINYMATH = '`TinyMath`'; diff --git a/x-pack/legacy/plugins/canvas/i18n/expression_types.ts b/x-pack/legacy/plugins/canvas/i18n/expression_types.ts index 6bc40a2758ab3..bdd190f26c97a 100644 --- a/x-pack/legacy/plugins/canvas/i18n/expression_types.ts +++ b/x-pack/legacy/plugins/canvas/i18n/expression_types.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { LUCENE } from './constants'; +import { LUCENE, ELASTICSEARCH } from './constants'; export const ArgTypesStrings = { Color: { @@ -101,13 +101,17 @@ export const ArgTypesStrings = { i18n.translate('xpack.canvas.expressionTypes.argTypes.seriesStyle.colorLabel', { defaultMessage: 'Color', }), + getColorValueDefault: () => + i18n.translate('xpack.canvas.expressionTypes.argTypes.seriesStyle.colorValueDefault', { + defaultMessage: 'Auto', + }), getStyleLabel: () => i18n.translate('xpack.canvas.expressionTypes.argTypes.seriesStyle.styleLabel', { defaultMessage: 'Style', }), getRemoveAriaLabel: () => i18n.translate('xpack.canvas.expressionTypes.argTypes.seriesStyle.removeAriaLabel', { - defaultMessage: 'Remove Series Color', + defaultMessage: 'Remove series color', }), getNoSeriesTooltip: () => i18n.translate('xpack.canvas.expressionTypes.argTypes.seriesStyle.noSeriesTooltip', { @@ -115,11 +119,11 @@ export const ArgTypesStrings = { }), getSeriesIdentifierLabel: () => i18n.translate('xpack.canvas.expressionTypes.argTypes.seriesStyle.seriesIdentifierLabel', { - defaultMessage: 'Series Identifier', + defaultMessage: 'Series id', }), getSelectSeriesOption: () => i18n.translate('xpack.canvas.expressionTypes.argTypes.seriesStyle.selectSeriesDropDown', { - defaultMessage: 'Select Series', + defaultMessage: 'Select series', }), getLineLabel: () => i18n.translate('xpack.canvas.expressionTypes.argTypes.seriesStyle.lineLabel', { @@ -152,15 +156,18 @@ export const ExpressionDataSourceStrings = { }), getWarningTitle: () => i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.warningTitle', { - defaultMessage: 'Be careful', + defaultMessage: 'Query with caution', }), getWarning: () => i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.warningDescription', { defaultMessage: ` - The Elasticsearch Docs datasource is used to pull documents directly from Elasticsearch + This datasource pulls directly from {elasticsearch} without the use of aggregations. It is best used with low volume datasets and in situations where you need to view raw documents or plot exact, non-aggregated values on a chart.`, + values: { + elasticsearch: ELASTICSEARCH, + }, }), getIndexTitle: () => i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.indexTitle', { diff --git a/x-pack/legacy/plugins/canvas/i18n/ui.ts b/x-pack/legacy/plugins/canvas/i18n/ui.ts index b65a666aa8809..323a6c97fd967 100644 --- a/x-pack/legacy/plugins/canvas/i18n/ui.ts +++ b/x-pack/legacy/plugins/canvas/i18n/ui.ts @@ -12,9 +12,9 @@ import { CANVAS, CSS, ELASTICSEARCH, + ELASTICSEARCH_SHORT, HEX, HTML, - KIBANA, LUCENE, MARKDOWN, MOMENTJS, @@ -35,6 +35,10 @@ export const ArgumentStrings = { i18n.translate('xpack.canvas.uis.arguments.axisConfigLabel', { defaultMessage: 'Visualization axis configuration', }), + getDisabledText: () => + i18n.translate('xpack.canvas.uis.arguments.axisConfigDisabledText', { + defaultMessage: 'Switch on to view axis settings', + }), getPositionBottom: () => i18n.translate('xpack.canvas.uis.arguments.axisConfig.position.options.bottomDropDown', { defaultMessage: 'bottom', @@ -124,6 +128,14 @@ export const ArgumentStrings = { i18n.translate('xpack.canvas.uis.arguments.filterGroup.createNewGroupLinkText', { defaultMessage: 'Create new group', }), + getButtonSet: () => + i18n.translate('xpack.canvas.uis.arguments.filterGroup.setValue', { + defaultMessage: 'Set', + }), + getButtonCancel: () => + i18n.translate('xpack.canvas.uis.arguments.filterGroup.cancelValue', { + defaultMessage: 'Cancel', + }), getDisplayName: () => i18n.translate('xpack.canvas.uis.arguments.filterGroupTitle', { defaultMessage: 'Filter Group', @@ -260,7 +272,7 @@ export const ArgumentStrings = { }), getHelp: () => i18n.translate('xpack.canvas.uis.arguments.shapeLabel', { - defaultMessage: 'Shape picker', + defaultMessage: 'Change the shape of the current element', }), }, String: { @@ -303,12 +315,20 @@ export const DataSourceStrings = { }), getHeading: () => i18n.translate('xpack.canvas.uis.dataSources.demoData.headingTitle', { - defaultMessage: 'You are using demo data', + defaultMessage: 'This element is using demo data', }), getHelp: () => i18n.translate('xpack.canvas.uis.dataSources.demoDataLabel', { defaultMessage: 'Mock data set with usernames, prices, projects, countries, and phases', }), + getDescription: () => + i18n.translate('xpack.canvas.uis.dataSources.demoDataDescription', { + defaultMessage: + 'By default, every {canvas} element is connected to the demo data source. Change the data source, above, to connect your own data.', + values: { + canvas: CANVAS, + }, + }), }, Essql: { getDisplayName: () => @@ -329,9 +349,13 @@ export const DataSourceStrings = { }), getLabel: () => i18n.translate('xpack.canvas.uis.dataSources.essql.queryTitle', { - defaultMessage: '{elasticsearch} {sql} query', + defaultMessage: 'Query', + }), + getLabelAppend: () => + i18n.translate('xpack.canvas.uis.dataSources.essql.queryTitleAppend', { + defaultMessage: 'Learn {elasticsearchShort} {sql} syntax', values: { - elasticsearch: ELASTICSEARCH, + elasticsearchShort: ELASTICSEARCH_SHORT, sql: SQL, }, }), @@ -340,10 +364,9 @@ export const DataSourceStrings = { getAbout: () => i18n.translate('xpack.canvas.uis.dataSources.timelion.aboutDetail', { defaultMessage: - '{canvas} integrates with {kibanaTimelion} application to allow you to use {timelion} queries to pull back timeseries data in a tabular format that can be used with {canvas} elements.', + 'Use {timelion} queries to pull back timeseries data that can be used with {canvas} elements.', values: { timelion: TIMELION, - kibanaTimelion: `${KIBANA}'s ${TIMELION}`, canvas: CANVAS, }, }), @@ -357,9 +380,8 @@ export const DataSourceStrings = { getIntervalHelp: () => i18n.translate('xpack.canvas.uis.dataSources.timelion.intervalLabel', { defaultMessage: - 'Accepts {elasticsearch} date math: {weeksExample}, {daysExample}, {secondsExample}, or {auto}', + 'Use date math like {weeksExample}, {daysExample}, {secondsExample}, or {auto}', values: { - elasticsearch: ELASTICSEARCH, secondsExample: '10s', daysExample: '5d', weeksExample: '1w', @@ -383,7 +405,11 @@ export const DataSourceStrings = { }), getTipsHeading: () => i18n.translate('xpack.canvas.uis.dataSources.timelion.tipsTitle', { - defaultMessage: 'Some tips', + defaultMessage: 'Tips for using {timelion} in {canvas}', + values: { + timelion: TIMELION, + canvas: CANVAS, + }, }), }, }; @@ -530,7 +556,7 @@ export const ViewStrings = { }), getValueDisplayName: () => i18n.translate('xpack.canvas.uis.views.dropdownControl.args.valueColumnTitle', { - defaultMessage: 'Values column', + defaultMessage: 'Value column', }), getValueHelp: () => i18n.translate('xpack.canvas.uis.views.dropdownControl.args.valueColumnLabel', { @@ -610,7 +636,7 @@ export const ViewStrings = { }), getNumberDisplayName: () => i18n.translate('xpack.canvas.uis.views.numberArgTitle', { - defaultMessage: 'Number', + defaultMessage: 'Value', }), getLabelDisplayName: () => i18n.translate('xpack.canvas.uis.views.metric.args.labelArgTitle', { @@ -618,7 +644,7 @@ export const ViewStrings = { }), getLabelFontDisplayName: () => i18n.translate('xpack.canvas.uis.views.metric.args.labelFontTitle', { - defaultMessage: 'Label text settings', + defaultMessage: 'Label text', }), getLabelFontHelp: () => i18n.translate('xpack.canvas.uis.views.metric.args.labelFontLabel', { @@ -626,11 +652,11 @@ export const ViewStrings = { }), getLabelHelp: () => i18n.translate('xpack.canvas.uis.views.metric.args.labelArgLabel', { - defaultMessage: 'Describes the metric', + defaultMessage: 'Enter a text label for the metric value', }), getMetricFontDisplayName: () => i18n.translate('xpack.canvas.uis.views.metric.args.metricFontTitle', { - defaultMessage: 'Metric text settings', + defaultMessage: 'Metric text', }), getMetricFontHelp: () => i18n.translate('xpack.canvas.uis.views.metric.args.metricFontLabel', { @@ -638,11 +664,11 @@ export const ViewStrings = { }), getMetricFormatDisplayName: () => i18n.translate('xpack.canvas.uis.views.metric.args.metricFormatTitle', { - defaultMessage: 'Metric Format', + defaultMessage: 'Format', }), getMetricFormatHelp: () => i18n.translate('xpack.canvas.uis.views.metric.args.metricFormatLabel', { - defaultMessage: 'Fonts, alignment and color', + defaultMessage: 'Select a format for the metric value', }), }, Pie: { @@ -676,7 +702,7 @@ export const ViewStrings = { }), getLegendDisplayName: () => i18n.translate('xpack.canvas.uis.views.pie.args.legendTitle', { - defaultMessage: 'Legend position', + defaultMessage: 'Legend', }), getLegendHelp: () => i18n.translate('xpack.canvas.uis.views.pie.args.legendLabel', { @@ -714,7 +740,7 @@ export const ViewStrings = { }), getLegendDisplayName: () => i18n.translate('xpack.canvas.uis.views.plot.args.legendTitle', { - defaultMessage: 'Legend position', + defaultMessage: 'Legend', }), getLegendHelp: () => i18n.translate('xpack.canvas.uis.views.plot.args.legendLabel', { @@ -744,7 +770,7 @@ export const ViewStrings = { }), getBarColorHelp: () => i18n.translate('xpack.canvas.uis.views.progress.args.barColorLabel', { - defaultMessage: 'Accepts HEX, RGB or HTML Color names', + defaultMessage: 'Accepts HEX, RGB or HTML color names', }), getBarWeightDisplayName: () => i18n.translate('xpack.canvas.uis.views.progress.args.barWeightTitle', { @@ -930,7 +956,7 @@ export const ViewStrings = { }), getBorderHelp: () => i18n.translate('xpack.canvas.uis.views.shape.args.borderLabel', { - defaultMessage: 'Accepts HEX, RGB or HTML Color names', + defaultMessage: 'Accepts HEX, RGB or HTML color names', }), getBorderWidthDisplayName: () => i18n.translate('xpack.canvas.uis.views.shape.args.borderWidthTitle', { @@ -950,22 +976,19 @@ export const ViewStrings = { }), getFillHelp: () => i18n.translate('xpack.canvas.uis.views.shape.args.fillLabel', { - defaultMessage: 'Accepts HEX, RGB or HTML Color names', + defaultMessage: 'Accepts HEX, RGB or HTML color names', }), getMaintainAspectDisplayName: () => i18n.translate('xpack.canvas.uis.views.shape.args.maintainAspectTitle', { - defaultMessage: 'Maintain aspect ratio', + defaultMessage: 'Fixed ratio', }), getMaintainAspectHelp: () => i18n.translate('xpack.canvas.uis.views.shape.args.maintainAspectLabel', { - defaultMessage: `Select '{true}' to maintain aspect ratio`, - values: { - true: BOOLEAN_TRUE, - }, + defaultMessage: `Enable to maintain aspect ratio`, }), getShapeDisplayName: () => i18n.translate('xpack.canvas.uis.views.shape.args.shapeTitle', { - defaultMessage: 'Select a shape', + defaultMessage: 'Select shape', }), }, Table: { @@ -988,7 +1011,7 @@ export const ViewStrings = { }), getPerPageDisplayName: () => i18n.translate('xpack.canvas.uis.views.table.args.perPageTitle', { - defaultMessage: 'Rows per page', + defaultMessage: 'Rows', }), getPerPageHelp: () => i18n.translate('xpack.canvas.uis.views.table.args.perPageLabel', { @@ -1022,7 +1045,7 @@ export const ViewStrings = { }), getFilterGroupDisplayName: () => i18n.translate('xpack.canvas.uis.views.timefilter.args.filterGroupTitle', { - defaultMessage: 'Filter group name', + defaultMessage: 'Filter group', }), getFilterGroupHelp: () => i18n.translate('xpack.canvas.uis.views.timefilter.args.filterGroupLabel', { diff --git a/x-pack/legacy/plugins/canvas/public/components/arg_add_popover/arg_add_popover.scss b/x-pack/legacy/plugins/canvas/public/components/arg_add_popover/arg_add_popover.scss index f2cdb1444ef23..15676d2b02490 100644 --- a/x-pack/legacy/plugins/canvas/public/components/arg_add_popover/arg_add_popover.scss +++ b/x-pack/legacy/plugins/canvas/public/components/arg_add_popover/arg_add_popover.scss @@ -1,3 +1,7 @@ +.canvasArg__addArg { + margin-right: -$euiSizeS; +} + .canvasArg__addPopover { width: 250px; } diff --git a/x-pack/legacy/plugins/canvas/public/components/arg_add_popover/arg_add_popover.tsx b/x-pack/legacy/plugins/canvas/public/components/arg_add_popover/arg_add_popover.tsx index e771c978d491b..9cc6f870b9bde 100644 --- a/x-pack/legacy/plugins/canvas/public/components/arg_add_popover/arg_add_popover.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/arg_add_popover/arg_add_popover.tsx @@ -33,6 +33,7 @@ export const ArgAddPopover = ({ options }: Props) => { iconType="plusInCircle" aria-label={strings.getAddAriaLabel()} onClick={handleClick} + className="canvasArg__addArg" /> ); diff --git a/x-pack/legacy/plugins/canvas/public/components/arg_form/arg_form.scss b/x-pack/legacy/plugins/canvas/public/components/arg_form/arg_form.scss index bef58d6bb6f5f..3fc220d41d551 100644 --- a/x-pack/legacy/plugins/canvas/public/components/arg_form/arg_form.scss +++ b/x-pack/legacy/plugins/canvas/public/components/arg_form/arg_form.scss @@ -8,6 +8,14 @@ .canvasSidebar__panel { .canvasArg--expandable:last-child { + .canvasArg__accordion { + margin-bottom: (-$euiSizeS); + } + + .canvasArg__accordion:after { + content: none; + } + .canvasArg__accordion.euiAccordion-isOpen:after { display: none; } @@ -15,12 +23,12 @@ } .canvasArg { - margin-top: $euiSize; - + margin-top: $euiSizeS; +} - .canvasArg--remove { - visibility: hidden; - } +.canvasArg__remove { + min-width: $euiSize; + padding: $euiSizeXS 0; } .canvasArg__content { @@ -29,47 +37,18 @@ .canvasArg__form { position: relative; - -} - -.canvasArg__form, -.canvasArg__accordion { - &:hover { - .canvasArg__remove { - opacity: 1; - visibility: visible; - } - } } .canvasArg__tooltip { margin-left: -$euiSizeXL; } -.canvasArg__remove { - position: absolute; - right: -$euiSizeL; - top: $euiSizeS - 2px; - border-radius: $euiBorderRadius; - border: $euiBorderThin; - background: $euiColorEmptyShade; - opacity: 0; - visibility: hidden; - transition: opacity $euiAnimSpeedNormal $euiAnimSlightResistance; - transition-delay: $euiAnimSpeedSlow; -} - .canvasArg__accordion { - padding: $euiSizeS $euiSize; - margin: 0 (-$euiSize); + padding: $euiSizeS $euiSizeM; + margin: 0 (-$euiSizeM); background: $euiColorLightestShade; position: relative; - // different spacing means leff shift - .canvasArg__remove { - right: -$euiSizeM; - } - // don't let remove button position here if this is nested in an accordion .canvasArg__form { position: static; @@ -97,3 +76,8 @@ bottom: 0; } } + +// this is a workaround since an EuiFormRow label cannot be passed in toggle.js +.canvasArg__switch { + padding-top: calc(#{$euiSizeS} * .75); +} diff --git a/x-pack/legacy/plugins/canvas/public/components/arg_form/arg_label.js b/x-pack/legacy/plugins/canvas/public/components/arg_form/arg_label.js index 143ce670d25f6..4324eed0892a5 100644 --- a/x-pack/legacy/plugins/canvas/public/components/arg_form/arg_label.js +++ b/x-pack/legacy/plugins/canvas/public/components/arg_form/arg_label.js @@ -6,7 +6,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { EuiFormRow, EuiAccordion, EuiText, EuiToolTip } from '@elastic/eui'; +import { EuiFormRow, EuiAccordion, EuiText, EuiToolTip, EuiIcon } from '@elastic/eui'; // This is what is being generated by render() from the Arg class. It is called in FunctionForm export const ArgLabel = props => { @@ -32,7 +32,17 @@ export const ArgLabel = props => { ) : ( simpleArg && ( - + + + {label} + + + } + id={argId} + > {simpleArg} ) diff --git a/x-pack/legacy/plugins/canvas/public/components/arg_form/arg_simple_form.tsx b/x-pack/legacy/plugins/canvas/public/components/arg_form/arg_simple_form.tsx index 5b45772c14373..846f912db6f84 100644 --- a/x-pack/legacy/plugins/canvas/public/components/arg_form/arg_simple_form.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/arg_form/arg_simple_form.tsx @@ -6,7 +6,7 @@ import React, { ReactNode, MouseEventHandler } from 'react'; import PropTypes from 'prop-types'; -import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import { TooltipIcon, IconType } from '../tooltip_icon'; import { ComponentStrings } from '../../../i18n'; @@ -41,13 +41,16 @@ export const ArgSimpleForm: React.FunctionComponent = ({ )} {!required && ( - + + + )} ); diff --git a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource.scss b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource.scss index ee6c082db1217..2407dcbbce593 100644 --- a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource.scss +++ b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource.scss @@ -6,6 +6,31 @@ padding: 0 $euiSizeS; } +.canvasDataSource__section { + padding: $euiSizeM; +} + +.canvasDataSource__triggerButton { + @include euiTitle('xs'); + line-height: $euiSizeXXL; +} + +.canvasDataSource__triggerButtonIcon { + margin-right: $euiSizeS; +} + +.canvasDataSource__list { + padding: $euiSizeM; +} + +.canvasDataSource__card .euiCard__content { + padding-top: 0 !important; // sass-lint:disable-line no-important +} + .canvasDataSource__card + .canvasDataSource__card { margin-top: $euiSizeS; } + +.canvasDataSource__card--isCurrent { + border-color: $euiColorSecondary; +} diff --git a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_component.js b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_component.js index 5f235d4479171..8b0061e047f33 100644 --- a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_component.js +++ b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_component.js @@ -7,20 +7,23 @@ import React, { Fragment, PureComponent } from 'react'; import PropTypes from 'prop-types'; import { - EuiPanel, EuiFlexGroup, EuiFlexItem, EuiButton, - EuiButtonEmpty, EuiSpacer, + EuiIcon, + EuiCallOut, + EuiButtonEmpty, + EuiHorizontalRule, } from '@elastic/eui'; import { isEqual } from 'lodash'; -import { ComponentStrings } from '../../../i18n'; +import { ComponentStrings, DataSourceStrings } from '../../../i18n'; import { getDefaultIndex } from '../../lib/es_service'; import { DatasourceSelector } from './datasource_selector'; import { DatasourcePreview } from './datasource_preview'; const { DatasourceDatasourceComponent: strings } = ComponentStrings; +const { DemoData: demoDataStrings } = DataSourceStrings; export class DatasourceComponent extends PureComponent { static propTypes = { @@ -113,7 +116,13 @@ export class DatasourceComponent extends PureComponent { const { defaultIndex } = this.state; if (selecting) { - return ; + return ( + + ); } const datasourcePreview = previewing ? ( @@ -124,47 +133,51 @@ export class DatasourceComponent extends PureComponent { /> ) : null; + const datasourceRender = stateDatasource.render({ + args: stateArgs, + updateArgs, + datasourceDef, + isInvalid, + setInvalid, + defaultIndex, + }); + return ( - +
setSelecting(!selecting)} + className="canvasDataSource__triggerButton" + flush="left" + size="s" > - {strings.getChangeButtonLabel()} + + {stateDatasource.displayName} - {stateDatasource.render({ - args: stateArgs, - updateArgs, - datasourceDef, - isInvalid, - setInvalid, - defaultIndex, - })} - + {stateDatasource.name === 'demodata' ? ( + + {datasourceRender} + + ) : ( + datasourceRender + )} + - setPreviewing(true)} icon="check"> + setPreviewing(true)}> {strings.getPreviewButtonLabel()} - + - + {strings.getSaveButtonLabel()} - +
{datasourcePreview}
diff --git a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_preview/datasource_preview.js b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_preview/datasource_preview.js index e6d2fe550a935..13cd2c5cd11f7 100644 --- a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_preview/datasource_preview.js +++ b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_preview/datasource_preview.js @@ -16,6 +16,7 @@ import { EuiPanel, EuiText, EuiEmptyPrompt, + EuiSpacer, } from '@elastic/eui'; import { Datatable } from '../../datatable'; import { Error } from '../../error'; @@ -31,21 +32,22 @@ export const DatasourcePreview = ({ done, datatable }) => ( {strings.getModalTitle()} - +

{datasourceStrings.getSaveButtonLabel()}, }} />

+ {datatable.type === 'error' ? ( ) : ( - + {datatable.rows.length > 0 ? ( ) : ( diff --git a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_selector.js b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_selector.js index 07df2a7007c4f..92f9b92cb1f06 100644 --- a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_selector.js +++ b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_selector.js @@ -8,17 +8,21 @@ import React from 'react'; import PropTypes from 'prop-types'; import { EuiCard, EuiIcon } from '@elastic/eui'; -export const DatasourceSelector = ({ onSelect, datasources }) => ( -
+export const DatasourceSelector = ({ onSelect, datasources, current }) => ( +
{datasources.map(d => ( } - onClick={() => onSelect(d.name)} + titleElement="h5" + icon={} description={d.help} layout="horizontal" className="canvasDataSource__card" + selectable={{ + isSelected: d.name === current ? true : false, + onClick: () => onSelect(d.name), + }} /> ))}
@@ -27,4 +31,5 @@ export const DatasourceSelector = ({ onSelect, datasources }) => ( DatasourceSelector.propTypes = { onSelect: PropTypes.func.isRequired, datasources: PropTypes.array.isRequired, + current: PropTypes.string.isRequired, }; diff --git a/x-pack/legacy/plugins/canvas/public/components/datasource/no_datasource.js b/x-pack/legacy/plugins/canvas/public/components/datasource/no_datasource.js index caafa068c6b5b..f531ee1668aef 100644 --- a/x-pack/legacy/plugins/canvas/public/components/datasource/no_datasource.js +++ b/x-pack/legacy/plugins/canvas/public/components/datasource/no_datasource.js @@ -6,18 +6,17 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { EuiPanel, EuiText } from '@elastic/eui'; +import { EuiCallOut } from '@elastic/eui'; import { ComponentStrings } from '../../../i18n'; const { DatasourceNoDatasource: strings } = ComponentStrings; export const NoDatasource = () => ( - - -

{strings.getPanelTitle()}

+
+

{strings.getPanelDescription()}

- - +
+
); NoDatasource.propTypes = { diff --git a/x-pack/legacy/plugins/canvas/public/components/datatable/datatable.scss b/x-pack/legacy/plugins/canvas/public/components/datatable/datatable.scss index daccfdff5d34b..bd11bff18e091 100644 --- a/x-pack/legacy/plugins/canvas/public/components/datatable/datatable.scss +++ b/x-pack/legacy/plugins/canvas/public/components/datatable/datatable.scss @@ -4,6 +4,7 @@ display: flex; flex-direction: column; justify-content: space-between; + font-size: $euiFontSizeS; .canvasDataTable__tableWrapper { @include euiScrollBar; @@ -12,7 +13,8 @@ overflow: auto; // removes white square in the scrollbar corner - &::-webkit-scrollbar-corner { // sass-lint:disable-line no-vendor-prefixes + // sass-lint:disable no-vendor-prefixes + &::-webkit-scrollbar-corner { background: transparent; } } @@ -21,6 +23,8 @@ width: 100%; display: flex; justify-content: space-around; + padding: $euiSizeS; + border-top: $euiBorderThin; } .canvasDataTable__table { @@ -30,7 +34,8 @@ .canvasDataTable__th, .canvasDataTable__td { text-align: left; - padding: $euiSizeS; + padding: $euiSizeS $euiSizeXS; + border-bottom: $euiBorderThin; } .canvasDataTable__th { diff --git a/x-pack/legacy/plugins/canvas/public/components/element_config/element_config.js b/x-pack/legacy/plugins/canvas/public/components/element_config/element_config.js index 76007994e56bf..5d710ef883548 100644 --- a/x-pack/legacy/plugins/canvas/public/components/element_config/element_config.js +++ b/x-pack/legacy/plugins/canvas/public/components/element_config/element_config.js @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiStat, EuiTitle } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiStat, EuiAccordion, EuiText, EuiSpacer } from '@elastic/eui'; import PropTypes from 'prop-types'; -import React, { Fragment } from 'react'; +import React from 'react'; import { ComponentStrings } from '../../../i18n'; const { ElementConfig: strings } = ComponentStrings; @@ -20,26 +20,51 @@ export const ElementConfig = ({ elementStats }) => { const progress = total > 0 ? Math.round(((ready + error) / total) * 100) : 100; return ( - - -

{strings.getTitle()}

-
- - + + {strings.getTitle()} +
+ } + initialIsOpen={false} + > + + - + - + - + - + - + ); }; diff --git a/x-pack/legacy/plugins/canvas/public/components/es_field_select/es_field_select.js b/x-pack/legacy/plugins/canvas/public/components/es_field_select/es_field_select.js index 636d9b0006ac6..11c8ab88a4cba 100644 --- a/x-pack/legacy/plugins/canvas/public/components/es_field_select/es_field_select.js +++ b/x-pack/legacy/plugins/canvas/public/components/es_field_select/es_field_select.js @@ -28,6 +28,7 @@ export const ESFieldSelect = ({ value, fields = [], onChange, onFocus, onBlur }) onBlur={onBlur} singleSelection={{ asPlainText: true }} isClearable={false} + compressed /> ); }; diff --git a/x-pack/legacy/plugins/canvas/public/components/es_fields_select/es_fields_select.js b/x-pack/legacy/plugins/canvas/public/components/es_fields_select/es_fields_select.js index fedb4aba7d3d0..ca2cac5a64793 100644 --- a/x-pack/legacy/plugins/canvas/public/components/es_fields_select/es_fields_select.js +++ b/x-pack/legacy/plugins/canvas/public/components/es_fields_select/es_fields_select.js @@ -25,6 +25,7 @@ export const ESFieldsSelect = ({ selected, fields, onChange, onFocus, onBlur }) className="canvasFieldsSelect" onFocus={onFocus} onBlur={onBlur} + compressed /> ); }; diff --git a/x-pack/legacy/plugins/canvas/public/components/es_index_select/es_index_select.js b/x-pack/legacy/plugins/canvas/public/components/es_index_select/es_index_select.js index edc4506f20bda..8f1a4932a5e6c 100644 --- a/x-pack/legacy/plugins/canvas/public/components/es_index_select/es_index_select.js +++ b/x-pack/legacy/plugins/canvas/public/components/es_index_select/es_index_select.js @@ -32,6 +32,7 @@ export const ESIndexSelect = ({ value, loading, indices, onChange, onFocus, onBl singleSelection={{ asPlainText: true }} isClearable={false} onCreateOption={input => onChange(input || defaultIndex)} + compressed /> ); }; diff --git a/x-pack/legacy/plugins/canvas/public/components/page_config/page_config.js b/x-pack/legacy/plugins/canvas/public/components/page_config/page_config.js index 2586b4ec61f04..583bf1427aab1 100644 --- a/x-pack/legacy/plugins/canvas/public/components/page_config/page_config.js +++ b/x-pack/legacy/plugins/canvas/public/components/page_config/page_config.js @@ -6,7 +6,15 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import { EuiCard, EuiFormRow, EuiTitle, EuiSpacer, EuiSelect } from '@elastic/eui'; +import { + EuiCard, + EuiFormRow, + EuiTitle, + EuiSpacer, + EuiSelect, + EuiToolTip, + EuiIcon, +} from '@elastic/eui'; import { WorkpadColorPicker } from '../workpad_color_picker'; import { ComponentStrings } from '../../../i18n'; @@ -22,14 +30,20 @@ export const PageConfig = ({ }) => { return ( - +

{strings.getTitle()}

- + + + {strings.getBackgroundColorLabel()}{' '} + + + + } > diff --git a/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/__examples__/__snapshots__/shape_picker_popover.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/__examples__/__snapshots__/shape_picker_popover.examples.storyshot index 426c07dac497e..a23452a43ae1e 100644 --- a/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/__examples__/__snapshots__/shape_picker_popover.examples.storyshot +++ b/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/__examples__/__snapshots__/shape_picker_popover.examples.storyshot @@ -13,20 +13,24 @@ exports[`Storyshots components/Shapes/ShapePickerPopover default 1`] = `
- + +
`; @@ -44,27 +48,31 @@ exports[`Storyshots components/Shapes/ShapePickerPopover interactive 1`] = `
- + /> + +
`; @@ -82,27 +90,31 @@ exports[`Storyshots components/Shapes/ShapePickerPopover shape selected 1`] = `
- + /> + +
`; diff --git a/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/shape_picker_popover.tsx b/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/shape_picker_popover.tsx index 472a14071208a..970f72da698ba 100644 --- a/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/shape_picker_popover.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/shape_picker_popover.tsx @@ -6,7 +6,7 @@ import React, { MouseEvent } from 'react'; import PropTypes from 'prop-types'; -import { EuiLink } from '@elastic/eui'; +import { EuiLink, EuiPanel } from '@elastic/eui'; import { Popover } from '../popover'; import { ShapePicker } from '../shape_picker'; import { ShapePreview } from '../shape_preview'; @@ -21,9 +21,11 @@ interface Props { export const ShapePickerPopover = ({ shapes, onChange, value }: Props) => { const button = (handleClick: (ev: MouseEvent) => void) => ( - - - + + + + + ); return ( diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/group_settings.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/group_settings.examples.storyshot index dc80af01f121f..1655320700f87 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/group_settings.examples.storyshot +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/group_settings.examples.storyshot @@ -2,13 +2,17 @@ exports[`Storyshots components/Sidebar/GroupSettings default 1`] = `
-

- Ungroup (U) to edit individual element settings. -

-

- Save this group as a new element to re-use it throughout your workpad. -

+
+

+ Ungroup (U) to edit individual element settings. +

+

+ Save this group as a new element to re-use it throughout your workpad. +

+
`; diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/multi_element_settings.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/multi_element_settings.examples.storyshot index b9b13ae36e730..49e804640081d 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/multi_element_settings.examples.storyshot +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/multi_element_settings.examples.storyshot @@ -2,13 +2,17 @@ exports[`Storyshots components/Sidebar/MultiElementSettings default 1`] = `
-

- Multiple elements are currently selected. -

-

- Deselect these elements to edit their individual settings, press (G) to group them, or save this selection as a new element to re-use it throughout your workpad. -

+
+

+ Multiple elements are currently selected. +

+

+ Deselect these elements to edit their individual settings, press (G) to group them, or save this selection as a new element to re-use it throughout your workpad. +

+
`; diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/element_settings/element_settings.tsx b/x-pack/legacy/plugins/canvas/public/components/sidebar/element_settings/element_settings.tsx index 6d884c05cd13a..74f4887601d30 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar/element_settings/element_settings.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar/element_settings/element_settings.tsx @@ -6,7 +6,7 @@ import React, { FunctionComponent } from 'react'; import PropTypes from 'prop-types'; -import { EuiSpacer, EuiTabbedContent } from '@elastic/eui'; +import { EuiTabbedContent } from '@elastic/eui'; // @ts-ignore unconverted component import { Datasource } from '../../datasource'; // @ts-ignore unconverted component @@ -30,7 +30,6 @@ export const ElementSettings: FunctionComponent = ({ element }) => { name: strings.getDisplayTabLabel(), content: (
-
@@ -42,7 +41,6 @@ export const ElementSettings: FunctionComponent = ({ element }) => { name: strings.getDataTabLabel(), content: (
-
), diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/global_config.tsx b/x-pack/legacy/plugins/canvas/public/components/sidebar/global_config.tsx index a5920ee197460..2e241681ccc6a 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar/global_config.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar/global_config.tsx @@ -20,10 +20,10 @@ export const GlobalConfig: FunctionComponent = () => ( - + - + ); diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/group_settings.tsx b/x-pack/legacy/plugins/canvas/public/components/sidebar/group_settings.tsx index b46465d9ec775..95d9035774a6a 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar/group_settings.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar/group_settings.tsx @@ -11,8 +11,10 @@ import { ComponentStrings } from '../../../i18n'; const { GroupSettings: strings } = ComponentStrings; export const GroupSettings: FunctionComponent = () => ( - -

{strings.getUngroupDescription()}

-

{strings.getSaveGroupDescription()}

-
+
+ +

{strings.getUngroupDescription()}

+

{strings.getSaveGroupDescription()}

+
+
); diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/multi_element_settings.tsx b/x-pack/legacy/plugins/canvas/public/components/sidebar/multi_element_settings.tsx index 2de3a805c95e9..999c1c2daaf5b 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar/multi_element_settings.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar/multi_element_settings.tsx @@ -11,8 +11,10 @@ import { ComponentStrings } from '../../../i18n'; const { MultiElementSettings: strings } = ComponentStrings; export const MultiElementSettings: FunctionComponent = () => ( - -

{strings.getMultipleElementsDescription()}

-

{strings.getMultipleElementsActionsDescription()}

-
+
+ +

{strings.getMultipleElementsDescription()}

+

{strings.getMultipleElementsActionsDescription()}

+
+
); diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar.scss b/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar.scss index f9ce6f3cfb555..338d515165e43 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar.scss +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar.scss @@ -2,7 +2,6 @@ @include euiScrollBar; width: 100%; - padding: $euiSizeM; max-height: 100vh; overflow-y: auto; overflow-x: hidden; @@ -25,6 +24,15 @@ margin-bottom: $euiSizeS; } +.canvasSidebar__panel { + border-bottom: $euiBorderThin; + padding: $euiSizeS $euiSizeM; + + &--isEmpty { + border-bottom: none; + } +} + .canvasSidebar__panel-noMinWidth .euiButton { min-width: 0; } diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar_section.js b/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar_section.js index 29ca72a9737a1..bf149a6c2acb8 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar_section.js +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar_section.js @@ -7,10 +7,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { EuiPanel } from '@elastic/eui'; - export const SidebarSection = ({ children }) => ( - {children} +
{children}
); SidebarSection.propTypes = { diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar_section_title.js b/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar_section_title.js index 192786ae86a45..8e1522eae8dcc 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar_section_title.js +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar_section_title.js @@ -10,7 +10,7 @@ import { EuiTitle, EuiFlexItem, EuiFlexGroup, EuiToolTip } from '@elastic/eui'; export const SidebarSectionTitle = ({ title, tip, children }) => { const formattedTitle = ( - +

{title}

); diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar_header/sidebar_header.scss b/x-pack/legacy/plugins/canvas/public/components/sidebar_header/sidebar_header.scss index 24453fcf0411e..92b0c50a6be4f 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar_header/sidebar_header.scss +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar_header/sidebar_header.scss @@ -1,3 +1,7 @@ .canvasLayout__sidebarHeader { - padding: ($euiSizeXS * .5) 0; + padding: calc(#{$euiSizeM} + 2px) $euiSizeS; } + +.canvasLayout__sidebarHeaderWorkpad { + padding: calc(#{$euiSizeS} * .75) 0; +} \ No newline at end of file diff --git a/x-pack/legacy/plugins/canvas/public/components/text_style_picker/text_style_picker.js b/x-pack/legacy/plugins/canvas/public/components/text_style_picker/text_style_picker.js index 9693540769d50..1a44181475091 100644 --- a/x-pack/legacy/plugins/canvas/public/components/text_style_picker/text_style_picker.js +++ b/x-pack/legacy/plugins/canvas/public/components/text_style_picker/text_style_picker.js @@ -105,22 +105,30 @@ export const TextStylePicker = ({ return (
+ + doChange('family', value)} /> + doChange('size', Number(e.target.value))} options={fontSizes.map(size => ({ text: String(size), value: size }))} + prepend="Size" /> - - doChange('family', value)} /> - - + - + + + doChange('color', value)} + colors={colors} + /> + @@ -138,13 +147,7 @@ export const TextStylePicker = ({ isIconOnly idSelected={align} onChange={onAlignmentChange} - /> - - - doChange('color', value)} - colors={colors} + className="canvasSidebar__buttonGroup" /> diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_config/workpad_config.js b/x-pack/legacy/plugins/canvas/public/components/workpad_config/workpad_config.js index ec7386bddace6..7dfc378432b57 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_config/workpad_config.js +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_config/workpad_config.js @@ -67,9 +67,11 @@ export class WorkpadConfig extends PureComponent { return (
- -

{strings.getTitle()}

-
+
+ +

{strings.getTitle()}

+
+
@@ -129,37 +131,38 @@ export class WorkpadConfig extends PureComponent {
- - - - {strings.getGlobalCSSLabel()} - - - } - > -
- this.setState({ css: e.target.value })} - rows={10} - /> - - setWorkpadCSS(css || DEFAULT_WORKPAD_CSS)}> - {strings.getApplyStylesheetButtonLabel()} - - -
-
+
+ + + {strings.getGlobalCSSLabel()} + + + } + > +
+ this.setState({ css: e.target.value })} + rows={10} + /> + + setWorkpadCSS(css || DEFAULT_WORKPAD_CSS)}> + {strings.getApplyStylesheetButtonLabel()} + + +
+
+
); } diff --git a/x-pack/legacy/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/extended_template.examples.storyshot b/x-pack/legacy/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/extended_template.examples.storyshot index 5525df639be01..ffe87129c76fa 100644 --- a/x-pack/legacy/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/extended_template.examples.storyshot +++ b/x-pack/legacy/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/extended_template.examples.storyshot @@ -12,7 +12,7 @@ exports[`Storyshots arguments/SeriesStyle extended 1`] = ` >
- Series Identifier + Series id
- Select Series + Select series