From 75e4aeedbc46bdc5c4e0df859aa5a93a13e1e0b3 Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Thu, 8 Apr 2021 14:16:31 +0100 Subject: [PATCH 1/9] [ML] Excludes metadata fields from jobs caps fields service response (#96548) --- .../ml/server/models/job_service/new_job_caps/field_service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts b/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts index 0287c2af11a7e..c6cf608fe1e0b 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts @@ -80,7 +80,7 @@ class FieldsService { if (firstKey !== undefined) { const field = fc[firstKey]; // add to the list of fields if the field type can be used by ML - if (supportedTypes.includes(field.type) === true) { + if (supportedTypes.includes(field.type) === true && field.metadata_field !== true) { fields.push({ id: k, name: k, From 02ba7c4543a265fc897c2354a323b22e30caf192 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Thu, 8 Apr 2021 08:49:13 -0500 Subject: [PATCH 2/9] [kbn-ui-shared-deps] Remove outdated polyfills (#96339) --- NOTICE.txt | 27 ----------- package.json | 1 - packages/kbn-ui-shared-deps/polyfills.js | 3 -- .../vendor/childnode_remove_polyfill.js | 48 ------------------- yarn.lock | 5 -- 5 files changed, 84 deletions(-) delete mode 100644 packages/kbn-ui-shared-deps/vendor/childnode_remove_polyfill.js diff --git a/NOTICE.txt b/NOTICE.txt index 2341a478cbda9..4eec329b7a603 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -261,33 +261,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---- -This product bundles childnode-remove which is available under a -"MIT" license. - -The MIT License (MIT) - -Copyright (c) 2016-present, jszhou -https://github.com/jserz/js_piece - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - --- This product bundles code based on probot-metadata@1.0.0 which is available under a "MIT" license. diff --git a/package.json b/package.json index ffe1a10f0bfea..9bddca4665467 100644 --- a/package.json +++ b/package.json @@ -208,7 +208,6 @@ "content-disposition": "0.5.3", "copy-to-clipboard": "^3.0.8", "core-js": "^3.6.5", - "custom-event-polyfill": "^0.3.0", "cytoscape": "^3.10.0", "cytoscape-dagre": "^2.2.2", "d3": "3.5.17", diff --git a/packages/kbn-ui-shared-deps/polyfills.js b/packages/kbn-ui-shared-deps/polyfills.js index abbf911cfc8fc..a9ec32023f2bf 100644 --- a/packages/kbn-ui-shared-deps/polyfills.js +++ b/packages/kbn-ui-shared-deps/polyfills.js @@ -8,7 +8,6 @@ require('core-js/stable'); require('regenerator-runtime/runtime'); -require('custom-event-polyfill'); if (typeof window.Event === 'object') { // IE11 doesn't support unknown event types, required by react-use @@ -17,6 +16,4 @@ if (typeof window.Event === 'object') { } require('whatwg-fetch'); -require('abortcontroller-polyfill/dist/polyfill-patch-fetch'); -require('./vendor/childnode_remove_polyfill'); require('symbol-observable'); diff --git a/packages/kbn-ui-shared-deps/vendor/childnode_remove_polyfill.js b/packages/kbn-ui-shared-deps/vendor/childnode_remove_polyfill.js deleted file mode 100644 index d8818fe809ccb..0000000000000 --- a/packages/kbn-ui-shared-deps/vendor/childnode_remove_polyfill.js +++ /dev/null @@ -1,48 +0,0 @@ -/* eslint-disable @kbn/eslint/require-license-header */ - -/* @notice - * This product bundles childnode-remove which is available under a - * "MIT" license. - * - * The MIT License (MIT) - * - * Copyright (c) 2016-present, jszhou - * https://github.com/jserz/js_piece - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/* eslint-disable */ - -(function (arr) { - arr.forEach(function (item) { - if (item.hasOwnProperty('remove')) { - return; - } - Object.defineProperty(item, 'remove', { - configurable: true, - enumerable: true, - writable: true, - value: function remove() { - if (this.parentNode !== null) - this.parentNode.removeChild(this); - } - }); - }); -})([Element.prototype, CharacterData.prototype, DocumentType.prototype]); diff --git a/yarn.lock b/yarn.lock index 786143fb3d1ef..0e6427d2e265e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10950,11 +10950,6 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" -custom-event-polyfill@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/custom-event-polyfill/-/custom-event-polyfill-0.3.0.tgz#99807839be62edb446b645832e0d80ead6fa1888" - integrity sha1-mYB4Ob5i7bRGtkWDLg2A6tb6GIg= - cwise-compiler@^1.0.0, cwise-compiler@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/cwise-compiler/-/cwise-compiler-1.1.3.tgz#f4d667410e850d3a313a7d2db7b1e505bb034cc5" From 5d54e2990b27a6febf1e38d909ad066d379c1631 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 8 Apr 2021 15:50:23 +0200 Subject: [PATCH 3/9] Update developer docs for upgrading Node.js (#96422) --- docs/developer/advanced/upgrading-nodejs.asciidoc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/developer/advanced/upgrading-nodejs.asciidoc b/docs/developer/advanced/upgrading-nodejs.asciidoc index c1e727b1eac65..3827cb6e9aa7d 100644 --- a/docs/developer/advanced/upgrading-nodejs.asciidoc +++ b/docs/developer/advanced/upgrading-nodejs.asciidoc @@ -14,10 +14,14 @@ Theses files must be updated when upgrading Node.js: - {kib-repo}blob/{branch}/.node-version[`.node-version`] - {kib-repo}blob/{branch}/.nvmrc[`.nvmrc`] - {kib-repo}blob/{branch}/package.json[`package.json`] - The version is specified in the `engines.node` field. + - {kib-repo}blob/{branch}/WORKSPACE.bazel[`WORKSPACE.bazel`] - The version is specified in the `node_version` property. + Besides this property, the list of files under `node_repositories` must be updated along with their respective SHA256 hashes. + These can be found on the https://nodejs.org[nodejs.org] website. + Example for Node.js v14.16.1: https://nodejs.org/dist/v14.16.1/SHASUMS256.txt.asc -See PR {kib-repo}pull/86593[#86593] for an example of how the Node.js version has been upgraded previously. +See PR {kib-repo}pull/96382[#96382] for an example of how the Node.js version has been upgraded previously. -In the 6.8 branch, the `.ci/Dockerfile` file does not exist, so when upgrading Node.js in that branch, just skip that file. +In the 6.8 branch, neither the `.ci/Dockerfile` file nor the `WORKSPACE.bazel` file exists, so when upgrading Node.js in that branch, just skip those files. === Backporting From e3f31ea9ad6ef84de4519e5799776b247c45ef16 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Thu, 8 Apr 2021 17:29:57 +0300 Subject: [PATCH 4/9] [Visualize] Allows editing broken visualizations caused by runtime fields changes (#94798) * Add possibility to open visualization when saved field doesn't exists anymore * Fix tests * Fix some remarks * Remove unneeded code * Fix tests * Fix tests * Fix some remarks * Fixed problem with double error popover in visualizations * Fix CI * Fix type * Fix API docs * Don't show error popup for error related to runtime fields * Fix some remarks Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- ...gin-plugins-data-public.kbn_field_types.md | 1 + ...gin-plugins-data-server.kbn_field_types.md | 1 + ...mbeddable-public.embeddable.getupdated_.md | 4 +- .../data/common/kbn_field_types/types.ts | 1 + .../common/search/aggs/agg_configs.test.ts | 2 +- .../_terms_other_bucket_helper.test.ts | 21 ++++- .../common/search/aggs/buckets/terms.test.ts | 78 ++++++++++++++----- .../common/search/aggs/param_types/field.ts | 76 ++++++++++++------ src/plugins/data/public/public.api.md | 2 + src/plugins/data/server/server.api.md | 2 + .../public/lib/embeddables/embeddable.tsx | 7 +- src/plugins/embeddable/public/public.api.md | 2 +- .../kibana_utils/common/errors/errors.ts | 22 +++++- .../public/components/controls/field.test.tsx | 15 +++- .../public/components/controls/field.tsx | 46 ++++++++++- .../public/embeddable/visualize_embeddable.ts | 3 +- .../utils/get_visualization_instance.ts | 11 ++- .../utils/use/use_saved_vis_instance.ts | 26 +------ .../public/application/utils/utils.ts | 35 +++++++++ 19 files changed, 268 insertions(+), 87 deletions(-) diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md index 4d75dda61d5c9..521ceeb1e37f2 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md @@ -27,6 +27,7 @@ export declare enum KBN_FIELD_TYPES | HISTOGRAM | "histogram" | | | IP | "ip" | | | IP\_RANGE | "ip_range" | | +| MISSING | "missing" | | | MURMUR3 | "murmur3" | | | NESTED | "nested" | | | NUMBER | "number" | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md index be4c3705bd8de..40fa872ff0fc6 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md @@ -27,6 +27,7 @@ export declare enum KBN_FIELD_TYPES | HISTOGRAM | "histogram" | | | IP | "ip" | | | IP\_RANGE | "ip_range" | | +| MISSING | "missing" | | | MURMUR3 | "murmur3" | | | NESTED | "nested" | | | NUMBER | "number" | | diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getupdated_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getupdated_.md index 5201444e69867..290dc10662569 100644 --- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getupdated_.md +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getupdated_.md @@ -9,9 +9,9 @@ Merges input$ and output$ streams and debounces emit till next macro-task. Could Signature: ```typescript -getUpdated$(): Readonly>; +getUpdated$(): Readonly>; ``` Returns: -`Readonly>` +`Readonly>` diff --git a/src/plugins/data/common/kbn_field_types/types.ts b/src/plugins/data/common/kbn_field_types/types.ts index c46e5c5266f55..e6f815e058ce3 100644 --- a/src/plugins/data/common/kbn_field_types/types.ts +++ b/src/plugins/data/common/kbn_field_types/types.ts @@ -80,4 +80,5 @@ export enum KBN_FIELD_TYPES { OBJECT = 'object', NESTED = 'nested', HISTOGRAM = 'histogram', + MISSING = 'missing', } diff --git a/src/plugins/data/common/search/aggs/agg_configs.test.ts b/src/plugins/data/common/search/aggs/agg_configs.test.ts index 297af560081b1..3ce528e6ed893 100644 --- a/src/plugins/data/common/search/aggs/agg_configs.test.ts +++ b/src/plugins/data/common/search/aggs/agg_configs.test.ts @@ -230,7 +230,7 @@ describe('AggConfigs', () => { describe('#toDsl', () => { beforeEach(() => { indexPattern = stubIndexPattern as IndexPattern; - indexPattern.fields.getByName = (name) => (name as unknown) as IndexPatternField; + indexPattern.fields.getByName = (name) => (({ name } as unknown) as IndexPatternField); }); it('uses the sorted aggs', () => { diff --git a/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts b/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts index 4e278d5872a3e..56e720d237c45 100644 --- a/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts +++ b/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts @@ -16,16 +16,33 @@ import { AggConfigs, CreateAggConfigParams } from '../agg_configs'; import { BUCKET_TYPES } from './bucket_agg_types'; import { IBucketAggConfig } from './bucket_agg_type'; import { mockAggTypesRegistry } from '../test_helpers'; +import type { IndexPatternField } from '../../../index_patterns'; +import { IndexPattern } from '../../../index_patterns/index_patterns/index_pattern'; const indexPattern = { id: '1234', title: 'logstash-*', fields: [ { - name: 'field', + name: 'machine.os.raw', + type: 'string', + esTypes: ['string'], + aggregatable: true, + filterable: true, + searchable: true, + }, + { + name: 'geo.src', + type: 'string', + esTypes: ['string'], + aggregatable: true, + filterable: true, + searchable: true, }, ], -} as any; +} as IndexPattern; + +indexPattern.fields.getByName = (name) => (({ name } as unknown) as IndexPatternField); const singleTerm = { aggs: [ diff --git a/src/plugins/data/common/search/aggs/buckets/terms.test.ts b/src/plugins/data/common/search/aggs/buckets/terms.test.ts index bb34d7ede453c..09dfbb28a4e53 100644 --- a/src/plugins/data/common/search/aggs/buckets/terms.test.ts +++ b/src/plugins/data/common/search/aggs/buckets/terms.test.ts @@ -10,6 +10,8 @@ import { AggConfigs } from '../agg_configs'; import { METRIC_TYPES } from '../metrics'; import { mockAggTypesRegistry } from '../test_helpers'; import { BUCKET_TYPES } from './bucket_agg_types'; +import type { IndexPatternField } from '../../../index_patterns'; +import { IndexPattern } from '../../../index_patterns/index_patterns/index_pattern'; describe('Terms Agg', () => { describe('order agg editor UI', () => { @@ -17,16 +19,44 @@ describe('Terms Agg', () => { const indexPattern = { id: '1234', title: 'logstash-*', - fields: { - getByName: () => field, - filter: () => [field], - }, - } as any; + fields: [ + { + name: 'field', + type: 'string', + esTypes: ['string'], + aggregatable: true, + filterable: true, + searchable: true, + }, + { + name: 'string_field', + type: 'string', + esTypes: ['string'], + aggregatable: true, + filterable: true, + searchable: true, + }, + { + name: 'empty_number_field', + type: 'number', + esTypes: ['number'], + aggregatable: true, + filterable: true, + searchable: true, + }, + { + name: 'number_field', + type: 'number', + esTypes: ['number'], + aggregatable: true, + filterable: true, + searchable: true, + }, + ], + } as IndexPattern; - const field = { - name: 'field', - indexPattern, - }; + indexPattern.fields.getByName = (name) => (({ name } as unknown) as IndexPatternField); + indexPattern.fields.filter = () => indexPattern.fields; return new AggConfigs( indexPattern, @@ -207,16 +237,28 @@ describe('Terms Agg', () => { const indexPattern = { id: '1234', title: 'logstash-*', - fields: { - getByName: () => field, - filter: () => [field], - }, - } as any; + fields: [ + { + name: 'string_field', + type: 'string', + esTypes: ['string'], + aggregatable: true, + filterable: true, + searchable: true, + }, + { + name: 'number_field', + type: 'number', + esTypes: ['number'], + aggregatable: true, + filterable: true, + searchable: true, + }, + ], + } as IndexPattern; - const field = { - name: 'field', - indexPattern, - }; + indexPattern.fields.getByName = (name) => (({ name } as unknown) as IndexPatternField); + indexPattern.fields.filter = () => indexPattern.fields; const aggConfigs = new AggConfigs( indexPattern, diff --git a/src/plugins/data/common/search/aggs/param_types/field.ts b/src/plugins/data/common/search/aggs/param_types/field.ts index 2d3ff8f5fdba8..62dac9831211a 100644 --- a/src/plugins/data/common/search/aggs/param_types/field.ts +++ b/src/plugins/data/common/search/aggs/param_types/field.ts @@ -8,7 +8,10 @@ import { i18n } from '@kbn/i18n'; import { IAggConfig } from '../agg_config'; -import { SavedObjectNotFound } from '../../../../../../plugins/kibana_utils/common'; +import { + SavedFieldNotFound, + SavedFieldTypeInvalidForAgg, +} from '../../../../../../plugins/kibana_utils/common'; import { BaseParamType } from './base'; import { propFilter } from '../utils'; import { KBN_FIELD_TYPES } from '../../../kbn_field_types/types'; @@ -47,13 +50,49 @@ export class FieldParamType extends BaseParamType { ); } - if (field.scripted) { + if (field.type === KBN_FIELD_TYPES.MISSING) { + throw new SavedFieldNotFound( + i18n.translate( + 'data.search.aggs.paramTypes.field.notFoundSavedFieldParameterErrorMessage', + { + defaultMessage: + 'The field "{fieldParameter}" associated with this object no longer exists in the index pattern. Please use another field.', + values: { + fieldParameter: field.name, + }, + } + ) + ); + } + + const validField = this.getAvailableFields(aggConfig).find( + (f: any) => f.name === field.name + ); + + if (!validField) { + throw new SavedFieldTypeInvalidForAgg( + i18n.translate( + 'data.search.aggs.paramTypes.field.invalidSavedFieldParameterErrorMessage', + { + defaultMessage: + 'Saved field "{fieldParameter}" of index pattern "{indexPatternTitle}" is invalid for use with the "{aggType}" aggregation. Please select a new field.', + values: { + fieldParameter: field.name, + aggType: aggConfig?.type?.title, + indexPatternTitle: aggConfig.getIndexPattern().title, + }, + } + ) + ); + } + + if (validField.scripted) { output.params.script = { - source: field.script, - lang: field.lang, + source: validField.script, + lang: validField.lang, }; } else { - output.params.field = field.name; + output.params.field = validField.name; } }; } @@ -69,28 +108,15 @@ export class FieldParamType extends BaseParamType { const field = aggConfig.getIndexPattern().fields.getByName(fieldName); if (!field) { - throw new SavedObjectNotFound('index-pattern-field', fieldName); - } - - const validField = this.getAvailableFields(aggConfig).find((f: any) => f.name === fieldName); - if (!validField) { - throw new Error( - i18n.translate( - 'data.search.aggs.paramTypes.field.invalidSavedFieldParameterErrorMessage', - { - defaultMessage: - 'Saved field "{fieldParameter}" of index pattern "{indexPatternTitle}" is invalid for use with the "{aggType}" aggregation. Please select a new field.', - values: { - fieldParameter: fieldName, - aggType: aggConfig?.type?.title, - indexPatternTitle: aggConfig.getIndexPattern().title, - }, - } - ) - ); + return new IndexPatternField({ + type: KBN_FIELD_TYPES.MISSING, + name: fieldName, + searchable: false, + aggregatable: false, + }); } - return validField; + return field; }; } diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index db7f814a83f79..05925f097de24 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1786,6 +1786,8 @@ export enum KBN_FIELD_TYPES { // (undocumented) IP_RANGE = "ip_range", // (undocumented) + MISSING = "missing", + // (undocumented) MURMUR3 = "murmur3", // (undocumented) NESTED = "nested", diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index 9fff4ac95c87e..053b60956fa92 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -1082,6 +1082,8 @@ export enum KBN_FIELD_TYPES { // (undocumented) IP_RANGE = "ip_range", // (undocumented) + MISSING = "missing", + // (undocumented) MURMUR3 = "murmur3", // (undocumented) NESTED = "nested", diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx index e8418970d83f7..a0cd213b7bf24 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx @@ -9,7 +9,7 @@ import { cloneDeep, isEqual } from 'lodash'; import * as Rx from 'rxjs'; import { merge } from 'rxjs'; -import { debounceTime, distinctUntilChanged, map, mapTo, skip } from 'rxjs/operators'; +import { debounceTime, distinctUntilChanged, map, skip } from 'rxjs/operators'; import { RenderCompleteDispatcher } from '../../../../kibana_utils/public'; import { Adapters } from '../types'; import { IContainer } from '../containers'; @@ -111,10 +111,9 @@ export abstract class Embeddable< * In case corresponding state change triggered `reload` this stream is guarantied to emit later, * which allows to skip any state handling in case `reload` already handled it. */ - public getUpdated$(): Readonly> { + public getUpdated$(): Readonly> { return merge(this.getInput$().pipe(skip(1)), this.getOutput$().pipe(skip(1))).pipe( - debounceTime(0), - mapTo(undefined) + debounceTime(0) ); } diff --git a/src/plugins/embeddable/public/public.api.md b/src/plugins/embeddable/public/public.api.md index b9719542adc81..3f0907acabdfa 100644 --- a/src/plugins/embeddable/public/public.api.md +++ b/src/plugins/embeddable/public/public.api.md @@ -282,7 +282,7 @@ export abstract class Embeddable>; + getUpdated$(): Readonly>; // (undocumented) readonly id: string; // (undocumented) diff --git a/src/plugins/kibana_utils/common/errors/errors.ts b/src/plugins/kibana_utils/common/errors/errors.ts index 7a9495cc8f413..7f3efc6d9571f 100644 --- a/src/plugins/kibana_utils/common/errors/errors.ts +++ b/src/plugins/kibana_utils/common/errors/errors.ts @@ -32,7 +32,7 @@ export class DuplicateField extends KbnError { export class SavedObjectNotFound extends KbnError { public savedObjectType: string; public savedObjectId?: string; - constructor(type: string, id?: string, link?: string) { + constructor(type: string, id?: string, link?: string, customMessage?: string) { const idMsg = id ? ` (id: ${id})` : ''; let message = `Could not locate that ${type}${idMsg}`; @@ -40,13 +40,31 @@ export class SavedObjectNotFound extends KbnError { message += `, [click here to re-create it](${link})`; } - super(message); + super(customMessage || message); this.savedObjectType = type; this.savedObjectId = id; } } +/** + * A saved field doesn't exist anymore + */ +export class SavedFieldNotFound extends KbnError { + constructor(message: string) { + super(message); + } +} + +/** + * A saved field type isn't compatible with aggregation + */ +export class SavedFieldTypeInvalidForAgg extends KbnError { + constructor(message: string) { + super(message); + } +} + /** * This error is for scenarios where a saved object is detected that has invalid JSON properties. * There was a scenario where we were importing objects with double-encoded JSON, and the system diff --git a/src/plugins/vis_default_editor/public/components/controls/field.test.tsx b/src/plugins/vis_default_editor/public/components/controls/field.test.tsx index 94f767510c4bd..277804567c2b7 100644 --- a/src/plugins/vis_default_editor/public/components/controls/field.test.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/field.test.tsx @@ -11,7 +11,7 @@ import { act } from 'react-dom/test-utils'; import { mount, shallow, ReactWrapper } from 'enzyme'; import { EuiComboBoxProps, EuiComboBox } from '@elastic/eui'; -import { IAggConfig, IndexPatternField } from 'src/plugins/data/public'; +import { IAggConfig, IndexPatternField, AggParam } from 'src/plugins/data/public'; import { ComboBoxGroupedOptions } from '../../utils'; import { FieldParamEditor, FieldParamEditorProps } from './field'; import { EditorVisState } from '../sidebar/state/reducers'; @@ -42,7 +42,7 @@ describe('FieldParamEditor component', () => { setTouched = jest.fn(); onChange = jest.fn(); - field = { displayName: 'bytes' } as IndexPatternField; + field = { displayName: 'bytes', type: 'bytes' } as IndexPatternField; option = { label: 'bytes', target: field }; indexedFields = [ { @@ -52,7 +52,16 @@ describe('FieldParamEditor component', () => { ]; defaultProps = { - agg: {} as IAggConfig, + agg: { + type: { + params: [ + ({ + name: 'field', + filterFieldTypes: ['bytes'], + } as unknown) as AggParam, + ], + }, + } as IAggConfig, aggParam: { name: 'field', type: 'field', diff --git a/src/plugins/vis_default_editor/public/components/controls/field.tsx b/src/plugins/vis_default_editor/public/components/controls/field.tsx index 95843dc6ae3a8..f8db2d89888a2 100644 --- a/src/plugins/vis_default_editor/public/components/controls/field.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/field.tsx @@ -13,7 +13,13 @@ import useMount from 'react-use/lib/useMount'; import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { AggParam, IAggConfig, IFieldParamType, IndexPatternField } from 'src/plugins/data/public'; +import { + AggParam, + IAggConfig, + IFieldParamType, + IndexPatternField, + KBN_FIELD_TYPES, +} from '../../../../../plugins/data/public'; import { formatListAsProse, parseCommaSeparatedList, useValidation } from './utils'; import { AggParamEditorProps } from '../agg_param_props'; import { ComboBoxGroupedOptions } from '../../utils'; @@ -55,6 +61,7 @@ function FieldParamEditor({ } }; const errors = customError ? [customError] : []; + let showErrorMessageImmediately = false; if (!indexedFields.length) { errors.push( @@ -69,9 +76,38 @@ function FieldParamEditor({ ); } + if (value && value.type === KBN_FIELD_TYPES.MISSING) { + errors.push( + i18n.translate('visDefaultEditor.controls.field.fieldIsNotExists', { + defaultMessage: + 'The field "{fieldParameter}" associated with this object no longer exists in the index pattern. Please use another field.', + values: { + fieldParameter: value.name, + }, + }) + ); + showErrorMessageImmediately = true; + } else if ( + value && + !getFieldTypes(agg).find((type: string) => type === value.type || type === '*') + ) { + errors.push( + i18n.translate('visDefaultEditor.controls.field.invalidFieldForAggregation', { + defaultMessage: + 'Saved field "{fieldParameter}" of index pattern "{indexPatternTitle}" is invalid for use with this aggregation. Please select a new field.', + values: { + fieldParameter: value?.name, + indexPatternTitle: agg.getIndexPattern && agg.getIndexPattern().title, + }, + }) + ); + showErrorMessageImmediately = true; + } + const isValid = !!value && !errors.length && !isDirty; // we show an error message right away if there is no compatible fields - const showErrorMessage = (showValidation || !indexedFields.length) && !isValid; + const showErrorMessage = + (showValidation || !indexedFields.length || showErrorMessageImmediately) && !isValid; useValidation(setValidity, isValid); useMount(() => { @@ -122,10 +158,14 @@ function FieldParamEditor({ } function getFieldTypesString(agg: IAggConfig) { + return formatListAsProse(getFieldTypes(agg), { inclusive: false }); +} + +function getFieldTypes(agg: IAggConfig) { const param = get(agg, 'type.params', []).find((p: AggParam) => p.name === 'field') || ({} as IFieldParamType); - return formatListAsProse(parseCommaSeparatedList(param.filterFieldTypes), { inclusive: false }); + return parseCommaSeparatedList(param.filterFieldTypes || []); } export { FieldParamEditor }; diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts index efb166c8975bb..3bb52eb15758a 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts @@ -149,8 +149,9 @@ export class VisualizeEmbeddable } this.subscriptions.push( - this.getUpdated$().subscribe(() => { + this.getUpdated$().subscribe((value) => { const isDirty = this.handleChanges(); + if (isDirty && this.handler) { this.updateHandler(); } diff --git a/src/plugins/visualize/public/application/utils/get_visualization_instance.ts b/src/plugins/visualize/public/application/utils/get_visualization_instance.ts index cc0f3ce2afae5..9eda709e58c3e 100644 --- a/src/plugins/visualize/public/application/utils/get_visualization_instance.ts +++ b/src/plugins/visualize/public/application/utils/get_visualization_instance.ts @@ -18,8 +18,17 @@ import { SavedObject } from 'src/plugins/saved_objects/public'; import { cloneDeep } from 'lodash'; import { ExpressionValueError } from 'src/plugins/expressions/public'; import { createSavedSearchesLoader } from '../../../../discover/public'; +import { SavedFieldNotFound, SavedFieldTypeInvalidForAgg } from '../../../../kibana_utils/common'; import { VisualizeServices } from '../types'; +function isErrorRelatedToRuntimeFields(error: ExpressionValueError['error']) { + const originalError = error.original || error; + return ( + originalError instanceof SavedFieldNotFound || + originalError instanceof SavedFieldTypeInvalidForAgg + ); +} + const createVisualizeEmbeddableAndLinkSavedSearch = async ( vis: Vis, visualizeServices: VisualizeServices @@ -37,7 +46,7 @@ const createVisualizeEmbeddableAndLinkSavedSearch = async ( })) as VisualizeEmbeddableContract; embeddableHandler.getOutput$().subscribe((output) => { - if (output.error) { + if (output.error && !isErrorRelatedToRuntimeFields(output.error)) { data.search.showError( ((output.error as unknown) as ExpressionValueError['error']).original || output.error ); diff --git a/src/plugins/visualize/public/application/utils/use/use_saved_vis_instance.ts b/src/plugins/visualize/public/application/utils/use/use_saved_vis_instance.ts index 64d61996495d7..965951bfbd88d 100644 --- a/src/plugins/visualize/public/application/utils/use/use_saved_vis_instance.ts +++ b/src/plugins/visualize/public/application/utils/use/use_saved_vis_instance.ts @@ -11,13 +11,12 @@ import { EventEmitter } from 'events'; import { parse } from 'query-string'; import { i18n } from '@kbn/i18n'; -import { redirectWhenMissing } from '../../../../../kibana_utils/public'; - import { getVisualizationInstance } from '../get_visualization_instance'; import { getEditBreadcrumbs, getCreateBreadcrumbs } from '../breadcrumbs'; import { SavedVisInstance, VisualizeServices, IEditorController } from '../../types'; import { VisualizeConstants } from '../../visualize_constants'; import { getVisEditorsRegistry } from '../../../services'; +import { redirectToSavedObjectPage } from '../utils'; /** * This effect is responsible for instantiating a saved vis or creating a new one @@ -43,9 +42,7 @@ export const useSavedVisInstance = ( chrome, history, dashboard, - setActiveUrl, toastNotifications, - http: { basePath }, stateTransferService, application: { navigateToApp }, } = services; @@ -131,27 +128,8 @@ export const useSavedVisInstance = ( visEditorController, }); } catch (error) { - const managementRedirectTarget = { - app: 'management', - path: `kibana/objects/savedVisualizations/${visualizationIdFromUrl}`, - }; - try { - redirectWhenMissing({ - history, - navigateToApp, - toastNotifications, - basePath, - mapping: { - visualization: VisualizeConstants.LANDING_PAGE_PATH, - search: managementRedirectTarget, - 'index-pattern': managementRedirectTarget, - 'index-pattern-field': managementRedirectTarget, - }, - onBeforeRedirect() { - setActiveUrl(VisualizeConstants.LANDING_PAGE_PATH); - }, - })(error); + redirectToSavedObjectPage(services, error, visualizationIdFromUrl); } catch (e) { toastNotifications.addWarning({ title: i18n.translate('visualize.createVisualization.failedToLoadErrorMessage', { diff --git a/src/plugins/visualize/public/application/utils/utils.ts b/src/plugins/visualize/public/application/utils/utils.ts index 0e529507f97e3..c906ff5304c90 100644 --- a/src/plugins/visualize/public/application/utils/utils.ts +++ b/src/plugins/visualize/public/application/utils/utils.ts @@ -10,6 +10,8 @@ import { i18n } from '@kbn/i18n'; import { ChromeStart, DocLinksStart } from 'kibana/public'; import { Filter } from '../../../../data/public'; +import { redirectWhenMissing } from '../../../../kibana_utils/public'; +import { VisualizeConstants } from '../visualize_constants'; import { VisualizeServices, VisualizeEditorVisInstance } from '../types'; export const addHelpMenuToAppChrome = (chrome: ChromeStart, docLinks: DocLinksStart) => { @@ -58,3 +60,36 @@ export const visStateToEditorState = ( linked: savedVis && savedVis.id ? !!savedVis.savedSearchId : !!savedVisState.savedSearchId, }; }; + +export const redirectToSavedObjectPage = ( + services: VisualizeServices, + error: any, + savedVisualizationsId?: string +) => { + const { + history, + setActiveUrl, + toastNotifications, + http: { basePath }, + application: { navigateToApp }, + } = services; + const managementRedirectTarget = { + app: 'management', + path: `kibana/objects/savedVisualizations/${savedVisualizationsId}`, + }; + redirectWhenMissing({ + history, + navigateToApp, + toastNotifications, + basePath, + mapping: { + visualization: VisualizeConstants.LANDING_PAGE_PATH, + search: managementRedirectTarget, + 'index-pattern': managementRedirectTarget, + 'index-pattern-field': managementRedirectTarget, + }, + onBeforeRedirect() { + setActiveUrl(VisualizeConstants.LANDING_PAGE_PATH); + }, + })(error); +}; From de8ba08ac00045535a209af251cf40c837753b89 Mon Sep 17 00:00:00 2001 From: Kevin Qualters <56408403+kqualters-elastic@users.noreply.github.com> Date: Thu, 8 Apr 2021 10:44:31 -0400 Subject: [PATCH 5/9] [Security Solution][Rac][Tgrid] Use correct prop name for disabling timeline context menu button (#96453) * Use correct prop name for disabling timeline context menu button * Update usages of disabled to isDisabled on EuiIconButton * Update failing snapshot and tests looking for old prop --- .../add_to_case_action.test.tsx | 4 +- .../timeline_actions/add_to_case_action.tsx | 2 +- .../timeline_actions/alert_context_menu.tsx | 167 +++++++++--------- .../tooltip_footer.test.tsx.snap | 4 +- .../map_tool_tip/tooltip_footer.test.tsx | 32 ++-- .../map_tool_tip/tooltip_footer.tsx | 4 +- 6 files changed, 110 insertions(+), 103 deletions(-) diff --git a/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.test.tsx b/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.test.tsx index c99cabb50e3dc..40a202f5257a7 100644 --- a/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.test.tsx @@ -341,7 +341,7 @@ describe('AddToCaseAction', () => { ); expect( - wrapper.find(`[data-test-subj="attach-alert-to-case-button"]`).first().prop('disabled') + wrapper.find(`[data-test-subj="attach-alert-to-case-button"]`).first().prop('isDisabled') ).toBeTruthy(); }); @@ -358,7 +358,7 @@ describe('AddToCaseAction', () => { ); expect( - wrapper.find(`[data-test-subj="attach-alert-to-case-button"]`).first().prop('disabled') + wrapper.find(`[data-test-subj="attach-alert-to-case-button"]`).first().prop('isDisabled') ).toBeTruthy(); }); }); diff --git a/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx b/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx index decd37a7646e7..45c1355cecfa7 100644 --- a/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx @@ -172,7 +172,7 @@ const AddToCaseActionComponent: React.FC = ({ size="s" iconType="folderClosed" onClick={openPopover} - disabled={isDisabled} + isDisabled={isDisabled} /> ), diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx index b2e5638ff120e..26b9662a8f19b 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx @@ -215,19 +215,20 @@ const AlertContextMenuComponent: React.FC = ({ setEventsLoading, ]); - // eslint-disable-next-line react-hooks/exhaustive-deps - const openAlertActionComponent = ( - - {i18n.ACTION_OPEN_ALERT} - - ); + const openAlertActionComponent = useMemo(() => { + return ( + + {i18n.ACTION_OPEN_ALERT} + + ); + }, [openAlertActionOnClick, hasIndexUpdateDelete, hasIndexMaintenance]); const closeAlertActionClick = useCallback(() => { updateAlertStatusAction({ @@ -248,19 +249,20 @@ const AlertContextMenuComponent: React.FC = ({ setEventsLoading, ]); - // eslint-disable-next-line react-hooks/exhaustive-deps - const closeAlertActionComponent = ( - - {i18n.ACTION_CLOSE_ALERT} - - ); + const closeAlertActionComponent = useMemo(() => { + return ( + + {i18n.ACTION_CLOSE_ALERT} + + ); + }, [closeAlertActionClick, hasIndexUpdateDelete, hasIndexMaintenance]); const inProgressAlertActionClick = useCallback(() => { updateAlertStatusAction({ @@ -281,72 +283,77 @@ const AlertContextMenuComponent: React.FC = ({ setEventsLoading, ]); - // eslint-disable-next-line react-hooks/exhaustive-deps - const inProgressAlertActionComponent = ( - - {i18n.ACTION_IN_PROGRESS_ALERT} - - ); - - const button = ( - - - - ); + const inProgressAlertActionComponent = useMemo(() => { + return ( + + {i18n.ACTION_IN_PROGRESS_ALERT} + + ); + }, [canUserCRUD, hasIndexUpdateDelete, inProgressAlertActionClick]); + + const button = useMemo(() => { + return ( + + + + ); + }, [disabled, onButtonClick, ariaLabel]); const handleAddEndpointExceptionClick = useCallback((): void => { closePopover(); setOpenAddExceptionModal('endpoint'); }, [closePopover]); - // eslint-disable-next-line react-hooks/exhaustive-deps - const addEndpointExceptionComponent = ( - - {i18n.ACTION_ADD_ENDPOINT_EXCEPTION} - - ); + const addEndpointExceptionComponent = useMemo(() => { + return ( + + {i18n.ACTION_ADD_ENDPOINT_EXCEPTION} + + ); + }, [canUserCRUD, hasIndexWrite, isEndpointAlert, handleAddEndpointExceptionClick]); const handleAddExceptionClick = useCallback((): void => { closePopover(); setOpenAddExceptionModal('detection'); }, [closePopover]); - // eslint-disable-next-line react-hooks/exhaustive-deps - const addExceptionComponent = ( - - - {i18n.ACTION_ADD_EXCEPTION} - - - ); + const addExceptionComponent = useMemo(() => { + return ( + + + {i18n.ACTION_ADD_EXCEPTION} + + + ); + }, [handleAddExceptionClick, canUserCRUD, hasIndexWrite]); const statusFilters = useMemo(() => { if (!alertStatus) { diff --git a/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/__snapshots__/tooltip_footer.test.tsx.snap b/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/__snapshots__/tooltip_footer.test.tsx.snap index 8db9006da6156..1b91d396bee30 100644 --- a/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/__snapshots__/tooltip_footer.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/__snapshots__/tooltip_footer.test.tsx.snap @@ -27,16 +27,16 @@ exports[`ToolTipFilter renders correctly against snapshot 1`] = ` aria-label="Next" color="text" data-test-subj="previous-feature-button" - disabled={true} iconType="arrowLeft" + isDisabled={true} onClick={[MockFunction]} /> diff --git a/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/tooltip_footer.test.tsx b/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/tooltip_footer.test.tsx index a74022a222528..cc7662cf1e960 100644 --- a/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/tooltip_footer.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/tooltip_footer.test.tsx @@ -42,7 +42,7 @@ describe('ToolTipFilter', () => { ); expect( - wrapper.find('[data-test-subj="previous-feature-button"]').first().prop('disabled') + wrapper.find('[data-test-subj="previous-feature-button"]').first().prop('isDisabled') ).toBe(true); }); @@ -70,9 +70,9 @@ describe('ToolTipFilter', () => { /> ); - expect(wrapper.find('[data-test-subj="next-feature-button"]').first().prop('disabled')).toBe( - false - ); + expect( + wrapper.find('[data-test-subj="next-feature-button"]').first().prop('isDisabled') + ).toBe(false); }); test('nextFeature is called when featureIndex is < totalFeatures', () => { @@ -102,7 +102,7 @@ describe('ToolTipFilter', () => { ); expect( - wrapper.find('[data-test-subj="previous-feature-button"]').first().prop('disabled') + wrapper.find('[data-test-subj="previous-feature-button"]').first().prop('isDisabled') ).toBe(false); }); @@ -130,9 +130,9 @@ describe('ToolTipFilter', () => { /> ); - expect(wrapper.find('[data-test-subj="next-feature-button"]').first().prop('disabled')).toBe( - true - ); + expect( + wrapper.find('[data-test-subj="next-feature-button"]').first().prop('isDisabled') + ).toBe(true); }); test('nextFunction is not called when featureIndex >== totalFeatures', () => { @@ -161,7 +161,7 @@ describe('ToolTipFilter', () => { ); expect( - wrapper.find('[data-test-subj="previous-feature-button"]').first().prop('disabled') + wrapper.find('[data-test-subj="previous-feature-button"]').first().prop('isDisabled') ).toBe(true); }); @@ -189,9 +189,9 @@ describe('ToolTipFilter', () => { /> ); - expect(wrapper.find('[data-test-subj="next-feature-button"]').first().prop('disabled')).toBe( - true - ); + expect( + wrapper.find('[data-test-subj="next-feature-button"]').first().prop('isDisabled') + ).toBe(true); }); test('nextFunction is not called when only a single feature is provided', () => { @@ -221,7 +221,7 @@ describe('ToolTipFilter', () => { ); expect( - wrapper.find('[data-test-subj="previous-feature-button"]').first().prop('disabled') + wrapper.find('[data-test-subj="previous-feature-button"]').first().prop('isDisabled') ).toBe(false); }); @@ -249,9 +249,9 @@ describe('ToolTipFilter', () => { /> ); - expect(wrapper.find('[data-test-subj="next-feature-button"]').first().prop('disabled')).toBe( - false - ); + expect( + wrapper.find('[data-test-subj="next-feature-button"]').first().prop('isDisabled') + ).toBe(false); }); test('nextFunction is called when featureIndex > 0 && featureIndex < totalFeatures', () => { diff --git a/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/tooltip_footer.tsx b/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/tooltip_footer.tsx index 252260b2c5a2b..dbb280228e504 100644 --- a/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/tooltip_footer.tsx +++ b/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/tooltip_footer.tsx @@ -54,7 +54,7 @@ export const ToolTipFooterComponent = ({ onClick={previousFeature} iconType="arrowLeft" aria-label="Next" - disabled={featureIndex <= 0} + isDisabled={featureIndex <= 0} /> = totalFeatures - 1} + isDisabled={featureIndex >= totalFeatures - 1} /> From 158932e37773f0b8560073b5775266b1ed291c4b Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 8 Apr 2021 18:03:55 +0300 Subject: [PATCH 6/9] [Visualizations] Fixes chart visibility on Safari small screens (#96276) * [Visualizations] Fix chart visibility on Safari small screens * Fix safari bug without changing the chrome behavior * fix layout inconsistencies across browsers Co-authored-by: Michael Marcialis Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- src/plugins/vis_default_editor/public/_default.scss | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/vis_default_editor/public/_default.scss b/src/plugins/vis_default_editor/public/_default.scss index c412b9d915e55..56c6a0f0f63f6 100644 --- a/src/plugins/vis_default_editor/public/_default.scss +++ b/src/plugins/vis_default_editor/public/_default.scss @@ -1,6 +1,4 @@ .visEditor--default { - // height: 1px is in place to make editor children take their height in the parent - height: 1px; flex: 1 1 auto; display: flex; } @@ -80,6 +78,7 @@ .visEditor__collapsibleSidebar { width: 100% !important; // force the editor to take 100% width + flex-grow: 0; } .visEditor__collapsibleSidebar-isClosed { @@ -91,8 +90,10 @@ } .visEditor__visualization__wrapper { - // force the visualization to take 100% width and height. + // force the visualization to take 100% width. width: 100% !important; - height: 100% !important; + flex: 1; + display: flex; + flex-direction: column; } } From 8658ef49d80e191f615950e2d8f427182fff4294 Mon Sep 17 00:00:00 2001 From: Caroline Horn <549577+cchaos@users.noreply.github.com> Date: Thu, 8 Apr 2021 11:06:47 -0400 Subject: [PATCH 7/9] [K8] Continuing to fix the KQL bar styles (#96264) --- .../ui/query_string_input/_query_bar.scss | 20 ++++++++++++++++++- .../query_string_input/query_string_input.tsx | 11 ++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/plugins/data/public/ui/query_string_input/_query_bar.scss b/src/plugins/data/public/ui/query_string_input/_query_bar.scss index 466cc8c3de0b7..4e12f11668734 100644 --- a/src/plugins/data/public/ui/query_string_input/_query_bar.scss +++ b/src/plugins/data/public/ui/query_string_input/_query_bar.scss @@ -17,6 +17,16 @@ @include kbnThemeStyle('v8') { background-color: $euiFormBackgroundColor; + border-radius: $euiFormControlBorderRadius; + + &.kbnQueryBar__textareaWrap--hasPrepend { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + &.kbnQueryBar__textareaWrap--hasAppend { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } } } @@ -35,8 +45,16 @@ } @include kbnThemeStyle('v8') { - border-radius: 0; padding-bottom: $euiSizeS + 1px; + + &.kbnQueryBar__textarea--hasPrepend { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + &.kbnQueryBar__textarea--hasAppend { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } } &:not(.kbnQueryBar__textarea--autoHeight):not(:invalid) { diff --git a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx index 900a4ab7d7eb7..0f660f87266fd 100644 --- a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx @@ -682,7 +682,14 @@ export default class QueryStringInputUI extends Component { ); const inputClassName = classNames( 'kbnQueryBar__textarea', - this.props.iconType ? 'kbnQueryBar__textarea--withIcon' : null + this.props.iconType ? 'kbnQueryBar__textarea--withIcon' : null, + this.props.prepend ? 'kbnQueryBar__textarea--hasPrepend' : null, + !this.props.disableLanguageSwitcher ? 'kbnQueryBar__textarea--hasAppend' : null + ); + const inputWrapClassName = classNames( + 'euiFormControlLayout__childrenWrapper kbnQueryBar__textareaWrap', + this.props.prepend ? 'kbnQueryBar__textareaWrap--hasPrepend' : null, + !this.props.disableLanguageSwitcher ? 'kbnQueryBar__textareaWrap--hasAppend' : null ); return ( @@ -711,7 +718,7 @@ export default class QueryStringInputUI extends Component { >
Date: Thu, 8 Apr 2021 08:13:51 -0700 Subject: [PATCH 8/9] skip entire fleet_api_integration suite to unblock es promotion (#96515) --- x-pack/scripts/functional_tests.js | 3 ++- x-pack/test/fleet_api_integration/apis/agents_setup.ts | 3 +-- x-pack/test/fleet_api_integration/apis/epm/list.ts | 3 +-- x-pack/test/fleet_api_integration/apis/fleet_setup.ts | 3 +-- .../security_solution_endpoint_api_int/apis/artifacts/index.ts | 3 +-- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/x-pack/scripts/functional_tests.js b/x-pack/scripts/functional_tests.js index 90306466a9753..6321aa8880587 100644 --- a/x-pack/scripts/functional_tests.js +++ b/x-pack/scripts/functional_tests.js @@ -73,7 +73,8 @@ const onlyNotInCoverageTests = [ require.resolve('../test/reporting_api_integration/reporting_and_security.config.ts'), require.resolve('../test/reporting_api_integration/reporting_without_security.config.ts'), require.resolve('../test/security_solution_endpoint_api_int/config.ts'), - require.resolve('../test/fleet_api_integration/config.ts'), + // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/96515 + // require.resolve('../test/fleet_api_integration/config.ts'), require.resolve('../test/search_sessions_integration/config.ts'), require.resolve('../test/saved_object_tagging/api_integration/security_and_spaces/config.ts'), require.resolve('../test/saved_object_tagging/api_integration/tagging_api/config.ts'), diff --git a/x-pack/test/fleet_api_integration/apis/agents_setup.ts b/x-pack/test/fleet_api_integration/apis/agents_setup.ts index d49bc91251b01..91d6ca0119d1d 100644 --- a/x-pack/test/fleet_api_integration/apis/agents_setup.ts +++ b/x-pack/test/fleet_api_integration/apis/agents_setup.ts @@ -15,8 +15,7 @@ export default function (providerContext: FtrProviderContext) { const es = getService('es'); const esArchiver = getService('esArchiver'); - // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/96515 - describe.skip('fleet_agents_setup', () => { + describe('fleet_agents_setup', () => { skipIfNoDockerRegistry(providerContext); before(async () => { await esArchiver.load('empty_kibana'); diff --git a/x-pack/test/fleet_api_integration/apis/epm/list.ts b/x-pack/test/fleet_api_integration/apis/epm/list.ts index 0a7002764a54c..5a991e52bdba4 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/list.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/list.ts @@ -19,8 +19,7 @@ export default function (providerContext: FtrProviderContext) { // because `this` has to point to the Mocha context // see https://mochajs.org/#arrow-functions - // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/96515 - describe.skip('EPM - list', async function () { + describe('EPM - list', async function () { skipIfNoDockerRegistry(providerContext); before(async () => { await esArchiver.load('fleet/empty_fleet_server'); diff --git a/x-pack/test/fleet_api_integration/apis/fleet_setup.ts b/x-pack/test/fleet_api_integration/apis/fleet_setup.ts index a82ed3f8cf22d..c9709475d182d 100644 --- a/x-pack/test/fleet_api_integration/apis/fleet_setup.ts +++ b/x-pack/test/fleet_api_integration/apis/fleet_setup.ts @@ -15,8 +15,7 @@ export default function (providerContext: FtrProviderContext) { const es = getService('es'); const esArchiver = getService('esArchiver'); - // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/96515 - describe.skip('fleet_setup', () => { + describe('fleet_setup', () => { skipIfNoDockerRegistry(providerContext); before(async () => { await esArchiver.load('empty_kibana'); diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/artifacts/index.ts b/x-pack/test/security_solution_endpoint_api_int/apis/artifacts/index.ts index 8ee028ae3f56b..e1edeb7808697 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/artifacts/index.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/artifacts/index.ts @@ -19,8 +19,7 @@ export default function (providerContext: FtrProviderContext) { const supertestWithoutAuth = getSupertestWithoutAuth(providerContext); let agentAccessAPIKey: string; - // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/96515 - describe.skip('artifact download', () => { + describe('artifact download', () => { const esArchiverSnapshots = [ 'endpoint/artifacts/fleet_artifacts', 'endpoint/artifacts/api_feature', From 0d62e11736faef221cd7d1f0044d862255fe0d34 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Thu, 8 Apr 2021 17:23:36 +0200 Subject: [PATCH 9/9] Document SO migrations enableV2 and batchSize config options (#96290) * document SO batchsize and migrationsv2 enablement options * use refs by name * Update docs/setup/settings.asciidoc Co-authored-by: Luke Elmers * apply Lukes suggestion * add a note that migrations.enableV2 will be removed soon * document migrations.retryAttempts * Apply suggestions from code review Co-authored-by: Kaarina Tungseth Co-authored-by: Luke Elmers Co-authored-by: Kaarina Tungseth --- docs/setup/settings.asciidoc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 643718b961650..90e813afad6f4 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -429,6 +429,15 @@ to display map tiles in tilemap visualizations. By default, override this parameter to use their own Tile Map Service. For example: `"https://tiles.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana"` +| `migrations.batchSize:` + | Defines the number of documents migrated at a time. The higher the value, the faster the Saved Objects migration process performs at the cost of higher memory consumption. If the migration fails due to a `circuit_breaking_exception`, set a smaller `batchSize` value. *Default: `1000`* + +| `migrations.enableV2:` + | experimental[]. Enables the new Saved Objects migration algorithm. For information about the migration algorithm, refer to <>. When `migrations v2` is stable, the setting will be removed in an upcoming release without any further notice. Setting the value to `false` causes {kib} to use the legacy migration algorithm, which shipped in 7.11 and earlier versions. *Default: `true`* + +| `migrations.retryAttempts:` + | The number of times migrations retry temporary failures, such as a network timeout, 503 status code, or `snapshot_in_progress_exception`. When upgrade migrations frequently fail after exhausting all retry attempts with a message such as `Unable to complete the [...] step after 15 attempts, terminating.`, increase the setting value. *Default: `15`* + | `newsfeed.enabled:` | Controls whether to enable the newsfeed system for the {kib} UI notification center. Set to `false` to disable the