From ccd01a3af0528d0217c626a99643ff19ba5274fb Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Thu, 24 Oct 2019 16:21:46 -0700 Subject: [PATCH 01/61] Migrate ui/doc_title to New platform (#48121) * create NP docTitle service and bridge LP to it Signed-off-by: pgayvallet * properly prefix the docTitle public types Signed-off-by: pgayvallet * update documentation Signed-off-by: pgayvallet * replace direct NP access with closure to avoid error when importing module in tests with no usages Signed-off-by: pgayvallet * remove arrow functions for doc generation Signed-off-by: pgayvallet * remove get$ from the api Signed-off-by: pgayvallet * remove apply param and excludeBase option Signed-off-by: pgayvallet * remove removed export Signed-off-by: pgayvallet * adapt legacy service to new api Signed-off-by: pgayvallet * add entry about docTitle in the migration guide Signed-off-by: pgayvallet * add link in migration guide Signed-off-by: pgayvallet * update generated doc Signed-off-by: pgayvallet * update chrome mock Signed-off-by: pgayvallet * update snapshots due to api change Signed-off-by: pgayvallet * remove ChromeDocTitleChange in favor of inline type Signed-off-by: pgayvallet --- ...ana-plugin-public.chromedoctitle.change.md | 34 ++++++ .../kibana-plugin-public.chromedoctitle.md | 39 +++++++ ...bana-plugin-public.chromedoctitle.reset.md | 17 +++ ...bana-plugin-public.chromestart.doctitle.md | 13 +++ .../kibana-plugin-public.chromestart.md | 1 + .../core/public/kibana-plugin-public.md | 1 + src/core/MIGRATION.md | 1 + src/core/public/chrome/chrome_service.mock.ts | 7 ++ src/core/public/chrome/chrome_service.tsx | 8 +- .../doc_title/doc_title_service.test.ts | 80 +++++++++++++ .../chrome/doc_title/doc_title_service.ts | 105 ++++++++++++++++++ src/core/public/chrome/doc_title/index.ts | 20 ++++ src/core/public/chrome/index.ts | 1 + src/core/public/index.ts | 2 + src/core/public/public.api.md | 11 ++ .../query_bar_input.test.tsx.snap | 42 +++++++ .../public/doc_title/__tests__/doc_title.js | 34 +++--- src/legacy/ui/public/doc_title/doc_title.js | 37 +----- 18 files changed, 402 insertions(+), 51 deletions(-) create mode 100644 docs/development/core/public/kibana-plugin-public.chromedoctitle.change.md create mode 100644 docs/development/core/public/kibana-plugin-public.chromedoctitle.md create mode 100644 docs/development/core/public/kibana-plugin-public.chromedoctitle.reset.md create mode 100644 docs/development/core/public/kibana-plugin-public.chromestart.doctitle.md create mode 100644 src/core/public/chrome/doc_title/doc_title_service.test.ts create mode 100644 src/core/public/chrome/doc_title/doc_title_service.ts create mode 100644 src/core/public/chrome/doc_title/index.ts diff --git a/docs/development/core/public/kibana-plugin-public.chromedoctitle.change.md b/docs/development/core/public/kibana-plugin-public.chromedoctitle.change.md new file mode 100644 index 0000000000000..eba149bf93a4c --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.chromedoctitle.change.md @@ -0,0 +1,34 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [ChromeDocTitle](./kibana-plugin-public.chromedoctitle.md) > [change](./kibana-plugin-public.chromedoctitle.change.md) + +## ChromeDocTitle.change() method + +Changes the current document title. + +Signature: + +```typescript +change(newTitle: string | string[]): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| newTitle | string | string[] | | + +Returns: + +`void` + +## Example + +How to change the title of the document + +```ts +chrome.docTitle.change('My application title') +chrome.docTitle.change(['My application', 'My section']) + +``` + diff --git a/docs/development/core/public/kibana-plugin-public.chromedoctitle.md b/docs/development/core/public/kibana-plugin-public.chromedoctitle.md new file mode 100644 index 0000000000000..3c6cfab486288 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.chromedoctitle.md @@ -0,0 +1,39 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [ChromeDocTitle](./kibana-plugin-public.chromedoctitle.md) + +## ChromeDocTitle interface + +APIs for accessing and updating the document title. + +Signature: + +```typescript +export interface ChromeDocTitle +``` + +## Methods + +| Method | Description | +| --- | --- | +| [change(newTitle)](./kibana-plugin-public.chromedoctitle.change.md) | Changes the current document title. | +| [reset()](./kibana-plugin-public.chromedoctitle.reset.md) | Resets the document title to it's initial value. (meaning the one present in the title meta at application load.) | + +## Example 1 + +How to change the title of the document + +```ts +chrome.docTitle.change('My application') + +``` + +## Example 2 + +How to reset the title of the document to it's initial value + +```ts +chrome.docTitle.reset() + +``` + diff --git a/docs/development/core/public/kibana-plugin-public.chromedoctitle.reset.md b/docs/development/core/public/kibana-plugin-public.chromedoctitle.reset.md new file mode 100644 index 0000000000000..4b4c6f573e006 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.chromedoctitle.reset.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [ChromeDocTitle](./kibana-plugin-public.chromedoctitle.md) > [reset](./kibana-plugin-public.chromedoctitle.reset.md) + +## ChromeDocTitle.reset() method + +Resets the document title to it's initial value. (meaning the one present in the title meta at application load.) + +Signature: + +```typescript +reset(): void; +``` +Returns: + +`void` + diff --git a/docs/development/core/public/kibana-plugin-public.chromestart.doctitle.md b/docs/development/core/public/kibana-plugin-public.chromestart.doctitle.md new file mode 100644 index 0000000000000..71eda64c24646 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.chromestart.doctitle.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [ChromeStart](./kibana-plugin-public.chromestart.md) > [docTitle](./kibana-plugin-public.chromestart.doctitle.md) + +## ChromeStart.docTitle property + +APIs for accessing and updating the document title. + +Signature: + +```typescript +docTitle: ChromeDocTitle; +``` diff --git a/docs/development/core/public/kibana-plugin-public.chromestart.md b/docs/development/core/public/kibana-plugin-public.chromestart.md index bc41aa10cce8f..153e06d591404 100644 --- a/docs/development/core/public/kibana-plugin-public.chromestart.md +++ b/docs/development/core/public/kibana-plugin-public.chromestart.md @@ -16,6 +16,7 @@ export interface ChromeStart | Property | Type | Description | | --- | --- | --- | +| [docTitle](./kibana-plugin-public.chromestart.doctitle.md) | ChromeDocTitle | APIs for accessing and updating the document title. | | [navControls](./kibana-plugin-public.chromestart.navcontrols.md) | ChromeNavControls | [APIs](./kibana-plugin-public.chromenavcontrols.md) for registering new controls to be displayed in the navigation bar. | | [navLinks](./kibana-plugin-public.chromestart.navlinks.md) | ChromeNavLinks | [APIs](./kibana-plugin-public.chromenavlinks.md) for manipulating nav links. | | [recentlyAccessed](./kibana-plugin-public.chromestart.recentlyaccessed.md) | ChromeRecentlyAccessed | [APIs](./kibana-plugin-public.chromerecentlyaccessed.md) for recently accessed history. | diff --git a/docs/development/core/public/kibana-plugin-public.md b/docs/development/core/public/kibana-plugin-public.md index 57ab8bedde95e..253e50f0f2c2e 100644 --- a/docs/development/core/public/kibana-plugin-public.md +++ b/docs/development/core/public/kibana-plugin-public.md @@ -32,6 +32,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [Capabilities](./kibana-plugin-public.capabilities.md) | The read-only set of capabilities available for the current UI session. Capabilities are simple key-value pairs of (string, boolean), where the string denotes the capability ID, and the boolean is a flag indicating if the capability is enabled or disabled. | | [ChromeBadge](./kibana-plugin-public.chromebadge.md) | | | [ChromeBrand](./kibana-plugin-public.chromebrand.md) | | +| [ChromeDocTitle](./kibana-plugin-public.chromedoctitle.md) | APIs for accessing and updating the document title. | | [ChromeNavControl](./kibana-plugin-public.chromenavcontrol.md) | | | [ChromeNavControls](./kibana-plugin-public.chromenavcontrols.md) | [APIs](./kibana-plugin-public.chromenavcontrols.md) for registering new controls to be displayed in the navigation bar. | | [ChromeNavLink](./kibana-plugin-public.chromenavlink.md) | | diff --git a/src/core/MIGRATION.md b/src/core/MIGRATION.md index 6a12b587085e1..b5942cc82941f 100644 --- a/src/core/MIGRATION.md +++ b/src/core/MIGRATION.md @@ -1111,6 +1111,7 @@ import { npStart: { core } } from 'ui/new_platform'; | `ui/notify` | [`core.notifications`](/docs/development/core/public/kibana-plugin-public.notificationsstart.md) and [`core.overlays`](/docs/development/core/public/kibana-plugin-public.overlaystart.md) | Toast messages are in `notifications`, banners are in `overlays`. May be combined later. | | `ui/routes` | -- | There is no global routing mechanism. Each app [configures its own routing](/rfcs/text/0004_application_service_mounting.md#complete-example). | | `ui/saved_objects` | [`core.savedObjects`](/docs/development/core/public/kibana-plugin-public.savedobjectsstart.md) | Client API is the same | +| `ui/doc_title` | [`core.chrome.docTitle`](/docs/development/core/public/kibana-plugin-public.chromedoctitle.md) | | _See also: [Public's CoreStart API Docs](/docs/development/core/public/kibana-plugin-public.corestart.md)_ diff --git a/src/core/public/chrome/chrome_service.mock.ts b/src/core/public/chrome/chrome_service.mock.ts index 3775989c5126b..6f61ee9dc21ba 100644 --- a/src/core/public/chrome/chrome_service.mock.ts +++ b/src/core/public/chrome/chrome_service.mock.ts @@ -43,6 +43,13 @@ const createStartContractMock = () => { get: jest.fn(), get$: jest.fn(), }, + docTitle: { + change: jest.fn(), + reset: jest.fn(), + __legacy: { + setBaseTitle: jest.fn(), + }, + }, navControls: { registerLeft: jest.fn(), registerRight: jest.fn(), diff --git a/src/core/public/chrome/chrome_service.tsx b/src/core/public/chrome/chrome_service.tsx index 71279ad6fed03..87389d2c10f03 100644 --- a/src/core/public/chrome/chrome_service.tsx +++ b/src/core/public/chrome/chrome_service.tsx @@ -33,10 +33,11 @@ import { HttpStart } from '../http'; import { ChromeNavLinks, NavLinksService } from './nav_links'; import { ChromeRecentlyAccessed, RecentlyAccessedService } from './recently_accessed'; import { NavControlsService, ChromeNavControls } from './nav_controls'; +import { DocTitleService, ChromeDocTitle } from './doc_title'; import { LoadingIndicator, HeaderWrapper as Header } from './ui'; import { DocLinksStart } from '../doc_links'; -export { ChromeNavControls, ChromeRecentlyAccessed }; +export { ChromeNavControls, ChromeRecentlyAccessed, ChromeDocTitle }; const IS_COLLAPSED_KEY = 'core.chrome.isCollapsed'; @@ -82,6 +83,7 @@ export class ChromeService { private readonly navControls = new NavControlsService(); private readonly navLinks = new NavLinksService(); private readonly recentlyAccessed = new RecentlyAccessedService(); + private readonly docTitle = new DocTitleService(); constructor(private readonly params: ConstructorParams) {} @@ -106,6 +108,7 @@ export class ChromeService { const navControls = this.navControls.start(); const navLinks = this.navLinks.start({ application, http }); const recentlyAccessed = await this.recentlyAccessed.start({ http }); + const docTitle = this.docTitle.start({ document: window.document }); if (!this.params.browserSupportsCsp && injectedMetadata.getCspConfig().warnLegacyBrowsers) { notifications.toasts.addWarning( @@ -119,6 +122,7 @@ export class ChromeService { navControls, navLinks, recentlyAccessed, + docTitle, getHeaderComponent: () => ( @@ -259,6 +263,8 @@ export interface ChromeStart { navControls: ChromeNavControls; /** {@inheritdoc ChromeRecentlyAccessed} */ recentlyAccessed: ChromeRecentlyAccessed; + /** {@inheritdoc ChromeDocTitle} */ + docTitle: ChromeDocTitle; /** * Sets the current app's title diff --git a/src/core/public/chrome/doc_title/doc_title_service.test.ts b/src/core/public/chrome/doc_title/doc_title_service.test.ts new file mode 100644 index 0000000000000..763e8c9ebd74a --- /dev/null +++ b/src/core/public/chrome/doc_title/doc_title_service.test.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. + */ + +import { DocTitleService } from './doc_title_service'; + +describe('DocTitleService', () => { + const defaultTitle = 'KibanaTest'; + const document = { title: '' }; + + const getStart = (title: string = defaultTitle) => { + document.title = title; + return new DocTitleService().start({ document }); + }; + + beforeEach(() => { + document.title = defaultTitle; + }); + + describe('#change()', () => { + it('changes the title of the document', async () => { + getStart().change('TitleA'); + expect(document.title).toEqual('TitleA - KibanaTest'); + }); + + it('appends the baseTitle to the title', async () => { + const start = getStart('BaseTitle'); + start.change('TitleA'); + expect(document.title).toEqual('TitleA - BaseTitle'); + start.change('TitleB'); + expect(document.title).toEqual('TitleB - BaseTitle'); + }); + + it('accepts string arrays as input', async () => { + const start = getStart(); + start.change(['partA', 'partB']); + expect(document.title).toEqual(`partA - partB - ${defaultTitle}`); + start.change(['partA', 'partB', 'partC']); + expect(document.title).toEqual(`partA - partB - partC - ${defaultTitle}`); + }); + }); + + describe('#reset()', () => { + it('resets the title to the initial value', async () => { + const start = getStart('InitialTitle'); + start.change('TitleA'); + expect(document.title).toEqual('TitleA - InitialTitle'); + start.reset(); + expect(document.title).toEqual('InitialTitle'); + }); + }); + + describe('#__legacy.setBaseTitle()', () => { + it('allows to change the baseTitle after startup', async () => { + const start = getStart('InitialTitle'); + start.change('WithInitial'); + expect(document.title).toEqual('WithInitial - InitialTitle'); + start.__legacy.setBaseTitle('NewBaseTitle'); + start.change('WithNew'); + expect(document.title).toEqual('WithNew - NewBaseTitle'); + start.reset(); + expect(document.title).toEqual('NewBaseTitle'); + }); + }); +}); diff --git a/src/core/public/chrome/doc_title/doc_title_service.ts b/src/core/public/chrome/doc_title/doc_title_service.ts new file mode 100644 index 0000000000000..9453abe54de66 --- /dev/null +++ b/src/core/public/chrome/doc_title/doc_title_service.ts @@ -0,0 +1,105 @@ +/* + * 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 { compact, flattenDeep, isString } from 'lodash'; + +interface StartDeps { + document: { title: string }; +} + +/** + * APIs for accessing and updating the document title. + * + * @example + * How to change the title of the document + * ```ts + * chrome.docTitle.change('My application') + * ``` + * + * @example + * How to reset the title of the document to it's initial value + * ```ts + * chrome.docTitle.reset() + * ``` + * + * @public + * */ +export interface ChromeDocTitle { + /** + * Changes the current document title. + * + * @example + * How to change the title of the document + * ```ts + * chrome.docTitle.change('My application title') + * chrome.docTitle.change(['My application', 'My section']) + * ``` + * + * @param newTitle The new title to set, either a string or string array + */ + change(newTitle: string | string[]): void; + /** + * Resets the document title to it's initial value. + * (meaning the one present in the title meta at application load.) + */ + reset(): void; + + /** @internal */ + __legacy: { + setBaseTitle(baseTitle: string): void; + }; +} + +const defaultTitle: string[] = []; +const titleSeparator = ' - '; + +/** @internal */ +export class DocTitleService { + private document = { title: '' }; + private baseTitle = ''; + + public start({ document }: StartDeps): ChromeDocTitle { + this.document = document; + this.baseTitle = document.title; + + return { + change: (title: string | string[]) => { + this.applyTitle(title); + }, + reset: () => { + this.applyTitle(defaultTitle); + }, + __legacy: { + setBaseTitle: baseTitle => { + this.baseTitle = baseTitle; + }, + }, + }; + } + + private applyTitle(title: string | string[]) { + this.document.title = this.render(title); + } + + private render(title: string | string[]) { + const parts = [...(isString(title) ? [title] : title), this.baseTitle]; + // ensuring compat with legacy that might be passing nested arrays + return compact(flattenDeep(parts)).join(titleSeparator); + } +} diff --git a/src/core/public/chrome/doc_title/index.ts b/src/core/public/chrome/doc_title/index.ts new file mode 100644 index 0000000000000..b070d01953f7a --- /dev/null +++ b/src/core/public/chrome/doc_title/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 './doc_title_service'; diff --git a/src/core/public/chrome/index.ts b/src/core/public/chrome/index.ts index 6e03f9e023983..b220a81f775f8 100644 --- a/src/core/public/chrome/index.ts +++ b/src/core/public/chrome/index.ts @@ -29,3 +29,4 @@ export { export { ChromeNavLink, ChromeNavLinks, ChromeNavLinkUpdateableFields } from './nav_links'; export { ChromeRecentlyAccessed, ChromeRecentlyAccessedHistoryItem } from './recently_accessed'; export { ChromeNavControl, ChromeNavControls } from './nav_controls'; +export { ChromeDocTitle } from './doc_title'; diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 24201ff0253cb..7391cf7f9454c 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -45,6 +45,7 @@ import { ChromeNavLink, ChromeNavLinks, ChromeNavLinkUpdateableFields, + ChromeDocTitle, ChromeStart, ChromeRecentlyAccessed, ChromeRecentlyAccessedHistoryItem, @@ -250,6 +251,7 @@ export { ChromeNavLink, ChromeNavLinks, ChromeNavLinkUpdateableFields, + ChromeDocTitle, ChromeRecentlyAccessed, ChromeRecentlyAccessedHistoryItem, ChromeStart, diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 11a1b5c0d1d9b..416fb13cbb73e 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -105,6 +105,16 @@ export interface ChromeBrand { // @public (undocumented) export type ChromeBreadcrumb = Breadcrumb; +// @public +export interface ChromeDocTitle { + // @internal (undocumented) + __legacy: { + setBaseTitle(baseTitle: string): void; + }; + change(newTitle: string | string[]): void; + reset(): void; +} + // @public (undocumented) export type ChromeHelpExtension = (element: HTMLDivElement) => () => void; @@ -186,6 +196,7 @@ export interface ChromeRecentlyAccessedHistoryItem { // @public export interface ChromeStart { addApplicationClass(className: string): void; + docTitle: ChromeDocTitle; getApplicationClasses$(): Observable; getBadge$(): Observable; getBrand$(): Observable; diff --git a/src/legacy/core_plugins/data/public/query/query_bar/components/__snapshots__/query_bar_input.test.tsx.snap b/src/legacy/core_plugins/data/public/query/query_bar/components/__snapshots__/query_bar_input.test.tsx.snap index f59afc7165bab..286e60cca9712 100644 --- a/src/legacy/core_plugins/data/public/query/query_bar/components/__snapshots__/query_bar_input.test.tsx.snap +++ b/src/legacy/core_plugins/data/public/query/query_bar/components/__snapshots__/query_bar_input.test.tsx.snap @@ -103,6 +103,13 @@ exports[`QueryBarInput Should disable autoFocus on EuiFieldText when disableAuto }, "chrome": Object { "addApplicationClass": [MockFunction], + "docTitle": Object { + "__legacy": Object { + "setBaseTitle": [MockFunction], + }, + "change": [MockFunction], + "reset": [MockFunction], + }, "getApplicationClasses$": [MockFunction], "getBadge$": [MockFunction], "getBrand$": [MockFunction], @@ -659,6 +666,13 @@ exports[`QueryBarInput Should disable autoFocus on EuiFieldText when disableAuto }, "chrome": Object { "addApplicationClass": [MockFunction], + "docTitle": Object { + "__legacy": Object { + "setBaseTitle": [MockFunction], + }, + "change": [MockFunction], + "reset": [MockFunction], + }, "getApplicationClasses$": [MockFunction], "getBadge$": [MockFunction], "getBrand$": [MockFunction], @@ -1203,6 +1217,13 @@ exports[`QueryBarInput Should pass the query language to the language switcher 1 }, "chrome": Object { "addApplicationClass": [MockFunction], + "docTitle": Object { + "__legacy": Object { + "setBaseTitle": [MockFunction], + }, + "change": [MockFunction], + "reset": [MockFunction], + }, "getApplicationClasses$": [MockFunction], "getBadge$": [MockFunction], "getBrand$": [MockFunction], @@ -1756,6 +1777,13 @@ exports[`QueryBarInput Should pass the query language to the language switcher 1 }, "chrome": Object { "addApplicationClass": [MockFunction], + "docTitle": Object { + "__legacy": Object { + "setBaseTitle": [MockFunction], + }, + "change": [MockFunction], + "reset": [MockFunction], + }, "getApplicationClasses$": [MockFunction], "getBadge$": [MockFunction], "getBrand$": [MockFunction], @@ -2300,6 +2328,13 @@ exports[`QueryBarInput Should render the given query 1`] = ` }, "chrome": Object { "addApplicationClass": [MockFunction], + "docTitle": Object { + "__legacy": Object { + "setBaseTitle": [MockFunction], + }, + "change": [MockFunction], + "reset": [MockFunction], + }, "getApplicationClasses$": [MockFunction], "getBadge$": [MockFunction], "getBrand$": [MockFunction], @@ -2853,6 +2888,13 @@ exports[`QueryBarInput Should render the given query 1`] = ` }, "chrome": Object { "addApplicationClass": [MockFunction], + "docTitle": Object { + "__legacy": Object { + "setBaseTitle": [MockFunction], + }, + "change": [MockFunction], + "reset": [MockFunction], + }, "getApplicationClasses$": [MockFunction], "getBadge$": [MockFunction], "getBrand$": [MockFunction], diff --git a/src/legacy/ui/public/doc_title/__tests__/doc_title.js b/src/legacy/ui/public/doc_title/__tests__/doc_title.js index b4c3700e36f68..fa8b83f755957 100644 --- a/src/legacy/ui/public/doc_title/__tests__/doc_title.js +++ b/src/legacy/ui/public/doc_title/__tests__/doc_title.js @@ -20,7 +20,8 @@ import sinon from 'sinon'; import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import { setBaseTitle, docTitle } from '../doc_title'; +import { docTitle } from '../doc_title'; +import { npStart } from '../../new_platform'; describe('docTitle Service', function () { let initialDocTitle; @@ -30,20 +31,24 @@ describe('docTitle Service', function () { beforeEach(function () { initialDocTitle = document.title; document.title = MAIN_TITLE; - setBaseTitle(MAIN_TITLE); + npStart.core.chrome.docTitle.__legacy.setBaseTitle(MAIN_TITLE); }); afterEach(function () { document.title = initialDocTitle; - setBaseTitle(initialDocTitle); + npStart.core.chrome.docTitle.__legacy.setBaseTitle(initialDocTitle); }); - beforeEach(ngMock.module('kibana', function ($provide) { - $provide.decorator('$rootScope', decorateWithSpy('$on')); - })); + beforeEach( + ngMock.module('kibana', function ($provide) { + $provide.decorator('$rootScope', decorateWithSpy('$on')); + }) + ); - beforeEach(ngMock.inject(function ($injector) { - $rootScope = $injector.get('$rootScope'); - })); + beforeEach( + ngMock.inject(function ($injector) { + $rootScope = $injector.get('$rootScope'); + }) + ); describe('setup', function () { it('resets the title when a route change begins', function () { @@ -60,13 +65,11 @@ describe('docTitle Service', function () { }); describe('#reset', function () { - it('clears the internal state, next update() will write the default', function () { + it('clears the internal state', function () { docTitle.change('some title'); - docTitle.update(); expect(document.title).to.be('some title - ' + MAIN_TITLE); docTitle.reset(); - docTitle.update(); expect(document.title).to.be(MAIN_TITLE); }); }); @@ -77,12 +80,6 @@ describe('docTitle Service', function () { docTitle.change('some secondary title'); expect(document.title).to.be('some secondary title - ' + MAIN_TITLE); }); - - it('will write just the first param if the second param is true', function () { - expect(document.title).to.be(MAIN_TITLE); - docTitle.change('entire name', true); - expect(document.title).to.be('entire name'); - }); }); function decorateWithSpy(prop) { @@ -91,5 +88,4 @@ describe('docTitle Service', function () { return $delegate; }; } - }); diff --git a/src/legacy/ui/public/doc_title/doc_title.js b/src/legacy/ui/public/doc_title/doc_title.js index 3692fd71f06cc..0edc55a0ac366 100644 --- a/src/legacy/ui/public/doc_title/doc_title.js +++ b/src/legacy/ui/public/doc_title/doc_title.js @@ -17,53 +17,28 @@ * under the License. */ -import _ from 'lodash'; +import { isArray } from 'lodash'; import { uiModules } from '../modules'; +import { npStart } from '../new_platform'; -let baseTitle = document.title; +const npDocTitle = () => npStart.core.chrome.docTitle; -// for karma test -export function setBaseTitle(str) { - baseTitle = str; -} - -let lastChange; - -function render() { - lastChange = lastChange || []; - - const parts = [lastChange[0]]; - - if (!lastChange[1]) parts.push(baseTitle); - - return _(parts).flattenDeep().compact().join(' - '); -} - -function change(title, complete) { - lastChange = [title, complete]; - update(); +function change(title) { + npDocTitle().change(isArray(title) ? title : [title]); } function reset() { - lastChange = null; -} - -function update() { - document.title = render(); + npDocTitle().reset(); } export const docTitle = { - render, change, reset, - update, }; uiModules.get('kibana') .run(function ($rootScope) { // always bind to the route events $rootScope.$on('$routeChangeStart', docTitle.reset); - $rootScope.$on('$routeChangeError', docTitle.update); - $rootScope.$on('$routeChangeSuccess', docTitle.update); }); From 296fa8e7229c2027ee7180e8c6612cba18bb351a Mon Sep 17 00:00:00 2001 From: Spencer Date: Thu, 24 Oct 2019 17:02:21 -0700 Subject: [PATCH 02/61] increase type check memory for x-pack to 4GB (#49255) --- src/dev/typescript/run_type_check_cli.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dev/typescript/run_type_check_cli.ts b/src/dev/typescript/run_type_check_cli.ts index bf6e8711fa81e..3deebcc0c18f9 100644 --- a/src/dev/typescript/run_type_check_cli.ts +++ b/src/dev/typescript/run_type_check_cli.ts @@ -88,7 +88,7 @@ export function runTypeCheckCli() { } execInProjects(log, projects, process.execPath, project => [ - ...(project.name === 'x-pack' ? ['--max-old-space-size=2048'] : []), + ...(project.name === 'x-pack' ? ['--max-old-space-size=4096'] : []), require.resolve('typescript/bin/tsc'), ...['--project', project.tsConfigPath], ...tscArgs, From 2ac82dec61f3fbf4b821fd72cf37b06afcc8a1ff Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Fri, 25 Oct 2019 08:28:55 +0100 Subject: [PATCH 03/61] [Saved Objects] Adds support for custom Refresh settings on mutating operations (#48932) Adds the ability to override the Refresh setting of mutating operations (Update, Delete, Bulk, Index) of Saved Objects. --- .../core/server/kibana-plugin-server.md | 3 + ...-server.mutatingoperationrefreshsetting.md | 13 ++ ...in-server.savedobjectsbulkupdateoptions.md | 19 ++ ...r.savedobjectsbulkupdateoptions.refresh.md | 13 ++ ...in-server.savedobjectsclient.bulkupdate.md | 4 +- ...plugin-server.savedobjectsclient.delete.md | 4 +- ...plugin-server.savedobjectscreateoptions.md | 1 + ...erver.savedobjectscreateoptions.refresh.md | 13 ++ ...plugin-server.savedobjectsdeleteoptions.md | 19 ++ ...erver.savedobjectsdeleteoptions.refresh.md | 13 ++ ...plugin-server.savedobjectsupdateoptions.md | 1 + ...erver.savedobjectsupdateoptions.refresh.md | 13 ++ src/core/server/index.ts | 3 + .../service/lib/repository.test.js | 218 ++++++++++++++++++ .../saved_objects/service/lib/repository.ts | 51 ++-- .../service/saved_objects_client.ts | 36 ++- src/core/server/saved_objects/types.ts | 6 + src/core/server/server.api.md | 19 +- 18 files changed, 426 insertions(+), 23 deletions(-) create mode 100644 docs/development/core/server/kibana-plugin-server.mutatingoperationrefreshsetting.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsbulkupdateoptions.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsbulkupdateoptions.refresh.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectscreateoptions.refresh.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsdeleteoptions.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsdeleteoptions.refresh.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsupdateoptions.refresh.md diff --git a/docs/development/core/server/kibana-plugin-server.md b/docs/development/core/server/kibana-plugin-server.md index 2f81afacf4bb4..5a8b702e0ec99 100644 --- a/docs/development/core/server/kibana-plugin-server.md +++ b/docs/development/core/server/kibana-plugin-server.md @@ -90,10 +90,12 @@ The plugin integrates with the core system via lifecycle events: `setup` | [SavedObjectsBulkGetObject](./kibana-plugin-server.savedobjectsbulkgetobject.md) | | | [SavedObjectsBulkResponse](./kibana-plugin-server.savedobjectsbulkresponse.md) | | | [SavedObjectsBulkUpdateObject](./kibana-plugin-server.savedobjectsbulkupdateobject.md) | | +| [SavedObjectsBulkUpdateOptions](./kibana-plugin-server.savedobjectsbulkupdateoptions.md) | | | [SavedObjectsBulkUpdateResponse](./kibana-plugin-server.savedobjectsbulkupdateresponse.md) | | | [SavedObjectsClientProviderOptions](./kibana-plugin-server.savedobjectsclientprovideroptions.md) | Options to control the creation of the Saved Objects Client. | | [SavedObjectsClientWrapperOptions](./kibana-plugin-server.savedobjectsclientwrapperoptions.md) | Options passed to each SavedObjectsClientWrapperFactory to aid in creating the wrapper instance. | | [SavedObjectsCreateOptions](./kibana-plugin-server.savedobjectscreateoptions.md) | | +| [SavedObjectsDeleteOptions](./kibana-plugin-server.savedobjectsdeleteoptions.md) | | | [SavedObjectsExportOptions](./kibana-plugin-server.savedobjectsexportoptions.md) | Options controlling the export operation. | | [SavedObjectsExportResultDetails](./kibana-plugin-server.savedobjectsexportresultdetails.md) | Structure of the export result details entry | | [SavedObjectsFindOptions](./kibana-plugin-server.savedobjectsfindoptions.md) | | @@ -149,6 +151,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [LifecycleResponseFactory](./kibana-plugin-server.lifecycleresponsefactory.md) | Creates an object containing redirection or error response with error details, HTTP headers, and other data transmitted to the client. | | [MIGRATION\_ASSISTANCE\_INDEX\_ACTION](./kibana-plugin-server.migration_assistance_index_action.md) | | | [MIGRATION\_DEPRECATION\_LEVEL](./kibana-plugin-server.migration_deprecation_level.md) | | +| [MutatingOperationRefreshSetting](./kibana-plugin-server.mutatingoperationrefreshsetting.md) | Elasticsearch Refresh setting for mutating operation | | [OnPostAuthHandler](./kibana-plugin-server.onpostauthhandler.md) | See [OnPostAuthToolkit](./kibana-plugin-server.onpostauthtoolkit.md). | | [OnPreAuthHandler](./kibana-plugin-server.onpreauthhandler.md) | See [OnPreAuthToolkit](./kibana-plugin-server.onpreauthtoolkit.md). | | [PluginInitializer](./kibana-plugin-server.plugininitializer.md) | The plugin export at the root of a plugin's server directory should conform to this interface. | diff --git a/docs/development/core/server/kibana-plugin-server.mutatingoperationrefreshsetting.md b/docs/development/core/server/kibana-plugin-server.mutatingoperationrefreshsetting.md new file mode 100644 index 0000000000000..94c8fa8c22ef6 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.mutatingoperationrefreshsetting.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [MutatingOperationRefreshSetting](./kibana-plugin-server.mutatingoperationrefreshsetting.md) + +## MutatingOperationRefreshSetting type + +Elasticsearch Refresh setting for mutating operation + +Signature: + +```typescript +export declare type MutatingOperationRefreshSetting = boolean | 'wait_for'; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsbulkupdateoptions.md b/docs/development/core/server/kibana-plugin-server.savedobjectsbulkupdateoptions.md new file mode 100644 index 0000000000000..920a6ca224df4 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsbulkupdateoptions.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsBulkUpdateOptions](./kibana-plugin-server.savedobjectsbulkupdateoptions.md) + +## SavedObjectsBulkUpdateOptions interface + + +Signature: + +```typescript +export interface SavedObjectsBulkUpdateOptions extends SavedObjectsBaseOptions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [refresh](./kibana-plugin-server.savedobjectsbulkupdateoptions.refresh.md) | MutatingOperationRefreshSetting | The Elasticsearch Refresh setting for this operation | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsbulkupdateoptions.refresh.md b/docs/development/core/server/kibana-plugin-server.savedobjectsbulkupdateoptions.refresh.md new file mode 100644 index 0000000000000..35e9e6483da10 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsbulkupdateoptions.refresh.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsBulkUpdateOptions](./kibana-plugin-server.savedobjectsbulkupdateoptions.md) > [refresh](./kibana-plugin-server.savedobjectsbulkupdateoptions.refresh.md) + +## SavedObjectsBulkUpdateOptions.refresh property + +The Elasticsearch Refresh setting for this operation + +Signature: + +```typescript +refresh?: MutatingOperationRefreshSetting; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsclient.bulkupdate.md b/docs/development/core/server/kibana-plugin-server.savedobjectsclient.bulkupdate.md index 107e71959f706..30db524ffa02c 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectsclient.bulkupdate.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsclient.bulkupdate.md @@ -9,7 +9,7 @@ Bulk Updates multiple SavedObject at once Signature: ```typescript -bulkUpdate(objects: Array>, options?: SavedObjectsBaseOptions): Promise>; +bulkUpdate(objects: Array>, options?: SavedObjectsBulkUpdateOptions): Promise>; ``` ## Parameters @@ -17,7 +17,7 @@ bulkUpdate(objects: ArrayArray<SavedObjectsBulkUpdateObject<T>> | | -| options | SavedObjectsBaseOptions | | +| options | SavedObjectsBulkUpdateOptions | | Returns: diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsclient.delete.md b/docs/development/core/server/kibana-plugin-server.savedobjectsclient.delete.md index 657f56d591e77..c20c7e886490a 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectsclient.delete.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsclient.delete.md @@ -9,7 +9,7 @@ Deletes a SavedObject Signature: ```typescript -delete(type: string, id: string, options?: SavedObjectsBaseOptions): Promise<{}>; +delete(type: string, id: string, options?: SavedObjectsDeleteOptions): Promise<{}>; ``` ## Parameters @@ -18,7 +18,7 @@ delete(type: string, id: string, options?: SavedObjectsBaseOptions): Promise<{}> | --- | --- | --- | | type | string | | | id | string | | -| options | SavedObjectsBaseOptions | | +| options | SavedObjectsDeleteOptions | | Returns: diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectscreateoptions.md b/docs/development/core/server/kibana-plugin-server.savedobjectscreateoptions.md index 16549e420ac01..e4ad636056915 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectscreateoptions.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectscreateoptions.md @@ -19,4 +19,5 @@ export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions | [migrationVersion](./kibana-plugin-server.savedobjectscreateoptions.migrationversion.md) | SavedObjectsMigrationVersion | Information about the migrations that have been applied to this SavedObject. When Kibana starts up, KibanaMigrator detects outdated documents and migrates them based on this value. For each migration that has been applied, the plugin's name is used as a key and the latest migration version as the value. | | [overwrite](./kibana-plugin-server.savedobjectscreateoptions.overwrite.md) | boolean | Overwrite existing documents (defaults to false) | | [references](./kibana-plugin-server.savedobjectscreateoptions.references.md) | SavedObjectReference[] | | +| [refresh](./kibana-plugin-server.savedobjectscreateoptions.refresh.md) | MutatingOperationRefreshSetting | The Elasticsearch Refresh setting for this operation | diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectscreateoptions.refresh.md b/docs/development/core/server/kibana-plugin-server.savedobjectscreateoptions.refresh.md new file mode 100644 index 0000000000000..785874a12c8c4 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectscreateoptions.refresh.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsCreateOptions](./kibana-plugin-server.savedobjectscreateoptions.md) > [refresh](./kibana-plugin-server.savedobjectscreateoptions.refresh.md) + +## SavedObjectsCreateOptions.refresh property + +The Elasticsearch Refresh setting for this operation + +Signature: + +```typescript +refresh?: MutatingOperationRefreshSetting; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsdeleteoptions.md b/docs/development/core/server/kibana-plugin-server.savedobjectsdeleteoptions.md new file mode 100644 index 0000000000000..2c641ba5cc8d8 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsdeleteoptions.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsDeleteOptions](./kibana-plugin-server.savedobjectsdeleteoptions.md) + +## SavedObjectsDeleteOptions interface + + +Signature: + +```typescript +export interface SavedObjectsDeleteOptions extends SavedObjectsBaseOptions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [refresh](./kibana-plugin-server.savedobjectsdeleteoptions.refresh.md) | MutatingOperationRefreshSetting | The Elasticsearch Refresh setting for this operation | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsdeleteoptions.refresh.md b/docs/development/core/server/kibana-plugin-server.savedobjectsdeleteoptions.refresh.md new file mode 100644 index 0000000000000..782c52956f297 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsdeleteoptions.refresh.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsDeleteOptions](./kibana-plugin-server.savedobjectsdeleteoptions.md) > [refresh](./kibana-plugin-server.savedobjectsdeleteoptions.refresh.md) + +## SavedObjectsDeleteOptions.refresh property + +The Elasticsearch Refresh setting for this operation + +Signature: + +```typescript +refresh?: MutatingOperationRefreshSetting; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsupdateoptions.md b/docs/development/core/server/kibana-plugin-server.savedobjectsupdateoptions.md index 7fcd362e937a0..49e8946ad2826 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectsupdateoptions.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsupdateoptions.md @@ -16,5 +16,6 @@ export interface SavedObjectsUpdateOptions extends SavedObjectsBaseOptions | Property | Type | Description | | --- | --- | --- | | [references](./kibana-plugin-server.savedobjectsupdateoptions.references.md) | SavedObjectReference[] | A reference to another saved object. | +| [refresh](./kibana-plugin-server.savedobjectsupdateoptions.refresh.md) | MutatingOperationRefreshSetting | The Elasticsearch Refresh setting for this operation | | [version](./kibana-plugin-server.savedobjectsupdateoptions.version.md) | string | An opaque version number which changes on each successful write operation. Can be used for implementing optimistic concurrency control. | diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsupdateoptions.refresh.md b/docs/development/core/server/kibana-plugin-server.savedobjectsupdateoptions.refresh.md new file mode 100644 index 0000000000000..bb1142c242012 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsupdateoptions.refresh.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsUpdateOptions](./kibana-plugin-server.savedobjectsupdateoptions.md) > [refresh](./kibana-plugin-server.savedobjectsupdateoptions.refresh.md) + +## SavedObjectsUpdateOptions.refresh property + +The Elasticsearch Refresh setting for this operation + +Signature: + +```typescript +refresh?: MutatingOperationRefreshSetting; +``` diff --git a/src/core/server/index.ts b/src/core/server/index.ts index e0d230006d587..c3f63c7c26e97 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -139,6 +139,7 @@ export { SavedObjectsBulkCreateObject, SavedObjectsBulkGetObject, SavedObjectsBulkUpdateObject, + SavedObjectsBulkUpdateOptions, SavedObjectsBulkResponse, SavedObjectsBulkUpdateResponse, SavedObjectsClient, @@ -166,6 +167,7 @@ export { SavedObjectsLegacyService, SavedObjectsUpdateOptions, SavedObjectsUpdateResponse, + SavedObjectsDeleteOptions, } from './saved_objects'; export { @@ -184,6 +186,7 @@ export { SavedObjectAttributeSingle, SavedObjectReference, SavedObjectsBaseOptions, + MutatingOperationRefreshSetting, SavedObjectsClientContract, SavedObjectsFindOptions, SavedObjectsMigrationVersion, diff --git a/src/core/server/saved_objects/service/lib/repository.test.js b/src/core/server/saved_objects/service/lib/repository.test.js index e514210752f51..9941bbd03f5dc 100644 --- a/src/core/server/saved_objects/service/lib/repository.test.js +++ b/src/core/server/saved_objects/service/lib/repository.test.js @@ -417,6 +417,32 @@ describe('SavedObjectsRepository', () => { }); }); + it('defaults to a refresh setting of `wait_for`', async () => { + await savedObjectsRepository.create('index-pattern', { + id: 'logstash-*', + title: 'Logstash', + }); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ + refresh: 'wait_for' + }); + }); + + it('accepts custom refresh settings', async () => { + await savedObjectsRepository.create('index-pattern', { + id: 'logstash-*', + title: 'Logstash', + }, { + refresh: true + }); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ + refresh: true + }); + }); + it('should use create action if ID defined and overwrite=false', async () => { await savedObjectsRepository.create( 'index-pattern', @@ -645,6 +671,61 @@ describe('SavedObjectsRepository', () => { expect(onBeforeWrite).toHaveBeenCalledTimes(1); }); + it('defaults to a refresh setting of `wait_for`', async () => { + callAdminCluster.mockReturnValue({ + items: [ + { create: { type: 'config', id: 'config:one', _primary_term: 1, _seq_no: 1 } }, + ], + }); + + await savedObjectsRepository.bulkCreate([ + { + type: 'config', + id: 'one', + attributes: { title: 'Test One' }, + references: [{ name: 'ref_0', type: 'test', id: '1' }], + } + ]); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ + refresh: 'wait_for' + }); + }); + + it('accepts a custom refresh setting', async () => { + callAdminCluster.mockReturnValue({ + items: [ + { create: { type: 'config', id: 'config:one', _primary_term: 1, _seq_no: 1 } }, + { create: { type: 'index-pattern', id: 'config:two', _primary_term: 1, _seq_no: 1 } }, + ], + }); + + await savedObjectsRepository.bulkCreate([ + { + type: 'config', + id: 'one', + attributes: { title: 'Test One' }, + references: [{ name: 'ref_0', type: 'test', id: '1' }], + }, + { + type: 'index-pattern', + id: 'two', + attributes: { title: 'Test Two' }, + references: [{ name: 'ref_0', type: 'test', id: '2' }], + }, + ], { + refresh: true + }); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ + refresh: true + }); + }); + it('migrates the docs', async () => { callAdminCluster.mockReturnValue({ items: [ @@ -1087,6 +1168,28 @@ describe('SavedObjectsRepository', () => { expect(onBeforeWrite).toHaveBeenCalledTimes(1); }); + + it('defaults to a refresh setting of `wait_for`', async () => { + callAdminCluster.mockReturnValue({ result: 'deleted' }); + await savedObjectsRepository.delete('globaltype', 'logstash-*'); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ + refresh: 'wait_for' + }); + }); + + it(`accepts a custom refresh setting`, async () => { + callAdminCluster.mockReturnValue({ result: 'deleted' }); + await savedObjectsRepository.delete('globaltype', 'logstash-*', { + refresh: false + }); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ + refresh: false, + }); + }); }); describe('#deleteByNamespace', () => { @@ -1126,6 +1229,26 @@ describe('SavedObjectsRepository', () => { refresh: 'wait_for', }); }); + + it('defaults to a refresh setting of `wait_for`', async () => { + callAdminCluster.mockReturnValue(deleteByQueryResults); + await savedObjectsRepository.deleteByNamespace('my-namespace'); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ + refresh: 'wait_for', + }); + }); + + it('accepts a custom refresh setting', async () => { + callAdminCluster.mockReturnValue(deleteByQueryResults); + await savedObjectsRepository.deleteByNamespace('my-namespace', { refresh: true }); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ + refresh: true, + }); + }); }); describe('#find', () => { @@ -1984,6 +2107,40 @@ describe('SavedObjectsRepository', () => { expect(onBeforeWrite).toHaveBeenCalledTimes(1); }); + + it('defaults to a refresh setting of `wait_for`', async () => { + await savedObjectsRepository.update( + 'globaltype', + 'foo', + { + name: 'bar', + } + ); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ + refresh: 'wait_for' + }); + }); + + it('accepts a custom refresh setting', async () => { + await savedObjectsRepository.update( + 'globaltype', + 'foo', + { + name: 'bar', + }, + { + refresh: true, + namespace: 'foo-namespace', + } + ); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ + refresh: true + }); + }); }); describe('#bulkUpdate', () => { @@ -2284,6 +2441,44 @@ describe('SavedObjectsRepository', () => { }); }); + it('defaults to a refresh setting of `wait_for`', async () => { + const objects = [ + { + type: 'index-pattern', + id: `logstash-no-ref`, + attributes: { title: `Testing no-ref` }, + references: [] + } + ]; + + mockValidResponse(objects); + + await savedObjectsRepository.bulkUpdate(objects); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ refresh: 'wait_for' }); + }); + + it('accepts a custom refresh setting', async () => { + const objects = [ + { + type: 'index-pattern', + id: `logstash-no-ref`, + attributes: { title: `Testing no-ref` }, + references: [] + } + ]; + + mockValidResponse(objects); + + await savedObjectsRepository.bulkUpdate(objects, { refresh: true }); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ refresh: true }); + }); + it(`prepends namespace to the id but doesn't add namespace to body when providing namespace for namespaced type`, async () => { const objects = [ @@ -2526,6 +2721,29 @@ describe('SavedObjectsRepository', () => { }); }); + it('defaults to a refresh setting of `wait_for`', async () => { + await savedObjectsRepository.incrementCounter('config', 'doesnotexist', 'buildNum', { + namespace: 'foo-namespace' + }); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ + refresh: 'wait_for' + }); + }); + + it('accepts a custom refresh setting', async () => { + await savedObjectsRepository.incrementCounter('config', 'doesnotexist', 'buildNum', { + namespace: 'foo-namespace', + refresh: true + }); + + expect(callAdminCluster).toHaveBeenCalledTimes(1); + expect(callAdminCluster.mock.calls[0][1]).toMatchObject({ + refresh: true + }); + }); + it(`prepends namespace to the id but doesn't add namespace to body when providing namespace for namespaced type`, async () => { await savedObjectsRepository.incrementCounter('config', '6.0.0-alpha1', 'buildNum', { namespace: 'foo-namespace', diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index 179aa6fffc7de..54b9938decb0a 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -40,6 +40,9 @@ import { SavedObjectsUpdateOptions, SavedObjectsUpdateResponse, SavedObjectsBulkUpdateObject, + SavedObjectsBulkUpdateOptions, + SavedObjectsDeleteOptions, + SavedObjectsDeleteByNamespaceOptions, } from '../saved_objects_client'; import { SavedObject, @@ -47,6 +50,7 @@ import { SavedObjectsBaseOptions, SavedObjectsFindOptions, SavedObjectsMigrationVersion, + MutatingOperationRefreshSetting, } from '../../types'; import { validateConvertFilterToKueryNode } from './filter_utils'; @@ -83,8 +87,12 @@ export interface SavedObjectsRepositoryOptions { export interface IncrementCounterOptions extends SavedObjectsBaseOptions { migrationVersion?: SavedObjectsMigrationVersion; + /** The Elasticsearch Refresh setting for this operation */ + refresh?: MutatingOperationRefreshSetting; } +const DEFAULT_REFRESH_SETTING = 'wait_for'; + export class SavedObjectsRepository { private _migrator: KibanaMigrator; private _index: string; @@ -154,7 +162,14 @@ export class SavedObjectsRepository { attributes: T, options: SavedObjectsCreateOptions = {} ): Promise> { - const { id, migrationVersion, overwrite = false, namespace, references = [] } = options; + const { + id, + migrationVersion, + overwrite = false, + namespace, + references = [], + refresh = DEFAULT_REFRESH_SETTING, + } = options; if (!this._allowedTypes.includes(type)) { throw SavedObjectsErrorHelpers.createUnsupportedTypeError(type); @@ -179,7 +194,7 @@ export class SavedObjectsRepository { const response = await this._writeToCluster(method, { id: raw._id, index: this.getIndexForType(type), - refresh: 'wait_for', + refresh, body: raw._source, }); @@ -210,7 +225,7 @@ export class SavedObjectsRepository { objects: Array>, options: SavedObjectsCreateOptions = {} ): Promise> { - const { namespace, overwrite = false } = options; + const { namespace, overwrite = false, refresh = DEFAULT_REFRESH_SETTING } = options; const time = this._getCurrentTime(); const bulkCreateParams: object[] = []; @@ -256,7 +271,7 @@ export class SavedObjectsRepository { }); const esResponse = await this._writeToCluster('bulk', { - refresh: 'wait_for', + refresh, body: bulkCreateParams, }); @@ -308,17 +323,17 @@ export class SavedObjectsRepository { * @property {string} [options.namespace] * @returns {promise} */ - async delete(type: string, id: string, options: SavedObjectsBaseOptions = {}): Promise<{}> { + async delete(type: string, id: string, options: SavedObjectsDeleteOptions = {}): Promise<{}> { if (!this._allowedTypes.includes(type)) { throw SavedObjectsErrorHelpers.createGenericNotFoundError(); } - const { namespace } = options; + const { namespace, refresh = DEFAULT_REFRESH_SETTING } = options; const response = await this._writeToCluster('delete', { id: this._serializer.generateRawId(namespace, type, id), index: this.getIndexForType(type), - refresh: 'wait_for', + refresh, ignore: [404], }); @@ -345,11 +360,16 @@ export class SavedObjectsRepository { * @param {string} namespace * @returns {promise} - { took, timed_out, total, deleted, batches, version_conflicts, noops, retries, failures } */ - async deleteByNamespace(namespace: string): Promise { + async deleteByNamespace( + namespace: string, + options: SavedObjectsDeleteByNamespaceOptions = {} + ): Promise { if (!namespace || typeof namespace !== 'string') { throw new TypeError(`namespace is required, and must be a string`); } + const { refresh = DEFAULT_REFRESH_SETTING } = options; + const allTypes = Object.keys(getRootPropertiesObjects(this._mappings)); const typesToDelete = allTypes.filter(type => !this._schema.isNamespaceAgnostic(type)); @@ -357,7 +377,7 @@ export class SavedObjectsRepository { const esOptions = { index: this.getIndicesForTypes(typesToDelete), ignore: [404], - refresh: 'wait_for', + refresh, body: { conflicts: 'proceed', ...getSearchDsl(this._mappings, this._schema, { @@ -626,7 +646,7 @@ export class SavedObjectsRepository { throw SavedObjectsErrorHelpers.createGenericNotFoundError(type, id); } - const { version, namespace, references } = options; + const { version, namespace, references, refresh = DEFAULT_REFRESH_SETTING } = options; const time = this._getCurrentTime(); @@ -643,7 +663,7 @@ export class SavedObjectsRepository { id: this._serializer.generateRawId(namespace, type, id), index: this.getIndexForType(type), ...(version && decodeRequestVersion(version)), - refresh: 'wait_for', + refresh, ignore: [404], body: { doc, @@ -675,7 +695,7 @@ export class SavedObjectsRepository { */ async bulkUpdate( objects: Array>, - options: SavedObjectsBaseOptions = {} + options: SavedObjectsBulkUpdateOptions = {} ): Promise> { const time = this._getCurrentTime(); const bulkUpdateParams: object[] = []; @@ -729,9 +749,10 @@ export class SavedObjectsRepository { return { tag: 'Right' as 'Right', value: expectedResult }; }); + const { refresh = DEFAULT_REFRESH_SETTING } = options; const esResponse = bulkUpdateParams.length ? await this._writeToCluster('bulk', { - refresh: 'wait_for', + refresh, body: bulkUpdateParams, }) : {}; @@ -794,7 +815,7 @@ export class SavedObjectsRepository { throw SavedObjectsErrorHelpers.createUnsupportedTypeError(type); } - const { migrationVersion, namespace } = options; + const { migrationVersion, namespace, refresh = DEFAULT_REFRESH_SETTING } = options; const time = this._getCurrentTime(); @@ -811,7 +832,7 @@ export class SavedObjectsRepository { const response = await this._writeToCluster('update', { id: this._serializer.generateRawId(namespace, type, id), index: this.getIndexForType(type), - refresh: 'wait_for', + refresh, _source: true, body: { script: { diff --git a/src/core/server/saved_objects/service/saved_objects_client.ts b/src/core/server/saved_objects/service/saved_objects_client.ts index 4e04a08bd5212..550e8a1de0d80 100644 --- a/src/core/server/saved_objects/service/saved_objects_client.ts +++ b/src/core/server/saved_objects/service/saved_objects_client.ts @@ -24,6 +24,7 @@ import { SavedObjectReference, SavedObjectsMigrationVersion, SavedObjectsBaseOptions, + MutatingOperationRefreshSetting, SavedObjectsFindOptions, } from '../types'; import { SavedObjectsErrorHelpers } from './lib/errors'; @@ -40,6 +41,8 @@ export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions { /** {@inheritDoc SavedObjectsMigrationVersion} */ migrationVersion?: SavedObjectsMigrationVersion; references?: SavedObjectReference[]; + /** The Elasticsearch Refresh setting for this operation */ + refresh?: MutatingOperationRefreshSetting; } /** @@ -101,6 +104,35 @@ export interface SavedObjectsUpdateOptions extends SavedObjectsBaseOptions { version?: string; /** {@inheritdoc SavedObjectReference} */ references?: SavedObjectReference[]; + /** The Elasticsearch Refresh setting for this operation */ + refresh?: MutatingOperationRefreshSetting; +} + +/** + * + * @public + */ +export interface SavedObjectsBulkUpdateOptions extends SavedObjectsBaseOptions { + /** The Elasticsearch Refresh setting for this operation */ + refresh?: MutatingOperationRefreshSetting; +} + +/** + * + * @public + */ +export interface SavedObjectsDeleteOptions extends SavedObjectsBaseOptions { + /** The Elasticsearch Refresh setting for this operation */ + refresh?: MutatingOperationRefreshSetting; +} + +/** + * + * @public + */ +export interface SavedObjectsDeleteByNamespaceOptions extends SavedObjectsBaseOptions { + /** The Elasticsearch Refresh setting for this operation */ + refresh?: MutatingOperationRefreshSetting; } /** @@ -189,7 +221,7 @@ export class SavedObjectsClient { * @param id * @param options */ - async delete(type: string, id: string, options: SavedObjectsBaseOptions = {}) { + async delete(type: string, id: string, options: SavedObjectsDeleteOptions = {}) { return await this._repository.delete(type, id, options); } @@ -260,7 +292,7 @@ export class SavedObjectsClient { */ async bulkUpdate( objects: Array>, - options?: SavedObjectsBaseOptions + options?: SavedObjectsBulkUpdateOptions ): Promise> { return await this._repository.bulkUpdate(objects, options); } diff --git a/src/core/server/saved_objects/types.ts b/src/core/server/saved_objects/types.ts index a968b6d9392f8..2c6f5e4a520a7 100644 --- a/src/core/server/saved_objects/types.ts +++ b/src/core/server/saved_objects/types.ts @@ -142,6 +142,12 @@ export interface SavedObjectsBaseOptions { namespace?: string; } +/** + * Elasticsearch Refresh setting for mutating operation + * @public + */ +export type MutatingOperationRefreshSetting = boolean | 'wait_for'; + /** * Saved Objects is Kibana's data persisentence mechanism allowing plugins to * use Elasticsearch for storing plugin state. diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 9740f1f7032d1..e7a4cdc0174b0 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -942,6 +942,9 @@ export type MIGRATION_ASSISTANCE_INDEX_ACTION = 'upgrade' | 'reindex'; // @public (undocumented) export type MIGRATION_DEPRECATION_LEVEL = 'none' | 'info' | 'warning' | 'critical'; +// @public +export type MutatingOperationRefreshSetting = boolean | 'wait_for'; + // Warning: (ae-forgotten-export) The symbol "OnPostAuthResult" needs to be exported by the entry point index.d.ts // // @public @@ -1196,6 +1199,11 @@ export interface SavedObjectsBulkUpdateObject { // (undocumented) @@ -1208,9 +1216,9 @@ export class SavedObjectsClient { constructor(repository: SavedObjectsRepository); bulkCreate(objects: Array>, options?: SavedObjectsCreateOptions): Promise>; bulkGet(objects?: SavedObjectsBulkGetObject[], options?: SavedObjectsBaseOptions): Promise>; - bulkUpdate(objects: Array>, options?: SavedObjectsBaseOptions): Promise>; + bulkUpdate(objects: Array>, options?: SavedObjectsBulkUpdateOptions): Promise>; create(type: string, attributes: T, options?: SavedObjectsCreateOptions): Promise>; - delete(type: string, id: string, options?: SavedObjectsBaseOptions): Promise<{}>; + delete(type: string, id: string, options?: SavedObjectsDeleteOptions): Promise<{}>; // (undocumented) errors: typeof SavedObjectsErrorHelpers; // (undocumented) @@ -1247,6 +1255,12 @@ export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions { overwrite?: boolean; // (undocumented) references?: SavedObjectReference[]; + refresh?: MutatingOperationRefreshSetting; +} + +// @public (undocumented) +export interface SavedObjectsDeleteOptions extends SavedObjectsBaseOptions { + refresh?: MutatingOperationRefreshSetting; } // @public (undocumented) @@ -1554,6 +1568,7 @@ export class SavedObjectsSerializer { // @public (undocumented) export interface SavedObjectsUpdateOptions extends SavedObjectsBaseOptions { references?: SavedObjectReference[]; + refresh?: MutatingOperationRefreshSetting; version?: string; } From 82d544775138bfda0162e165c56be9e4e24be713 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Fri, 25 Oct 2019 09:50:52 +0200 Subject: [PATCH 04/61] [Graph] Shim plugin (#47469) --- src/dev/i18n/extractors/code.js | 2 +- .../ui/public/kbn_top_nav/kbn_top_nav.js | 12 +- .../public/legacy_compat/angular_config.tsx | 6 +- src/legacy/ui/public/modals/confirm_modal.js | 24 +- .../new_platform/new_platform.karma_mock.js | 4 + src/legacy/ui/public/private/private.js | 146 +-- src/legacy/ui/public/promises/promises.js | 10 +- .../show_saved_object_save_modal.tsx | 2 +- .../state_management/config_provider.js | 32 +- x-pack/legacy/plugins/graph/index.js | 2 +- .../angular/directives/graph_inspect.js | 17 - .../angular/services/saved_workspace.js | 8 - .../angular/services/saved_workspaces.js | 5 - .../graph/public/angular/templates/index.html | 44 +- .../public/angular/templates/inspect.html | 43 - x-pack/legacy/plugins/graph/public/app.js | 1010 ++++++++--------- .../public/hacks/toggle_app_link_in_nav.js | 22 +- x-pack/legacy/plugins/graph/public/index.ts | 61 + x-pack/legacy/plugins/graph/public/plugin.ts | 79 ++ .../legacy/plugins/graph/public/render_app.ts | 145 +++ .../plugins/graph/public/services/url.ts | 17 +- .../public/state_management/meta_data.test.ts | 12 +- .../graph/public/state_management/mocks.ts | 8 +- .../graph/public/state_management/store.ts | 4 +- 24 files changed, 984 insertions(+), 731 deletions(-) delete mode 100644 x-pack/legacy/plugins/graph/public/angular/directives/graph_inspect.js delete mode 100644 x-pack/legacy/plugins/graph/public/angular/templates/inspect.html create mode 100644 x-pack/legacy/plugins/graph/public/index.ts create mode 100644 x-pack/legacy/plugins/graph/public/plugin.ts create mode 100644 x-pack/legacy/plugins/graph/public/render_app.ts diff --git a/src/dev/i18n/extractors/code.js b/src/dev/i18n/extractors/code.js index 58ca059be5491..fa0d834824e97 100644 --- a/src/dev/i18n/extractors/code.js +++ b/src/dev/i18n/extractors/code.js @@ -67,7 +67,7 @@ export function* extractCodeMessages(buffer, reporter) { try { ast = parse(buffer.toString(), { sourceType: 'module', - plugins: ['jsx', 'typescript', 'objectRestSpread', 'classProperties', 'asyncGenerators'], + plugins: ['jsx', 'typescript', 'objectRestSpread', 'classProperties', 'asyncGenerators', 'dynamicImport'], }); } catch (error) { if (error instanceof SyntaxError) { diff --git a/src/legacy/ui/public/kbn_top_nav/kbn_top_nav.js b/src/legacy/ui/public/kbn_top_nav/kbn_top_nav.js index 79365eb5cf1cc..72fa6bc4c1182 100644 --- a/src/legacy/ui/public/kbn_top_nav/kbn_top_nav.js +++ b/src/legacy/ui/public/kbn_top_nav/kbn_top_nav.js @@ -24,7 +24,7 @@ import { TopNavMenu } from '../../../core_plugins/kibana_react/public'; const module = uiModules.get('kibana'); -module.directive('kbnTopNav', () => { +export function createTopNavDirective() { return { restrict: 'E', template: '', @@ -71,9 +71,11 @@ module.directive('kbnTopNav', () => { return linkFn; } }; -}); +} -module.directive('kbnTopNavHelper', (reactDirective) => { +module.directive('kbnTopNav', createTopNavDirective); + +export function createTopNavHelper(reactDirective) { return reactDirective( wrapInI18nContext(TopNavMenu), [ @@ -113,4 +115,6 @@ module.directive('kbnTopNavHelper', (reactDirective) => { 'showAutoRefreshOnly', ], ); -}); +} + +module.directive('kbnTopNavHelper', createTopNavHelper); diff --git a/src/legacy/ui/public/legacy_compat/angular_config.tsx b/src/legacy/ui/public/legacy_compat/angular_config.tsx index 8eac31e24530c..785b0345aa999 100644 --- a/src/legacy/ui/public/legacy_compat/angular_config.tsx +++ b/src/legacy/ui/public/legacy_compat/angular_config.tsx @@ -286,14 +286,12 @@ const $setupHelpExtensionAutoClear = (newPlatform: CoreStart) => ( const $setupUrlOverflowHandling = (newPlatform: CoreStart) => ( $location: ILocationService, - $rootScope: IRootScopeService, - Private: any, - config: any + $rootScope: IRootScopeService ) => { const urlOverflow = new UrlOverflowService(); const check = () => { // disable long url checks when storing state in session storage - if (config.get('state:storeInSessionStorage')) { + if (newPlatform.uiSettings.get('state:storeInSessionStorage')) { return; } diff --git a/src/legacy/ui/public/modals/confirm_modal.js b/src/legacy/ui/public/modals/confirm_modal.js index 6d5abfca64aaf..9c3f46da4e927 100644 --- a/src/legacy/ui/public/modals/confirm_modal.js +++ b/src/legacy/ui/public/modals/confirm_modal.js @@ -36,16 +36,7 @@ export const ConfirmationButtonTypes = { CANCEL: CANCEL_BUTTON }; -/** - * @typedef {Object} ConfirmModalOptions - * @property {String} confirmButtonText - * @property {String=} cancelButtonText - * @property {function} onConfirm - * @property {function=} onCancel - * @property {String=} title - If given, shows a title on the confirm modal. - */ - -module.factory('confirmModal', function ($rootScope, $compile) { +export function confirmModalFactory($rootScope, $compile) { let modalPopover; const confirmQueue = []; @@ -114,4 +105,15 @@ module.factory('confirmModal', function ($rootScope, $compile) { } } }; -}); +} + +/** + * @typedef {Object} ConfirmModalOptions + * @property {String} confirmButtonText + * @property {String=} cancelButtonText + * @property {function} onConfirm + * @property {function=} onCancel + * @property {String=} title - If given, shows a title on the confirm modal. + */ + +module.factory('confirmModal', confirmModalFactory); diff --git a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js index ae5c0a83bd781..20ea9c9141aca 100644 --- a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js +++ b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js @@ -96,6 +96,10 @@ export const npStart = { export function __setup__(coreSetup) { npSetup.core = coreSetup; + + // no-op application register calls (this is overwritten to + // bootstrap an LP plugin outside of tests) + npSetup.core.application.register = () => {}; } export function __start__(coreStart) { diff --git a/src/legacy/ui/public/private/private.js b/src/legacy/ui/public/private/private.js index ef5c59c21dd7a..6257c12ecf696 100644 --- a/src/legacy/ui/public/private/private.js +++ b/src/legacy/ui/public/private/private.js @@ -108,98 +108,100 @@ function name(fn) { return fn.name || fn.toString().split('\n').shift(); } -uiModules.get('kibana/private') - .provider('Private', function () { - const provider = this; - - // one cache/swaps per Provider - const cache = {}; - const swaps = {}; +export function PrivateProvider() { + const provider = this; - // return the uniq id for this function - function identify(fn) { - if (typeof fn !== 'function') { - throw new TypeError('Expected private module "' + fn + '" to be a function'); - } + // one cache/swaps per Provider + const cache = {}; + const swaps = {}; - if (fn.$$id) return fn.$$id; - else return (fn.$$id = nextId()); + // return the uniq id for this function + function identify(fn) { + if (typeof fn !== 'function') { + throw new TypeError('Expected private module "' + fn + '" to be a function'); } - provider.stub = function (fn, instance) { - cache[identify(fn)] = instance; - return instance; - }; + if (fn.$$id) return fn.$$id; + else return (fn.$$id = nextId()); + } - provider.swap = function (fn, prov) { - const id = identify(fn); - swaps[id] = prov; - }; + provider.stub = function (fn, instance) { + cache[identify(fn)] = instance; + return instance; + }; - provider.$get = ['$injector', function PrivateFactory($injector) { + provider.swap = function (fn, prov) { + const id = identify(fn); + swaps[id] = prov; + }; - // prevent circular deps by tracking where we came from - const privPath = []; - const pathToString = function () { - return privPath.map(name).join(' -> '); - }; + provider.$get = ['$injector', function PrivateFactory($injector) { - // call a private provider and return the instance it creates - function instantiate(prov, locals) { - if (~privPath.indexOf(prov)) { - throw new Error( - 'Circular reference to "' + name(prov) + '"' + - ' found while resolving private deps: ' + pathToString() - ); - } + // prevent circular deps by tracking where we came from + const privPath = []; + const pathToString = function () { + return privPath.map(name).join(' -> '); + }; - privPath.push(prov); + // call a private provider and return the instance it creates + function instantiate(prov, locals) { + if (~privPath.indexOf(prov)) { + throw new Error( + 'Circular reference to "' + name(prov) + '"' + + ' found while resolving private deps: ' + pathToString() + ); + } - const context = {}; - let instance = $injector.invoke(prov, context, locals); - if (!_.isObject(instance)) instance = context; + privPath.push(prov); - privPath.pop(); - return instance; - } + const context = {}; + let instance = $injector.invoke(prov, context, locals); + if (!_.isObject(instance)) instance = context; - // retrieve an instance from cache or create and store on - function get(id, prov, $delegateId, $delegateProv) { - if (cache[id]) return cache[id]; + privPath.pop(); + return instance; + } - let instance; + // retrieve an instance from cache or create and store on + function get(id, prov, $delegateId, $delegateProv) { + if (cache[id]) return cache[id]; - if ($delegateId != null && $delegateProv != null) { - instance = instantiate(prov, { - $decorate: _.partial(get, $delegateId, $delegateProv) - }); - } else { - instance = instantiate(prov); - } + let instance; - return (cache[id] = instance); + if ($delegateId != null && $delegateProv != null) { + instance = instantiate(prov, { + $decorate: _.partial(get, $delegateId, $delegateProv) + }); + } else { + instance = instantiate(prov); } - // main api, get the appropriate instance for a provider - function Private(prov) { - let id = identify(prov); - let $delegateId; - let $delegateProv; + return (cache[id] = instance); + } - if (swaps[id]) { - $delegateId = id; - $delegateProv = prov; + // main api, get the appropriate instance for a provider + function Private(prov) { + let id = identify(prov); + let $delegateId; + let $delegateProv; - prov = swaps[$delegateId]; - id = identify(prov); - } + if (swaps[id]) { + $delegateId = id; + $delegateProv = prov; - return get(id, prov, $delegateId, $delegateProv); + prov = swaps[$delegateId]; + id = identify(prov); } - Private.stub = provider.stub; - Private.swap = provider.swap; + return get(id, prov, $delegateId, $delegateProv); + } + + Private.stub = provider.stub; + Private.swap = provider.swap; + + return Private; + }]; +} - return Private; - }]; - }); +uiModules.get('kibana/private') + .provider('Private', PrivateProvider); diff --git a/src/legacy/ui/public/promises/promises.js b/src/legacy/ui/public/promises/promises.js index 99c9a11be7431..af8a5081e0c55 100644 --- a/src/legacy/ui/public/promises/promises.js +++ b/src/legacy/ui/public/promises/promises.js @@ -22,9 +22,7 @@ import { uiModules } from '../modules'; const module = uiModules.get('kibana'); -// Provides a tiny subset of the excellent API from -// bluebird, reimplemented using the $q service -module.service('Promise', function ($q, $timeout) { +export function PromiseServiceCreator($q, $timeout) { function Promise(fn) { if (typeof this === 'undefined') throw new Error('Promise constructor must be called with "new"'); @@ -122,4 +120,8 @@ module.service('Promise', function ($q, $timeout) { }; return Promise; -}); +} + +// Provides a tiny subset of the excellent API from +// bluebird, reimplemented using the $q service +module.service('Promise', PromiseServiceCreator); diff --git a/src/legacy/ui/public/saved_objects/show_saved_object_save_modal.tsx b/src/legacy/ui/public/saved_objects/show_saved_object_save_modal.tsx index 6aea3c72e0c34..3c691c692948a 100644 --- a/src/legacy/ui/public/saved_objects/show_saved_object_save_modal.tsx +++ b/src/legacy/ui/public/saved_objects/show_saved_object_save_modal.tsx @@ -34,7 +34,7 @@ function isSuccess(result: SaveResult): result is { id?: string } { return 'id' in result; } -interface MinimalSaveModalProps { +export interface MinimalSaveModalProps { onSave: (...args: any[]) => Promise; onClose: () => void; } diff --git a/src/legacy/ui/public/state_management/config_provider.js b/src/legacy/ui/public/state_management/config_provider.js index 090210cc8723e..ec770e7fef6ca 100644 --- a/src/legacy/ui/public/state_management/config_provider.js +++ b/src/legacy/ui/public/state_management/config_provider.js @@ -25,21 +25,23 @@ import { uiModules } from '../modules'; -uiModules.get('kibana/state_management') - .provider('stateManagementConfig', class StateManagementConfigProvider { - _enabled = true +export class StateManagementConfigProvider { + _enabled = true + + $get(/* inject stuff */) { + return { + enabled: this._enabled, + }; + } - $get(/* inject stuff */) { - return { - enabled: this._enabled, - }; - } + disable() { + this._enabled = false; + } - disable() { - this._enabled = false; - } + enable() { + this._enabled = true; + } +} - enable() { - this._enabled = true; - } - }); +uiModules.get('kibana/state_management') + .provider('stateManagementConfig', StateManagementConfigProvider); diff --git a/x-pack/legacy/plugins/graph/index.js b/x-pack/legacy/plugins/graph/index.js index 1a61caca7a7c1..9ece9966b7da4 100644 --- a/x-pack/legacy/plugins/graph/index.js +++ b/x-pack/legacy/plugins/graph/index.js @@ -23,7 +23,7 @@ export function graph(kibana) { order: 9000, icon: 'plugins/graph/icon.png', euiIconType: 'graphApp', - main: 'plugins/graph/app', + main: 'plugins/graph/index', }, styleSheetPaths: resolve(__dirname, 'public/index.scss'), hacks: ['plugins/graph/hacks/toggle_app_link_in_nav'], diff --git a/x-pack/legacy/plugins/graph/public/angular/directives/graph_inspect.js b/x-pack/legacy/plugins/graph/public/angular/directives/graph_inspect.js deleted file mode 100644 index 1e6622fd796fb..0000000000000 --- a/x-pack/legacy/plugins/graph/public/angular/directives/graph_inspect.js +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { uiModules } from 'ui/modules'; -import template from '../templates/inspect.html'; -const app = uiModules.get('app/graph'); - -app.directive('graphInspect', function () { - return { - replace: true, - restrict: 'E', - template, - }; -}); diff --git a/x-pack/legacy/plugins/graph/public/angular/services/saved_workspace.js b/x-pack/legacy/plugins/graph/public/angular/services/saved_workspace.js index 1d28b4ba5ab30..444e68dd03520 100644 --- a/x-pack/legacy/plugins/graph/public/angular/services/saved_workspace.js +++ b/x-pack/legacy/plugins/graph/public/angular/services/saved_workspace.js @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { uiModules } from 'ui/modules'; import { SavedObjectProvider } from 'ui/saved_objects/saved_object'; import { i18n } from '@kbn/i18n'; import { @@ -12,8 +11,6 @@ import { injectReferences, } from './saved_workspace_references'; -const module = uiModules.get('app/dashboard'); - export function SavedWorkspaceProvider(Private) { // SavedWorkspace constructor. Usually you'd interact with an instance of this. // ID is option, without it one will be generated on save. @@ -68,8 +65,3 @@ export function SavedWorkspaceProvider(Private) { SavedWorkspace.searchsource = false; return SavedWorkspace; } - -// Used only by the savedDashboards service, usually no reason to change this -module.factory('SavedGraphWorkspace', function (Private) { - return Private(SavedWorkspaceProvider); -}); diff --git a/x-pack/legacy/plugins/graph/public/angular/services/saved_workspaces.js b/x-pack/legacy/plugins/graph/public/angular/services/saved_workspaces.js index 7af0dad3c704c..1fef4b7c38c07 100644 --- a/x-pack/legacy/plugins/graph/public/angular/services/saved_workspaces.js +++ b/x-pack/legacy/plugins/graph/public/angular/services/saved_workspaces.js @@ -6,7 +6,6 @@ import _ from 'lodash'; -import { uiModules } from 'ui/modules'; import chrome from 'ui/chrome'; import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_registry'; import { SavedObjectsClientProvider } from 'ui/saved_objects'; @@ -87,9 +86,5 @@ export function SavedWorkspacesProvider(kbnUrl, Private, Promise) { }); }; } -// This is the only thing that gets injected into controllers -uiModules.get('app/graph').service('savedGraphWorkspaces', function (Private) { - return Private(SavedWorkspacesProvider); -}); SavedObjectRegistryProvider.register(SavedWorkspacesProvider); diff --git a/x-pack/legacy/plugins/graph/public/angular/templates/index.html b/x-pack/legacy/plugins/graph/public/angular/templates/index.html index a3b025ff9d6df..686f0f590a19c 100644 --- a/x-pack/legacy/plugins/graph/public/angular/templates/index.html +++ b/x-pack/legacy/plugins/graph/public/angular/templates/index.html @@ -4,7 +4,49 @@
- +
+
+ +
+ http://host:port/{{ selectedIndex.name }}/_graph/explore + + +
+
+
+
-
- -
- http://host:port/{{ selectedIndex.name }}/_graph/explore - - -
-
-
-
diff --git a/x-pack/legacy/plugins/graph/public/app.js b/x-pack/legacy/plugins/graph/public/app.js index ba69756e7b070..41e5819bcbf37 100644 --- a/x-pack/legacy/plugins/graph/public/app.js +++ b/x-pack/legacy/plugins/graph/public/app.js @@ -11,31 +11,10 @@ import React from 'react'; import { Provider } from 'react-redux'; import { isColorDark, hexToRgb } from '@elastic/eui'; -// import the uiExports that we want to "use" -import 'uiExports/fieldFormats'; -import 'uiExports/savedObjectTypes'; - -import 'ui/autoload/all'; -import 'ui/angular-bootstrap'; -import 'ui/kbn_top_nav'; -import 'ui/directives/saved_object_finder'; -import 'ui/directives/input_focus'; -import 'ui/saved_objects/ui/saved_object_save_as_checkbox'; -import 'uiExports/autocompleteProviders'; -import chrome from 'ui/chrome'; -import { uiModules } from 'ui/modules'; -import uiRoutes from 'ui/routes'; -import { addAppRedirectMessageToUrl, toastNotifications } from 'ui/notify'; -import { formatAngularHttpError } from 'ui/notify/lib'; -import { start as data } from '../../../../../src/legacy/core_plugins/data/public/legacy'; -import { SavedObjectsClientProvider } from 'ui/saved_objects'; -import { npStart } from 'ui/new_platform'; -import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_registry'; -import { capabilities } from 'ui/capabilities'; +import { KibanaParsedUrl } from 'ui/url/kibana_parsed_url'; import { showSaveModal } from 'ui/saved_objects/show_saved_object_save_modal'; -import { Storage } from 'ui/storage'; - -import { xpackInfo } from 'plugins/xpack_main/services/xpack_info'; +import { formatAngularHttpError } from 'ui/notify/lib'; +import { addAppRedirectMessageToUrl } from 'ui/notify'; import appTemplate from './angular/templates/index.html'; import listingTemplate from './angular/templates/listing_ng_wrapper.html'; @@ -48,7 +27,6 @@ import { Settings } from './components/settings'; import { GraphVisualization } from './components/graph_visualization'; import gws from './angular/graph_client_workspace.js'; -import { SavedWorkspacesProvider } from './angular/services/saved_workspaces'; import { getEditUrl, getNewPath, getEditPath, setBreadcrumbs } from './services/url'; import { createCachedIndexPatternProvider } from './services/index_pattern_cache'; import { urlTemplateRegex } from './helpers/url_template'; @@ -62,528 +40,528 @@ import { hasFieldsSelector } from './state_management'; -import './angular/directives/graph_inspect'; +export function initGraphApp(angularModule, deps) { + const { + xpackInfo, + chrome, + savedGraphWorkspaces, + toastNotifications, + savedObjectsClient, + indexPatterns, + kbnBaseUrl, + addBasePath, + getBasePath, + npData, + config, + savedObjectRegistry, + capabilities, + coreStart, + $http, + Storage, + canEditDrillDownUrls, + graphSavePolicy, + } = deps; + + const app = angularModule; + + function checkLicense(kbnBaseUrl) { + const licenseAllowsToShowThisPage = xpackInfo.get('features.graph.showAppLink') && + xpackInfo.get('features.graph.enableAppLink'); + if (!licenseAllowsToShowThisPage) { + const message = xpackInfo.get('features.graph.message'); + const newUrl = addAppRedirectMessageToUrl(addBasePath(kbnBaseUrl), message); + window.location.href = newUrl; + throw new Error('Graph license error'); + } + } -const app = uiModules.get('app/graph'); + app.directive('vennDiagram', function (reactDirective) { + return reactDirective(VennDiagram); + }); -function checkLicense(kbnBaseUrl) { - const licenseAllowsToShowThisPage = xpackInfo.get('features.graph.showAppLink') && - xpackInfo.get('features.graph.enableAppLink'); - if (!licenseAllowsToShowThisPage) { - const message = xpackInfo.get('features.graph.message'); - const newUrl = addAppRedirectMessageToUrl(chrome.addBasePath(kbnBaseUrl), message); - window.location.href = newUrl; - throw new Error('Graph license error'); - } -} + app.directive('graphVisualization', function (reactDirective) { + return reactDirective(GraphVisualization); + }); -app.directive('vennDiagram', function (reactDirective) { - return reactDirective(VennDiagram); -}); - -app.directive('graphListing', function (reactDirective) { - return reactDirective(Listing, [ - ['coreStart', { watchDepth: 'reference' }], - ['createItem', { watchDepth: 'reference' }], - ['findItems', { watchDepth: 'reference' }], - ['deleteItems', { watchDepth: 'reference' }], - ['editItem', { watchDepth: 'reference' }], - ['getViewUrl', { watchDepth: 'reference' }], - ['listingLimit', { watchDepth: 'reference' }], - ['hideWriteControls', { watchDepth: 'reference' }], - ['capabilities', { watchDepth: 'reference' }], - ['initialFilter', { watchDepth: 'reference' }], - ]); -}); - -app.directive('graphApp', function (reactDirective) { - return reactDirective(GraphApp, [ - ['store', { watchDepth: 'reference' }], - ['isInitialized', { watchDepth: 'reference' }], - ['currentIndexPattern', { watchDepth: 'reference' }], - ['indexPatternProvider', { watchDepth: 'reference' }], - ['isLoading', { watchDepth: 'reference' }], - ['onQuerySubmit', { watchDepth: 'reference' }], - ['initialQuery', { watchDepth: 'reference' }], - ['confirmWipeWorkspace', { watchDepth: 'reference' }], - ['coreStart', { watchDepth: 'reference' }], - ['noIndexPatterns', { watchDepth: 'reference' }], - ['reduxStore', { watchDepth: 'reference' }], - ['pluginDataStart', { watchDepth: 'reference' }], - ], { restrict: 'A' }); -}); - -app.directive('graphVisualization', function (reactDirective) { - return reactDirective(GraphVisualization, undefined, { restrict: 'A' }); -}); - -if (uiRoutes.enable) { - uiRoutes.enable(); -} + app.directive('graphListing', function (reactDirective) { + return reactDirective(Listing, [ + ['coreStart', { watchDepth: 'reference' }], + ['createItem', { watchDepth: 'reference' }], + ['findItems', { watchDepth: 'reference' }], + ['deleteItems', { watchDepth: 'reference' }], + ['editItem', { watchDepth: 'reference' }], + ['getViewUrl', { watchDepth: 'reference' }], + ['listingLimit', { watchDepth: 'reference' }], + ['hideWriteControls', { watchDepth: 'reference' }], + ['capabilities', { watchDepth: 'reference' }], + ['initialFilter', { watchDepth: 'reference' }], + ]); + }); -uiRoutes - .when('/home', { - template: listingTemplate, - badge: getReadonlyBadge, - controller($injector, $location, $scope, Private, config, kbnBaseUrl) { - checkLicense(kbnBaseUrl); - const services = Private(SavedObjectRegistryProvider).byLoaderPropertiesName; - const graphService = services['Graph workspace']; - const kbnUrl = $injector.get('kbnUrl'); + app.directive('graphApp', function (reactDirective) { + return reactDirective(GraphApp, [ + ['store', { watchDepth: 'reference' }], + ['isInitialized', { watchDepth: 'reference' }], + ['currentIndexPattern', { watchDepth: 'reference' }], + ['indexPatternProvider', { watchDepth: 'reference' }], + ['isLoading', { watchDepth: 'reference' }], + ['onQuerySubmit', { watchDepth: 'reference' }], + ['initialQuery', { watchDepth: 'reference' }], + ['confirmWipeWorkspace', { watchDepth: 'reference' }], + ['coreStart', { watchDepth: 'reference' }], + ['noIndexPatterns', { watchDepth: 'reference' }], + ['reduxStore', { watchDepth: 'reference' }], + ['pluginDataStart', { watchDepth: 'reference' }], + ], { restrict: 'A' }); + }); - $scope.listingLimit = config.get('savedObjects:listingLimit'); - $scope.create = () => { - kbnUrl.redirect(getNewPath()); - }; - $scope.find = (search) => { - return graphService.find(search, $scope.listingLimit); - }; - $scope.editItem = (workspace) => { - kbnUrl.redirect(getEditPath(workspace)); - }; - $scope.getViewUrl = (workspace) => getEditUrl(chrome, workspace); - $scope.delete = (workspaces) => { - return graphService.delete(workspaces.map(({ id }) => id)); - }; - $scope.capabilities = capabilities.get().graph; - $scope.initialFilter = ($location.search()).filter || ''; - $scope.coreStart = npStart.core; - setBreadcrumbs({ chrome }); - } - }) - .when('/workspace/:id?', { - template: appTemplate, - badge: getReadonlyBadge, - resolve: { - savedWorkspace: function (savedGraphWorkspaces, $route) { - return $route.current.params.id ? savedGraphWorkspaces.get($route.current.params.id) - .catch( - function () { - toastNotifications.addDanger( - i18n.translate('xpack.graph.missingWorkspaceErrorMessage', { - defaultMessage: 'Missing workspace', - }) - ); - } - ) : savedGraphWorkspaces.get(); - }, - indexPatterns: function (Private) { - const savedObjectsClient = Private(SavedObjectsClientProvider); - - return savedObjectsClient.find({ - type: 'index-pattern', - fields: ['title', 'type'], - perPage: 10000 - }).then(response => response.savedObjects); - }, - GetIndexPatternProvider: function (Private) { - return data.indexPatterns.indexPatterns; - }, - SavedWorkspacesProvider: function (Private) { - return Private(SavedWorkspacesProvider); - } - } - }) - .otherwise({ - redirectTo: '/home' + app.directive('graphVisualization', function (reactDirective) { + return reactDirective(GraphVisualization, undefined, { restrict: 'A' }); }); + app.config(function ($routeProvider) { + $routeProvider.when('/home', { + template: listingTemplate, + badge: getReadonlyBadge, + controller($location, $scope) { + checkLicense(kbnBaseUrl); + const services = savedObjectRegistry.byLoaderPropertiesName; + const graphService = services['Graph workspace']; + + $scope.listingLimit = config.get('savedObjects:listingLimit'); + $scope.create = () => { + $location.url(getNewPath()); + }; + $scope.find = (search) => { + return graphService.find(search, $scope.listingLimit); + }; + $scope.editItem = (workspace) => { + $location.url(getEditPath(workspace)); + }; + $scope.getViewUrl = (workspace) => getEditUrl(addBasePath, workspace); + $scope.delete = (workspaces) => { + return graphService.delete(workspaces.map(({ id }) => id)); + }; + $scope.capabilities = capabilities; + $scope.initialFilter = ($location.search()).filter || ''; + $scope.coreStart = coreStart; + setBreadcrumbs({ chrome }); + } + }) + .when('/workspace/:id?', { + template: appTemplate, + badge: getReadonlyBadge, + resolve: { + savedWorkspace: function ($route) { + return $route.current.params.id ? savedGraphWorkspaces.get($route.current.params.id) + .catch( + function () { + toastNotifications.addDanger( + i18n.translate('xpack.graph.missingWorkspaceErrorMessage', { + defaultMessage: 'Missing workspace', + }) + ); + } + ) : savedGraphWorkspaces.get(); + + }, + //Copied from example found in wizard.js ( Kibana TODO - can't + indexPatterns: function () { + return savedObjectsClient.find({ + type: 'index-pattern', + fields: ['title', 'type'], + perPage: 10000 + }).then(response => response.savedObjects); + }, + GetIndexPatternProvider: function () { + return indexPatterns; + }, + } + }) + .otherwise({ + redirectTo: '/home' + }); + }); -//======== Controller for basic UI ================== -app.controller('graphuiPlugin', function ( - $scope, - $route, - $http, - kbnUrl, - confirmModal, - kbnBaseUrl -) { - checkLicense(kbnBaseUrl); - function handleError(err) { + //======== Controller for basic UI ================== + app.controller('graphuiPlugin', function ($scope, $route, $location, confirmModal) { checkLicense(kbnBaseUrl); - const toastTitle = i18n.translate('xpack.graph.errorToastTitle', { - defaultMessage: 'Graph Error', - description: '"Graph" is a product name and should not be translated.', - }); - if (err instanceof Error) { - toastNotifications.addError(err, { - title: toastTitle, - }); - } else { - toastNotifications.addDanger({ - title: toastTitle, - text: String(err), + + function handleError(err) { + checkLicense(kbnBaseUrl); + const toastTitle = i18n.translate('xpack.graph.errorToastTitle', { + defaultMessage: 'Graph Error', + description: '"Graph" is a product name and should not be translated.', }); + if (err instanceof Error) { + toastNotifications.addError(err, { + title: toastTitle, + }); + } else { + toastNotifications.addDanger({ + title: toastTitle, + text: String(err), + }); + } } - } - async function handleHttpError(error) { - checkLicense(kbnBaseUrl); - toastNotifications.addDanger(formatAngularHttpError(error)); - } + async function handleHttpError(error) { + checkLicense(kbnBaseUrl); + toastNotifications.addDanger(formatAngularHttpError(error)); + } - // Replacement function for graphClientWorkspace's comms so - // that it works with Kibana. - function callNodeProxy(indexName, query, responseHandler) { - const request = { - index: indexName, - query: query - }; - $scope.loading = true; - return $http.post('../api/graph/graphExplore', request) - .then(function (resp) { - if (resp.data.resp.timed_out) { - toastNotifications.addWarning( - i18n.translate('xpack.graph.exploreGraph.timedOutWarningText', { - defaultMessage: 'Exploration timed out', - }) - ); - } - responseHandler(resp.data.resp); - }) - .catch(handleHttpError) - .finally(() => { - $scope.loading = false; - }); - } + // Replacement function for graphClientWorkspace's comms so + // that it works with Kibana. + function callNodeProxy(indexName, query, responseHandler) { + const request = { + index: indexName, + query: query + }; + $scope.loading = true; + return $http.post('../api/graph/graphExplore', request) + .then(function (resp) { + if (resp.data.resp.timed_out) { + toastNotifications.addWarning( + i18n.translate('xpack.graph.exploreGraph.timedOutWarningText', { + defaultMessage: 'Exploration timed out', + }) + ); + } + responseHandler(resp.data.resp); + }) + .catch(handleHttpError) + .finally(() => { + $scope.loading = false; + }); + } - //Helper function for the graphClientWorkspace to perform a query - const callSearchNodeProxy = function (indexName, query, responseHandler) { - const request = { - index: indexName, - body: query - }; - $scope.loading = true; - $http.post('../api/graph/searchProxy', request) - .then(function (resp) { - responseHandler(resp.data.resp); - }) - .catch(handleHttpError) - .finally(() => { - $scope.loading = false; - }); - }; - - $scope.indexPatternProvider = createCachedIndexPatternProvider($route.current.locals.GetIndexPatternProvider.get); - - const store = createGraphStore({ - basePath: chrome.getBasePath(), - indexPatternProvider: $scope.indexPatternProvider, - indexPatterns: $route.current.locals.indexPatterns, - createWorkspace: (indexPattern, exploreControls) => { - const options = { - indexName: indexPattern, - vertex_fields: [], - // Here we have the opportunity to look up labels for nodes... - nodeLabeller: function () { - // console.log(newNodes); - }, - changeHandler: function () { - //Allows DOM to update with graph layout changes. - $scope.$apply(); - }, - graphExploreProxy: callNodeProxy, - searchProxy: callSearchNodeProxy, - exploreControls, + //Helper function for the graphClientWorkspace to perform a query + const callSearchNodeProxy = function (indexName, query, responseHandler) { + const request = { + index: indexName, + body: query }; - $scope.workspace = gws.createWorkspace(options); - }, - setLiveResponseFields: (fields) => { - $scope.liveResponseFields = fields; - }, - setUrlTemplates: (urlTemplates) => { - $scope.urlTemplates = urlTemplates; - }, - getWorkspace: () => { - return $scope.workspace; - }, - getSavedWorkspace: () => { - return $route.current.locals.savedWorkspace; - }, - notifications: npStart.core.notifications, - http: npStart.core.http, - showSaveModal, - setWorkspaceInitialized: () => { - $scope.workspaceInitialized = true; - }, - savePolicy: chrome.getInjected('graphSavePolicy'), - changeUrl: (newUrl) => { - $scope.$evalAsync(() => { - kbnUrl.change(newUrl, {}); - }); - }, - notifyAngular: () => { - $scope.$digest(); - }, - chrome, - }); + $scope.loading = true; + $http.post('../api/graph/searchProxy', request) + .then(function (resp) { + responseHandler(resp.data.resp); + }) + .catch(handleHttpError) + .finally(() => { + $scope.loading = false; + }); + }; - // register things on scope passed down to react components - $scope.pluginDataStart = npStart.plugins.data; - $scope.store = new Storage(window.localStorage); - $scope.coreStart = npStart.core; - $scope.loading = false; - $scope.reduxStore = store; - $scope.savedWorkspace = $route.current.locals.savedWorkspace; - - // register things for legacy angular UI - const allSavingDisabled = chrome.getInjected('graphSavePolicy') === 'none'; - $scope.spymode = 'request'; - $scope.colors = colorChoices; - $scope.isColorDark = (color) => isColorDark(...hexToRgb(color)); - $scope.nodeClick = function (n, $event) { - - //Selection logic - shift key+click helps selects multiple nodes - // Without the shift key we deselect all prior selections (perhaps not - // a great idea for touch devices with no concept of shift key) - if (!$event.shiftKey) { - const prevSelection = n.isSelected; - $scope.workspace.selectNone(); - n.isSelected = prevSelection; - } + $scope.indexPatternProvider = createCachedIndexPatternProvider($route.current.locals.GetIndexPatternProvider.get); + + const store = createGraphStore({ + basePath: getBasePath(), + indexPatternProvider: $scope.indexPatternProvider, + indexPatterns: $route.current.locals.indexPatterns, + createWorkspace: (indexPattern, exploreControls) => { + const options = { + indexName: indexPattern, + vertex_fields: [], + // Here we have the opportunity to look up labels for nodes... + nodeLabeller: function () { + // console.log(newNodes); + }, + changeHandler: function () { + //Allows DOM to update with graph layout changes. + $scope.$apply(); + }, + graphExploreProxy: callNodeProxy, + searchProxy: callSearchNodeProxy, + exploreControls, + }; + $scope.workspace = gws.createWorkspace(options); + }, + setLiveResponseFields: (fields) => { + $scope.liveResponseFields = fields; + }, + setUrlTemplates: (urlTemplates) => { + $scope.urlTemplates = urlTemplates; + }, + getWorkspace: () => { + return $scope.workspace; + }, + getSavedWorkspace: () => { + return $route.current.locals.savedWorkspace; + }, + notifications: coreStart.notifications, + http: coreStart.http, + showSaveModal, + setWorkspaceInitialized: () => { + $scope.workspaceInitialized = true; + }, + savePolicy: graphSavePolicy, + changeUrl: (newUrl) => { + $scope.$evalAsync(() => { + $location.url(newUrl); + }); + }, + notifyAngular: () => { + $scope.$digest(); + }, + chrome, + }); + // register things on scope passed down to react components + $scope.pluginDataStart = npData; + $scope.store = new Storage(window.localStorage); + $scope.coreStart = coreStart; + $scope.loading = false; + $scope.reduxStore = store; + $scope.savedWorkspace = $route.current.locals.savedWorkspace; + + // register things for legacy angular UI + const allSavingDisabled = graphSavePolicy === 'none'; + $scope.spymode = 'request'; + $scope.colors = colorChoices; + $scope.isColorDark = (color) => isColorDark(...hexToRgb(color)); + $scope.nodeClick = function (n, $event) { + + //Selection logic - shift key+click helps selects multiple nodes + // Without the shift key we deselect all prior selections (perhaps not + // a great idea for touch devices with no concept of shift key) + if (!$event.shiftKey) { + const prevSelection = n.isSelected; + $scope.workspace.selectNone(); + n.isSelected = prevSelection; + } - if ($scope.workspace.toggleNodeSelection(n)) { - $scope.selectSelected(n); - } else { - $scope.detail = null; - } - }; - function canWipeWorkspace(callback, text, options) { - if (!hasFieldsSelector(store.getState())) { - callback(); - return; - } - const confirmModalOptions = { - onConfirm: callback, - onCancel: (() => {}), - confirmButtonText: i18n.translate('xpack.graph.leaveWorkspace.confirmButtonLabel', { - defaultMessage: 'Leave anyway', - }), - title: i18n.translate('xpack.graph.leaveWorkspace.modalTitle', { - defaultMessage: 'Unsaved changes', - }), - ...options, + if ($scope.workspace.toggleNodeSelection(n)) { + $scope.selectSelected(n); + } else { + $scope.detail = null; + } }; - confirmModal(text || i18n.translate('xpack.graph.leaveWorkspace.confirmText', { - defaultMessage: 'If you leave now, you will lose unsaved changes.', - }), confirmModalOptions); - } - $scope.confirmWipeWorkspace = canWipeWorkspace; - $scope.clickEdge = function (edge) { - if (edge.inferred) { - $scope.setDetail ({ 'inferredEdge': edge }); - }else { - $scope.workspace.getAllIntersections($scope.handleMergeCandidatesCallback, [edge.topSrc, edge.topTarget]); - } - }; - - $scope.submit = function (searchTerm) { - $scope.workspaceInitialized = true; - const numHops = 2; - if (searchTerm.startsWith('{')) { - try { - const query = JSON.parse(searchTerm); - if (query.vertices) { - // Is a graph explore request - $scope.workspace.callElasticsearch(query); - }else { - // Is a regular query DSL query - $scope.workspace.search(query, $scope.liveResponseFields, numHops); - } + $scope.clickEdge = function (edge) { + if (edge.inferred) { + $scope.setDetail ({ 'inferredEdge': edge }); + }else { + $scope.workspace.getAllIntersections($scope.handleMergeCandidatesCallback, [edge.topSrc, edge.topTarget]); } - catch (err) { - handleError(err); + }; + + $scope.submit = function (searchTerm) { + $scope.workspaceInitialized = true; + const numHops = 2; + if (searchTerm.startsWith('{')) { + try { + const query = JSON.parse(searchTerm); + if (query.vertices) { + // Is a graph explore request + $scope.workspace.callElasticsearch(query); + }else { + // Is a regular query DSL query + $scope.workspace.search(query, $scope.liveResponseFields, numHops); + } + } + catch (err) { + handleError(err); + } + return; } - return; - } - $scope.workspace.simpleSearch(searchTerm, $scope.liveResponseFields, numHops); - }; + $scope.workspace.simpleSearch(searchTerm, $scope.liveResponseFields, numHops); + }; - $scope.selectSelected = function (node) { - $scope.detail = { - latestNodeSelection: node + $scope.selectSelected = function (node) { + $scope.detail = { + latestNodeSelection: node + }; + return $scope.selectedSelectedVertex = node; }; - return $scope.selectedSelectedVertex = node; - }; - - $scope.isSelectedSelected = function (node) { - return $scope.selectedSelectedVertex === node; - }; - - $scope.openUrlTemplate = function (template) { - const url = template.url; - const newUrl = url.replace(urlTemplateRegex, template.encoder.encode($scope.workspace)); - window.open(newUrl, '_blank'); - }; - - $scope.aceLoaded = (editor) => { - editor.$blockScrolling = Infinity; - }; - - $scope.setDetail = function (data) { - $scope.detail = data; - }; - - $scope.performMerge = function (parentId, childId) { - let found = true; - while (found) { - found = false; - for (const i in $scope.detail.mergeCandidates) { - const mc = $scope.detail.mergeCandidates[i]; - if ((mc.id1 === childId) || (mc.id2 === childId)) { - $scope.detail.mergeCandidates.splice(i, 1); - found = true; - break; - } + + $scope.isSelectedSelected = function (node) { + return $scope.selectedSelectedVertex === node; + }; + + $scope.openUrlTemplate = function (template) { + const url = template.url; + const newUrl = url.replace(urlTemplateRegex, template.encoder.encode($scope.workspace)); + window.open(newUrl, '_blank'); + }; + + $scope.aceLoaded = (editor) => { + editor.$blockScrolling = Infinity; + }; + + $scope.setDetail = function (data) { + $scope.detail = data; + }; + + function canWipeWorkspace(callback, text, options) { + if (!hasFieldsSelector(store.getState())) { + callback(); + return; } + const confirmModalOptions = { + onConfirm: callback, + onCancel: (() => {}), + confirmButtonText: i18n.translate('xpack.graph.leaveWorkspace.confirmButtonLabel', { + defaultMessage: 'Leave anyway', + }), + title: i18n.translate('xpack.graph.leaveWorkspace.modalTitle', { + defaultMessage: 'Unsaved changes', + }), + ...options, + }; + confirmModal(text || i18n.translate('xpack.graph.leaveWorkspace.confirmText', { + defaultMessage: 'If you leave now, you will lose unsaved changes.', + }), confirmModalOptions); } - $scope.workspace.mergeIds(parentId, childId); - $scope.detail = null; - }; - - - $scope.handleMergeCandidatesCallback = function (termIntersects) { - const mergeCandidates = []; - for (const i in termIntersects) { - const ti = termIntersects[i]; - mergeCandidates.push({ - 'id1': ti.id1, - 'id2': ti.id2, - 'term1': ti.term1, - 'term2': ti.term2, - 'v1': ti.v1, - 'v2': ti.v2, - 'overlap': ti.overlap - }); + $scope.confirmWipeWorkspace = canWipeWorkspace; + + $scope.performMerge = function (parentId, childId) { + let found = true; + while (found) { + found = false; + for (const i in $scope.detail.mergeCandidates) { + const mc = $scope.detail.mergeCandidates[i]; + if ((mc.id1 === childId) || (mc.id2 === childId)) { + $scope.detail.mergeCandidates.splice(i, 1); + found = true; + break; + } + } + } + $scope.workspace.mergeIds(parentId, childId); + $scope.detail = null; + }; - } - $scope.detail = { mergeCandidates }; - }; - - // ===== Menubar configuration ========= - $scope.topNavMenu = []; - $scope.topNavMenu.push({ - key: 'new', - label: i18n.translate('xpack.graph.topNavMenu.newWorkspaceLabel', { - defaultMessage: 'New', - }), - description: i18n.translate('xpack.graph.topNavMenu.newWorkspaceAriaLabel', { - defaultMessage: 'New Workspace', - }), - tooltip: i18n.translate('xpack.graph.topNavMenu.newWorkspaceTooltip', { - defaultMessage: 'Create a new workspace', - }), - run: function () { - canWipeWorkspace(function () { - kbnUrl.change('/workspace/', {}); - }); }, - testId: 'graphNewButton', - }); + $scope.handleMergeCandidatesCallback = function (termIntersects) { + const mergeCandidates = []; + for (const i in termIntersects) { + const ti = termIntersects[i]; + mergeCandidates.push({ + 'id1': ti.id1, + 'id2': ti.id2, + 'term1': ti.term1, + 'term2': ti.term2, + 'v1': ti.v1, + 'v2': ti.v2, + 'overlap': ti.overlap + }); - // if saving is disabled using uiCapabilities, we don't want to render the save - // button so it's consistent with all of the other applications - if (capabilities.get().graph.save) { - // allSavingDisabled is based on the xpack.graph.savePolicy, we'll maintain this functionality + } + $scope.detail = { mergeCandidates }; + }; + // ===== Menubar configuration ========= + $scope.topNavMenu = []; $scope.topNavMenu.push({ - key: 'save', - label: i18n.translate('xpack.graph.topNavMenu.saveWorkspace.enabledLabel', { - defaultMessage: 'Save', + key: 'new', + label: i18n.translate('xpack.graph.topNavMenu.newWorkspaceLabel', { + defaultMessage: 'New', }), - description: i18n.translate('xpack.graph.topNavMenu.saveWorkspace.enabledAriaLabel', { - defaultMessage: 'Save workspace', + description: i18n.translate('xpack.graph.topNavMenu.newWorkspaceAriaLabel', { + defaultMessage: 'New Workspace', }), - tooltip: () => { - if (allSavingDisabled) { - return i18n.translate('xpack.graph.topNavMenu.saveWorkspace.disabledTooltip', { - defaultMessage: 'No changes to saved workspaces are permitted by the current save policy', - }); - } else { - return i18n.translate('xpack.graph.topNavMenu.saveWorkspace.enabledTooltip', { - defaultMessage: 'Save this workspace', + tooltip: i18n.translate('xpack.graph.topNavMenu.newWorkspaceTooltip', { + defaultMessage: 'Create a new workspace', + }), + run: function () { + canWipeWorkspace(function () { + $scope.$evalAsync(() => { + if ($location.url() === '/workspace/') { + $route.reload(); + } else { + $location.url('/workspace/'); + } }); - } - }, - disableButton: function () { - return allSavingDisabled || !hasFieldsSelector(store.getState()); - }, - run: () => { - store.dispatch({ - type: 'x-pack/graph/SAVE_WORKSPACE', - payload: $route.current.locals.savedWorkspace, }); }, - testId: 'graphSaveButton', + testId: 'graphNewButton', }); - } - $scope.topNavMenu.push({ - key: 'inspect', - disableButton: function () { return $scope.workspace === null; }, - label: i18n.translate('xpack.graph.topNavMenu.inspectLabel', { - defaultMessage: 'Inspect', - }), - description: i18n.translate('xpack.graph.topNavMenu.inspectAriaLabel', { - defaultMessage: 'Inspect', - }), - run: () => { - $scope.$evalAsync(() => { - const curState = $scope.menus.showInspect; - $scope.closeMenus(); - $scope.menus.showInspect = !curState; - }); - }, - }); - $scope.topNavMenu.push({ - key: 'settings', - disableButton: function () { return datasourceSelector(store.getState()).type === 'none'; }, - label: i18n.translate('xpack.graph.topNavMenu.settingsLabel', { - defaultMessage: 'Settings', - }), - description: i18n.translate('xpack.graph.topNavMenu.settingsAriaLabel', { - defaultMessage: 'Settings', - }), - run: () => { - const settingsObservable = asAngularSyncedObservable(() => ({ - blacklistedNodes: $scope.workspace ? [...$scope.workspace.blacklistedNodes] : undefined, - unblacklistNode: $scope.workspace ? $scope.workspace.unblacklist : undefined, - canEditDrillDownUrls: chrome.getInjected('canEditDrillDownUrls') - }), $scope.$digest.bind($scope)); - npStart.core.overlays.openFlyout( - - - , { - size: 'm', - closeButtonAriaLabel: i18n.translate('xpack.graph.settings.closeLabel', { defaultMessage: 'Close' }), - 'data-test-subj': 'graphSettingsFlyout', - ownFocus: true, - className: 'gphSettingsFlyout', - maxWidth: 520, + // if saving is disabled using uiCapabilities, we don't want to render the save + // button so it's consistent with all of the other applications + if (capabilities.save) { + // allSavingDisabled is based on the xpack.graph.savePolicy, we'll maintain this functionality + + $scope.topNavMenu.push({ + key: 'save', + label: i18n.translate('xpack.graph.topNavMenu.saveWorkspace.enabledLabel', { + defaultMessage: 'Save', + }), + description: i18n.translate('xpack.graph.topNavMenu.saveWorkspace.enabledAriaLabel', { + defaultMessage: 'Save workspace', + }), + tooltip: () => { + if (allSavingDisabled) { + return i18n.translate('xpack.graph.topNavMenu.saveWorkspace.disabledTooltip', { + defaultMessage: 'No changes to saved workspaces are permitted by the current save policy', + }); + } else { + return i18n.translate('xpack.graph.topNavMenu.saveWorkspace.enabledTooltip', { + defaultMessage: 'Save this workspace', + }); + } + }, + disableButton: function () { + return allSavingDisabled || !hasFieldsSelector(store.getState()); + }, + run: () => { + store.dispatch({ + type: 'x-pack/graph/SAVE_WORKSPACE', + payload: $route.current.locals.savedWorkspace, + }); + }, + testId: 'graphSaveButton', + }); + } + $scope.topNavMenu.push({ + key: 'inspect', + disableButton: function () { return $scope.workspace === null; }, + label: i18n.translate('xpack.graph.topNavMenu.inspectLabel', { + defaultMessage: 'Inspect', + }), + description: i18n.translate('xpack.graph.topNavMenu.inspectAriaLabel', { + defaultMessage: 'Inspect', + }), + run: () => { + $scope.$evalAsync(() => { + const curState = $scope.menus.showInspect; + $scope.closeMenus(); + $scope.menus.showInspect = !curState; }); - }, - }); - - $scope.menus = { - showSettings: false, - }; - - $scope.closeMenus = () => { - _.forOwn($scope.menus, function (_, key) { - $scope.menus[key] = false; + }, }); - }; - // Deal with situation of request to open saved workspace - if ($route.current.locals.savedWorkspace.id) { - store.dispatch({ - type: 'x-pack/graph/LOAD_WORKSPACE', - payload: $route.current.locals.savedWorkspace, + $scope.topNavMenu.push({ + key: 'settings', + disableButton: function () { return datasourceSelector(store.getState()).type === 'none'; }, + label: i18n.translate('xpack.graph.topNavMenu.settingsLabel', { + defaultMessage: 'Settings', + }), + description: i18n.translate('xpack.graph.topNavMenu.settingsAriaLabel', { + defaultMessage: 'Settings', + }), + run: () => { + const settingsObservable = asAngularSyncedObservable(() => ({ + blacklistedNodes: $scope.workspace ? [...$scope.workspace.blacklistedNodes] : undefined, + unblacklistNode: $scope.workspace ? $scope.workspace.unblacklist : undefined, + canEditDrillDownUrls: canEditDrillDownUrls + }), $scope.$digest.bind($scope)); + coreStart.overlays.openFlyout( + + + , { + size: 'm', + closeButtonAriaLabel: i18n.translate('xpack.graph.settings.closeLabel', { defaultMessage: 'Close' }), + 'data-test-subj': 'graphSettingsFlyout', + ownFocus: true, + className: 'gphSettingsFlyout', + maxWidth: 520, + }); + }, }); + // Allow URLs to include a user-defined text query if ($route.current.params.query) { $scope.initialQuery = $route.current.params.query; @@ -595,8 +573,26 @@ app.controller('graphuiPlugin', function ( $scope.submit($route.current.params.query); }); } - } else { - $scope.noIndexPatterns = $route.current.locals.indexPatterns.length === 0; - } -}); + $scope.menus = { + showSettings: false, + }; + + $scope.closeMenus = () => { + _.forOwn($scope.menus, function (_, key) { + $scope.menus[key] = false; + }); + }; + + // Deal with situation of request to open saved workspace + if ($route.current.locals.savedWorkspace.id) { + store.dispatch({ + type: 'x-pack/graph/LOAD_WORKSPACE', + payload: $route.current.locals.savedWorkspace, + }); + } else { + $scope.noIndexPatterns = $route.current.locals.indexPatterns.length === 0; + } + }); +//End controller +} diff --git a/x-pack/legacy/plugins/graph/public/hacks/toggle_app_link_in_nav.js b/x-pack/legacy/plugins/graph/public/hacks/toggle_app_link_in_nav.js index 11b02354a97c5..5b1eb6181fd61 100644 --- a/x-pack/legacy/plugins/graph/public/hacks/toggle_app_link_in_nav.js +++ b/x-pack/legacy/plugins/graph/public/hacks/toggle_app_link_in_nav.js @@ -4,20 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { uiModules } from 'ui/modules'; import { npStart } from 'ui/new_platform'; import { xpackInfo } from 'plugins/xpack_main/services/xpack_info'; -uiModules.get('xpack/graph') - .run(() => { - const navLinkUpdates = {}; - navLinkUpdates.hidden = true; - const showAppLink = xpackInfo.get('features.graph.showAppLink', false); - navLinkUpdates.hidden = !showAppLink; - if (showAppLink) { - navLinkUpdates.disabled = !xpackInfo.get('features.graph.enableAppLink', false); - navLinkUpdates.tooltip = xpackInfo.get('features.graph.message'); - } +const navLinkUpdates = {}; +navLinkUpdates.hidden = true; +const showAppLink = xpackInfo.get('features.graph.showAppLink', false); +navLinkUpdates.hidden = !showAppLink; +if (showAppLink) { + navLinkUpdates.disabled = !xpackInfo.get('features.graph.enableAppLink', false); + navLinkUpdates.tooltip = xpackInfo.get('features.graph.message'); +} - npStart.core.chrome.navLinks.update('graph', navLinkUpdates); - }); +npStart.core.chrome.navLinks.update('graph', navLinkUpdates); diff --git a/x-pack/legacy/plugins/graph/public/index.ts b/x-pack/legacy/plugins/graph/public/index.ts new file mode 100644 index 0000000000000..0249ca74035d6 --- /dev/null +++ b/x-pack/legacy/plugins/graph/public/index.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// legacy imports currently necessary to power Graph +// for a cutover all of these have to be resolved +import 'uiExports/fieldFormats'; +import 'uiExports/savedObjectTypes'; +import 'uiExports/autocompleteProviders'; +import 'ui/autoload/all'; +import chrome from 'ui/chrome'; +import { IPrivate } from 'ui/private'; +// @ts-ignore +import { xpackInfo } from 'plugins/xpack_main/services/xpack_info'; +import { Storage } from 'ui/storage'; +// @ts-ignore +import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_registry'; + +import { npSetup, npStart } from 'ui/new_platform'; +import { start as data } from '../../../../../src/legacy/core_plugins/data/public/legacy'; +import { GraphPlugin } from './plugin'; + +// @ts-ignore +import { SavedWorkspacesProvider } from './angular/services/saved_workspaces'; +import { LegacyAngularInjectedDependencies } from './render_app'; + +/** + * Get dependencies relying on the global angular context. + * They also have to get resolved together with the legacy imports above + */ +async function getAngularInjectedDependencies(): Promise { + const injector = await chrome.dangerouslyGetActiveInjector(); + + const Private = injector.get('Private'); + + return { + $http: injector.get('$http'), + savedObjectRegistry: Private(SavedObjectRegistryProvider), + kbnBaseUrl: injector.get('kbnBaseUrl'), + savedGraphWorkspaces: Private(SavedWorkspacesProvider), + }; +} + +(async () => { + const instance = new GraphPlugin(); + instance.setup(npSetup.core, { + __LEGACY: { + xpackInfo, + Storage, + }, + }); + instance.start(npStart.core, { + data, + npData: npStart.plugins.data, + __LEGACY: { + angularDependencies: await getAngularInjectedDependencies(), + }, + }); +})(); diff --git a/x-pack/legacy/plugins/graph/public/plugin.ts b/x-pack/legacy/plugins/graph/public/plugin.ts new file mode 100644 index 0000000000000..d01f325dd8b70 --- /dev/null +++ b/x-pack/legacy/plugins/graph/public/plugin.ts @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// NP type imports +import { CoreSetup, CoreStart, Plugin, SavedObjectsClientContract } from 'src/core/public'; +import { DataStart } from 'src/legacy/core_plugins/data/public'; +import { Plugin as DataPlugin } from 'src/plugins/data/public'; +import { LegacyAngularInjectedDependencies } from './render_app'; + +export interface GraphPluginStartDependencies { + data: DataStart; + npData: ReturnType; +} + +export interface GraphPluginSetupDependencies { + __LEGACY: { + Storage: any; + xpackInfo: any; + }; +} + +export interface GraphPluginStartDependencies { + __LEGACY: { + angularDependencies: LegacyAngularInjectedDependencies; + }; +} + +export class GraphPlugin implements Plugin { + private dataStart: DataStart | null = null; + private npDataStart: ReturnType | null = null; + private savedObjectsClient: SavedObjectsClientContract | null = null; + private angularDependencies: LegacyAngularInjectedDependencies | null = null; + + setup(core: CoreSetup, { __LEGACY: { xpackInfo, Storage } }: GraphPluginSetupDependencies) { + core.application.register({ + id: 'graph', + title: 'Graph', + mount: async ({ core: contextCore }, params) => { + const { renderApp } = await import('./render_app'); + return renderApp({ + ...params, + npData: this.npDataStart!, + savedObjectsClient: this.savedObjectsClient!, + xpackInfo, + addBasePath: core.http.basePath.prepend, + getBasePath: core.http.basePath.get, + canEditDrillDownUrls: core.injectedMetadata.getInjectedVar( + 'canEditDrillDownUrls' + ) as boolean, + graphSavePolicy: core.injectedMetadata.getInjectedVar('graphSavePolicy') as string, + Storage, + capabilities: contextCore.application.capabilities.graph, + coreStart: contextCore, + chrome: contextCore.chrome, + config: contextCore.uiSettings, + toastNotifications: contextCore.notifications.toasts, + indexPatterns: this.dataStart!.indexPatterns.indexPatterns, + ...this.angularDependencies!, + }); + }, + }); + } + + start( + core: CoreStart, + { data, npData, __LEGACY: { angularDependencies } }: GraphPluginStartDependencies + ) { + // TODO is this really the right way? I though the app context would give us those + this.dataStart = data; + this.npDataStart = npData; + this.angularDependencies = angularDependencies; + this.savedObjectsClient = core.savedObjects.client; + } + + stop() {} +} diff --git a/x-pack/legacy/plugins/graph/public/render_app.ts b/x-pack/legacy/plugins/graph/public/render_app.ts new file mode 100644 index 0000000000000..8625e20ab9c52 --- /dev/null +++ b/x-pack/legacy/plugins/graph/public/render_app.ts @@ -0,0 +1,145 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiConfirmModal } from '@elastic/eui'; + +// inner angular imports +// these are necessary to bootstrap the local angular. +// They can stay even after NP cutover +import angular from 'angular'; +import { i18nDirective, i18nFilter, I18nProvider } from '@kbn/i18n/angular'; +import 'ui/angular-bootstrap'; +import 'ace'; +import 'ui/kbn_top_nav'; +import { configureAppAngularModule } from 'ui/legacy_compat'; +// @ts-ignore +import { createTopNavDirective, createTopNavHelper } from 'ui/kbn_top_nav/kbn_top_nav'; +// @ts-ignore +import { confirmModalFactory } from 'ui/modals/confirm_modal'; + +// type imports +import { DataStart } from 'src/legacy/core_plugins/data/public'; +import { + AppMountContext, + ChromeStart, + SavedObjectsClientContract, + ToastsStart, + UiSettingsClientContract, +} from 'kibana/public'; +// @ts-ignore +import { initGraphApp } from './app'; +import { Plugin as DataPlugin } from '../../../../../src/plugins/data/public'; + +/** + * These are dependencies of the Graph app besides the base dependencies + * provided by the application service. Some of those still rely on non-shimmed + * plugins in LP-world, but if they are migrated only the import path in the plugin + * itself changes + */ +export interface GraphDependencies extends LegacyAngularInjectedDependencies { + element: HTMLElement; + appBasePath: string; + capabilities: Record>; + coreStart: AppMountContext['core']; + chrome: ChromeStart; + config: UiSettingsClientContract; + toastNotifications: ToastsStart; + indexPatterns: DataStart['indexPatterns']['indexPatterns']; + npData: ReturnType; + savedObjectsClient: SavedObjectsClientContract; + xpackInfo: { get(path: string): unknown }; + addBasePath: (url: string) => string; + getBasePath: () => string; + Storage: any; + canEditDrillDownUrls: boolean; + graphSavePolicy: string; +} + +/** + * Dependencies of the Graph app which rely on the global angular instance. + * These dependencies have to be migrated to their NP counterparts. + */ +export interface LegacyAngularInjectedDependencies { + /** + * angular $http service + */ + $http: any; + /** + * Instance of SavedObjectRegistryProvider + */ + savedObjectRegistry: any; + kbnBaseUrl: any; + /** + * Instance of SavedWorkspacesProvider + */ + savedGraphWorkspaces: any; +} + +export const renderApp = ({ appBasePath, element, ...deps }: GraphDependencies) => { + const graphAngularModule = createLocalAngularModule(deps.coreStart); + configureAppAngularModule(graphAngularModule); + initGraphApp(graphAngularModule, deps); + const $injector = mountGraphApp(appBasePath, element); + return () => $injector.get('$rootScope').$destroy(); +}; + +const mainTemplate = (basePath: string) => `
+ +
+
+`; + +const moduleName = 'app/graph'; + +const thirdPartyAngularDependencies = ['ngSanitize', 'ngRoute', 'react', 'ui.bootstrap', 'ui.ace']; + +function mountGraphApp(appBasePath: string, element: HTMLElement) { + const mountpoint = document.createElement('div'); + mountpoint.setAttribute('style', 'height: 100%'); + // eslint-disable-next-line + mountpoint.innerHTML = mainTemplate(appBasePath); + // bootstrap angular into detached element and attach it later to + // make angular-within-angular possible + const $injector = angular.bootstrap(mountpoint, [moduleName]); + element.appendChild(mountpoint); + return $injector; +} + +function createLocalAngularModule(core: AppMountContext['core']) { + createLocalI18nModule(); + createLocalTopNavModule(); + createLocalConfirmModalModule(); + + const graphAngularModule = angular.module(moduleName, [ + ...thirdPartyAngularDependencies, + 'graphI18n', + 'graphTopNav', + 'graphConfirmModal', + ]); + return graphAngularModule; +} + +function createLocalConfirmModalModule() { + angular + .module('graphConfirmModal', ['react']) + .factory('confirmModal', confirmModalFactory) + .directive('confirmModal', reactDirective => reactDirective(EuiConfirmModal)); +} + +function createLocalTopNavModule() { + angular + .module('graphTopNav', ['react']) + .directive('kbnTopNav', createTopNavDirective) + .directive('kbnTopNavHelper', createTopNavHelper); +} + +function createLocalI18nModule() { + angular + .module('graphI18n', []) + .provider('i18n', I18nProvider) + .filter('i18n', i18nFilter) + .directive('i18nId', i18nDirective); +} diff --git a/x-pack/legacy/plugins/graph/public/services/url.ts b/x-pack/legacy/plugins/graph/public/services/url.ts index 91e14564bf3aa..b709683a457fb 100644 --- a/x-pack/legacy/plugins/graph/public/services/url.ts +++ b/x-pack/legacy/plugins/graph/public/services/url.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { Chrome } from 'ui/chrome'; +import { ChromeStart } from 'kibana/public'; import { GraphWorkspaceSavedObject } from '../types'; import { MetaDataState } from '../state_management'; @@ -21,23 +21,26 @@ export function getEditPath({ id }: GraphWorkspaceSavedObject) { return `/workspace/${id}`; } -export function getEditUrl(chrome: Chrome, workspace: GraphWorkspaceSavedObject) { - return chrome.addBasePath(`#${getEditPath(workspace)}`); +export function getEditUrl( + addBasePath: (url: string) => string, + workspace: GraphWorkspaceSavedObject +) { + return addBasePath(`#${getEditPath(workspace)}`); } export type SetBreadcrumbOptions = | { - chrome: Chrome; + chrome: ChromeStart; } | { - chrome: Chrome; + chrome: ChromeStart; metaData: MetaDataState; navigateTo: (path: string) => void; }; export function setBreadcrumbs(options: SetBreadcrumbOptions) { if ('metaData' in options) { - options.chrome.breadcrumbs.set([ + options.chrome.setBreadcrumbs([ { text: i18n.translate('xpack.graph.home.breadcrumb', { defaultMessage: 'Graph', @@ -53,7 +56,7 @@ export function setBreadcrumbs(options: SetBreadcrumbOptions) { }, ]); } else { - options.chrome.breadcrumbs.set([ + options.chrome.setBreadcrumbs([ { text: i18n.translate('xpack.graph.home.breadcrumb', { defaultMessage: 'Graph', diff --git a/x-pack/legacy/plugins/graph/public/state_management/meta_data.test.ts b/x-pack/legacy/plugins/graph/public/state_management/meta_data.test.ts index 8ac3746158f3f..25be050edfc13 100644 --- a/x-pack/legacy/plugins/graph/public/state_management/meta_data.test.ts +++ b/x-pack/legacy/plugins/graph/public/state_management/meta_data.test.ts @@ -6,7 +6,6 @@ import { createMockGraphStore, MockedGraphEnvironment } from './mocks'; import { syncBreadcrumbSaga, updateMetaData } from './meta_data'; -import { Chrome } from 'ui/chrome'; describe('breadcrumb sync saga', () => { let env: MockedGraphEnvironment; @@ -14,22 +13,15 @@ describe('breadcrumb sync saga', () => { beforeEach(() => { env = createMockGraphStore({ sagas: [syncBreadcrumbSaga], - mockedDepsOverwrites: { - chrome: ({ - breadcrumbs: { - set: jest.fn(), - }, - } as unknown) as Chrome, - }, }); }); it('syncs breadcrumb initially', () => { - expect(env.mockedDeps.chrome.breadcrumbs.set).toHaveBeenCalled(); + expect(env.mockedDeps.chrome.setBreadcrumbs).toHaveBeenCalled(); }); it('syncs breadcrumb with each change to meta data', () => { env.store.dispatch(updateMetaData({})); - expect(env.mockedDeps.chrome.breadcrumbs.set).toHaveBeenCalledTimes(2); + expect(env.mockedDeps.chrome.setBreadcrumbs).toHaveBeenCalledTimes(2); }); }); diff --git a/x-pack/legacy/plugins/graph/public/state_management/mocks.ts b/x-pack/legacy/plugins/graph/public/state_management/mocks.ts index 11cbf84e759ea..9672edef31d6f 100644 --- a/x-pack/legacy/plugins/graph/public/state_management/mocks.ts +++ b/x-pack/legacy/plugins/graph/public/state_management/mocks.ts @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Chrome } from 'ui/chrome'; import { IndexPattern } from 'src/legacy/core_plugins/data/public'; import { NotificationsStart, HttpStart } from 'kibana/public'; import createSagaMiddleware from 'redux-saga'; import { createStore, applyMiddleware, AnyAction } from 'redux'; +import { ChromeStart } from 'kibana/public'; import { GraphStoreDependencies, createRootReducer, GraphStore, GraphState } from './store'; import { Workspace, GraphWorkspaceSavedObject, IndexPatternSavedObject } from '../types'; @@ -52,10 +52,8 @@ export function createMockGraphStore({ basePath: 'basepath', changeUrl: jest.fn(), chrome: ({ - breadcrumbs: { - set: jest.fn(), - }, - } as unknown) as Chrome, + setBreadcrumbs: jest.fn(), + } as unknown) as ChromeStart, createWorkspace: jest.fn(), getWorkspace: jest.fn(() => workspaceMock), getSavedWorkspace: jest.fn(() => savedWorkspace), diff --git a/x-pack/legacy/plugins/graph/public/state_management/store.ts b/x-pack/legacy/plugins/graph/public/state_management/store.ts index 752483e65d8cc..bb01f20196f87 100644 --- a/x-pack/legacy/plugins/graph/public/state_management/store.ts +++ b/x-pack/legacy/plugins/graph/public/state_management/store.ts @@ -6,8 +6,8 @@ import createSagaMiddleware, { SagaMiddleware } from 'redux-saga'; import { combineReducers, createStore, Store, AnyAction, Dispatch, applyMiddleware } from 'redux'; +import { ChromeStart } from 'kibana/public'; import { CoreStart } from 'src/core/public'; -import { Chrome } from 'ui/chrome'; import { fieldsReducer, FieldsState, @@ -61,7 +61,7 @@ export interface GraphStoreDependencies { setLiveResponseFields: (fields: WorkspaceField[]) => void; setUrlTemplates: (templates: UrlTemplate[]) => void; setWorkspaceInitialized: () => void; - chrome: Chrome; + chrome: ChromeStart; } export function createRootReducer(basePath: string) { From 210e643b0c453481ebfd33d01d7ef573376e66ed Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Fri, 25 Oct 2019 09:51:10 +0200 Subject: [PATCH 05/61] Add outline parameter to gauge (#47827) --- .../components/options/gauge/ranges_panel.tsx | 33 +++++++++++++++++-- .../kbn_vislib_vis_types/public/gauge.d.ts | 1 + src/legacy/ui/public/vislib/_index.scss | 1 + .../vislib/visualizations/gauges/_index.scss | 1 + .../vislib/visualizations/gauges/_meter.scss | 3 ++ .../vislib/visualizations/gauges/meter.js | 3 ++ 6 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 src/legacy/ui/public/vislib/visualizations/gauges/_index.scss create mode 100644 src/legacy/ui/public/vislib/visualizations/gauges/_meter.scss diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/ranges_panel.tsx b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/ranges_panel.tsx index c1fa3475470f1..1045543512c6b 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/ranges_panel.tsx +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/ranges_panel.tsx @@ -17,14 +17,16 @@ * under the License. */ -import React from 'react'; +import React, { useCallback } from 'react'; import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { ColorSchemas } from 'ui/vislib/components/color/colormaps'; import { ColorRanges, ColorSchemaOptions, SwitchOption } from '../../common'; -import { SetColorSchemaOptionsValue } from '../../common/color_schema'; import { GaugeOptionsInternalProps } from '.'; +import { ColorSchemaVislibParams } from '../../../types'; +import { Gauge } from '../../../gauge'; function RangesPanel({ setGaugeValue, @@ -35,6 +37,22 @@ function RangesPanel({ uiState, vis, }: GaugeOptionsInternalProps) { + const setColorSchemaOptions = useCallback( + (paramName: T, value: ColorSchemaVislibParams[T]) => { + setGaugeValue(paramName, value as Gauge[T]); + // set outline if color schema is changed to greys + // if outline wasn't set explicitly yet + if ( + paramName === 'colorSchema' && + (value as string) === ColorSchemas.Greys && + typeof stateParams.gauge.outline === 'undefined' + ) { + setGaugeValue('outline', true); + } + }, + [setGaugeValue, stateParams] + ); + return ( @@ -84,7 +102,16 @@ function RangesPanel({ colorSchemas={vis.type.editorConfig.collections.colorSchemas} invertColors={stateParams.gauge.invertColors} uiState={uiState} - setValue={setGaugeValue as SetColorSchemaOptionsValue} + setValue={setColorSchemaOptions} + /> + + this.getColorBucket(Math.max(min, d.y))); const smallContainer = svg.node().getBBox().height < 70; From a3e16bf286eca7ae7195b2b94381025deb3164b5 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Fri, 25 Oct 2019 01:17:47 -0700 Subject: [PATCH 06/61] [ML] Fix code editor console error. (#49193) Fixes console errors caused by EuiCodeEditor by adding a missing theme attribute. --- .../components/analytics_list/expanded_row_json_pane.tsx | 1 + .../create_analytics_advanced_editor.tsx | 1 + .../jobs/jobs_list/components/ml_job_editor/ml_job_editor.js | 4 ++++ .../components/aggregation_list/popover_form.tsx | 2 +- .../components/group_by_list/popover_form.tsx | 2 +- .../components/step_define/step_define_form.tsx | 2 ++ .../__snapshots__/expanded_row_json_pane.test.tsx.snap | 1 + .../components/transform_list/expanded_row_json_pane.tsx | 1 + 8 files changed, 12 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row_json_pane.tsx b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row_json_pane.tsx index d0e23f96de049..ac7fdcb129531 100644 --- a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row_json_pane.tsx +++ b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row_json_pane.tsx @@ -28,6 +28,7 @@ export const ExpandedRowJsonPane: FC = ({ json }) => { readOnly={true} mode="json" style={{ width: '100%' }} + theme="textmate" />   diff --git a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/create_analytics_advanced_editor/create_analytics_advanced_editor.tsx b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/create_analytics_advanced_editor/create_analytics_advanced_editor.tsx index 9a5344cd1f984..daf21d57b0510 100644 --- a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/create_analytics_advanced_editor/create_analytics_advanced_editor.tsx +++ b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/create_analytics_advanced_editor/create_analytics_advanced_editor.tsx @@ -127,6 +127,7 @@ export const CreateAnalyticsAdvancedEditor: FC = ({ ac fontSize: '12px', maxLines: 20, }} + theme="textmate" aria-label={i18n.translate( 'xpack.ml.dataframe.analytics.create.advancedEditor.codeEditorAriaLabel', { diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/ml_job_editor/ml_job_editor.js b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/ml_job_editor/ml_job_editor.js index 22d45a70075e9..39cd21688dec5 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/ml_job_editor/ml_job_editor.js +++ b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/ml_job_editor/ml_job_editor.js @@ -21,6 +21,7 @@ export function MLJobEditor({ mode = EDITOR_MODE.JSON, readOnly = false, syntaxChecking = true, + theme = 'textmate', onChange = () => {} }) { return ( @@ -32,6 +33,7 @@ export function MLJobEditor({ readOnly={readOnly} wrapEnabled={true} showPrintMargin={false} + theme={theme} editorProps={{ $blockScrolling: true }} setOptions={{ useWorker: syntaxChecking, @@ -48,5 +50,7 @@ MLJobEditor.propTypes = { width: PropTypes.string, mode: PropTypes.string, readOnly: PropTypes.bool, + syntaxChecking: PropTypes.bool, + theme: PropTypes.string, onChange: PropTypes.func, }; diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/aggregation_list/popover_form.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/aggregation_list/popover_form.tsx index e7f79b240d81a..65dd8a34330a5 100644 --- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/aggregation_list/popover_form.tsx +++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/aggregation_list/popover_form.tsx @@ -142,7 +142,7 @@ export const PopoverForm: React.SFC = ({ {isUnsupportedAgg && ( = ({ = React.memo(({ overrides = {}, onChange setOptions={{ fontSize: '12px', }} + theme="textmate" aria-label={i18n.translate( 'xpack.transform.stepDefineForm.advancedSourceEditorAriaLabel', { @@ -751,6 +752,7 @@ export const StepDefineForm: SFC = React.memo(({ overrides = {}, onChange setOptions={{ fontSize: '12px', }} + theme="textmate" aria-label={i18n.translate( 'xpack.transform.stepDefineForm.advancedEditorAriaLabel', { diff --git a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/__snapshots__/expanded_row_json_pane.test.tsx.snap b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/__snapshots__/expanded_row_json_pane.test.tsx.snap index f185579fd9e4c..0d4a80a94ee51 100644 --- a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/__snapshots__/expanded_row_json_pane.test.tsx.snap +++ b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/__snapshots__/expanded_row_json_pane.test.tsx.snap @@ -15,6 +15,7 @@ exports[`Transform: Transform List Expanded Row Minimal "width": "100%", } } + theme="textmate" value="{ \\"id\\": \\"fq_date_histogram_1m_1441\\", \\"source\\": { diff --git a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_json_pane.tsx b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_json_pane.tsx index d24fc19f216a3..416d93007daba 100644 --- a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_json_pane.tsx +++ b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_json_pane.tsx @@ -28,6 +28,7 @@ export const ExpandedRowJsonPane: SFC = ({ json }) => { readOnly={true} mode="json" style={{ width: '100%' }} + theme="textmate" />   From 058168dee944a689afbe4d72de0c37b2b571d527 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Fri, 25 Oct 2019 01:38:44 -0700 Subject: [PATCH 07/61] [ML] Transform: Fix transform creation. (#49221) Fixes a regression where creating a transform in the wizard would result in an error toast even if the transform was created successfully. The response format of the create API was handled in the wrong way. --- .../components/step_create/step_create_form.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx index 47ce0f19f8f69..9623ff6abeced 100644 --- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx +++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx @@ -89,13 +89,14 @@ export const StepCreateForm: SFC = React.memo( try { const resp = await api.createTransform(transformId, transformConfig); - - if (resp.errors !== undefined) { - if (Array.isArray(resp.errors) && resp.errors.length === 1) { + if (resp.errors !== undefined && Array.isArray(resp.errors)) { + if (resp.errors.length === 1) { throw resp.errors[0]; } - throw resp.errors; + if (resp.errors.length > 1) { + throw resp.errors; + } } toastNotifications.addSuccess( From a5b541e0b65f8d6b0a8589ff117cb8f948fa48a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20St=C3=BCrmer?= Date: Fri, 25 Oct 2019 10:43:03 +0200 Subject: [PATCH 08/61] [Logs UI] Fix analysis page auto refresh (#49170) This fixes the auto-refresh not being triggered by the date-picker when a prop change happened before the timeout expired. The upstream issue is tracked in elastic/eui#2483. It also introduces tracking of the last change's timestamp to enable in-place refreshes such as when the selected time range is absolute. fixes #49152 --- .../log_analysis/log_analysis_results.tsx | 4 +- .../logs/analysis/page_results_content.tsx | 47 ++++++++++++++----- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/x-pack/legacy/plugins/infra/public/containers/logs/log_analysis/log_analysis_results.tsx b/x-pack/legacy/plugins/infra/public/containers/logs/log_analysis/log_analysis_results.tsx index d834b825e414a..8bd9f1074ac54 100644 --- a/x-pack/legacy/plugins/infra/public/containers/logs/log_analysis/log_analysis_results.tsx +++ b/x-pack/legacy/plugins/infra/public/containers/logs/log_analysis/log_analysis_results.tsx @@ -14,11 +14,13 @@ export const useLogAnalysisResults = ({ startTime, endTime, bucketDuration = 15 * 60 * 1000, + lastRequestTime, }: { sourceId: string; startTime: number; endTime: number; bucketDuration?: number; + lastRequestTime: number; }) => { const { isLoading: isLoadingLogEntryRate, logEntryRate, getLogEntryRate } = useLogEntryRate({ sourceId, @@ -31,7 +33,7 @@ export const useLogAnalysisResults = ({ useEffect(() => { getLogEntryRate(); - }, [sourceId, startTime, endTime, bucketDuration]); + }, [sourceId, startTime, endTime, bucketDuration, lastRequestTime]); return { isLoading, diff --git a/x-pack/legacy/plugins/infra/public/pages/logs/analysis/page_results_content.tsx b/x-pack/legacy/plugins/infra/public/pages/logs/analysis/page_results_content.tsx index e846d4e9e4ac5..ffc48a0af9de9 100644 --- a/x-pack/legacy/plugins/infra/public/pages/logs/analysis/page_results_content.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/logs/analysis/page_results_content.tsx @@ -57,9 +57,13 @@ export const AnalysisResultsContent = ({ setAutoRefresh, } = useLogAnalysisResultsUrlState(); - const [queryTimeRange, setQueryTimeRange] = useState( - stringToNumericTimeRange(selectedTimeRange) - ); + const [queryTimeRange, setQueryTimeRange] = useState<{ + value: TimeRange; + lastChangedTime: number; + }>(() => ({ + value: stringToNumericTimeRange(selectedTimeRange), + lastChangedTime: Date.now(), + })); const bucketDuration = useMemo(() => { // This function takes the current time range in ms, @@ -69,18 +73,21 @@ export const AnalysisResultsContent = ({ // 900000 (15 minutes) to it, so that we don't end up with // jaggy bucket boundaries between the ML buckets and our // aggregation buckets. - const msRange = moment(queryTimeRange.endTime).diff(moment(queryTimeRange.startTime)); + const msRange = moment(queryTimeRange.value.endTime).diff( + moment(queryTimeRange.value.startTime) + ); const bucketIntervalInMs = msRange / 100; const result = bucketSpan * Math.round(bucketIntervalInMs / bucketSpan); const roundedResult = parseInt(Number(result).toFixed(0), 10); return roundedResult < bucketSpan ? bucketSpan : roundedResult; - }, [queryTimeRange.startTime, queryTimeRange.endTime]); + }, [queryTimeRange.value.startTime, queryTimeRange.value.endTime]); const { isLoading, logEntryRate } = useLogAnalysisResults({ sourceId, - startTime: queryTimeRange.startTime, - endTime: queryTimeRange.endTime, + startTime: queryTimeRange.value.startTime, + endTime: queryTimeRange.value.endTime, bucketDuration, + lastRequestTime: queryTimeRange.lastChangedTime, }); const hasResults = useMemo(() => logEntryRate && logEntryRate.histogramBuckets.length > 0, [ logEntryRate, @@ -88,7 +95,10 @@ export const AnalysisResultsContent = ({ const handleQueryTimeRangeChange = useCallback( ({ start: startTime, end: endTime }: { start: string; end: string }) => { - setQueryTimeRange(stringToNumericTimeRange({ startTime, endTime })); + setQueryTimeRange({ + value: stringToNumericTimeRange({ startTime, endTime }), + lastChangedTime: Date.now(), + }); }, [setQueryTimeRange] ); @@ -141,6 +151,16 @@ export const AnalysisResultsContent = ({ fetchJobStatus(); }, JOB_STATUS_POLLING_INTERVAL); + useInterval( + () => { + handleQueryTimeRangeChange({ + start: selectedTimeRange.startTime, + end: selectedTimeRange.endTime, + }); + }, + autoRefresh.isPaused ? null : autoRefresh.interval + ); + return ( <> {isLoading && !logEntryRate ? ( @@ -171,9 +191,11 @@ export const AnalysisResultsContent = ({ ), startTime: ( - {moment(queryTimeRange.startTime).format(dateFormat)} + {moment(queryTimeRange.value.startTime).format(dateFormat)} + ), + endTime: ( + {moment(queryTimeRange.value.endTime).format(dateFormat)} ), - endTime: {moment(queryTimeRange.endTime).format(dateFormat)}, }} /> @@ -187,7 +209,6 @@ export const AnalysisResultsContent = ({ isPaused={autoRefresh.isPaused} refreshInterval={autoRefresh.interval} onRefreshChange={handleAutoRefreshChange} - onRefresh={handleQueryTimeRangeChange} /> @@ -200,7 +221,7 @@ export const AnalysisResultsContent = ({ isLoading={isLoading} results={logEntryRate} setTimeRange={handleChartTimeRangeChange} - timeRange={queryTimeRange} + timeRange={queryTimeRange.value} /> @@ -214,7 +235,7 @@ export const AnalysisResultsContent = ({ results={logEntryRate} setTimeRange={handleChartTimeRangeChange} setupStatus={setupStatus} - timeRange={queryTimeRange} + timeRange={queryTimeRange.value} jobId={jobIds['log-entry-rate']} /> From a4c2fa2d7ef69bdd4d00c407075c1a0395b37992 Mon Sep 17 00:00:00 2001 From: Rudolf Meijering Date: Fri, 25 Oct 2019 11:22:07 +0200 Subject: [PATCH 09/61] Consistent capitalization for savedObjectsClientMock (#49162) --- src/core/server/mocks.ts | 2 +- .../export/get_sorted_objects_for_export.test.ts | 4 ++-- .../export/inject_nested_depdendencies.test.ts | 4 ++-- .../saved_objects/import/import_saved_objects.test.ts | 4 ++-- .../saved_objects/import/resolve_import_errors.test.ts | 4 ++-- .../server/saved_objects/import/validate_references.test.ts | 6 +++--- .../saved_objects/service/saved_objects_client.mock.ts | 2 +- src/core/server/ui_settings/ui_settings_service.test.ts | 4 ++-- .../server/lib/export/collect_references_deep.test.ts | 4 ++-- src/legacy/server/saved_objects/routes/bulk_create.test.ts | 4 ++-- src/legacy/server/saved_objects/routes/bulk_get.test.ts | 4 ++-- src/legacy/server/saved_objects/routes/bulk_update.test.ts | 4 ++-- src/legacy/server/saved_objects/routes/create.test.ts | 4 ++-- src/legacy/server/saved_objects/routes/delete.test.ts | 4 ++-- src/legacy/server/saved_objects/routes/export.test.ts | 4 ++-- src/legacy/server/saved_objects/routes/find.test.ts | 4 ++-- src/legacy/server/saved_objects/routes/get.test.ts | 4 ++-- src/legacy/server/saved_objects/routes/import.test.ts | 4 ++-- .../saved_objects/routes/resolve_import_errors.test.ts | 4 ++-- src/legacy/server/saved_objects/routes/update.test.ts | 4 ++-- .../ui_settings/integration_tests/ui_settings_mixin.test.ts | 4 ++-- x-pack/legacy/plugins/actions/server/actions_client.test.ts | 4 ++-- .../actions/server/builtin_action_types/email.test.ts | 4 ++-- .../actions/server/builtin_action_types/es_index.test.ts | 4 ++-- .../actions/server/builtin_action_types/pagerduty.test.ts | 4 ++-- .../actions/server/builtin_action_types/server_log.test.ts | 4 ++-- .../actions/server/builtin_action_types/slack.test.ts | 4 ++-- .../plugins/actions/server/create_execute_function.test.ts | 4 ++-- .../plugins/actions/server/lib/action_executor.test.ts | 4 ++-- .../plugins/actions/server/lib/task_runner_factory.test.ts | 4 ++-- x-pack/legacy/plugins/actions/server/routes/_mock_server.ts | 4 ++-- x-pack/legacy/plugins/alerting/server/alerts_client.test.ts | 4 ++-- .../plugins/alerting/server/lib/task_runner_factory.test.ts | 4 ++-- .../lib/encrypted_saved_objects_client_wrapper.test.ts | 4 ++-- x-pack/legacy/plugins/task_manager/task_manager.test.ts | 4 ++-- x-pack/legacy/plugins/task_manager/task_store.test.ts | 4 ++-- .../spaces_saved_objects_client.test.ts | 4 ++-- 37 files changed, 73 insertions(+), 73 deletions(-) diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index fb703c6c35008..deb5984564db1 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -29,7 +29,7 @@ export { configServiceMock } from './config/config_service.mock'; export { elasticsearchServiceMock } from './elasticsearch/elasticsearch_service.mock'; export { httpServiceMock } from './http/http_service.mock'; export { loggingServiceMock } from './logging/logging_service.mock'; -export { SavedObjectsClientMock } from './saved_objects/service/saved_objects_client.mock'; +export { savedObjectsClientMock } from './saved_objects/service/saved_objects_client.mock'; export { uiSettingsServiceMock } from './ui_settings/ui_settings_service.mock'; export function pluginInitializerContextConfigMock(config: T) { diff --git a/src/core/server/saved_objects/export/get_sorted_objects_for_export.test.ts b/src/core/server/saved_objects/export/get_sorted_objects_for_export.test.ts index 1a2a843ebb2b8..9a3449b65a941 100644 --- a/src/core/server/saved_objects/export/get_sorted_objects_for_export.test.ts +++ b/src/core/server/saved_objects/export/get_sorted_objects_for_export.test.ts @@ -18,7 +18,7 @@ */ import { getSortedObjectsForExport } from './get_sorted_objects_for_export'; -import { SavedObjectsClientMock } from '../service/saved_objects_client.mock'; +import { savedObjectsClientMock } from '../service/saved_objects_client.mock'; import { Readable } from 'stream'; import { createPromiseFromStreams, createConcatStream } from '../../../../legacy/utils/streams'; @@ -27,7 +27,7 @@ async function readStreamToCompletion(stream: Readable) { } describe('getSortedObjectsForExport()', () => { - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); afterEach(() => { savedObjectsClient.find.mockReset(); diff --git a/src/core/server/saved_objects/export/inject_nested_depdendencies.test.ts b/src/core/server/saved_objects/export/inject_nested_depdendencies.test.ts index 57feebbf67ccd..a571f62e3d1c1 100644 --- a/src/core/server/saved_objects/export/inject_nested_depdendencies.test.ts +++ b/src/core/server/saved_objects/export/inject_nested_depdendencies.test.ts @@ -18,7 +18,7 @@ */ import { SavedObject } from '../types'; -import { SavedObjectsClientMock } from '../../mocks'; +import { savedObjectsClientMock } from '../../mocks'; import { getObjectReferencesToFetch, fetchNestedDependencies } from './inject_nested_depdendencies'; describe('getObjectReferencesToFetch()', () => { @@ -109,7 +109,7 @@ describe('getObjectReferencesToFetch()', () => { }); describe('injectNestedDependencies', () => { - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); afterEach(() => { jest.resetAllMocks(); diff --git a/src/core/server/saved_objects/import/import_saved_objects.test.ts b/src/core/server/saved_objects/import/import_saved_objects.test.ts index df95fb75f0f4f..f0719cbf4c829 100644 --- a/src/core/server/saved_objects/import/import_saved_objects.test.ts +++ b/src/core/server/saved_objects/import/import_saved_objects.test.ts @@ -20,7 +20,7 @@ import { Readable } from 'stream'; import { SavedObject } from '../types'; import { importSavedObjects } from './import_saved_objects'; -import { SavedObjectsClientMock } from '../../mocks'; +import { savedObjectsClientMock } from '../../mocks'; const emptyResponse = { saved_objects: [], @@ -63,7 +63,7 @@ describe('importSavedObjects()', () => { references: [], }, ]; - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); beforeEach(() => { jest.resetAllMocks(); diff --git a/src/core/server/saved_objects/import/resolve_import_errors.test.ts b/src/core/server/saved_objects/import/resolve_import_errors.test.ts index 6aab8ef5adf9e..c522d76f1ff04 100644 --- a/src/core/server/saved_objects/import/resolve_import_errors.test.ts +++ b/src/core/server/saved_objects/import/resolve_import_errors.test.ts @@ -20,7 +20,7 @@ import { Readable } from 'stream'; import { SavedObject } from '../types'; import { resolveImportErrors } from './resolve_import_errors'; -import { SavedObjectsClientMock } from '../../mocks'; +import { savedObjectsClientMock } from '../../mocks'; describe('resolveImportErrors()', () => { const savedObjects: SavedObject[] = [ @@ -63,7 +63,7 @@ describe('resolveImportErrors()', () => { ], }, ]; - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); beforeEach(() => { jest.resetAllMocks(); diff --git a/src/core/server/saved_objects/import/validate_references.test.ts b/src/core/server/saved_objects/import/validate_references.test.ts index 269cd3055b047..6642cf149eda9 100644 --- a/src/core/server/saved_objects/import/validate_references.test.ts +++ b/src/core/server/saved_objects/import/validate_references.test.ts @@ -18,10 +18,10 @@ */ import { getNonExistingReferenceAsKeys, validateReferences } from './validate_references'; -import { SavedObjectsClientMock } from '../../mocks'; +import { savedObjectsClientMock } from '../../mocks'; describe('getNonExistingReferenceAsKeys()', () => { - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); beforeEach(() => { jest.resetAllMocks(); @@ -222,7 +222,7 @@ describe('getNonExistingReferenceAsKeys()', () => { }); describe('validateReferences()', () => { - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); beforeEach(() => { jest.resetAllMocks(); diff --git a/src/core/server/saved_objects/service/saved_objects_client.mock.ts b/src/core/server/saved_objects/service/saved_objects_client.mock.ts index 63c9a0ee35ae0..c6de9fa94291c 100644 --- a/src/core/server/saved_objects/service/saved_objects_client.mock.ts +++ b/src/core/server/saved_objects/service/saved_objects_client.mock.ts @@ -33,4 +33,4 @@ const create = () => update: jest.fn(), } as unknown) as jest.Mocked); -export const SavedObjectsClientMock = { create }; +export const savedObjectsClientMock = { create }; diff --git a/src/core/server/ui_settings/ui_settings_service.test.ts b/src/core/server/ui_settings/ui_settings_service.test.ts index 832d61bdb4137..e219d0c962344 100644 --- a/src/core/server/ui_settings/ui_settings_service.test.ts +++ b/src/core/server/ui_settings/ui_settings_service.test.ts @@ -23,7 +23,7 @@ import { MockUiSettingsClientConstructor } from './ui_settings_service.test.mock import { UiSettingsService } from './ui_settings_service'; import { httpServiceMock } from '../http/http_service.mock'; import { loggingServiceMock } from '../logging/logging_service.mock'; -import { SavedObjectsClientMock } from '../mocks'; +import { savedObjectsClientMock } from '../mocks'; import { mockCoreContext } from '../core_context.mock'; const overrides = { @@ -43,7 +43,7 @@ const coreContext = mockCoreContext.create(); coreContext.configService.atPath.mockReturnValue(new BehaviorSubject({ overrides })); const httpSetup = httpServiceMock.createSetupContract(); const setupDeps = { http: httpSetup }; -const savedObjectsClient = SavedObjectsClientMock.create(); +const savedObjectsClient = savedObjectsClientMock.create(); afterEach(() => { MockUiSettingsClientConstructor.mockClear(); diff --git a/src/legacy/core_plugins/kibana/server/lib/export/collect_references_deep.test.ts b/src/legacy/core_plugins/kibana/server/lib/export/collect_references_deep.test.ts index b5e112a489ce4..8aedc6f7332dc 100644 --- a/src/legacy/core_plugins/kibana/server/lib/export/collect_references_deep.test.ts +++ b/src/legacy/core_plugins/kibana/server/lib/export/collect_references_deep.test.ts @@ -19,7 +19,7 @@ import { SavedObject, SavedObjectAttributes } from 'src/core/server'; import { collectReferencesDeep } from './collect_references_deep'; -import { SavedObjectsClientMock } from '../../../../../../core/server/mocks'; +import { savedObjectsClientMock } from '../../../../../../core/server/mocks'; const data: Array> = [ { @@ -102,7 +102,7 @@ const data: Array> = [ ]; test('collects dashboard and all dependencies', async () => { - const savedObjectClient = SavedObjectsClientMock.create(); + const savedObjectClient = savedObjectsClientMock.create(); savedObjectClient.bulkGet.mockImplementation(objects => { if (!objects) { throw new Error('Invalid test data'); diff --git a/src/legacy/server/saved_objects/routes/bulk_create.test.ts b/src/legacy/server/saved_objects/routes/bulk_create.test.ts index 1e041bb28f75f..b49554995aab6 100644 --- a/src/legacy/server/saved_objects/routes/bulk_create.test.ts +++ b/src/legacy/server/saved_objects/routes/bulk_create.test.ts @@ -22,11 +22,11 @@ import { createMockServer } from './_mock_server'; import { createBulkCreateRoute } from './bulk_create'; // Disable lint errors for imports from src/core/* until SavedObjects migration is complete // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SavedObjectsClientMock } from '../../../../core/server/saved_objects/service/saved_objects_client.mock'; +import { savedObjectsClientMock } from '../../../../core/server/saved_objects/service/saved_objects_client.mock'; describe('POST /api/saved_objects/_bulk_create', () => { let server: Hapi.Server; - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); beforeEach(() => { savedObjectsClient.bulkCreate.mockImplementation(() => Promise.resolve('' as any)); diff --git a/src/legacy/server/saved_objects/routes/bulk_get.test.ts b/src/legacy/server/saved_objects/routes/bulk_get.test.ts index 546164be65c9f..e154649e2cf04 100644 --- a/src/legacy/server/saved_objects/routes/bulk_get.test.ts +++ b/src/legacy/server/saved_objects/routes/bulk_get.test.ts @@ -20,11 +20,11 @@ import Hapi from 'hapi'; import { createMockServer } from './_mock_server'; import { createBulkGetRoute } from './bulk_get'; -import { SavedObjectsClientMock } from '../../../../core/server/mocks'; +import { savedObjectsClientMock } from '../../../../core/server/mocks'; describe('POST /api/saved_objects/_bulk_get', () => { let server: Hapi.Server; - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); beforeEach(() => { savedObjectsClient.bulkGet.mockImplementation(() => diff --git a/src/legacy/server/saved_objects/routes/bulk_update.test.ts b/src/legacy/server/saved_objects/routes/bulk_update.test.ts index ee74ddfc535d2..dc21ab08035ce 100644 --- a/src/legacy/server/saved_objects/routes/bulk_update.test.ts +++ b/src/legacy/server/saved_objects/routes/bulk_update.test.ts @@ -20,11 +20,11 @@ import Hapi from 'hapi'; import { createMockServer } from './_mock_server'; import { createBulkUpdateRoute } from './bulk_update'; -import { SavedObjectsClientMock } from '../../../../core/server/mocks'; +import { savedObjectsClientMock } from '../../../../core/server/mocks'; describe('PUT /api/saved_objects/_bulk_update', () => { let server: Hapi.Server; - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); beforeEach(() => { server = createMockServer(); diff --git a/src/legacy/server/saved_objects/routes/create.test.ts b/src/legacy/server/saved_objects/routes/create.test.ts index 85096228c3175..4f096a9ee5c93 100644 --- a/src/legacy/server/saved_objects/routes/create.test.ts +++ b/src/legacy/server/saved_objects/routes/create.test.ts @@ -20,7 +20,7 @@ import Hapi from 'hapi'; import { createMockServer } from './_mock_server'; import { createCreateRoute } from './create'; -import { SavedObjectsClientMock } from '../../../../core/server/mocks'; +import { savedObjectsClientMock } from '../../../../core/server/mocks'; describe('POST /api/saved_objects/{type}', () => { let server: Hapi.Server; @@ -32,7 +32,7 @@ describe('POST /api/saved_objects/{type}', () => { references: [], attributes: {}, }; - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); beforeEach(() => { savedObjectsClient.create.mockImplementation(() => Promise.resolve(clientResponse)); diff --git a/src/legacy/server/saved_objects/routes/delete.test.ts b/src/legacy/server/saved_objects/routes/delete.test.ts index 9e2adcf9d3b91..f3e5e83771471 100644 --- a/src/legacy/server/saved_objects/routes/delete.test.ts +++ b/src/legacy/server/saved_objects/routes/delete.test.ts @@ -20,11 +20,11 @@ import Hapi from 'hapi'; import { createMockServer } from './_mock_server'; import { createDeleteRoute } from './delete'; -import { SavedObjectsClientMock } from '../../../../core/server/mocks'; +import { savedObjectsClientMock } from '../../../../core/server/mocks'; describe('DELETE /api/saved_objects/{type}/{id}', () => { let server: Hapi.Server; - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); beforeEach(() => { savedObjectsClient.delete.mockImplementation(() => Promise.resolve('{}')); diff --git a/src/legacy/server/saved_objects/routes/export.test.ts b/src/legacy/server/saved_objects/routes/export.test.ts index 2670535ab995e..93ca3a419e6df 100644 --- a/src/legacy/server/saved_objects/routes/export.test.ts +++ b/src/legacy/server/saved_objects/routes/export.test.ts @@ -28,14 +28,14 @@ import * as exportMock from '../../../../core/server/saved_objects/export'; import { createMockServer } from './_mock_server'; import { createExportRoute } from './export'; import { createListStream } from '../../../utils/streams'; -import { SavedObjectsClientMock } from '../../../../core/server/mocks'; +import { savedObjectsClientMock } from '../../../../core/server/mocks'; const getSortedObjectsForExport = exportMock.getSortedObjectsForExport as jest.Mock; describe('POST /api/saved_objects/_export', () => { let server: Hapi.Server; const savedObjectsClient = { - ...SavedObjectsClientMock.create(), + ...savedObjectsClientMock.create(), errors: {} as any, }; diff --git a/src/legacy/server/saved_objects/routes/find.test.ts b/src/legacy/server/saved_objects/routes/find.test.ts index 89cd0dd28d035..4bf5f57fec199 100644 --- a/src/legacy/server/saved_objects/routes/find.test.ts +++ b/src/legacy/server/saved_objects/routes/find.test.ts @@ -20,11 +20,11 @@ import Hapi from 'hapi'; import { createMockServer } from './_mock_server'; import { createFindRoute } from './find'; -import { SavedObjectsClientMock } from '../../../../core/server/mocks'; +import { savedObjectsClientMock } from '../../../../core/server/mocks'; describe('GET /api/saved_objects/_find', () => { let server: Hapi.Server; - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); const clientResponse = { total: 0, diff --git a/src/legacy/server/saved_objects/routes/get.test.ts b/src/legacy/server/saved_objects/routes/get.test.ts index 2f7eaea1bc770..7ede2a8b4d7b4 100644 --- a/src/legacy/server/saved_objects/routes/get.test.ts +++ b/src/legacy/server/saved_objects/routes/get.test.ts @@ -20,11 +20,11 @@ import Hapi from 'hapi'; import { createMockServer } from './_mock_server'; import { createGetRoute } from './get'; -import { SavedObjectsClientMock } from '../../../../core/server/mocks'; +import { savedObjectsClientMock } from '../../../../core/server/mocks'; describe('GET /api/saved_objects/{type}/{id}', () => { let server: Hapi.Server; - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); beforeEach(() => { savedObjectsClient.get.mockImplementation(() => diff --git a/src/legacy/server/saved_objects/routes/import.test.ts b/src/legacy/server/saved_objects/routes/import.test.ts index 1a0684a35ec79..2b8d9d7523507 100644 --- a/src/legacy/server/saved_objects/routes/import.test.ts +++ b/src/legacy/server/saved_objects/routes/import.test.ts @@ -20,11 +20,11 @@ import Hapi from 'hapi'; import { createMockServer } from './_mock_server'; import { createImportRoute } from './import'; -import { SavedObjectsClientMock } from '../../../../core/server/mocks'; +import { savedObjectsClientMock } from '../../../../core/server/mocks'; describe('POST /api/saved_objects/_import', () => { let server: Hapi.Server; - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); const emptyResponse = { saved_objects: [], total: 0, diff --git a/src/legacy/server/saved_objects/routes/resolve_import_errors.test.ts b/src/legacy/server/saved_objects/routes/resolve_import_errors.test.ts index 7988165207e63..44fa46bccfce5 100644 --- a/src/legacy/server/saved_objects/routes/resolve_import_errors.test.ts +++ b/src/legacy/server/saved_objects/routes/resolve_import_errors.test.ts @@ -20,11 +20,11 @@ import Hapi from 'hapi'; import { createMockServer } from './_mock_server'; import { createResolveImportErrorsRoute } from './resolve_import_errors'; -import { SavedObjectsClientMock } from '../../../../core/server/mocks'; +import { savedObjectsClientMock } from '../../../../core/server/mocks'; describe('POST /api/saved_objects/_resolve_import_errors', () => { let server: Hapi.Server; - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); beforeEach(() => { server = createMockServer(); diff --git a/src/legacy/server/saved_objects/routes/update.test.ts b/src/legacy/server/saved_objects/routes/update.test.ts index 69a6fe3030009..aaeaff489d30a 100644 --- a/src/legacy/server/saved_objects/routes/update.test.ts +++ b/src/legacy/server/saved_objects/routes/update.test.ts @@ -20,11 +20,11 @@ import Hapi from 'hapi'; import { createMockServer } from './_mock_server'; import { createUpdateRoute } from './update'; -import { SavedObjectsClientMock } from '../../../../core/server/mocks'; +import { savedObjectsClientMock } from '../../../../core/server/mocks'; describe('PUT /api/saved_objects/{type}/{id?}', () => { let server: Hapi.Server; - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); beforeEach(() => { const clientResponse = { diff --git a/src/legacy/ui/ui_settings/integration_tests/ui_settings_mixin.test.ts b/src/legacy/ui/ui_settings/integration_tests/ui_settings_mixin.test.ts index 9f553b37935d7..3da7f83be4894 100644 --- a/src/legacy/ui/ui_settings/integration_tests/ui_settings_mixin.test.ts +++ b/src/legacy/ui/ui_settings/integration_tests/ui_settings_mixin.test.ts @@ -20,7 +20,7 @@ import sinon from 'sinon'; import expect from '@kbn/expect'; -import { SavedObjectsClientMock } from '../../../../core/server/mocks'; +import { savedObjectsClientMock } from '../../../../core/server/mocks'; import * as uiSettingsServiceFactoryNS from '../ui_settings_service_factory'; import * as getUiSettingsServiceForRequestNS from '../ui_settings_service_for_request'; // @ts-ignore @@ -129,7 +129,7 @@ describe('uiSettingsMixin()', () => { sinon.assert.notCalled(uiSettingsServiceFactoryStub); - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); decorations.server.uiSettingsServiceFactory({ savedObjectsClient, }); diff --git a/x-pack/legacy/plugins/actions/server/actions_client.test.ts b/x-pack/legacy/plugins/actions/server/actions_client.test.ts index b582d9f2a1b0d..b4940b23ba61c 100644 --- a/x-pack/legacy/plugins/actions/server/actions_client.test.ts +++ b/x-pack/legacy/plugins/actions/server/actions_client.test.ts @@ -11,9 +11,9 @@ import { ActionsClient } from './actions_client'; import { ExecutorType } from './types'; import { ActionExecutor, TaskRunnerFactory } from './lib'; import { taskManagerMock } from '../../task_manager/task_manager.mock'; -import { SavedObjectsClientMock } from '../../../../../src/core/server/mocks'; +import { savedObjectsClientMock } from '../../../../../src/core/server/mocks'; -const savedObjectsClient = SavedObjectsClientMock.create(); +const savedObjectsClient = savedObjectsClientMock.create(); const mockTaskManager = taskManagerMock.create(); diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/email.test.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/email.test.ts index 4e2ef29dd740f..8e6b1f19b172c 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/email.test.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/email.test.ts @@ -10,7 +10,7 @@ jest.mock('./lib/send_email', () => ({ import { ActionType, ActionTypeExecutorOptions } from '../types'; import { validateConfig, validateSecrets, validateParams } from '../lib'; -import { SavedObjectsClientMock } from '../../../../../../src/core/server/mocks'; +import { savedObjectsClientMock } from '../../../../../../src/core/server/mocks'; import { createActionTypeRegistry } from './index.test'; import { sendEmail } from './lib/send_email'; import { ActionParamsType, ActionTypeConfigType, ActionTypeSecretsType } from './email'; @@ -23,7 +23,7 @@ const NO_OP_FN = () => {}; const services = { log: NO_OP_FN, callCluster: async (path: string, opts: any) => {}, - savedObjectsClient: SavedObjectsClientMock.create(), + savedObjectsClient: savedObjectsClientMock.create(), }; let actionType: ActionType; diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/es_index.test.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/es_index.test.ts index 57a107968ba70..35d81ba74fa72 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/es_index.test.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/es_index.test.ts @@ -10,7 +10,7 @@ jest.mock('./lib/send_email', () => ({ import { ActionType, ActionTypeExecutorOptions } from '../types'; import { validateConfig, validateParams } from '../lib'; -import { SavedObjectsClientMock } from '../../../../../../src/core/server/mocks'; +import { savedObjectsClientMock } from '../../../../../../src/core/server/mocks'; import { createActionTypeRegistry } from './index.test'; import { ActionParamsType, ActionTypeConfigType } from './es_index'; @@ -20,7 +20,7 @@ const NO_OP_FN = () => {}; const services = { log: NO_OP_FN, callCluster: jest.fn(), - savedObjectsClient: SavedObjectsClientMock.create(), + savedObjectsClient: savedObjectsClientMock.create(), }; let actionType: ActionType; diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/pagerduty.test.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/pagerduty.test.ts index a9f3ea757e33b..1d453d2bd2340 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/pagerduty.test.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/pagerduty.test.ts @@ -10,7 +10,7 @@ jest.mock('./lib/post_pagerduty', () => ({ import { ActionType, Services, ActionTypeExecutorOptions } from '../types'; import { validateConfig, validateSecrets, validateParams } from '../lib'; -import { SavedObjectsClientMock } from '../../../../../../src/core/server/mocks'; +import { savedObjectsClientMock } from '../../../../../../src/core/server/mocks'; import { postPagerduty } from './lib/post_pagerduty'; import { createActionTypeRegistry } from './index.test'; @@ -20,7 +20,7 @@ const ACTION_TYPE_ID = '.pagerduty'; const services: Services = { callCluster: async (path: string, opts: any) => {}, - savedObjectsClient: SavedObjectsClientMock.create(), + savedObjectsClient: savedObjectsClientMock.create(), }; let actionType: ActionType; diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/server_log.test.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/server_log.test.ts index e3feec6d1bc67..76e639c994834 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/server_log.test.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/server_log.test.ts @@ -7,7 +7,7 @@ import { ActionType } from '../types'; import { validateParams } from '../lib'; import { Logger } from '../../../../../../src/core/server'; -import { SavedObjectsClientMock } from '../../../../../../src/core/server/mocks'; +import { savedObjectsClientMock } from '../../../../../../src/core/server/mocks'; import { createActionTypeRegistry } from './index.test'; const ACTION_TYPE_ID = '.server-log'; @@ -92,7 +92,7 @@ describe('execute()', () => { actionId, services: { callCluster: async (path: string, opts: any) => {}, - savedObjectsClient: SavedObjectsClientMock.create(), + savedObjectsClient: savedObjectsClientMock.create(), }, params: { message: 'message text here', level: 'info' }, config: {}, diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/slack.test.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/slack.test.ts index 681f508b1d214..f6bd2d2b254df 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/slack.test.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/slack.test.ts @@ -6,7 +6,7 @@ import { ActionType, Services, ActionTypeExecutorOptions } from '../types'; import { ActionTypeRegistry } from '../action_type_registry'; -import { SavedObjectsClientMock } from '../../../../../../src/core/server/mocks'; +import { savedObjectsClientMock } from '../../../../../../src/core/server/mocks'; import { ActionExecutor, validateParams, validateSecrets, TaskRunnerFactory } from '../lib'; import { getActionType } from './slack'; import { taskManagerMock } from '../../../task_manager/task_manager.mock'; @@ -15,7 +15,7 @@ const ACTION_TYPE_ID = '.slack'; const services: Services = { callCluster: async (path: string, opts: any) => {}, - savedObjectsClient: SavedObjectsClientMock.create(), + savedObjectsClient: savedObjectsClientMock.create(), }; let actionTypeRegistry: ActionTypeRegistry; diff --git a/x-pack/legacy/plugins/actions/server/create_execute_function.test.ts b/x-pack/legacy/plugins/actions/server/create_execute_function.test.ts index e928eb491c1b5..c6817b3bc12f3 100644 --- a/x-pack/legacy/plugins/actions/server/create_execute_function.test.ts +++ b/x-pack/legacy/plugins/actions/server/create_execute_function.test.ts @@ -6,10 +6,10 @@ import { taskManagerMock } from '../../task_manager/task_manager.mock'; import { createExecuteFunction } from './create_execute_function'; -import { SavedObjectsClientMock } from '../../../../../src/core/server/mocks'; +import { savedObjectsClientMock } from '../../../../../src/core/server/mocks'; const mockTaskManager = taskManagerMock.create(); -const savedObjectsClient = SavedObjectsClientMock.create(); +const savedObjectsClient = savedObjectsClientMock.create(); const getBasePath = jest.fn(); beforeEach(() => jest.resetAllMocks()); diff --git a/x-pack/legacy/plugins/actions/server/lib/action_executor.test.ts b/x-pack/legacy/plugins/actions/server/lib/action_executor.test.ts index 661a08df3dc30..c724717bef9eb 100644 --- a/x-pack/legacy/plugins/actions/server/lib/action_executor.test.ts +++ b/x-pack/legacy/plugins/actions/server/lib/action_executor.test.ts @@ -10,12 +10,12 @@ import { ActionExecutor } from './action_executor'; import { actionTypeRegistryMock } from '../action_type_registry.mock'; import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/plugin.mock'; import { - SavedObjectsClientMock, + savedObjectsClientMock, loggingServiceMock, } from '../../../../../../src/core/server/mocks'; const actionExecutor = new ActionExecutor(); -const savedObjectsClient = SavedObjectsClientMock.create(); +const savedObjectsClient = savedObjectsClientMock.create(); function getServices() { return { diff --git a/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts b/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts index cc18c7b169429..6411bc7462c9f 100644 --- a/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts +++ b/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts @@ -13,7 +13,7 @@ import { actionTypeRegistryMock } from '../action_type_registry.mock'; import { actionExecutorMock } from './action_executor.mock'; import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/plugin.mock'; import { - SavedObjectsClientMock, + savedObjectsClientMock, loggingServiceMock, } from '../../../../../../src/core/server/mocks'; @@ -54,7 +54,7 @@ afterAll(() => fakeTimer.restore()); const services = { log: jest.fn(), callCluster: jest.fn(), - savedObjectsClient: SavedObjectsClientMock.create(), + savedObjectsClient: savedObjectsClientMock.create(), }; const actionExecutorInitializerParams = { logger: loggingServiceMock.create().get(), diff --git a/x-pack/legacy/plugins/actions/server/routes/_mock_server.ts b/x-pack/legacy/plugins/actions/server/routes/_mock_server.ts index 340d341a5ef14..7f2341c1aa010 100644 --- a/x-pack/legacy/plugins/actions/server/routes/_mock_server.ts +++ b/x-pack/legacy/plugins/actions/server/routes/_mock_server.ts @@ -5,7 +5,7 @@ */ import Hapi from 'hapi'; -import { SavedObjectsClientMock } from '../../../../../../src/core/server/mocks'; +import { savedObjectsClientMock } from '../../../../../../src/core/server/mocks'; import { actionsClientMock } from '../actions_client.mock'; import { actionTypeRegistryMock } from '../action_type_registry.mock'; import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/plugin.mock'; @@ -21,7 +21,7 @@ export function createMockServer(config: Record = defaultConfig) { const actionsClient = actionsClientMock.create(); const actionTypeRegistry = actionTypeRegistryMock.create(); - const savedObjectsClient = SavedObjectsClientMock.create(); + const savedObjectsClient = savedObjectsClientMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.create(); server.config = () => { diff --git a/x-pack/legacy/plugins/alerting/server/alerts_client.test.ts b/x-pack/legacy/plugins/alerting/server/alerts_client.test.ts index 574aed3fe9329..093f5f7484004 100644 --- a/x-pack/legacy/plugins/alerting/server/alerts_client.test.ts +++ b/x-pack/legacy/plugins/alerting/server/alerts_client.test.ts @@ -6,13 +6,13 @@ import { schema } from '@kbn/config-schema'; import { AlertsClient } from './alerts_client'; -import { SavedObjectsClientMock, loggingServiceMock } from '../../../../../src/core/server/mocks'; +import { savedObjectsClientMock, loggingServiceMock } from '../../../../../src/core/server/mocks'; import { taskManagerMock } from '../../task_manager/task_manager.mock'; import { alertTypeRegistryMock } from './alert_type_registry.mock'; const taskManager = taskManagerMock.create(); const alertTypeRegistry = alertTypeRegistryMock.create(); -const savedObjectsClient = SavedObjectsClientMock.create(); +const savedObjectsClient = savedObjectsClientMock.create(); const alertsClientParams = { taskManager, diff --git a/x-pack/legacy/plugins/alerting/server/lib/task_runner_factory.test.ts b/x-pack/legacy/plugins/alerting/server/lib/task_runner_factory.test.ts index ccc91ae2a9034..23591692bca1f 100644 --- a/x-pack/legacy/plugins/alerting/server/lib/task_runner_factory.test.ts +++ b/x-pack/legacy/plugins/alerting/server/lib/task_runner_factory.test.ts @@ -11,7 +11,7 @@ import { ConcreteTaskInstance } from '../../../task_manager'; import { TaskRunnerContext, TaskRunnerFactory } from './task_runner_factory'; import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/plugin.mock'; import { - SavedObjectsClientMock, + savedObjectsClientMock, loggingServiceMock, } from '../../../../../../src/core/server/mocks'; @@ -51,7 +51,7 @@ beforeAll(() => { afterAll(() => fakeTimer.restore()); -const savedObjectsClient = SavedObjectsClientMock.create(); +const savedObjectsClient = savedObjectsClientMock.create(); const encryptedSavedObjectsPlugin = encryptedSavedObjectsMock.create(); const services = { log: jest.fn(), diff --git a/x-pack/legacy/plugins/encrypted_saved_objects/server/lib/encrypted_saved_objects_client_wrapper.test.ts b/x-pack/legacy/plugins/encrypted_saved_objects/server/lib/encrypted_saved_objects_client_wrapper.test.ts index 703ba64b95a7c..a9f41513fbf14 100644 --- a/x-pack/legacy/plugins/encrypted_saved_objects/server/lib/encrypted_saved_objects_client_wrapper.test.ts +++ b/x-pack/legacy/plugins/encrypted_saved_objects/server/lib/encrypted_saved_objects_client_wrapper.test.ts @@ -9,14 +9,14 @@ jest.mock('uuid', () => ({ v4: jest.fn().mockReturnValue('uuid-v4-id') })); import { EncryptedSavedObjectsClientWrapper } from './encrypted_saved_objects_client_wrapper'; import { EncryptedSavedObjectsService } from './encrypted_saved_objects_service'; import { createEncryptedSavedObjectsServiceMock } from './encrypted_saved_objects_service.mock'; -import { SavedObjectsClientMock } from 'src/core/server/saved_objects/service/saved_objects_client.mock'; +import { savedObjectsClientMock } from 'src/core/server/saved_objects/service/saved_objects_client.mock'; import { SavedObjectsClientContract } from 'src/core/server'; let wrapper: EncryptedSavedObjectsClientWrapper; let mockBaseClient: jest.Mocked; let encryptedSavedObjectsServiceMock: jest.Mocked; beforeEach(() => { - mockBaseClient = SavedObjectsClientMock.create(); + mockBaseClient = savedObjectsClientMock.create(); encryptedSavedObjectsServiceMock = createEncryptedSavedObjectsServiceMock([ { type: 'known-type', diff --git a/x-pack/legacy/plugins/task_manager/task_manager.test.ts b/x-pack/legacy/plugins/task_manager/task_manager.test.ts index 2bcfdb2f4d4e3..8592ff31d700f 100644 --- a/x-pack/legacy/plugins/task_manager/task_manager.test.ts +++ b/x-pack/legacy/plugins/task_manager/task_manager.test.ts @@ -7,11 +7,11 @@ import _ from 'lodash'; import sinon from 'sinon'; import { TaskManager, claimAvailableTasks } from './task_manager'; -import { SavedObjectsClientMock } from 'src/core/server/mocks'; +import { savedObjectsClientMock } from 'src/core/server/mocks'; import { SavedObjectsSerializer, SavedObjectsSchema } from 'src/core/server'; import { mockLogger } from './test_utils'; -const savedObjectsClient = SavedObjectsClientMock.create(); +const savedObjectsClient = savedObjectsClientMock.create(); const serializer = new SavedObjectsSerializer(new SavedObjectsSchema()); describe('TaskManager', () => { diff --git a/x-pack/legacy/plugins/task_manager/task_store.test.ts b/x-pack/legacy/plugins/task_manager/task_store.test.ts index 65b49820d6e6c..9779dc5efd28b 100644 --- a/x-pack/legacy/plugins/task_manager/task_store.test.ts +++ b/x-pack/legacy/plugins/task_manager/task_store.test.ts @@ -10,7 +10,7 @@ import uuid from 'uuid'; import { TaskDictionary, TaskDefinition, TaskInstance, TaskStatus } from './task'; import { FetchOpts, StoreOpts, OwnershipClaimingOpts, TaskStore } from './task_store'; import { mockLogger } from './test_utils'; -import { SavedObjectsClientMock } from 'src/core/server/mocks'; +import { savedObjectsClientMock } from 'src/core/server/mocks'; import { SavedObjectsSerializer, SavedObjectsSchema, SavedObjectAttributes } from 'src/core/server'; const taskDefinitions: TaskDictionary = { @@ -31,7 +31,7 @@ const taskDefinitions: TaskDictionary = { }, }; -const savedObjectsClient = SavedObjectsClientMock.create(); +const savedObjectsClient = savedObjectsClientMock.create(); const serializer = new SavedObjectsSerializer(new SavedObjectsSchema()); beforeEach(() => jest.resetAllMocks()); diff --git a/x-pack/plugins/spaces/server/lib/saved_objects_client/spaces_saved_objects_client.test.ts b/x-pack/plugins/spaces/server/lib/saved_objects_client/spaces_saved_objects_client.test.ts index 2e19f85875616..c2bc534f742a8 100644 --- a/x-pack/plugins/spaces/server/lib/saved_objects_client/spaces_saved_objects_client.test.ts +++ b/x-pack/plugins/spaces/server/lib/saved_objects_client/spaces_saved_objects_client.test.ts @@ -7,13 +7,13 @@ import { DEFAULT_SPACE_ID } from '../../../common/constants'; import { SpacesSavedObjectsClient } from './spaces_saved_objects_client'; import { spacesServiceMock } from '../../spaces_service/spaces_service.mock'; -import { SavedObjectsClientMock } from '../../../../../../src/core/server/mocks'; +import { savedObjectsClientMock } from '../../../../../../src/core/server/mocks'; const types = ['foo', 'bar', 'space']; const createMockRequest = () => ({}); -const createMockClient = () => SavedObjectsClientMock.create(); +const createMockClient = () => savedObjectsClientMock.create(); const createSpacesService = async (spaceId: string) => { return spacesServiceMock.createSetupContract(spaceId); From 5accc3c315994ef8f5256f1f8e86d0bd066bb58d Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Fri, 25 Oct 2019 13:32:14 +0300 Subject: [PATCH 10/61] Add Consul Metricbeat module tutorial to Kibana home (#48497) --- .../consul_metrics/screenshot.png | Bin 0 -> 541112 bytes .../home/tutorial_resources/logos/consul.svg | 1 + .../server/tutorials/consul_metrics/index.js | 63 ++++++++++++++++++ .../kibana/server/tutorials/register.js | 2 + 4 files changed, 66 insertions(+) create mode 100644 src/legacy/core_plugins/kibana/public/home/tutorial_resources/consul_metrics/screenshot.png create mode 100644 src/legacy/core_plugins/kibana/public/home/tutorial_resources/logos/consul.svg create mode 100644 src/legacy/core_plugins/kibana/server/tutorials/consul_metrics/index.js diff --git a/src/legacy/core_plugins/kibana/public/home/tutorial_resources/consul_metrics/screenshot.png b/src/legacy/core_plugins/kibana/public/home/tutorial_resources/consul_metrics/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..90aaa7477e8eb24d3bc3a1d3f0fefb164596a56f GIT binary patch literal 541112 zcmbTebySmY{Qs|Df{3(;fKIv_X@nsm(w#~-(gHF>L`plM%E3g!ck~+CWqyb@F~yfeIlZ;J7fN#rU}TlVZP`0TRwiwwt!&fS^2zpv=}O$Rj>6m|Ji)gM|#jn9St`F>x&BiSYkf#Al~wbt(y zUNdDT7XRmq3rf`dFG#Gme3JV2AfZbXR)P*-N%sw&mW=at5DfpRI=qxfCie_Ed*j)y zzf1=IFF4rc5>$Y1+L?yq^nd+^xa2avaH9LyH>;zu`$;rXx7ekv5b^oa!!I%op6L)v z!+)*?8EVcw|NRNu65=c7?i=j#O9y0c^JaeV_a=7>i*uAJohP^I{eR3QL0>2y6zUY; zN|ACsNV%1gEK|0JF|BL%|Ko3ltJf(?qw%oa3btGKSScShj z@nO2;cf-LX8CR-ZTu;f1n8V{oR0d&tlJ(F;x z#&ku_>@>P+RCU+3Dv2G7#hS}Ktq~dpUU?frqN|U+FsIi0{QoxD-_$JU(RW(I9?uu# zQ_Viy3P9*Tp_V#P9rpi3vhJ0r3tEosgV^xuv+3Nu39c33KlL@2nfllC|8x8~iNC>*0GMT%w8Wc&wa*%u%ZjC`Q(h8X8SBB1tLqkJ}}qPS(zDQ!q{7 z$&-&^kBo2HamOqq1}N0`3_n=$Rio0?$?)KML&OLBt$%SVJA%k;jiFNHUz6W9&qyJM zEU}WSH)&O(7m~LI_pD<-??FsOsPk39QWO^(r{y=ZZ#Oo-YSFqno;XPxXZpDibed5G ziIJ%!KeINr@IoOE?+{BM2qc~XE;K|g=EP;busdv<(4^f zrk|7lP{5svYm2uEY&Jf)BP*-@qp~qx`QucXF~RYrOg(xoFi9pg0bK2YVZ<`j{=+&e zKFVrpjw)sjws>E$koo%hwhCUr)#&GnOcUE{;%aIr<}wo!aMR^&#`Swx`>lwY4Ib

8uwLFC~a3<f7@2Mzgx?zm>Cie{L!=INgvOm(xiR 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⪼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

p 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�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 Z&$SSpFWZP3I|l!W-;ueUD|-LI{{hu?(PjVu literal 0 HcmV?d00001 diff --git a/src/legacy/core_plugins/kibana/public/home/tutorial_resources/logos/consul.svg b/src/legacy/core_plugins/kibana/public/home/tutorial_resources/logos/consul.svg new file mode 100644 index 0000000000000..28bbadd24c8a6 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/home/tutorial_resources/logos/consul.svg @@ -0,0 +1 @@ +Asset 1 \ No newline at end of file diff --git a/src/legacy/core_plugins/kibana/server/tutorials/consul_metrics/index.js b/src/legacy/core_plugins/kibana/server/tutorials/consul_metrics/index.js new file mode 100644 index 0000000000000..8823fe5ee5067 --- /dev/null +++ b/src/legacy/core_plugins/kibana/server/tutorials/consul_metrics/index.js @@ -0,0 +1,63 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +import { TUTORIAL_CATEGORY } from '../../../common/tutorials/tutorial_category'; +import { onPremInstructions, cloudInstructions, onPremCloudInstructions } from '../../../common/tutorials/metricbeat_instructions'; + +export function consulMetricsSpecProvider(server, context) { + const moduleName = 'consul'; + return { + id: 'consulMetrics', + name: i18n.translate('kbn.server.tutorials.consulMetrics.nameTitle', { + defaultMessage: 'Consul metrics', + }), + category: TUTORIAL_CATEGORY.METRICS, + shortDescription: i18n.translate('kbn.server.tutorials.consulMetrics.shortDescription', { + defaultMessage: 'Fetch monitoring metrics from the Consul server.', + }), + longDescription: i18n.translate('kbn.server.tutorials.consulMetrics.longDescription', { + defaultMessage: 'The `consul` Metricbeat module fetches monitoring metrics from Consul. \ +[Learn more]({learnMoreLink}).', + values: { + learnMoreLink: '{config.docs.beats.metricbeat}/metricbeat-module-consul.html', + }, + }), + euiIconType: '/plugins/kibana/home/tutorial_resources/logos/consul.svg', + artifacts: { + dashboards: [ + { + id: '496910f0-b952-11e9-a579-f5c0a5d81340', + linkLabel: i18n.translate('kbn.server.tutorials.consulMetrics.artifacts.dashboards.linkLabel', { + defaultMessage: 'Consul metrics dashboard', + }), + isOverview: true + } + ], + exportedFields: { + documentationUrl: '{config.docs.beats.metricbeat}/exported-fields-consul.html' + } + }, + completionTimeMinutes: 10, + previewImagePath: '/plugins/kibana/home/tutorial_resources/consul_metrics/screenshot.png', + onPrem: onPremInstructions(moduleName, null, null, null, context), + elasticCloud: cloudInstructions(moduleName), + onPremElasticCloud: onPremCloudInstructions(moduleName) + }; +} diff --git a/src/legacy/core_plugins/kibana/server/tutorials/register.js b/src/legacy/core_plugins/kibana/server/tutorials/register.js index 0299d00856c64..70bc0f4d3c9eb 100644 --- a/src/legacy/core_plugins/kibana/server/tutorials/register.js +++ b/src/legacy/core_plugins/kibana/server/tutorials/register.js @@ -77,6 +77,7 @@ import { ciscoLogsSpecProvider } from './cisco_logs'; import { envoyproxyLogsSpecProvider } from './envoyproxy_logs'; import { couchdbMetricsSpecProvider } from './couchdb_metrics'; import { emsBoundariesSpecProvider } from './ems'; +import { consulMetricsSpecProvider } from './consul_metrics'; export function registerTutorials(server) { server.registerTutorial(systemLogsSpecProvider); @@ -139,4 +140,5 @@ export function registerTutorials(server) { server.registerTutorial(envoyproxyLogsSpecProvider); server.registerTutorial(couchdbMetricsSpecProvider); server.registerTutorial(emsBoundariesSpecProvider); + server.registerTutorial(consulMetricsSpecProvider); } From 2ddbc9eef6cff440dfd264c2cf6f6373280fe5bb Mon Sep 17 00:00:00 2001 From: Tim Roes Date: Fri, 25 Oct 2019 13:35:24 +0200 Subject: [PATCH 11/61] Revert "Set values as html to table rows" (#49306) * Revert "Set values as html to table rows (#48911)" This reverts commit 3fd9f914374f08e17afd4b054c22eca6d5a65ffe. * Remove unrelated change from the revert --- .../kbn_doc_views/public/views/table/table_row.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/legacy/core_plugins/kbn_doc_views/public/views/table/table_row.tsx b/src/legacy/core_plugins/kbn_doc_views/public/views/table/table_row.tsx index cfc539eafe7b9..2059e35b2c42e 100644 --- a/src/legacy/core_plugins/kbn_doc_views/public/views/table/table_row.tsx +++ b/src/legacy/core_plugins/kbn_doc_views/public/views/table/table_row.tsx @@ -93,11 +93,9 @@ export function DocViewTableRow({ )} {displayUnderscoreWarning && } {displayNoMappingWarning && } -

+
+ {value} +
); From bcbdb92135e43e3c66a06fd732750f94a2684f92 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Fri, 25 Oct 2019 13:04:06 +0100 Subject: [PATCH 12/61] [ML] Adding advanced wizard duplicate detector warning (#49305) --- .../advanced_view/detector_list.tsx | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_view/detector_list.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_view/detector_list.tsx index 2500cf79535d9..b82cc9b9c24bc 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_view/detector_list.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_view/detector_list.tsx @@ -18,10 +18,12 @@ import { EuiSpacer, EuiCallOut, EuiHorizontalRule, + EuiFormRow, } from '@elastic/eui'; import { JobCreatorContext } from '../../../job_creator_context'; import { AdvancedJobCreator } from '../../../../../common/job_creator'; +import { Validation } from '../../../../../common/job_validator'; import { detectorToString } from '../../../../../../../util/string_utils'; interface Props { @@ -31,14 +33,21 @@ interface Props { } export const DetectorList: FC = ({ isActive, onEditJob, onDeleteJob }) => { - const { jobCreator: jc, jobCreatorUpdated } = useContext(JobCreatorContext); + const { jobCreator: jc, jobCreatorUpdated, jobValidator, jobValidatorUpdated } = useContext( + JobCreatorContext + ); const jobCreator = jc as AdvancedJobCreator; const [detectors, setDetectors] = useState(jobCreator.detectors); + const [validation, setValidation] = useState(jobValidator.duplicateDetectors); useEffect(() => { setDetectors(jobCreator.detectors); }, [jobCreatorUpdated]); + useEffect(() => { + setValidation(jobValidator.duplicateDetectors); + }, [jobValidatorUpdated]); + const Buttons: FC<{ index: number }> = ({ index }) => { return ( @@ -113,6 +122,7 @@ export const DetectorList: FC = ({ isActive, onEditJob, onDeleteJob }) => ))} + ); }; @@ -140,3 +150,17 @@ const NoDetectorsWarning: FC<{ show: boolean }> = ({ show }) => { ); }; + +const DuplicateDetectorsWarning: FC<{ validation: Validation }> = ({ validation }) => { + if (validation.valid === true) { + return null; + } + return ( + + + + + + + ); +}; From 54a9de8d48b53969adc2158290ea5f2db0d41322 Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com> Date: Fri, 25 Oct 2019 08:56:42 -0400 Subject: [PATCH 13/61] [SIEM] General Performance for 7.5 (#49138) * add useCallback to avoid re-render of component + fix memoize on the SourceQuery/Timeline/DetailsTimeline + Avoid all the events to re-render when pinned and/or adding note to an event * Update x-pack/legacy/plugins/siem/public/components/open_timeline/index.tsx Co-Authored-By: Garrett Spong * fix merging + bug --- .../drag_drop_context_wrapper.tsx | 37 ++-- .../components/edit_data_provider/index.tsx | 26 +-- .../event_details/stateful_event_details.tsx | 5 +- .../public/components/events_viewer/index.tsx | 50 +++-- .../fields_browser/field_browser.tsx | 34 ++-- .../components/fields_browser/index.test.tsx | 20 +- .../components/fields_browser/index.tsx | 96 ++++----- .../public/components/flyout/header/index.tsx | 58 +++--- .../public/components/flyout/pane/index.tsx | 31 +-- .../components/lazy_accordion/index.tsx | 10 +- .../components/notes/note_cards/index.tsx | 13 +- .../public/components/open_timeline/index.tsx | 145 +++++++------- .../open_timeline_modal/index.tsx | 24 ++- .../page/hosts/hosts_table/index.tsx | 31 +-- .../page/network/network_dns_table/index.tsx | 44 ++-- .../network_top_n_flow_table/index.tsx | 43 ++-- .../page/network/tls_table/index.tsx | 36 ++-- .../page/network/users_table/index.tsx | 35 ++-- .../public/components/search_bar/index.tsx | 188 ++++++++++-------- .../components/super_date_picker/index.tsx | 134 +++++++------ .../body/events/event_column_view.tsx | 15 +- .../components/timeline/body/events/index.tsx | 5 +- .../timeline/body/events/stateful_event.tsx | 39 ++-- .../body/events/stateful_event_child.tsx | 26 +-- .../components/timeline/body/helpers.ts | 9 +- .../components/timeline/body/index.test.tsx | 4 +- .../timeline/body/stateful_body.tsx | 62 +++--- .../data_providers/provider_item_badge.tsx | 18 +- .../components/timeline/footer/index.tsx | 10 +- .../siem/public/components/timeline/index.tsx | 137 +++++++------ .../components/timeline/properties/index.tsx | 14 +- .../timeline/search_or_filter/index.tsx | 42 ++-- .../components/with_hover_actions/index.tsx | 11 +- .../siem/public/containers/source/index.tsx | 26 ++- .../public/containers/timeline/all/index.tsx | 70 +++---- .../containers/timeline/details/index.tsx | 9 +- .../siem/public/store/app/selectors.ts | 8 +- 37 files changed, 831 insertions(+), 734 deletions(-) diff --git a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/drag_drop_context_wrapper.tsx b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/drag_drop_context_wrapper.tsx index 11b604571378b..c513f7a451240 100644 --- a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/drag_drop_context_wrapper.tsx +++ b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/drag_drop_context_wrapper.tsx @@ -5,7 +5,7 @@ */ import { defaultTo, noop } from 'lodash/fp'; -import * as React from 'react'; +import React, { useCallback } from 'react'; import { DragDropContext, DropResult, DragStart } from 'react-beautiful-dnd'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; @@ -59,22 +59,25 @@ const onDragEndHandler = ({ */ export const DragDropContextWrapperComponent = React.memo( ({ browserFields, children, dataProviders, dispatch }) => { - function onDragEnd(result: DropResult) { - enableScrolling(); - - if (dataProviders != null) { - onDragEndHandler({ - browserFields, - result, - dataProviders, - dispatch, - }); - } - - if (!draggableIsField(result)) { - document.body.classList.remove(IS_DRAGGING_CLASS_NAME); - } - } + const onDragEnd = useCallback( + (result: DropResult) => { + enableScrolling(); + + if (dataProviders != null) { + onDragEndHandler({ + browserFields, + result, + dataProviders, + dispatch, + }); + } + + if (!draggableIsField(result)) { + document.body.classList.remove(IS_DRAGGING_CLASS_NAME); + } + }, + [browserFields, dataProviders] + ); return ( {children} diff --git a/x-pack/legacy/plugins/siem/public/components/edit_data_provider/index.tsx b/x-pack/legacy/plugins/siem/public/components/edit_data_provider/index.tsx index dc7f2185c26b7..ec6646fc76085 100644 --- a/x-pack/legacy/plugins/siem/public/components/edit_data_provider/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/edit_data_provider/index.tsx @@ -17,7 +17,7 @@ import { EuiSpacer, EuiToolTip, } from '@elastic/eui'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useCallback } from 'react'; import styled, { injectGlobal } from 'styled-components'; import { BrowserFields } from '../../containers/source'; @@ -101,7 +101,7 @@ export const StatefulEditDataProvider = React.memo( const [updatedValue, setUpdatedValue] = useState(value); /** Focuses the Value input if it is visible, falling back to the Save button if it's not */ - function focusInput() { + const focusInput = () => { const elements = document.getElementsByClassName(VALUE_INPUT_CLASS_NAME); if (elements.length > 0) { @@ -113,25 +113,25 @@ export const StatefulEditDataProvider = React.memo( (saveElements[0] as HTMLElement).focus(); } } - } + }; - function onFieldSelected(selectedField: EuiComboBoxOptionProps[]) { + const onFieldSelected = useCallback((selectedField: EuiComboBoxOptionProps[]) => { setUpdatedField(selectedField); focusInput(); - } + }, []); - function onOperatorSelected(operatorSelected: EuiComboBoxOptionProps[]) { + const onOperatorSelected = useCallback((operatorSelected: EuiComboBoxOptionProps[]) => { setUpdatedOperator(operatorSelected); focusInput(); - } + }, []); - function onValueChange(e: React.ChangeEvent) { + const onValueChange = useCallback((e: React.ChangeEvent) => { setUpdatedValue(e.target.value); - } + }, []); - function disableScrolling() { + const disableScrolling = () => { const x = window.pageXOffset !== undefined ? window.pageXOffset @@ -143,11 +143,11 @@ export const StatefulEditDataProvider = React.memo( : (document.documentElement || document.body.parentNode || document.body).scrollTop; window.onscroll = () => window.scrollTo(x, y); - } + }; - function enableScrolling() { + const enableScrolling = () => { window.onscroll = () => noop; - } + }; useEffect(() => { disableScrolling(); diff --git a/x-pack/legacy/plugins/siem/public/components/event_details/stateful_event_details.tsx b/x-pack/legacy/plugins/siem/public/components/event_details/stateful_event_details.tsx index cb67736829878..c614fd52316bc 100644 --- a/x-pack/legacy/plugins/siem/public/components/event_details/stateful_event_details.tsx +++ b/x-pack/legacy/plugins/siem/public/components/event_details/stateful_event_details.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useState } from 'react'; +import React, { useCallback, useState } from 'react'; import { BrowserFields } from '../../containers/source'; import { ColumnHeader } from '../timeline/body/column_headers/column_header'; @@ -27,6 +27,7 @@ export const StatefulEventDetails = React.memo( ({ browserFields, columnHeaders, data, id, onUpdateColumns, timelineId, toggleColumn }) => { const [view, setView] = useState('table-view'); + const handleSetView = useCallback(newView => setView(newView), []); return ( ( data={data} id={id} onUpdateColumns={onUpdateColumns} - onViewSelected={newView => setView(newView)} + onViewSelected={handleSetView} timelineId={timelineId} toggleColumn={toggleColumn} view={view} diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx index 0ecfb15a67f3b..9483c60dcc552 100644 --- a/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx @@ -6,7 +6,7 @@ import { Filter } from '@kbn/es-query'; import { isEqual } from 'lodash/fp'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useCallback } from 'react'; import { connect } from 'react-redux'; import { ActionCreator } from 'typescript-fsa'; import { Query } from 'src/plugins/data/common'; @@ -102,32 +102,40 @@ const StatefulEventsViewerComponent = React.memo( }; }, []); - const onChangeItemsPerPage: OnChangeItemsPerPage = itemsChangedPerPage => - updateItemsPerPage({ id, itemsPerPage: itemsChangedPerPage }); - - const toggleColumn = (column: ColumnHeader) => { - const exists = columns.findIndex(c => c.id === column.id) !== -1; + const onChangeItemsPerPage: OnChangeItemsPerPage = useCallback( + itemsChangedPerPage => updateItemsPerPage({ id, itemsPerPage: itemsChangedPerPage }), + [id, updateItemsPerPage] + ); - if (!exists && upsertColumn != null) { - upsertColumn({ - column, - id, - index: 1, - }); - } + const toggleColumn = useCallback( + (column: ColumnHeader) => { + const exists = columns.findIndex(c => c.id === column.id) !== -1; + + if (!exists && upsertColumn != null) { + upsertColumn({ + column, + id, + index: 1, + }); + } + + if (exists && removeColumn != null) { + removeColumn({ + columnId: column.id, + id, + }); + } + }, + [columns, id, upsertColumn, removeColumn] + ); - if (exists && removeColumn != null) { - removeColumn({ - columnId: column.id, - id, - }); - } - }; + const handleOnMouseEnter = useCallback(() => setShowInspect(true), []); + const handleOnMouseLeave = useCallback(() => setShowInspect(false), []); return ( {({ indexPattern, browserFields }) => ( -
setShowInspect(true)} onMouseLeave={() => setShowInspect(false)}> +
( width, }) => { /** Focuses the input that filters the field browser */ - function focusInput() { + const focusInput = () => { const elements = document.getElementsByClassName( getFieldBrowserSearchInputClassName(timelineId) ); @@ -130,22 +130,28 @@ export const FieldsBrowser = React.memo( if (elements.length > 0) { (elements[0] as HTMLElement).focus(); // this cast is required because focus() does not exist on every `Element` returned by `getElementsByClassName` } - } + }; /** Invoked when the user types in the input to filter the field browser */ - function onInputChange(event: React.ChangeEvent) { - onSearchInputChange(event.target.value); - } + const onInputChange = useCallback( + (event: React.ChangeEvent) => { + onSearchInputChange(event.target.value); + }, + [onSearchInputChange] + ); - function selectFieldAndHide(fieldId: string) { - if (onFieldSelected != null) { - onFieldSelected(fieldId); - } + const selectFieldAndHide = useCallback( + (fieldId: string) => { + if (onFieldSelected != null) { + onFieldSelected(fieldId); + } - onHideFieldBrowser(); - } + onHideFieldBrowser(); + }, + [onFieldSelected, onHideFieldBrowser] + ); - function scrollViews() { + const scrollViews = () => { if (selectedCategoryId !== '') { const categoryPaneTitles = document.getElementsByClassName( getCategoryPaneCategoryClassName({ @@ -171,7 +177,7 @@ export const FieldsBrowser = React.memo( } focusInput(); // always re-focus the input to enable additional filtering - } + }; useEffect(() => { scrollViews(); diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/index.test.tsx index 2a13d1549d90a..8948f765b8fbc 100644 --- a/x-pack/legacy/plugins/siem/public/components/fields_browser/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/index.test.tsx @@ -13,7 +13,7 @@ import { TestProviders } from '../../mock'; import { FIELD_BROWSER_HEIGHT, FIELD_BROWSER_WIDTH } from './helpers'; -import { INPUT_TIMEOUT, StatefulFieldsBrowser } from '.'; +import { StatefulFieldsBrowser } from '.'; // Suppress warnings about "act" until async/await syntax is supported: https://github.com/facebook/react/issues/14769 /* eslint-disable no-console */ const originalError = console.error; @@ -95,7 +95,7 @@ describe('StatefulFieldsBrowser', () => { describe('updateSelectedCategoryId', () => { beforeEach(() => { - jest.setTimeout(10000); + jest.useFakeTimers(); }); test('it updates the selectedCategoryId state, which makes the category bold, when the user clicks a category name in the left hand side of the field browser', () => { const wrapper = mount( @@ -127,7 +127,8 @@ describe('StatefulFieldsBrowser', () => { wrapper.find(`.field-browser-category-pane-auditd-${timelineId}`).first() ).toHaveStyleRule('font-weight', 'bold', { modifier: '.euiText' }); }); - test('it updates the selectedCategoryId state according to most fields returned', done => { + + test('it updates the selectedCategoryId state according to most fields returned', () => { const wrapper = mount( { .last() .simulate('change', { target: { value: 'cloud' } }); - setTimeout(() => { - wrapper.update(); - expect( - wrapper.find(`.field-browser-category-pane-cloud-${timelineId}`).first() - ).toHaveStyleRule('font-weight', 'bold', { modifier: '.euiText' }); - wrapper.unmount(); - done(); - }, INPUT_TIMEOUT); + jest.runOnlyPendingTimers(); + wrapper.update(); + expect( + wrapper.find(`.field-browser-category-pane-cloud-${timelineId}`).first() + ).toHaveStyleRule('font-weight', 'bold', { modifier: '.euiText' }); }); }); diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/index.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/index.tsx index a58721eb5a87f..2c8092a3295ad 100644 --- a/x-pack/legacy/plugins/siem/public/components/fields_browser/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/index.tsx @@ -6,7 +6,7 @@ import { EuiButtonEmpty, EuiButtonIcon, EuiToolTip } from '@elastic/eui'; import { noop } from 'lodash/fp'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useRef, useState, useCallback, useMemo } from 'react'; import { connect } from 'react-redux'; import styled from 'styled-components'; import { ActionCreator } from 'typescript-fsa'; @@ -82,77 +82,79 @@ export const StatefulFieldsBrowserComponent = React.memo { setShow(!show); - } + }, [show]); /** Invoked when the user types in the filter input */ - function updateFilter(newFilterInput: string) { - setFilterInput(newFilterInput); - setIsSearching(true); - - if (inputTimeoutId.current !== 0) { - clearTimeout(inputTimeoutId.current); // ⚠️ mutation: cancel any previous timers - } - // ⚠️ mutation: schedule a new timer that will apply the filter when it fires: - inputTimeoutId.current = window.setTimeout(() => { - const newFilteredBrowserFields = filterBrowserFieldsByFieldName({ - browserFields: mergeBrowserFieldsWithDefaultCategory(browserFields), - substring: newFilterInput, - }); - - setFilteredBrowserFields(newFilteredBrowserFields); - setIsSearching(false); - - const newSelectedCategoryId = - newFilterInput === '' || Object.keys(newFilteredBrowserFields).length === 0 - ? DEFAULT_CATEGORY_NAME - : Object.keys(newFilteredBrowserFields) - .sort() - .reduce( - (selected, category) => - newFilteredBrowserFields[category].fields != null && - newFilteredBrowserFields[selected].fields != null && - Object.keys(newFilteredBrowserFields[category].fields!).length > - Object.keys(newFilteredBrowserFields[selected].fields!).length - ? category - : selected, - Object.keys(newFilteredBrowserFields)[0] - ); - setSelectedCategoryId(newSelectedCategoryId); - }, INPUT_TIMEOUT); - } + const updateFilter = useCallback( + (newFilterInput: string) => { + setFilterInput(newFilterInput); + setIsSearching(true); + if (inputTimeoutId.current !== 0) { + clearTimeout(inputTimeoutId.current); // ⚠️ mutation: cancel any previous timers + } + // ⚠️ mutation: schedule a new timer that will apply the filter when it fires: + inputTimeoutId.current = window.setTimeout(() => { + const newFilteredBrowserFields = filterBrowserFieldsByFieldName({ + browserFields: mergeBrowserFieldsWithDefaultCategory(browserFields), + substring: newFilterInput, + }); + setFilteredBrowserFields(newFilteredBrowserFields); + setIsSearching(false); + + const newSelectedCategoryId = + newFilterInput === '' || Object.keys(newFilteredBrowserFields).length === 0 + ? DEFAULT_CATEGORY_NAME + : Object.keys(newFilteredBrowserFields) + .sort() + .reduce( + (selected, category) => + newFilteredBrowserFields[category].fields != null && + newFilteredBrowserFields[selected].fields != null && + Object.keys(newFilteredBrowserFields[category].fields!).length > + Object.keys(newFilteredBrowserFields[selected].fields!).length + ? category + : selected, + Object.keys(newFilteredBrowserFields)[0] + ); + setSelectedCategoryId(newSelectedCategoryId); + }, INPUT_TIMEOUT); + }, + [browserFields, filterInput, inputTimeoutId.current] + ); /** * Invoked when the user clicks a category name in the left-hand side of * the field browser */ - function updateSelectedCategoryId(categoryId: string) { + const updateSelectedCategoryId = useCallback((categoryId: string) => { setSelectedCategoryId(categoryId); - } + }, []); /** * Invoked when the user clicks on the context menu to view a category's * columns in the timeline, this function dispatches the action that * causes the timeline display those columns. */ - function updateColumnsAndSelectCategoryId(columns: ColumnHeader[]) { + const updateColumnsAndSelectCategoryId = useCallback((columns: ColumnHeader[]) => { onUpdateColumns(columns); // show the category columns in the timeline - } + }, []); /** Invoked when the field browser should be hidden */ - function hideFieldBrowser() { + const hideFieldBrowser = useCallback(() => { setFilterInput(''); setFilterInput(''); setFilteredBrowserFields(null); setIsSearching(false); setSelectedCategoryId(DEFAULT_CATEGORY_NAME); setShow(false); - } + }, []); // only merge in the default category if the field browser is visible - const browserFieldsWithDefaultCategory = show - ? mergeBrowserFieldsWithDefaultCategory(browserFields) - : {}; + const browserFieldsWithDefaultCategory = useMemo( + () => (show ? mergeBrowserFieldsWithDefaultCategory(browserFields) : {}), + [show, browserFields] + ); return ( <> diff --git a/x-pack/legacy/plugins/siem/public/components/flyout/header/index.tsx b/x-pack/legacy/plugins/siem/public/components/flyout/header/index.tsx index 1d0e03265f5ea..2f4da30672e8c 100644 --- a/x-pack/legacy/plugins/siem/public/components/flyout/header/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/flyout/header/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import * as React from 'react'; +import React, { useCallback } from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; import { ActionCreator } from 'typescript-fsa'; @@ -22,7 +22,7 @@ import { import { UpdateNote } from '../../notes/helpers'; import { defaultHeaders } from '../../timeline/body/column_headers/default_headers'; import { Properties } from '../../timeline/properties'; -import { appActions } from '../../../store/app'; +import { appActions, appModel } from '../../../store/app'; import { inputsActions } from '../../../store/inputs'; import { timelineActions } from '../../../store/actions'; import { TimelineModel } from '../../../store/timeline/model'; @@ -36,7 +36,7 @@ interface OwnProps { interface StateReduxProps { description: string; - getNotesByIds: (noteIds: string[]) => Note[]; + notesById: appModel.NotesById; isDataInTimeline: boolean; isDatepickerLocked: boolean; isFavorite: boolean; @@ -75,13 +75,13 @@ const StatefulFlyoutHeader = React.memo( associateNote, createTimeline, description, - getNotesByIds, isFavorite, isDataInTimeline, isDatepickerLocked, title, width = DEFAULT_TIMELINE_WIDTH, noteIds, + notesById, timelineId, toggleLock, updateDescription, @@ -89,27 +89,33 @@ const StatefulFlyoutHeader = React.memo( updateNote, updateTitle, usersViewing, - }) => ( - - ) + }) => { + const getNotesByIds = useCallback( + (noteIdsVar: string[]): Note[] => appSelectors.getNotes(notesById, noteIdsVar), + [notesById] + ); + return ( + + ); + } ); StatefulFlyoutHeader.displayName = 'StatefulFlyoutHeader'; @@ -139,7 +145,7 @@ const makeMapStateToProps = () => { return { description, - getNotesByIds: getNotesByIds(state), + notesById: getNotesByIds(state), history, isDataInTimeline: !isEmpty(dataProviders) || !isEmpty(get('filterQuery.kuery.expression', kqlQuery)), diff --git a/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.tsx b/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.tsx index ceaff289f776c..ba5275ed79aef 100644 --- a/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.tsx @@ -5,7 +5,7 @@ */ import { EuiButtonIcon, EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiToolTip } from '@elastic/eui'; -import * as React from 'react'; +import React, { useCallback } from 'react'; import { connect } from 'react-redux'; import styled from 'styled-components'; import { ActionCreator } from 'typescript-fsa'; @@ -122,19 +122,22 @@ const FlyoutPaneComponent = React.memo( usersViewing, width, }) => { - const renderFlyout = () => <>; - - const onResize: OnResize = ({ delta, id }) => { - const bodyClientWidthPixels = document.body.clientWidth; - - applyDeltaToWidth({ - bodyClientWidthPixels, - delta, - id, - maxWidthPercent, - minWidthPixels, - }); - }; + const renderFlyout = useCallback(() => <>, []); + + const onResize: OnResize = useCallback( + ({ delta, id }) => { + const bodyClientWidthPixels = document.body.clientWidth; + + applyDeltaToWidth({ + bodyClientWidthPixels, + delta, + id, + maxWidthPercent, + minWidthPixels, + }); + }, + [applyDeltaToWidth, maxWidthPercent, minWidthPixels] + ); return ( > & { forceExpand?: boolean; @@ -42,19 +42,19 @@ export const LazyAccordion = React.memo( renderExpandedContent, }) => { const [expanded, setExpanded] = useState(false); - const onCollapsedClick = () => { + const onCollapsedClick = useCallback(() => { setExpanded(true); if (onExpand != null) { onExpand(); } - }; + }, [onExpand]); - const onExpandedClick = () => { + const onExpandedClick = useCallback(() => { setExpanded(false); if (onCollapse != null) { onCollapse(); } - }; + }, [onCollapse]); return ( <> diff --git a/x-pack/legacy/plugins/siem/public/components/notes/note_cards/index.tsx b/x-pack/legacy/plugins/siem/public/components/notes/note_cards/index.tsx index aa9415aadeda1..6664660eb6bdc 100644 --- a/x-pack/legacy/plugins/siem/public/components/notes/note_cards/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/notes/note_cards/index.tsx @@ -5,7 +5,7 @@ */ import { EuiFlexGroup, EuiPanel } from '@elastic/eui'; -import React, { useState } from 'react'; +import React, { useState, useCallback } from 'react'; import styled from 'styled-components'; import { Note } from '../../../lib/note'; @@ -66,10 +66,13 @@ export const NoteCards = React.memo( }) => { const [newNote, setNewNote] = useState(''); - const associateNoteAndToggleShow = (noteId: string) => { - associateNote(noteId); - toggleShowAddNote(); - }; + const associateNoteAndToggleShow = useCallback( + (noteId: string) => { + associateNote(noteId); + toggleShowAddNote(); + }, + [associateNote, toggleShowAddNote] + ); return ( diff --git a/x-pack/legacy/plugins/siem/public/components/open_timeline/index.tsx b/x-pack/legacy/plugins/siem/public/components/open_timeline/index.tsx index d101d1f4d39f4..c96d25f0d11f0 100644 --- a/x-pack/legacy/plugins/siem/public/components/open_timeline/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/open_timeline/index.tsx @@ -5,7 +5,7 @@ */ import ApolloClient from 'apollo-client'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useCallback } from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; @@ -98,9 +98,9 @@ export const StatefulOpenTimelineComponent = React.memo( const [sortField, setSortField] = useState(DEFAULT_SORT_FIELD); /** Invoked when the user presses enters to submit the text in the search input */ - const onQueryChange: OnQueryChange = (query: EuiSearchBarQuery) => { + const onQueryChange: OnQueryChange = useCallback((query: EuiSearchBarQuery) => { setSearch(query.queryText.trim()); - }; + }, []); /** Focuses the input that filters the field browser */ const focusInput = () => { @@ -126,23 +126,26 @@ export const StatefulOpenTimelineComponent = React.memo( // } // }; - const onDeleteOneTimeline: OnDeleteOneTimeline = (timelineIds: string[]) => { - deleteTimelines(timelineIds, { - search, - pageInfo: { - pageIndex: pageIndex + 1, - pageSize, - }, - sort: { - sortField: sortField as SortFieldTimeline, - sortOrder: sortDirection as Direction, - }, - onlyUserFavorite: onlyFavorites, - }); - }; + const onDeleteOneTimeline: OnDeleteOneTimeline = useCallback( + (timelineIds: string[]) => { + deleteTimelines(timelineIds, { + search, + pageInfo: { + pageIndex: pageIndex + 1, + pageSize, + }, + sort: { + sortField: sortField as SortFieldTimeline, + sortOrder: sortDirection as Direction, + }, + onlyUserFavorite: onlyFavorites, + }); + }, + [search, pageIndex, pageSize, sortField, sortDirection, onlyFavorites] + ); /** Invoked when the user clicks the action to delete the selected timelines */ - const onDeleteSelected: OnDeleteSelected = () => { + const onDeleteSelected: OnDeleteSelected = useCallback(() => { deleteTimelines(getSelectedTimelineIds(selectedItems), { search, pageInfo: { @@ -161,79 +164,81 @@ export const StatefulOpenTimelineComponent = React.memo( resetSelectionState(); // TODO: the query must re-execute to show the results of the deletion - }; + }, [selectedItems, search, pageIndex, pageSize, sortField, sortDirection, onlyFavorites]); /** Invoked when the user selects (or de-selects) timelines */ - const onSelectionChange: OnSelectionChange = (newSelectedItems: OpenTimelineResult[]) => { - setSelectedItems(newSelectedItems); // <-- this is NOT passed down as props to the table: https://github.com/elastic/eui/issues/1077 - }; + const onSelectionChange: OnSelectionChange = useCallback( + (newSelectedItems: OpenTimelineResult[]) => { + setSelectedItems(newSelectedItems); // <-- this is NOT passed down as props to the table: https://github.com/elastic/eui/issues/1077 + }, + [] + ); /** Invoked by the EUI table implementation when the user interacts with the table (i.e. to update sorting) */ - const onTableChange: OnTableChange = ({ page, sort }: OnTableChangeParams) => { + const onTableChange: OnTableChange = useCallback(({ page, sort }: OnTableChangeParams) => { const { index, size } = page; const { field, direction } = sort; setPageIndex(index); setPageSize(size); setSortDirection(direction); setSortField(field); - }; + }, []); /** Invoked when the user toggles the option to only view favorite timelines */ - const onToggleOnlyFavorites: OnToggleOnlyFavorites = () => { + const onToggleOnlyFavorites: OnToggleOnlyFavorites = useCallback(() => { setOnlyFavorites(!onlyFavorites); - }; + }, [onlyFavorites]); /** Invoked when the user toggles the expansion or collapse of inline notes in a table row */ - const onToggleShowNotes: OnToggleShowNotes = ( - newItemIdToExpandedNotesRowMap: Record - ) => { - setItemIdToExpandedNotesRowMap(newItemIdToExpandedNotesRowMap); - }; + const onToggleShowNotes: OnToggleShowNotes = useCallback( + (newItemIdToExpandedNotesRowMap: Record) => { + setItemIdToExpandedNotesRowMap(newItemIdToExpandedNotesRowMap); + }, + [] + ); /** Resets the selection state such that all timelines are unselected */ - const resetSelectionState = () => { + const resetSelectionState = useCallback(() => { setSelectedItems([]); - }; + }, []); - const openTimeline: OnOpenTimeline = ({ - duplicate, - timelineId, - }: { - duplicate: boolean; - timelineId: string; - }) => { - if (isModal && closeModalTimeline != null) { - closeModalTimeline(); - } + const openTimeline: OnOpenTimeline = useCallback( + ({ duplicate, timelineId }: { duplicate: boolean; timelineId: string }) => { + if (isModal && closeModalTimeline != null) { + closeModalTimeline(); + } - queryTimelineById({ - apolloClient, - duplicate, - timelineId, - updateIsLoading, - updateTimeline, - }); - }; + queryTimelineById({ + apolloClient, + duplicate, + timelineId, + updateIsLoading, + updateTimeline, + }); + }, + [apolloClient, updateIsLoading, updateTimeline] + ); + + const deleteTimelines: DeleteTimelines = useCallback( + (timelineIds: string[], variables?: AllTimelinesVariables) => { + if (timelineIds.includes(timeline.savedObjectId || '')) { + createNewTimeline({ id: 'timeline-1', columns: defaultHeaders, show: false }); + } + apolloClient.mutate({ + mutation: deleteTimelineMutation, + fetchPolicy: 'no-cache', + variables: { id: timelineIds }, + refetchQueries: [ + { + query: allTimelinesQuery, + variables, + }, + ], + }); + }, + [apolloClient, createNewTimeline, timeline] + ); - const deleteTimelines: DeleteTimelines = ( - timelineIds: string[], - variables?: AllTimelinesVariables - ) => { - if (timelineIds.includes(timeline.savedObjectId || '')) { - createNewTimeline({ id: 'timeline-1', columns: defaultHeaders, show: false }); - } - apolloClient.mutate({ - mutation: deleteTimelineMutation, - fetchPolicy: 'no-cache', - variables: { id: timelineIds }, - refetchQueries: [ - { - query: allTimelinesQuery, - variables, - }, - ], - }); - }; useEffect(() => { focusInput(); }, []); diff --git a/x-pack/legacy/plugins/siem/public/components/open_timeline/open_timeline_modal/index.tsx b/x-pack/legacy/plugins/siem/public/components/open_timeline/open_timeline_modal/index.tsx index 41907e07d5c1b..e8242237cd2c8 100644 --- a/x-pack/legacy/plugins/siem/public/components/open_timeline/open_timeline_modal/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/open_timeline/open_timeline_modal/index.tsx @@ -5,7 +5,7 @@ */ import { EuiButtonEmpty, EuiModal, EuiOverlayMask } from '@elastic/eui'; -import React, { useState } from 'react'; +import React, { useCallback, useState } from 'react'; import { ApolloConsumer } from 'react-apollo'; import * as i18n from '../translations'; @@ -29,16 +29,20 @@ export const OpenTimelineModalButton = React.memo( const [showModal, setShowModal] = useState(false); /** shows or hides the `Open Timeline` modal */ - function toggleShowModal() { + const openModal = useCallback(() => { if (onToggle != null) { onToggle(); } - setShowModal(!showModal); - } + setShowModal(true); + }, [onToggle]); + + const closeModal = useCallback(() => { + if (onToggle != null) { + onToggle(); + } + setShowModal(false); + }, [onToggle]); - function closeModalTimeline() { - toggleShowModal(); - } return ( {client => ( @@ -48,7 +52,7 @@ export const OpenTimelineModalButton = React.memo( data-test-subj="open-timeline-button" iconSide="left" iconType="folderOpen" - onClick={toggleShowModal} + onClick={openModal} > {i18n.OPEN_TIMELINE} @@ -58,11 +62,11 @@ export const OpenTimelineModalButton = React.memo( ( updateTableActivePage, updateTableLimit, }) => { - const onChange = (criteria: Criteria) => { - if (criteria.sort != null) { - const sort: HostsSortField = { - field: getSortField(criteria.sort.field), - direction: criteria.sort.direction, - }; - if (sort.direction !== direction || sort.field !== sortField) { - updateHostsSort({ - sort, - hostsType: type, - }); + const onChange = useCallback( + (criteria: Criteria) => { + if (criteria.sort != null) { + const sort: HostsSortField = { + field: getSortField(criteria.sort.field), + direction: criteria.sort.direction, + }; + if (sort.direction !== direction || sort.field !== sortField) { + updateHostsSort({ + sort, + hostsType: type, + }); + } } - } - }; + }, + [direction, sortField, type] + ); const hostsColumns = useMemo(() => getHostsColumns(), []); diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/index.tsx index c1c1bec80d676..ac5470ee4f236 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/index.tsx @@ -5,7 +5,7 @@ */ import { isEqual } from 'lodash/fp'; -import React from 'react'; +import React, { useCallback } from 'react'; import { connect } from 'react-redux'; import { ActionCreator } from 'typescript-fsa'; @@ -77,24 +77,34 @@ export const NetworkDnsTableComponent = React.memo( type, updateNetworkTable, }) => { - const onChange = (criteria: Criteria) => { - if (criteria.sort != null) { - const newDnsSortField: NetworkDnsSortField = { - field: criteria.sort.field.split('.')[1] as NetworkDnsFields, - direction: criteria.sort.direction, - }; - if (!isEqual(newDnsSortField, sort)) { - updateNetworkTable({ networkType: type, tableType, updates: { sort: newDnsSortField } }); + const onChange = useCallback( + (criteria: Criteria) => { + if (criteria.sort != null) { + const newDnsSortField: NetworkDnsSortField = { + field: criteria.sort.field.split('.')[1] as NetworkDnsFields, + direction: criteria.sort.direction, + }; + if (!isEqual(newDnsSortField, sort)) { + updateNetworkTable({ + networkType: type, + tableType, + updates: { sort: newDnsSortField }, + }); + } } - } - }; + }, + [sort, type] + ); - const onChangePtrIncluded = () => - updateNetworkTable({ - networkType: type, - tableType, - updates: { isPtrIncluded: !isPtrIncluded }, - }); + const onChangePtrIncluded = useCallback( + () => + updateNetworkTable({ + networkType: type, + tableType, + updates: { isPtrIncluded: !isPtrIncluded }, + }), + [type, isPtrIncluded] + ); return ( ( type, updateNetworkTable, }) => { - const onChange = (criteria: Criteria, tableType: networkModel.TopNTableType) => { - if (criteria.sort != null) { - const splitField = criteria.sort.field.split('.'); - const field = last(splitField); - const newSortDirection = field !== sort.field ? Direction.desc : criteria.sort.direction; // sort by desc on init click - const newTopNFlowSort: NetworkTopTablesSortField = { - field: field as NetworkTopTablesFields, - direction: newSortDirection, - }; - if (!isEqual(newTopNFlowSort, sort)) { - updateNetworkTable({ - networkType: type, - tableType, - updates: { - sort: newTopNFlowSort, - }, - }); + const onChange = useCallback( + (criteria: Criteria, tableType: networkModel.TopNTableType) => { + if (criteria.sort != null) { + const splitField = criteria.sort.field.split('.'); + const field = last(splitField); + const newSortDirection = field !== sort.field ? Direction.desc : criteria.sort.direction; // sort by desc on init click + const newTopNFlowSort: NetworkTopTablesSortField = { + field: field as NetworkTopTablesFields, + direction: newSortDirection, + }; + if (!isEqual(newTopNFlowSort, sort)) { + updateNetworkTable({ + networkType: type, + tableType, + updates: { + sort: newTopNFlowSort, + }, + }); + } } - } - }; + }, + [sort, type] + ); let tableType: networkModel.TopNTableType; const headerTitle: string = diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/tls_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/tls_table/index.tsx index 3a4712e53c4d4..6adb335839982 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/tls_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/tls_table/index.tsx @@ -5,7 +5,7 @@ */ import { isEqual } from 'lodash/fp'; -import React from 'react'; +import React, { useCallback } from 'react'; import { connect } from 'react-redux'; import { compose } from 'redux'; import { ActionCreator } from 'typescript-fsa'; @@ -78,22 +78,26 @@ const TlsTableComponent = React.memo( type === networkModel.NetworkType.page ? networkModel.NetworkTableType.tls : networkModel.IpDetailsTableType.tls; - const onChange = (criteria: Criteria) => { - if (criteria.sort != null) { - const splitField = criteria.sort.field.split('.'); - const newTlsSort: TlsSortField = { - field: getSortFromString(splitField[splitField.length - 1]), - direction: criteria.sort.direction, - }; - if (!isEqual(newTlsSort, sort)) { - updateNetworkTable({ - networkType: type, - tableType, - updates: { sort: newTlsSort }, - }); + + const onChange = useCallback( + (criteria: Criteria) => { + if (criteria.sort != null) { + const splitField = criteria.sort.field.split('.'); + const newTlsSort: TlsSortField = { + field: getSortFromString(splitField[splitField.length - 1]), + direction: criteria.sort.direction, + }; + if (!isEqual(newTlsSort, sort)) { + updateNetworkTable({ + networkType: type, + tableType, + updates: { sort: newTlsSort }, + }); + } } - } - }; + }, + [sort, type] + ); return ( ( updateNetworkTable, sort, }) => { - const onChange = (criteria: Criteria) => { - if (criteria.sort != null) { - const splitField = criteria.sort.field.split('.'); - const newUsersSort: UsersSortField = { - field: getSortFromString(splitField[splitField.length - 1]), - direction: criteria.sort.direction, - }; - if (!isEqual(newUsersSort, sort)) { - updateNetworkTable({ - networkType: type, - tableType, - updates: { sort: newUsersSort }, - }); + const onChange = useCallback( + (criteria: Criteria) => { + if (criteria.sort != null) { + const splitField = criteria.sort.field.split('.'); + const newUsersSort: UsersSortField = { + field: getSortFromString(splitField[splitField.length - 1]), + direction: criteria.sort.direction, + }; + if (!isEqual(newUsersSort, sort)) { + updateNetworkTable({ + networkType: type, + tableType, + updates: { sort: newUsersSort }, + }); + } } - } - }; + }, + [sort, type] + ); return ( { - const isQuickSelection = - payload.dateRange.from.includes('now') || payload.dateRange.to.includes('now'); - let updateSearchBar: UpdateReduxSearchBar = { - id, - end: toStr != null ? toStr : new Date(end).toISOString(), - start: fromStr != null ? fromStr : new Date(start).toISOString(), - isInvalid: false, - isQuickSelection, - updateTime: false, - }; - let isStateUpdated = false; - - if ( - (isQuickSelection && - (fromStr !== payload.dateRange.from || toStr !== payload.dateRange.to)) || - (!isQuickSelection && - (start !== formatDate(payload.dateRange.from) || - end !== formatDate(payload.dateRange.to))) - ) { - isStateUpdated = true; - updateSearchBar.updateTime = true; - updateSearchBar.end = payload.dateRange.to; - updateSearchBar.start = payload.dateRange.from; - } - - if (payload.query != null && !isEqual(payload.query, filterQuery)) { - isStateUpdated = true; - updateSearchBar = set('query', payload.query, updateSearchBar); - } - - if (!isStateUpdated) { - // That mean we are doing a refresh! - if (isQuickSelection) { + const onQuerySubmit = useCallback( + (payload: { dateRange: TimeRange; query?: Query }) => { + const isQuickSelection = + payload.dateRange.from.includes('now') || payload.dateRange.to.includes('now'); + let updateSearchBar: UpdateReduxSearchBar = { + id, + end: toStr != null ? toStr : new Date(end).toISOString(), + start: fromStr != null ? fromStr : new Date(start).toISOString(), + isInvalid: false, + isQuickSelection, + updateTime: false, + }; + let isStateUpdated = false; + + if ( + (isQuickSelection && + (fromStr !== payload.dateRange.from || toStr !== payload.dateRange.to)) || + (!isQuickSelection && + (start !== formatDate(payload.dateRange.from) || + end !== formatDate(payload.dateRange.to))) + ) { + isStateUpdated = true; updateSearchBar.updateTime = true; updateSearchBar.end = payload.dateRange.to; updateSearchBar.start = payload.dateRange.from; - } else { - queries.forEach(q => q.refetch && (q.refetch as inputsModel.Refetch)()); } - } - window.setTimeout(() => updateSearch(updateSearchBar), 0); - }; + if (payload.query != null && !isEqual(payload.query, filterQuery)) { + isStateUpdated = true; + updateSearchBar = set('query', payload.query, updateSearchBar); + } - const onRefresh = (payload: { dateRange: TimeRange }) => { - if (payload.dateRange.from.includes('now') || payload.dateRange.to.includes('now')) { - updateSearch({ - id, - end: payload.dateRange.to, - start: payload.dateRange.from, - isInvalid: false, - isQuickSelection: true, - updateTime: true, - }); - } else { - queries.forEach(q => q.refetch && (q.refetch as inputsModel.Refetch)()); - } - }; + if (!isStateUpdated) { + // That mean we are doing a refresh! + if (isQuickSelection) { + updateSearchBar.updateTime = true; + updateSearchBar.end = payload.dateRange.to; + updateSearchBar.start = payload.dateRange.from; + } else { + queries.forEach(q => q.refetch && (q.refetch as inputsModel.Refetch)()); + } + } - const onSaved = (newSavedQuery: SavedQuery) => { - setSavedQuery({ id, savedQuery: newSavedQuery }); - }; + window.setTimeout(() => updateSearch(updateSearchBar), 0); + }, + [id, end, filterQuery, fromStr, queries, start, toStr] + ); - const onSavedQueryUpdated = (savedQueryUpdated: SavedQuery) => { - const isQuickSelection = savedQueryUpdated.attributes.timefilter - ? savedQueryUpdated.attributes.timefilter.from.includes('now') || - savedQueryUpdated.attributes.timefilter.to.includes('now') - : false; + const onRefresh = useCallback( + (payload: { dateRange: TimeRange }) => { + if (payload.dateRange.from.includes('now') || payload.dateRange.to.includes('now')) { + updateSearch({ + id, + end: payload.dateRange.to, + start: payload.dateRange.from, + isInvalid: false, + isQuickSelection: true, + updateTime: true, + }); + } else { + queries.forEach(q => q.refetch && (q.refetch as inputsModel.Refetch)()); + } + }, + [id, queries] + ); - let updateSearchBar: UpdateReduxSearchBar = { - id, - filters: savedQueryUpdated.attributes.filters || [], - end: toStr != null ? toStr : new Date(end).toISOString(), - start: fromStr != null ? fromStr : new Date(start).toISOString(), - isInvalid: false, - isQuickSelection, - updateTime: false, - }; + const onSaved = useCallback( + (newSavedQuery: SavedQuery) => { + setSavedQuery({ id, savedQuery: newSavedQuery }); + }, + [id] + ); - if (savedQueryUpdated.attributes.timefilter) { - updateSearchBar.end = savedQueryUpdated.attributes.timefilter - ? savedQueryUpdated.attributes.timefilter.to - : updateSearchBar.end; - updateSearchBar.start = savedQueryUpdated.attributes.timefilter - ? savedQueryUpdated.attributes.timefilter.from - : updateSearchBar.start; - updateSearchBar.updateTime = true; - } + const onSavedQueryUpdated = useCallback( + (savedQueryUpdated: SavedQuery) => { + const isQuickSelection = savedQueryUpdated.attributes.timefilter + ? savedQueryUpdated.attributes.timefilter.from.includes('now') || + savedQueryUpdated.attributes.timefilter.to.includes('now') + : false; + + let updateSearchBar: UpdateReduxSearchBar = { + id, + filters: savedQueryUpdated.attributes.filters || [], + end: toStr != null ? toStr : new Date(end).toISOString(), + start: fromStr != null ? fromStr : new Date(start).toISOString(), + isInvalid: false, + isQuickSelection, + updateTime: false, + }; + + if (savedQueryUpdated.attributes.timefilter) { + updateSearchBar.end = savedQueryUpdated.attributes.timefilter + ? savedQueryUpdated.attributes.timefilter.to + : updateSearchBar.end; + updateSearchBar.start = savedQueryUpdated.attributes.timefilter + ? savedQueryUpdated.attributes.timefilter.from + : updateSearchBar.start; + updateSearchBar.updateTime = true; + } - updateSearchBar = set('query', savedQueryUpdated.attributes.query, updateSearchBar); - updateSearchBar = set('savedQuery', savedQueryUpdated, updateSearchBar); + updateSearchBar = set('query', savedQueryUpdated.attributes.query, updateSearchBar); + updateSearchBar = set('savedQuery', savedQueryUpdated, updateSearchBar); - updateSearch(updateSearchBar); - }; + updateSearch(updateSearchBar); + }, + [id, end, fromStr, start, toStr] + ); - const onClearSavedQuery = () => { + const onClearSavedQuery = useCallback(() => { if (savedQuery != null) { updateSearch({ id, @@ -222,7 +234,7 @@ const SearchBarComponent = memo { let isSubscribed = true; @@ -246,13 +258,13 @@ const SearchBarComponent = memo [indexPattern as IndexPattern], [indexPattern]); return ( ( const [recentlyUsedRanges, setRecentlyUsedRanges] = useState( [] ); - const onRefresh = ({ start: newStart, end: newEnd }: OnRefreshProps): void => { - updateReduxTime({ - end: newEnd, - id, - isInvalid: false, - isQuickSelection, - kql: kqlQuery, - start: newStart, - timelineId, - }); - const currentStart = formatDate(newStart); - const currentEnd = isQuickSelection - ? formatDate(newEnd, { roundUp: true }) - : formatDate(newEnd); - if (!isQuickSelection || (start === currentStart && end === currentEnd)) { - refetchQuery(queries); - } - }; - - const onRefreshChange = ({ isPaused, refreshInterval }: OnRefreshChangeProps): void => { - if (duration !== refreshInterval) { - setDuration({ id, duration: refreshInterval }); - } - - if (isPaused && policy === 'interval') { - stopAutoReload({ id }); - } else if (!isPaused && policy === 'manual') { - startAutoReload({ id }); - } - - if (!isPaused && (!isQuickSelection || (isQuickSelection && toStr !== 'now'))) { - refetchQuery(queries); - } - }; - - const refetchQuery = (newQueries: inputsModel.GlobalGraphqlQuery[]) => { - newQueries.forEach(q => q.refetch && (q.refetch as inputsModel.Refetch)()); - }; - - const onTimeChange = ({ - start: newStart, - end: newEnd, - isQuickSelection: newIsQuickSelection, - isInvalid, - }: OnTimeChangeProps) => { - if (!isInvalid) { + const onRefresh = useCallback( + ({ start: newStart, end: newEnd }: OnRefreshProps): void => { updateReduxTime({ end: newEnd, id, - isInvalid, - isQuickSelection: newIsQuickSelection, + isInvalid: false, + isQuickSelection, kql: kqlQuery, start: newStart, timelineId, }); - const newRecentlyUsedRanges = [ - { start: newStart, end: newEnd }, - ...take( - MAX_RECENTLY_USED_RANGES, - recentlyUsedRanges.filter( - recentlyUsedRange => - !(recentlyUsedRange.start === newStart && recentlyUsedRange.end === newEnd) - ) - ), - ]; + const currentStart = formatDate(newStart); + const currentEnd = isQuickSelection + ? formatDate(newEnd, { roundUp: true }) + : formatDate(newEnd); + if (!isQuickSelection || (start === currentStart && end === currentEnd)) { + refetchQuery(queries); + } + }, + [end, id, isQuickSelection, kqlQuery, start, timelineId] + ); + + const onRefreshChange = useCallback( + ({ isPaused, refreshInterval }: OnRefreshChangeProps): void => { + if (duration !== refreshInterval) { + setDuration({ id, duration: refreshInterval }); + } - setRecentlyUsedRanges(newRecentlyUsedRanges); - setIsQuickSelection(newIsQuickSelection); - } + if (isPaused && policy === 'interval') { + stopAutoReload({ id }); + } else if (!isPaused && policy === 'manual') { + startAutoReload({ id }); + } + + if (!isPaused && (!isQuickSelection || (isQuickSelection && toStr !== 'now'))) { + refetchQuery(queries); + } + }, + [id, isQuickSelection, duration, policy, toStr] + ); + + const refetchQuery = (newQueries: inputsModel.GlobalGraphqlQuery[]) => { + newQueries.forEach(q => q.refetch && (q.refetch as inputsModel.Refetch)()); }; + + const onTimeChange = useCallback( + ({ + start: newStart, + end: newEnd, + isQuickSelection: newIsQuickSelection, + isInvalid, + }: OnTimeChangeProps) => { + if (!isInvalid) { + updateReduxTime({ + end: newEnd, + id, + isInvalid, + isQuickSelection: newIsQuickSelection, + kql: kqlQuery, + start: newStart, + timelineId, + }); + const newRecentlyUsedRanges = [ + { start: newStart, end: newEnd }, + ...take( + MAX_RECENTLY_USED_RANGES, + recentlyUsedRanges.filter( + recentlyUsedRange => + !(recentlyUsedRange.start === newStart && recentlyUsedRange.end === newEnd) + ) + ), + ]; + + setRecentlyUsedRanges(newRecentlyUsedRanges); + setIsQuickSelection(newIsQuickSelection); + } + }, + [recentlyUsedRanges, kqlQuery] + ); + const endDate = kind === 'relative' ? toStr : new Date(end).toISOString(); const startDate = kind === 'relative' ? fromStr : new Date(start).toISOString(); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/events/event_column_view.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/body/events/event_column_view.tsx index 7afa6ca70ff9b..96cb9f754f525 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/events/event_column_view.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/events/event_column_view.tsx @@ -15,7 +15,7 @@ import { EventsTrData } from '../../styles'; import { Actions } from '../actions'; import { ColumnHeader } from '../column_headers/column_header'; import { DataDrivenColumns } from '../data_driven_columns'; -import { eventHasNotes, eventIsPinned, getPinOnClick } from '../helpers'; +import { eventHasNotes, getPinOnClick } from '../helpers'; import { ColumnRenderer } from '../renderers/column_renderer'; interface Props { @@ -28,13 +28,13 @@ interface Props { eventIdToNoteIds: Readonly>; expanded: boolean; getNotesByIds: (noteIds: string[]) => Note[]; + isEventPinned: boolean; isEventViewer?: boolean; loading: boolean; onColumnResized: OnColumnResized; onEventToggled: () => void; onPinEvent: OnPinEvent; onUnPinEvent: OnUnPinEvent; - pinnedEventIds: Readonly>; showNotes: boolean; timelineId: string; toggleShowNotes: () => void; @@ -56,13 +56,13 @@ export const EventColumnView = React.memo( eventIdToNoteIds, expanded, getNotesByIds, + isEventPinned = false, isEventViewer = false, loading, onColumnResized, onEventToggled, onPinEvent, onUnPinEvent, - pinnedEventIds, showNotes, timelineId, toggleShowNotes, @@ -76,10 +76,7 @@ export const EventColumnView = React.memo( expanded={expanded} data-test-subj="actions" eventId={id} - eventIsPinned={eventIsPinned({ - eventId: id, - pinnedEventIds, - })} + eventIsPinned={isEventPinned} getNotesByIds={getNotesByIds} isEventViewer={isEventViewer} loading={loading} @@ -90,7 +87,7 @@ export const EventColumnView = React.memo( eventId: id, onPinEvent, onUnPinEvent, - pinnedEventIds, + isEventPinned, })} showCheckboxes={false} showNotes={showNotes} @@ -118,7 +115,7 @@ export const EventColumnView = React.memo( prevProps.eventIdToNoteIds === nextProps.eventIdToNoteIds && prevProps.expanded === nextProps.expanded && prevProps.loading === nextProps.loading && - prevProps.pinnedEventIds === nextProps.pinnedEventIds && + prevProps.isEventPinned === nextProps.isEventPinned && prevProps.showNotes === nextProps.showNotes && prevProps.timelineId === nextProps.timelineId ); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/events/index.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/body/events/index.tsx index 78992dceea4dc..34281219bcc0c 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/events/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/events/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import * as React from 'react'; +import React from 'react'; import { BrowserFields } from '../../../../containers/source'; import { TimelineItem } from '../../../../graphql/types'; @@ -17,6 +17,7 @@ import { ColumnHeader } from '../column_headers/column_header'; import { ColumnRenderer } from '../renderers/column_renderer'; import { RowRenderer } from '../renderers/row_renderer'; import { StatefulEvent } from './stateful_event'; +import { eventIsPinned } from '../helpers'; interface Props { actionsColumnWidth: number; @@ -74,6 +75,7 @@ export const Events = React.memo( event={event} eventIdToNoteIds={eventIdToNoteIds} getNotesByIds={getNotesByIds} + isEventPinned={eventIsPinned({ eventId: event._id, pinnedEventIds })} isEventViewer={isEventViewer} key={event._id} maxDelay={maxDelay(i)} @@ -81,7 +83,6 @@ export const Events = React.memo( onPinEvent={onPinEvent} onUnPinEvent={onUnPinEvent} onUpdateColumns={onUpdateColumns} - pinnedEventIds={pinnedEventIds} rowRenderers={rowRenderers} timelineId={id} toggleColumn={toggleColumn} diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/events/stateful_event.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/body/events/stateful_event.tsx index 766a75c05f17c..d54fe8df28a85 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/events/stateful_event.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/events/stateful_event.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useRef, useState, useCallback } from 'react'; import uuid from 'uuid'; import VisibilitySensor from 'react-visibility-sensor'; @@ -21,7 +21,6 @@ import { STATEFUL_EVENT_CSS_CLASS_NAME } from '../../helpers'; import { EventsTrGroup, EventsTrSupplement, OFFSET_SCROLLBAR } from '../../styles'; import { useTimelineWidthContext } from '../../timeline_context'; import { ColumnHeader } from '../column_headers/column_header'; -import { eventIsPinned } from '../helpers'; import { ColumnRenderer } from '../renderers/column_renderer'; import { getRowRenderer } from '../renderers/get_row_renderer'; import { RowRenderer } from '../renderers/row_renderer'; @@ -42,7 +41,7 @@ interface Props { onPinEvent: OnPinEvent; onUnPinEvent: OnUnPinEvent; onUpdateColumns: OnUpdateColumns; - pinnedEventIds: Readonly>; + isEventPinned: boolean; rowRenderers: RowRenderer[]; timelineId: string; toggleColumn: (column: ColumnHeader) => void; @@ -110,12 +109,12 @@ export const StatefulEvent = React.memo( eventIdToNoteIds, getNotesByIds, isEventViewer = false, + isEventPinned = false, maxDelay = 0, onColumnResized, onPinEvent, onUnPinEvent, onUpdateColumns, - pinnedEventIds, rowRenderers, timelineId, toggleColumn, @@ -127,27 +126,28 @@ export const StatefulEvent = React.memo( const divElement = useRef(null); - const onToggleShowNotes = (eventId: string): (() => void) => () => { + const onToggleShowNotes = useCallback(() => { + const eventId = event._id; setShowNotes({ ...showNotes, [eventId]: !showNotes[eventId] }); - }; + }, [event, showNotes]); - const onToggleExpanded = (eventId: string): (() => void) => () => { + const onToggleExpanded = useCallback(() => { + const eventId = event._id; setExpanded({ ...expanded, [eventId]: !expanded[eventId], }); - }; + }, [event, expanded]); - const associateNote = ( - eventId: string, - addNoteToEventChild: AddNoteToEvent, - onPinEventChild: OnPinEvent - ): ((noteId: string) => void) => (noteId: string) => { - addNoteToEventChild({ eventId, noteId }); - if (!eventIsPinned({ eventId, pinnedEventIds })) { - onPinEventChild(eventId); // pin the event, because it has notes - } - }; + const associateNote = useCallback( + (noteId: string) => { + addNoteToEvent({ eventId: event._id, noteId }); + if (!isEventPinned) { + onPinEvent(event._id); // pin the event, because it has notes + } + }, + [addNoteToEvent, event, isEventPinned, onPinEvent] + ); /** * Incrementally loads the events when it mounts by trying to @@ -155,7 +155,6 @@ export const StatefulEvent = React.memo( * indicate to React that it should render its self by setting * its initialRender to true. */ - useEffect(() => { let _isMounted = true; @@ -222,6 +221,7 @@ export const StatefulEvent = React.memo( expanded={!!expanded[event._id]} getNotesByIds={getNotesByIds} id={event._id} + isEventPinned={isEventPinned} isEventViewer={isEventViewer} loading={loading} onColumnResized={onColumnResized} @@ -229,7 +229,6 @@ export const StatefulEvent = React.memo( onToggleExpanded={onToggleExpanded} onToggleShowNotes={onToggleShowNotes} onUnPinEvent={onUnPinEvent} - pinnedEventIds={pinnedEventIds} showNotes={!!showNotes[event._id]} timelineId={timelineId} updateNote={updateNote} diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/events/stateful_event_child.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/body/events/stateful_event_child.tsx index 4a623ce99c9e9..668139349a377 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/events/stateful_event_child.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/events/stateful_event_child.tsx @@ -29,21 +29,17 @@ interface Props { expanded: boolean; eventIdToNoteIds: Readonly>; isEventViewer?: boolean; + isEventPinned: boolean; loading: boolean; onColumnResized: OnColumnResized; onUnPinEvent: OnUnPinEvent; - pinnedEventIds: Readonly>; showNotes: boolean; timelineId: string; updateNote: UpdateNote; - onToggleExpanded: (eventId: string) => () => void; - onToggleShowNotes: (eventId: string) => () => void; + onToggleExpanded: () => void; + onToggleShowNotes: () => void; getNotesByIds: (noteIds: string[]) => Note[]; - associateNote: ( - eventId: string, - addNoteToEvent: AddNoteToEvent, - onPinEvent: OnPinEvent - ) => (noteId: string) => void; + associateNote: (noteId: string) => void; } export const getNewNoteId = (): string => uuid.v4(); @@ -64,11 +60,11 @@ export const StatefulEventChild = React.memo( eventIdToNoteIds, getNotesByIds, isEventViewer = false, + isEventPinned = false, loading, onColumnResized, onToggleExpanded, onUnPinEvent, - pinnedEventIds, showNotes, timelineId, onToggleShowNotes, @@ -84,23 +80,23 @@ export const StatefulEventChild = React.memo( @@ -110,13 +106,13 @@ export const StatefulEventChild = React.memo( style={{ width: `${width - OFFSET_SCROLLBAR}px` }} > diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/helpers.ts b/x-pack/legacy/plugins/siem/public/components/timeline/body/helpers.ts index 1cd83cb5560ea..0b1d21b2371ee 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/helpers.ts +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/helpers.ts @@ -55,7 +55,7 @@ export interface GetPinOnClickParams { eventId: string; onPinEvent: OnPinEvent; onUnPinEvent: OnUnPinEvent; - pinnedEventIds: Readonly>; + isEventPinned: boolean; } export const getPinOnClick = ({ @@ -63,15 +63,12 @@ export const getPinOnClick = ({ eventId, onPinEvent, onUnPinEvent, - pinnedEventIds, + isEventPinned, }: GetPinOnClickParams): (() => void) => { if (!allowUnpinning) { return noop; } - - return eventIsPinned({ eventId, pinnedEventIds }) - ? () => onUnPinEvent(eventId) - : () => onPinEvent(eventId); + return isEventPinned ? () => onUnPinEvent(eventId) : () => onPinEvent(eventId); }; export const getColumnWidthFromType = (type: string): number => diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/body/index.test.tsx index 73b208757c7ad..86a6ebe22799b 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/index.test.tsx @@ -215,7 +215,7 @@ describe('Body', () => { wrapper.update(); wrapper .find('[data-test-subj="new-note-tabs"] textarea') - .simulate('change', { target: { value: 'hello world' } }); + .simulate('change', { target: { value: note } }); wrapper.update(); wrapper .find('button[data-test-subj="add-note"]') @@ -314,13 +314,11 @@ describe('Body', () => { /> ); addaNoteToEvent(wrapper, 'hello world'); - dispatchAddNoteToEvent.mockClear(); dispatchOnPinEvent.mockClear(); wrapper.setProps({ pinnedEventIds: { 1: true } }); wrapper.update(); addaNoteToEvent(wrapper, 'new hello world'); - expect(dispatchAddNoteToEvent).toHaveBeenCalled(); expect(dispatchOnPinEvent).not.toHaveBeenCalled(); }); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/stateful_body.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/body/stateful_body.tsx index d93446b2af95b..531e61dd7dc60 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/stateful_body.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/stateful_body.tsx @@ -6,14 +6,14 @@ import { noop } from 'lodash/fp'; import memoizeOne from 'memoize-one'; -import * as React from 'react'; +import React, { useCallback } from 'react'; import { connect } from 'react-redux'; import { ActionCreator } from 'typescript-fsa'; import { BrowserFields } from '../../../containers/source'; import { TimelineItem } from '../../../graphql/types'; import { Note } from '../../../lib/note'; -import { appSelectors, State, timelineSelectors } from '../../../store'; +import { appModel, appSelectors, State, timelineSelectors } from '../../../store'; import { AddNoteToEvent, UpdateNote } from '../../notes/helpers'; import { OnColumnRemoved, @@ -45,7 +45,7 @@ interface OwnProps { interface ReduxProps { columnHeaders: ColumnHeader[]; eventIdToNoteIds: Readonly>; - getNotesByIds: (noteIds: string[]) => Note[]; + notesById: appModel.NotesById; pinnedEventIds: Readonly>; range?: string; } @@ -92,10 +92,10 @@ const StatefulBodyComponent = React.memo( columnHeaders, data, eventIdToNoteIds, - getNotesByIds, height, id, isEventViewer = false, + notesById, pinEvent, pinnedEventIds, range, @@ -107,30 +107,44 @@ const StatefulBodyComponent = React.memo( updateNote, updateSort, }) => { - const onAddNoteToEvent: AddNoteToEvent = ({ - eventId, - noteId, - }: { - eventId: string; - noteId: string; - }) => addNoteToEvent!({ id, eventId, noteId }); - - const onColumnSorted: OnColumnSorted = sorted => { - updateSort!({ id, sort: sorted }); - }; + const getNotesByIds = useCallback( + (noteIds: string[]): Note[] => appSelectors.getNotes(notesById, noteIds), + [notesById] + ); - const onColumnRemoved: OnColumnRemoved = columnId => removeColumn!({ id, columnId }); + const onAddNoteToEvent: AddNoteToEvent = useCallback( + ({ eventId, noteId }: { eventId: string; noteId: string }) => + addNoteToEvent!({ id, eventId, noteId }), + [id] + ); - const onColumnResized: OnColumnResized = ({ columnId, delta }) => - applyDeltaToColumnWidth!({ id, columnId, delta }); + const onColumnSorted: OnColumnSorted = useCallback( + sorted => { + updateSort!({ id, sort: sorted }); + }, + [id] + ); - const onPinEvent: OnPinEvent = eventId => pinEvent!({ id, eventId }); + const onColumnRemoved: OnColumnRemoved = useCallback( + columnId => removeColumn!({ id, columnId }), + [id] + ); - const onUnPinEvent: OnUnPinEvent = eventId => unPinEvent!({ id, eventId }); + const onColumnResized: OnColumnResized = useCallback( + ({ columnId, delta }) => applyDeltaToColumnWidth!({ id, columnId, delta }), + [id] + ); + + const onPinEvent: OnPinEvent = useCallback(eventId => pinEvent!({ id, eventId }), [id]); - const onUpdateNote: UpdateNote = (note: Note) => updateNote!({ note }); + const onUnPinEvent: OnUnPinEvent = useCallback(eventId => unPinEvent!({ id, eventId }), [id]); - const onUpdateColumns: OnUpdateColumns = columns => updateColumns!({ id, columns }); + const onUpdateNote: UpdateNote = useCallback((note: Note) => updateNote!({ note }), []); + + const onUpdateColumns: OnUpdateColumns = useCallback( + columns => updateColumns!({ id, columns }), + [id] + ); return ( ( prevProps.columnHeaders === nextProps.columnHeaders && prevProps.data === nextProps.data && prevProps.eventIdToNoteIds === nextProps.eventIdToNoteIds && - prevProps.getNotesByIds === nextProps.getNotesByIds && + prevProps.notesById === nextProps.notesById && prevProps.height === nextProps.height && prevProps.id === nextProps.id && prevProps.isEventViewer === nextProps.isEventViewer && @@ -194,7 +208,7 @@ const makeMapStateToProps = () => { return { columnHeaders: memoizedColumnHeaders(columns, browserFields), eventIdToNoteIds, - getNotesByIds: getNotesByIds(state), + notesById: getNotesByIds(state), id, pinnedEventIds, }; diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/data_providers/provider_item_badge.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/data_providers/provider_item_badge.tsx index 98cf0a78b1d1f..79f9c32a176f5 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/data_providers/provider_item_badge.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/data_providers/provider_item_badge.tsx @@ -5,7 +5,7 @@ */ import { noop } from 'lodash/fp'; -import React, { useState } from 'react'; +import React, { useCallback, useState } from 'react'; import { BrowserFields } from '../../../containers/source'; @@ -51,23 +51,23 @@ export const ProviderItemBadge = React.memo( }) => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); - function togglePopover() { + const togglePopover = useCallback(() => { setIsPopoverOpen(!isPopoverOpen); - } + }, [isPopoverOpen]); - function closePopover() { + const closePopover = useCallback(() => { setIsPopoverOpen(false); - } + }, []); - function onToggleEnabledProvider() { + const onToggleEnabledProvider = useCallback(() => { toggleEnabledProvider(); closePopover(); - } + }, [toggleEnabledProvider]); - function onToggleExcludedProvider() { + const onToggleExcludedProvider = useCallback(() => { toggleExcludedProvider(); closePopover(); - } + }, [toggleExcludedProvider]); return ( diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/footer/index.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/footer/index.tsx index c1772d9e55577..a0942cbaba091 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/footer/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/footer/index.tsx @@ -18,7 +18,7 @@ import { EuiToolTip, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { pure } from 'recompose'; import styled from 'styled-components'; @@ -182,14 +182,14 @@ export const Footer = React.memo( const [paginationLoading, setPaginationLoading] = useState(false); const [updatedAt, setUpdatedAt] = useState(null); - const loadMore = () => { + const loadMore = useCallback(() => { setPaginationLoading(true); onLoadMore(nextCursor, tieBreaker); - }; + }, [nextCursor, tieBreaker, onLoadMore]); - const onButtonClick = () => setIsPopoverOpen(!isPopoverOpen); + const onButtonClick = useCallback(() => setIsPopoverOpen(!isPopoverOpen), [isPopoverOpen]); - const closePopover = () => setIsPopoverOpen(false); + const closePopover = useCallback(() => setIsPopoverOpen(false), []); useEffect(() => { if (paginationLoading && !isLoading) { diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/index.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/index.tsx index ab92f22a4c89f..78a9488b2fdbb 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/index.tsx @@ -5,7 +5,7 @@ */ import { isEqual } from 'lodash/fp'; -import React, { useEffect } from 'react'; +import React, { useEffect, useCallback } from 'react'; import { connect } from 'react-redux'; import { ActionCreator } from 'typescript-fsa'; @@ -159,79 +159,84 @@ const StatefulTimelineComponent = React.memo( updateItemsPerPage, upsertColumn, }) => { - const onDataProviderRemoved: OnDataProviderRemoved = ( - providerId: string, - andProviderId?: string - ) => removeProvider!({ id, providerId, andProviderId }); + const onDataProviderRemoved: OnDataProviderRemoved = useCallback( + (providerId: string, andProviderId?: string) => + removeProvider!({ id, providerId, andProviderId }), + [id] + ); - const onToggleDataProviderEnabled: OnToggleDataProviderEnabled = ({ - providerId, - enabled, - andProviderId, - }) => - updateDataProviderEnabled!({ - id, - enabled, - providerId, - andProviderId, - }); + const onToggleDataProviderEnabled: OnToggleDataProviderEnabled = useCallback( + ({ providerId, enabled, andProviderId }) => + updateDataProviderEnabled!({ + id, + enabled, + providerId, + andProviderId, + }), + [id] + ); - const onToggleDataProviderExcluded: OnToggleDataProviderExcluded = ({ - providerId, - excluded, - andProviderId, - }) => - updateDataProviderExcluded!({ - id, - excluded, - providerId, - andProviderId, - }); + const onToggleDataProviderExcluded: OnToggleDataProviderExcluded = useCallback( + ({ providerId, excluded, andProviderId }) => + updateDataProviderExcluded!({ + id, + excluded, + providerId, + andProviderId, + }), + [id] + ); - const onDataProviderEditedLocal: OnDataProviderEdited = ({ - andProviderId, - excluded, - field, - operator, - providerId, - value, - }) => - onDataProviderEdited!({ - andProviderId, - excluded, - field, - id, - operator, - providerId, - value, - }); - const onChangeDataProviderKqlQuery: OnChangeDataProviderKqlQuery = ({ providerId, kqlQuery }) => - updateDataProviderKqlQuery!({ id, kqlQuery, providerId }); + const onDataProviderEditedLocal: OnDataProviderEdited = useCallback( + ({ andProviderId, excluded, field, operator, providerId, value }) => + onDataProviderEdited!({ + andProviderId, + excluded, + field, + id, + operator, + providerId, + value, + }), + [id] + ); - const onChangeItemsPerPage: OnChangeItemsPerPage = itemsChangedPerPage => - updateItemsPerPage!({ id, itemsPerPage: itemsChangedPerPage }); + const onChangeDataProviderKqlQuery: OnChangeDataProviderKqlQuery = useCallback( + ({ providerId, kqlQuery }) => updateDataProviderKqlQuery!({ id, kqlQuery, providerId }), + [id] + ); - const onChangeDroppableAndProvider: OnChangeDroppableAndProvider = providerId => - updateHighlightedDropAndProviderId!({ id, providerId }); + const onChangeItemsPerPage: OnChangeItemsPerPage = useCallback( + itemsChangedPerPage => updateItemsPerPage!({ id, itemsPerPage: itemsChangedPerPage }), + [id] + ); - const toggleColumn = (column: ColumnHeader) => { - const exists = columns.findIndex(c => c.id === column.id) !== -1; + const onChangeDroppableAndProvider: OnChangeDroppableAndProvider = useCallback( + providerId => updateHighlightedDropAndProviderId!({ id, providerId }), + [id] + ); - if (!exists && upsertColumn != null) { - upsertColumn({ - column, - id, - index: 1, - }); - } + const toggleColumn = useCallback( + (column: ColumnHeader) => { + const exists = columns.findIndex(c => c.id === column.id) !== -1; - if (exists && removeColumn != null) { - removeColumn({ - columnId: column.id, - id, - }); - } - }; + if (!exists && upsertColumn != null) { + upsertColumn({ + column, + id, + index: 1, + }); + } + + if (exists && removeColumn != null) { + removeColumn({ + columnId: column.id, + id, + }); + } + }, + [columns, id] + ); useEffect(() => { if (createTimeline != null) { diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/properties/index.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/properties/index.tsx index b983963c34f55..111e31479932a 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/properties/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/properties/index.tsx @@ -5,7 +5,7 @@ */ import { EuiAvatar, EuiFlexItem, EuiIcon } from '@elastic/eui'; -import React, { useState } from 'react'; +import React, { useState, useCallback } from 'react'; import styled, { injectGlobal } from 'styled-components'; import { Note } from '../../../lib/note'; @@ -114,17 +114,17 @@ export const Properties = React.memo( const [showActions, setShowActions] = useState(false); const [showNotes, setShowNotes] = useState(false); - const onButtonClick = () => { + const onButtonClick = useCallback(() => { setShowActions(!showActions); - }; + }, [showActions]); - const onToggleShowNotes = () => { + const onToggleShowNotes = useCallback(() => { setShowNotes(!showNotes); - }; + }, [showNotes]); - const onClosePopover = () => { + const onClosePopover = useCallback(() => { setShowActions(false); - }; + }, []); const datePickerWidth = width - diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/search_or_filter/index.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/search_or_filter/index.tsx index 91113a545821d..0ebceccfa90c5 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/search_or_filter/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/search_or_filter/index.tsx @@ -5,7 +5,7 @@ */ import { getOr } from 'lodash/fp'; -import * as React from 'react'; +import React, { useCallback } from 'react'; import { connect } from 'react-redux'; import { ActionCreator } from 'typescript-fsa'; import { StaticIndexPattern } from 'ui/index_patterns'; @@ -56,26 +56,32 @@ const StatefulSearchOrFilterComponent = React.memo( timelineId, updateKqlMode, }) => { - const applyFilterQueryFromKueryExpression = (expression: string) => - applyKqlFilterQuery({ - id: timelineId, - filterQuery: { - kuery: { + const applyFilterQueryFromKueryExpression = useCallback( + (expression: string) => + applyKqlFilterQuery({ + id: timelineId, + filterQuery: { + kuery: { + kind: 'kuery', + expression, + }, + serializedQuery: convertKueryToElasticSearchQuery(expression, indexPattern), + }, + }), + [indexPattern, timelineId] + ); + + const setFilterQueryDraftFromKueryExpression = useCallback( + (expression: string) => + setKqlFilterQueryDraft({ + id: timelineId, + filterQueryDraft: { kind: 'kuery', expression, }, - serializedQuery: convertKueryToElasticSearchQuery(expression, indexPattern), - }, - }); - - const setFilterQueryDraftFromKueryExpression = (expression: string) => - setKqlFilterQueryDraft({ - id: timelineId, - filterQueryDraft: { - kind: 'kuery', - expression, - }, - }); + }), + [timelineId] + ); return ( ( ({ alwaysShow = false, hoverContent, render }) => { const [showHoverContent, setShowHoverContent] = useState(false); - function onMouseEnter() { + const onMouseEnter = useCallback(() => { setShowHoverContent(true); - } + }, []); - function onMouseLeave() { + const onMouseLeave = useCallback(() => { setShowHoverContent(false); - } + }, []); + return ( <>{render(showHoverContent)} diff --git a/x-pack/legacy/plugins/siem/public/containers/source/index.tsx b/x-pack/legacy/plugins/siem/public/containers/source/index.tsx index edd5740f62879..ff6e5e4d0c788 100644 --- a/x-pack/legacy/plugins/siem/public/containers/source/index.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/source/index.tsx @@ -57,30 +57,28 @@ interface WithSourceProps { sourceId: string; } -export const WithSource = React.memo(({ children, sourceId }) => { - const getIndexFields = (title: string, fields: IndexField[]): StaticIndexPattern => +const getIndexFields = memoizeOne( + (title: string, fields: IndexField[]): StaticIndexPattern => fields && fields.length > 0 ? { fields: fields.map(field => pick(['name', 'searchable', 'type', 'aggregatable'], field)), title, } - : { fields: [], title }; + : { fields: [], title } +); - const getBrowserFields = (fields: IndexField[]): BrowserFields => +const getBrowserFields = memoizeOne( + (fields: IndexField[]): BrowserFields => fields && fields.length > 0 ? fields.reduce( (accumulator: BrowserFields, field: IndexField) => set([field.category, 'fields', field.name], field, accumulator), {} ) - : {}; - const getBrowserFieldsMemo: (fields: IndexField[]) => BrowserFields = memoizeOne( - getBrowserFields - ); - const getIndexFieldsMemo: ( - title: string, - fields: IndexField[] - ) => StaticIndexPattern = memoizeOne(getIndexFields); + : {} +); + +export const WithSource = React.memo(({ children, sourceId }) => { return ( query={sourceQuery} @@ -94,8 +92,8 @@ export const WithSource = React.memo(({ children, sourceId }) = {({ data }) => children({ indicesExist: get('source.status.indicesExist', data), - browserFields: getBrowserFieldsMemo(get('source.status.indexFields', data)), - indexPattern: getIndexFieldsMemo( + browserFields: getBrowserFields(get('source.status.indexFields', data)), + indexPattern: getIndexFields( chrome .getUiSettingsClient() .get(DEFAULT_INDEX_KEY) diff --git a/x-pack/legacy/plugins/siem/public/containers/timeline/all/index.tsx b/x-pack/legacy/plugins/siem/public/containers/timeline/all/index.tsx index c3bff998fdefd..5ff28480f1b3f 100644 --- a/x-pack/legacy/plugins/siem/public/containers/timeline/all/index.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/timeline/all/index.tsx @@ -36,43 +36,43 @@ interface OwnProps extends AllTimelinesVariables { children?: (args: AllTimelinesArgs) => React.ReactNode; } -const getAllTimeline = (variables: string, timelines: TimelineResult[]): OpenTimelineResult[] => - timelines.map(timeline => ({ - created: timeline.created, - description: timeline.description, - eventIdToNoteIds: - timeline.eventIdToNoteIds != null - ? timeline.eventIdToNoteIds.reduce((acc, note) => { - if (note.eventId != null) { - const notes = getOr([], note.eventId, acc); - return { ...acc, [note.eventId]: [...notes, note.noteId] }; - } - return acc; - }, {}) - : null, - favorite: timeline.favorite, - noteIds: timeline.noteIds, - notes: - timeline.notes != null - ? timeline.notes.map(note => ({ ...note, savedObjectId: note.noteId })) - : null, - pinnedEventIds: - timeline.pinnedEventIds != null - ? timeline.pinnedEventIds.reduce( - (acc, pinnedEventId) => ({ ...acc, [pinnedEventId]: true }), - {} - ) - : null, - savedObjectId: timeline.savedObjectId, - title: timeline.title, - updated: timeline.updated, - updatedBy: timeline.updatedBy, - })); +const getAllTimeline = memoizeOne( + (variables: string, timelines: TimelineResult[]): OpenTimelineResult[] => + timelines.map(timeline => ({ + created: timeline.created, + description: timeline.description, + eventIdToNoteIds: + timeline.eventIdToNoteIds != null + ? timeline.eventIdToNoteIds.reduce((acc, note) => { + if (note.eventId != null) { + const notes = getOr([], note.eventId, acc); + return { ...acc, [note.eventId]: [...notes, note.noteId] }; + } + return acc; + }, {}) + : null, + favorite: timeline.favorite, + noteIds: timeline.noteIds, + notes: + timeline.notes != null + ? timeline.notes.map(note => ({ ...note, savedObjectId: note.noteId })) + : null, + pinnedEventIds: + timeline.pinnedEventIds != null + ? timeline.pinnedEventIds.reduce( + (acc, pinnedEventId) => ({ ...acc, [pinnedEventId]: true }), + {} + ) + : null, + savedObjectId: timeline.savedObjectId, + title: timeline.title, + updated: timeline.updated, + updatedBy: timeline.updatedBy, + })) +); export const AllTimelinesQuery = React.memo( ({ children, onlyUserFavorite, pageInfo, search, sort }) => { - const memoizedAllTimeline = memoizeOne(getAllTimeline); - const variables: GetAllTimeline.Variables = { onlyUserFavorite, pageInfo, @@ -90,7 +90,7 @@ export const AllTimelinesQuery = React.memo( return children!({ loading, totalCount: getOr(0, 'getAllTimeline.totalCount', data), - timelines: memoizedAllTimeline( + timelines: getAllTimeline( JSON.stringify(variables), getOr([], 'getAllTimeline.timeline', data) ), diff --git a/x-pack/legacy/plugins/siem/public/containers/timeline/details/index.tsx b/x-pack/legacy/plugins/siem/public/containers/timeline/details/index.tsx index 54dd44063f5da..cfb3f8bd8dc77 100644 --- a/x-pack/legacy/plugins/siem/public/containers/timeline/details/index.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/timeline/details/index.tsx @@ -28,11 +28,12 @@ export interface TimelineDetailsProps { sourceId: string; } +const getDetailsEvent = memoizeOne( + (variables: string, detail: DetailItem[]): DetailItem[] => detail +); + export const TimelineDetailsComponentQuery = React.memo( ({ children, indexName, eventId, executeQuery, sourceId }) => { - const getDetailsEvent = (variables: string, detail: DetailItem[]): DetailItem[] => detail; - const getDetailsEventMemo = memoizeOne(getDetailsEvent); - const variables: GetTimelineDetailsQuery.Variables = { sourceId, indexName, @@ -49,7 +50,7 @@ export const TimelineDetailsComponentQuery = React.memo( {({ data, loading, refetch }) => { return children!({ loading, - detailsData: getDetailsEventMemo( + detailsData: getDetailsEvent( JSON.stringify(variables), getOr([], 'source.TimelineDetails.data', data) ), diff --git a/x-pack/legacy/plugins/siem/public/store/app/selectors.ts b/x-pack/legacy/plugins/siem/public/store/app/selectors.ts index cc006b216da8e..9037583d278a7 100644 --- a/x-pack/legacy/plugins/siem/public/store/app/selectors.ts +++ b/x-pack/legacy/plugins/siem/public/store/app/selectors.ts @@ -17,14 +17,15 @@ const selectNotesById = (state: State): NotesById => state.app.notesById; const getErrors = (state: State): ErrorModel => state.app.errors; -const getNotes = (notesById: NotesById, noteIds: string[]) => +export const getNotes = memoizeOne((notesById: NotesById, noteIds: string[]): Note[] => keys(notesById).reduce((acc: Note[], noteId: string) => { if (noteIds.includes(noteId)) { const note: Note = notesById[noteId]; return [...acc, note]; } return acc; - }, []); + }, []) +); export const selectNotesByIdSelector = createSelector( selectNotesById, @@ -34,8 +35,7 @@ export const selectNotesByIdSelector = createSelector( export const notesByIdsSelector = () => createSelector( selectNotesById, - (notesById: NotesById) => - memoizeOne((noteIds: string[]): Note[] => getNotes(notesById, noteIds)) + (notesById: NotesById) => notesById ); export const errorsSelector = () => From 6deac56d583ef87ad5211e8d2e021f6799b6cc76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Casper=20H=C3=BCbertz?= Date: Fri, 25 Oct 2019 15:36:36 +0200 Subject: [PATCH 14/61] [APM] Update metadata order (#49313) Reordering the metadata sections for transactions, errors and spans. --- .../shared/MetadataTable/ErrorMetadata/sections.ts | 2 +- .../shared/MetadataTable/SpanMetadata/sections.ts | 8 ++++---- .../shared/MetadataTable/TransactionMetadata/sections.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/ErrorMetadata/sections.ts b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/ErrorMetadata/sections.ts index 526bb4e5bcf71..1eeebc8543d72 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/ErrorMetadata/sections.ts +++ b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/ErrorMetadata/sections.ts @@ -20,8 +20,8 @@ import { } from '../sections'; export const ERROR_METADATA_SECTIONS: Section[] = [ - ERROR, { ...LABELS, required: true }, + ERROR, HTTP, HOST, CONTAINER, diff --git a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/SpanMetadata/sections.ts b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/SpanMetadata/sections.ts index 01e56bdb09f19..7012bbcc8fcea 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/SpanMetadata/sections.ts +++ b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/SpanMetadata/sections.ts @@ -15,10 +15,10 @@ import { } from '../sections'; export const SPAN_METADATA_SECTIONS: Section[] = [ + LABELS, SPAN, - AGENT, - SERVICE, TRANSACTION, - LABELS, - TRACE + TRACE, + SERVICE, + AGENT ]; diff --git a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/TransactionMetadata/sections.ts b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/TransactionMetadata/sections.ts index 04a0d64077c15..6b30c82bc35a0 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/TransactionMetadata/sections.ts +++ b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/TransactionMetadata/sections.ts @@ -22,8 +22,8 @@ import { } from '../sections'; export const TRANSACTION_METADATA_SECTIONS: Section[] = [ - TRANSACTION, { ...LABELS, required: true }, + TRANSACTION, HTTP, HOST, CONTAINER, From f104e23b42fe75661e328d75846821e95ddd61f9 Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Fri, 25 Oct 2019 15:44:59 +0200 Subject: [PATCH 15/61] [Discover] Centralize dependencies in kibana_services.ts (#48072) * Move doc folder to discover folder * Move doc_viewer folder to discover folder * Move context folder to discover folder * Move context scss import to discover folder * Introduce angular folder, start migration * Add basic NP structure, structural refactoring * Add context placeholder readme * Move doc_viewer directive to angular * Move doc_table directive to angular directory * Migrate doc_table dependencies to central file * Create kibana_services.ts * Centralize context deps * Centralize embeddable deps * Migrate context to angular folder * Add dependencies to kibana_services.ts, implement getServices function * Refactor SEARCH_EMBEDDABLE_TYPE to contants.ts * Fix tests --- .../__tests__/directives/discover_field.js | 1 - .../__tests__/directives/field_calculator.js | 1 - .../__tests__/directives/field_chooser.js | 1 - .../kibana/public/discover/_index.scss | 4 +- .../index.html => angular/context.html} | 0 .../{context/index.js => angular/context.js} | 16 +-- .../discover/{ => angular}/context/NOTES.md | 0 .../{ => angular}/context/_index.scss | 0 .../context/api/__tests__/_stubs.js | 2 +- .../context/api/__tests__/anchor.js | 0 .../context/api/__tests__/predecessors.js | 0 .../context/api/__tests__/successors.js | 0 .../{ => angular}/context/api/anchor.js | 5 +- .../{ => angular}/context/api/context.ts | 6 +- .../utils/__tests__/date_conversion.test.ts | 0 .../api/utils/__tests__/sorting.test.ts | 0 .../context/api/utils/date_conversion.ts | 0 .../api/utils/fetch_hits_in_interval.ts | 2 +- .../context/api/utils/generate_intervals.ts | 0 .../api/utils/get_es_query_search_after.ts | 0 .../context/api/utils/get_es_query_sort.ts | 0 .../context/api/utils/sorting.ts | 2 +- .../components/action_bar/_action_bar.scss | 0 .../context/components/action_bar/_index.scss | 0 .../components/action_bar/action_bar.test.tsx | 0 .../components/action_bar/action_bar.tsx | 0 .../action_bar/action_bar_directive.ts | 6 +- .../action_bar/action_bar_warning.tsx | 0 .../context/components/action_bar/index.ts | 0 .../{ => angular}/context/query/actions.js | 4 +- .../{ => angular}/context/query/constants.js | 0 .../{ => angular}/context/query/index.js | 0 .../{ => angular}/context/query/state.js | 0 .../query_parameters/__tests__/_utils.js | 0 .../__tests__/action_add_filter.js | 6 +- .../__tests__/action_set_predecessor_count.js | 0 .../__tests__/action_set_query_parameters.js | 0 .../__tests__/action_set_successor_count.js | 0 .../context/query_parameters/actions.js | 5 +- .../context/query_parameters/constants.ts | 0 .../context/query_parameters/index.js | 0 .../context/query_parameters/state.ts | 0 .../app.html => angular/context_app.html} | 0 .../app.js => angular/context_app.js} | 17 ++- .../discover/angular/directives/histogram.tsx | 14 +- .../discover/angular/directives/index.js | 7 +- .../discover/angular/directives/no_results.js | 5 +- .../angular/directives/no_results.test.js | 69 +++++----- .../directives/unsupported_index_pattern.js | 1 - .../{index.html => angular/discover.html} | 0 .../public/discover/angular/discover.js | 104 +++++++-------- .../{doc/index.html => angular/doc.html} | 0 .../discover/{doc/index.ts => angular/doc.ts} | 25 +++- .../doc_table/__tests__/actions/filter.js | 0 .../doc_table/__tests__/doc_table.js | 0 .../doc_table/__tests__/lib/get_sort.js | 0 .../doc_table/__tests__/lib/rows_headers.js | 0 .../{ => angular}/doc_table/_doc_table.scss | 0 .../{ => angular}/doc_table/_index.scss | 0 .../doc_table/actions/columns.ts | 0 .../{ => angular}/doc_table/actions/filter.js | 0 .../doc_table/components/_index.scss | 0 .../doc_table/components/_table_header.scss | 0 .../tool_bar_pager_buttons.test.tsx.snap | 0 .../tool_bar_pager_text.test.tsx.snap | 0 .../doc_table/components/pager/index.js | 6 +- .../pager/tool_bar_pager_buttons.test.tsx | 0 .../pager/tool_bar_pager_buttons.tsx | 0 .../pager/tool_bar_pager_text.test.tsx | 0 .../components/pager/tool_bar_pager_text.tsx | 0 .../doc_table/components/table_header.ts | 5 +- .../__snapshots__/table_header.test.tsx.snap | 0 .../components/table_header/helpers.tsx | 5 +- .../table_header/table_header.test.tsx | 2 +- .../components/table_header/table_header.tsx | 5 +- .../table_header/table_header_column.tsx | 3 - .../doc_table/components/table_row.js | 9 +- .../doc_table/components/table_row/_cell.scss | 0 .../components/table_row/_details.scss | 0 .../components/table_row/_index.scss | 0 .../doc_table/components/table_row/_open.scss | 0 .../doc_table/components/table_row/cell.html | 0 .../components/table_row/details.html | 0 .../doc_table/components/table_row/open.html | 0 .../table_row/truncate_by_height.html | 0 .../{ => angular}/doc_table/doc_table.html | 0 .../{ => angular}/doc_table/doc_table.js | 6 +- .../doc_table/doc_table_strings.js | 0 .../index.js => angular/doc_table/index.ts} | 0 .../doc_table/infinite_scroll.js | 5 +- .../{ => angular}/doc_table/lib/get_sort.d.ts | 2 +- .../{ => angular}/doc_table/lib/get_sort.js | 0 .../lib/get_sort_for_search_source.ts | 2 +- .../doc_table/lib/pager/index.js | 0 .../doc_table/lib/pager/pager.js | 0 .../doc_table/lib/pager/pager_factory.js | 4 +- .../doc_viewer.ts} | 6 +- .../doc_directive.ts => angular/index.ts} | 23 +--- .../{breadcrumbs.js => breadcrumbs.ts} | 10 +- .../components/fetch_error/fetch_error.js | 44 +++---- .../field_chooser/discover_field.js | 8 +- .../discover_field_search_directive.ts | 5 +- .../discover_index_pattern_directive.ts | 5 +- .../components/field_chooser/field_chooser.js | 12 +- .../field_chooser/string_progress_bar.js | 8 +- .../components/help_menu/help_menu.js | 5 +- .../components/help_menu/help_menu_util.js | 2 +- .../kibana/public/discover/context/README.md | 4 + .../kibana/public/discover/doc/doc.test.tsx | 31 ++++- .../kibana/public/discover/doc/doc.tsx | 10 +- .../public/discover/doc/use_es_doc_search.ts | 3 +- .../discover/doc_viewer/doc_viewer.test.tsx | 20 ++- .../public/discover/doc_viewer/doc_viewer.tsx | 35 ++--- .../doc_viewer/doc_viewer_render_tab.test.tsx | 2 +- .../doc_viewer/doc_viewer_render_tab.tsx | 2 +- .../discover/doc_viewer/doc_viewer_tab.tsx | 2 +- .../index.ts => embeddable/constants.ts} | 5 +- .../public/discover/embeddable/index.ts | 1 + .../discover/embeddable/search_embeddable.ts | 48 +++---- .../embeddable/search_embeddable_factory.ts | 31 +++-- .../public/discover/embeddable/types.ts | 4 +- .../discover/helpers/register_feature.ts | 41 ++++++ .../kibana/public/discover/index.js | 46 ------- .../kibana/public/discover/index.ts | 32 +++++ .../kibana/public/discover/kibana_services.ts | 121 ++++++++++++++++++ .../kibana/public/discover/plugin.ts | 60 +++++++++ .../discover/saved_searches/_saved_search.js | 10 +- .../saved_searches/saved_search_register.js | 4 +- .../discover/top_nav/open_search_panel.js | 3 +- .../top_nav/open_search_panel.test.js | 8 ++ .../kibana/public/discover/types.d.ts | 4 +- .../expression_types/embeddable_types.ts | 2 +- 132 files changed, 617 insertions(+), 397 deletions(-) rename src/legacy/core_plugins/kibana/public/discover/{context/index.html => angular/context.html} (100%) rename src/legacy/core_plugins/kibana/public/discover/{context/index.js => angular/context.js} (87%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/NOTES.md (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/_index.scss (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/__tests__/_stubs.js (98%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/__tests__/anchor.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/__tests__/predecessors.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/__tests__/successors.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/anchor.js (95%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/context.ts (97%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/utils/__tests__/date_conversion.test.ts (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/utils/__tests__/sorting.test.ts (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/utils/date_conversion.ts (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/utils/fetch_hits_in_interval.ts (97%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/utils/generate_intervals.ts (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/utils/get_es_query_search_after.ts (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/utils/get_es_query_sort.ts (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/api/utils/sorting.ts (96%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/components/action_bar/_action_bar.scss (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/components/action_bar/_index.scss (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/components/action_bar/action_bar.test.tsx (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/components/action_bar/action_bar.tsx (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/components/action_bar/action_bar_directive.ts (89%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/components/action_bar/action_bar_warning.tsx (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/components/action_bar/index.ts (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query/actions.js (97%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query/constants.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query/index.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query/state.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query_parameters/__tests__/_utils.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query_parameters/__tests__/action_add_filter.js (94%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query_parameters/__tests__/action_set_predecessor_count.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query_parameters/__tests__/action_set_query_parameters.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query_parameters/__tests__/action_set_successor_count.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query_parameters/actions.js (92%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query_parameters/constants.ts (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query_parameters/index.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/context/query_parameters/state.ts (100%) rename src/legacy/core_plugins/kibana/public/discover/{context/app.html => angular/context_app.html} (100%) rename src/legacy/core_plugins/kibana/public/discover/{context/app.js => angular/context_app.js} (92%) rename src/legacy/core_plugins/kibana/public/discover/{index.html => angular/discover.html} (100%) rename src/legacy/core_plugins/kibana/public/discover/{doc/index.html => angular/doc.html} (100%) rename src/legacy/core_plugins/kibana/public/discover/{doc/index.ts => angular/doc.ts} (71%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/__tests__/actions/filter.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/__tests__/doc_table.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/__tests__/lib/get_sort.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/__tests__/lib/rows_headers.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/_doc_table.scss (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/_index.scss (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/actions/columns.ts (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/actions/filter.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/_index.scss (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/_table_header.scss (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/pager/__snapshots__/tool_bar_pager_buttons.test.tsx.snap (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/pager/__snapshots__/tool_bar_pager_text.test.tsx.snap (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/pager/index.js (91%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/pager/tool_bar_pager_buttons.test.tsx (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/pager/tool_bar_pager_buttons.tsx (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/pager/tool_bar_pager_text.test.tsx (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/pager/tool_bar_pager_text.tsx (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_header.ts (93%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_header/helpers.tsx (94%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_header/table_header.test.tsx (98%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_header/table_header.tsx (91%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_header/table_header_column.tsx (98%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_row.js (96%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_row/_cell.scss (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_row/_details.scss (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_row/_index.scss (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_row/_open.scss (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_row/cell.html (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_row/details.html (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_row/open.html (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/components/table_row/truncate_by_height.html (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/doc_table.html (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/doc_table.js (95%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/doc_table_strings.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{doc_table/index.js => angular/doc_table/index.ts} (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/infinite_scroll.js (94%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/lib/get_sort.d.ts (94%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/lib/get_sort.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/lib/get_sort_for_search_source.ts (96%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/lib/pager/index.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/lib/pager/pager.js (100%) rename src/legacy/core_plugins/kibana/public/discover/{ => angular}/doc_table/lib/pager/pager_factory.js (89%) rename src/legacy/core_plugins/kibana/public/discover/{doc_viewer/doc_viewer_directive.ts => angular/doc_viewer.ts} (90%) rename src/legacy/core_plugins/kibana/public/discover/{doc/doc_directive.ts => angular/index.ts} (58%) rename src/legacy/core_plugins/kibana/public/discover/{breadcrumbs.js => breadcrumbs.ts} (88%) create mode 100644 src/legacy/core_plugins/kibana/public/discover/context/README.md rename src/legacy/core_plugins/kibana/public/discover/{doc_viewer/index.ts => embeddable/constants.ts} (92%) create mode 100644 src/legacy/core_plugins/kibana/public/discover/helpers/register_feature.ts delete mode 100644 src/legacy/core_plugins/kibana/public/discover/index.js create mode 100644 src/legacy/core_plugins/kibana/public/discover/index.ts create mode 100644 src/legacy/core_plugins/kibana/public/discover/kibana_services.ts create mode 100644 src/legacy/core_plugins/kibana/public/discover/plugin.ts diff --git a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/discover_field.js b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/discover_field.js index 5e8cfc8e1609c..9ac76bfcfe04e 100644 --- a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/discover_field.js +++ b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/discover_field.js @@ -23,7 +23,6 @@ import _ from 'lodash'; import sinon from 'sinon'; import ngMock from 'ng_mock'; import expect from '@kbn/expect'; -import 'ui/private'; import '../../components/field_chooser/discover_field'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_calculator.js b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_calculator.js index 3130ac29eb84d..3ddee3495f36d 100644 --- a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_calculator.js +++ b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_calculator.js @@ -22,7 +22,6 @@ import _ from 'lodash'; import ngMock from 'ng_mock'; import { fieldCalculator } from '../../components/field_chooser/lib/field_calculator'; import expect from '@kbn/expect'; -import 'ui/private'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; // Load the kibana app dependencies. diff --git a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js index c2be750ec7f63..a5b55e50eb90e 100644 --- a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js +++ b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js @@ -23,7 +23,6 @@ import _ from 'lodash'; import sinon from 'sinon'; import expect from '@kbn/expect'; import $ from 'jquery'; -import 'ui/private'; import '../../components/field_chooser/field_chooser'; import FixturesHitsProvider from 'fixtures/hits'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/core_plugins/kibana/public/discover/_index.scss b/src/legacy/core_plugins/kibana/public/discover/_index.scss index 0b0bd12cb268b..b311dd8a34778 100644 --- a/src/legacy/core_plugins/kibana/public/discover/_index.scss +++ b/src/legacy/core_plugins/kibana/public/discover/_index.scss @@ -11,7 +11,7 @@ @import 'components/fetch_error/index'; @import 'components/field_chooser/index'; @import 'angular/directives/index'; -@import 'doc_table/index'; +@import 'angular/doc_table/index'; @import 'hacks'; @@ -23,4 +23,4 @@ @import 'doc_viewer/index'; // Context styles -@import 'context/index'; +@import 'angular/context/index'; diff --git a/src/legacy/core_plugins/kibana/public/discover/context/index.html b/src/legacy/core_plugins/kibana/public/discover/angular/context.html similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/index.html rename to src/legacy/core_plugins/kibana/public/discover/angular/context.html diff --git a/src/legacy/core_plugins/kibana/public/discover/context/index.js b/src/legacy/core_plugins/kibana/public/discover/angular/context.js similarity index 87% rename from src/legacy/core_plugins/kibana/public/discover/context/index.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context.js index 902bee2badb7c..58d1626ca4b14 100644 --- a/src/legacy/core_plugins/kibana/public/discover/context/index.js +++ b/src/legacy/core_plugins/kibana/public/discover/angular/context.js @@ -18,16 +18,13 @@ */ import _ from 'lodash'; - -import { FilterBarQueryFilterProvider } from 'ui/filter_manager/query_filter'; -import uiRoutes from 'ui/routes'; import { i18n } from '@kbn/i18n'; +import { getServices, subscribeWithScope } from './../kibana_services'; -import './app'; -import contextAppRouteTemplate from './index.html'; +import './context_app'; +import contextAppRouteTemplate from './context.html'; import { getRootBreadcrumbs } from '../breadcrumbs'; -import { npStart } from 'ui/new_platform'; -import { subscribeWithScope } from 'ui/utils/subscribe_with_scope'; +const { FilterBarQueryFilterProvider, uiRoutes, chrome } = getServices(); const k7Breadcrumbs = $route => { const { indexPattern } = $route.current.locals; @@ -47,12 +44,11 @@ const k7Breadcrumbs = $route => { ]; }; - uiRoutes // deprecated route, kept for compatibility // should be removed in the future .when('/context/:indexPatternId/:type/:id*', { - redirectTo: '/context/:indexPatternId/:id' + redirectTo: '/context/:indexPatternId/:id', }) .when('/context/:indexPatternId/:id*', { controller: ContextAppRouteController, @@ -92,7 +88,7 @@ function ContextAppRouteController($routeParams, $scope, AppState, config, index }); this.anchorId = $routeParams.id; this.indexPattern = indexPattern; - this.discoverUrl = npStart.core.chrome.navLinks.get('kibana:discover').url; + this.discoverUrl = chrome.navLinks.get('kibana:discover').url; this.filters = _.cloneDeep(queryFilter.getFilters()); } diff --git a/src/legacy/core_plugins/kibana/public/discover/context/NOTES.md b/src/legacy/core_plugins/kibana/public/discover/angular/context/NOTES.md similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/NOTES.md rename to src/legacy/core_plugins/kibana/public/discover/angular/context/NOTES.md diff --git a/src/legacy/core_plugins/kibana/public/discover/context/_index.scss b/src/legacy/core_plugins/kibana/public/discover/angular/context/_index.scss similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/_index.scss rename to src/legacy/core_plugins/kibana/public/discover/angular/context/_index.scss diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/__tests__/_stubs.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/_stubs.js similarity index 98% rename from src/legacy/core_plugins/kibana/public/discover/context/api/__tests__/_stubs.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/_stubs.js index ecb22b20e4d86..f472ff9250eb5 100644 --- a/src/legacy/core_plugins/kibana/public/discover/context/api/__tests__/_stubs.js +++ b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/_stubs.js @@ -19,7 +19,7 @@ import sinon from 'sinon'; import moment from 'moment'; -import { SearchSource } from 'ui/courier'; +import { SearchSource } from '../../../../kibana_services'; export function createIndexPatternsStub() { return { diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/__tests__/anchor.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/anchor.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/api/__tests__/anchor.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/anchor.js diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/__tests__/predecessors.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/predecessors.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/api/__tests__/predecessors.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/predecessors.js diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/__tests__/successors.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/successors.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/api/__tests__/successors.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/successors.js diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/anchor.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/anchor.js similarity index 95% rename from src/legacy/core_plugins/kibana/public/discover/context/api/anchor.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/anchor.js index 02a309eaa0165..62bbc6166662f 100644 --- a/src/legacy/core_plugins/kibana/public/discover/context/api/anchor.js +++ b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/anchor.js @@ -18,11 +18,10 @@ */ import _ from 'lodash'; - import { i18n } from '@kbn/i18n'; +import { getServices } from '../../../kibana_services'; -import { SearchSource } from 'ui/courier'; - +const { SearchSource } = getServices(); export function fetchAnchorProvider(indexPatterns) { return async function fetchAnchor( indexPatternId, diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/context.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/context.ts similarity index 97% rename from src/legacy/core_plugins/kibana/public/discover/context/api/context.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/context.ts index 48ac59f1f0855..268f176f2c61e 100644 --- a/src/legacy/core_plugins/kibana/public/discover/context/api/context.ts +++ b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/context.ts @@ -17,10 +17,8 @@ * under the License. */ -// @ts-ignore -import { SearchSource } from 'ui/courier'; import { Filter } from '@kbn/es-query'; -import { IndexPatterns, IndexPattern } from 'ui/index_patterns'; +import { IndexPatterns, IndexPattern, getServices } from '../../../kibana_services'; import { reverseSortDir, SortDirection } from './utils/sorting'; import { extractNanos, convertIsoToMillis } from './utils/date_conversion'; import { fetchHitsInInterval } from './utils/fetch_hits_in_interval'; @@ -36,6 +34,8 @@ export interface EsHitRecord { } export type EsHitRecordList = EsHitRecord[]; +const { SearchSource } = getServices(); + const DAY_MILLIS = 24 * 60 * 60 * 1000; // look from 1 day up to 10000 days into the past and future diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/utils/__tests__/date_conversion.test.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/__tests__/date_conversion.test.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/api/utils/__tests__/date_conversion.test.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/__tests__/date_conversion.test.ts diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/utils/__tests__/sorting.test.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/__tests__/sorting.test.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/api/utils/__tests__/sorting.test.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/__tests__/sorting.test.ts diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/utils/date_conversion.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/date_conversion.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/api/utils/date_conversion.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/date_conversion.ts diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/utils/fetch_hits_in_interval.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/fetch_hits_in_interval.ts similarity index 97% rename from src/legacy/core_plugins/kibana/public/discover/context/api/utils/fetch_hits_in_interval.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/fetch_hits_in_interval.ts index 9a5436b59714d..2810e5d9d7e66 100644 --- a/src/legacy/core_plugins/kibana/public/discover/context/api/utils/fetch_hits_in_interval.ts +++ b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/fetch_hits_in_interval.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { SearchSource } from 'ui/courier'; +import { SearchSource } from '../../../../kibana_services'; import { convertTimeValueToIso } from './date_conversion'; import { SortDirection } from './sorting'; import { EsHitRecordList } from '../context'; diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/utils/generate_intervals.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/generate_intervals.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/api/utils/generate_intervals.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/generate_intervals.ts diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/utils/get_es_query_search_after.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/get_es_query_search_after.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/api/utils/get_es_query_search_after.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/get_es_query_search_after.ts diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/utils/get_es_query_sort.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/get_es_query_sort.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/api/utils/get_es_query_sort.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/get_es_query_sort.ts diff --git a/src/legacy/core_plugins/kibana/public/discover/context/api/utils/sorting.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/sorting.ts similarity index 96% rename from src/legacy/core_plugins/kibana/public/discover/context/api/utils/sorting.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/sorting.ts index b673270d7a645..4a0f531845f46 100644 --- a/src/legacy/core_plugins/kibana/public/discover/context/api/utils/sorting.ts +++ b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/utils/sorting.ts @@ -17,7 +17,7 @@ * under the License. */ -import { IndexPattern } from 'src/legacy/core_plugins/data/public'; +import { IndexPattern } from '../../../../kibana_services'; export enum SortDirection { asc = 'asc', diff --git a/src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/_action_bar.scss b/src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/_action_bar.scss similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/_action_bar.scss rename to src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/_action_bar.scss diff --git a/src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/_index.scss b/src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/_index.scss similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/_index.scss rename to src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/_index.scss diff --git a/src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/action_bar.test.tsx b/src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/action_bar.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/action_bar.test.tsx rename to src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/action_bar.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/action_bar.tsx b/src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/action_bar.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/action_bar.tsx rename to src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/action_bar.tsx diff --git a/src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/action_bar_directive.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/action_bar_directive.ts similarity index 89% rename from src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/action_bar_directive.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/action_bar_directive.ts index 0942539e63785..579d9d95c6f71 100644 --- a/src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/action_bar_directive.ts +++ b/src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/action_bar_directive.ts @@ -16,11 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -// @ts-ignore -import { uiModules } from 'ui/modules'; -import { wrapInI18nContext } from 'ui/i18n'; +import { getServices } from '../../../../kibana_services'; import { ActionBar } from './action_bar'; +const { uiModules, wrapInI18nContext } = getServices(); + uiModules.get('apps/context').directive('contextActionBar', function(reactDirective: any) { return reactDirective(wrapInI18nContext(ActionBar)); }); diff --git a/src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/action_bar_warning.tsx b/src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/action_bar_warning.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/action_bar_warning.tsx rename to src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/action_bar_warning.tsx diff --git a/src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/index.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/components/action_bar/index.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/components/action_bar/index.ts diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query/actions.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query/actions.js similarity index 97% rename from src/legacy/core_plugins/kibana/public/discover/context/query/actions.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query/actions.js index c55dcc374fa5a..b88e54379f448 100644 --- a/src/legacy/core_plugins/kibana/public/discover/context/query/actions.js +++ b/src/legacy/core_plugins/kibana/public/discover/angular/context/query/actions.js @@ -20,13 +20,13 @@ import _ from 'lodash'; import { i18n } from '@kbn/i18n'; import React from 'react'; -import { toastNotifications } from 'ui/notify'; +import { toastNotifications } from '../../../kibana_services'; import { fetchAnchorProvider } from '../api/anchor'; import { fetchContextProvider } from '../api/context'; import { QueryParameterActionsProvider } from '../query_parameters'; import { FAILURE_REASONS, LOADING_STATUS } from './constants'; -import { MarkdownSimple } from '../../../../../kibana_react/public'; +import { MarkdownSimple } from '../../../../../../kibana_react/public'; export function QueryActionsProvider(Private, Promise) { const fetchAnchor = Private(fetchAnchorProvider); diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query/constants.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query/constants.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/query/constants.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query/constants.js diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query/index.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query/index.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/query/index.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query/index.js diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query/state.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query/state.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/query/state.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query/state.js diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query_parameters/__tests__/_utils.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/_utils.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/query_parameters/__tests__/_utils.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/_utils.js diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query_parameters/__tests__/action_add_filter.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_add_filter.js similarity index 94% rename from src/legacy/core_plugins/kibana/public/discover/context/query_parameters/__tests__/action_add_filter.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_add_filter.js index 1c96cbeec04a3..b136b03bd500b 100644 --- a/src/legacy/core_plugins/kibana/public/discover/context/query_parameters/__tests__/action_add_filter.js +++ b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_add_filter.js @@ -20,9 +20,7 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import sinon from 'sinon'; - -import { FilterBarQueryFilterProvider } from 'ui/filter_manager/query_filter'; - +import { getServices } from '../../../../kibana_services'; import { createStateStub } from './_utils'; import { QueryParameterActionsProvider } from '../actions'; @@ -36,7 +34,7 @@ describe('context app', function () { beforeEach(ngMock.inject(function createPrivateStubs(Private) { filterManagerStub = createQueryFilterStub(); - Private.stub(FilterBarQueryFilterProvider, filterManagerStub); + Private.stub(getServices().FilterBarQueryFilterProvider, filterManagerStub); addFilter = Private(QueryParameterActionsProvider).addFilter; })); diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query_parameters/__tests__/action_set_predecessor_count.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_set_predecessor_count.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/query_parameters/__tests__/action_set_predecessor_count.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_set_predecessor_count.js diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query_parameters/__tests__/action_set_query_parameters.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_set_query_parameters.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/query_parameters/__tests__/action_set_query_parameters.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_set_query_parameters.js diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query_parameters/__tests__/action_set_successor_count.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_set_successor_count.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/query_parameters/__tests__/action_set_successor_count.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_set_successor_count.js diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query_parameters/actions.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/actions.js similarity index 92% rename from src/legacy/core_plugins/kibana/public/discover/context/query_parameters/actions.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/actions.js index 1c895b8d9e1c5..9f7b180e8fe7d 100644 --- a/src/legacy/core_plugins/kibana/public/discover/context/query_parameters/actions.js +++ b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/actions.js @@ -18,9 +18,8 @@ */ import _ from 'lodash'; +import { getServices, getFilterGenerator } from '../../../kibana_services'; -import { FilterBarQueryFilterProvider } from 'ui/filter_manager/query_filter'; -import { getFilterGenerator } from 'ui/filter_manager'; import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE, @@ -29,7 +28,7 @@ import { export function QueryParameterActionsProvider(indexPatterns, Private) { - const queryFilter = Private(FilterBarQueryFilterProvider); + const queryFilter = Private(getServices().FilterBarQueryFilterProvider); const filterGen = getFilterGenerator(queryFilter); const setPredecessorCount = (state) => (predecessorCount) => ( diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query_parameters/constants.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/constants.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/query_parameters/constants.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/constants.ts diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query_parameters/index.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/index.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/query_parameters/index.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/index.js diff --git a/src/legacy/core_plugins/kibana/public/discover/context/query_parameters/state.ts b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/state.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/query_parameters/state.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/state.ts diff --git a/src/legacy/core_plugins/kibana/public/discover/context/app.html b/src/legacy/core_plugins/kibana/public/discover/angular/context_app.html similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/context/app.html rename to src/legacy/core_plugins/kibana/public/discover/angular/context_app.html diff --git a/src/legacy/core_plugins/kibana/public/discover/context/app.js b/src/legacy/core_plugins/kibana/public/discover/angular/context_app.js similarity index 92% rename from src/legacy/core_plugins/kibana/public/discover/context/app.js rename to src/legacy/core_plugins/kibana/public/discover/angular/context_app.js index 7754f743632cb..c9856ad794952 100644 --- a/src/legacy/core_plugins/kibana/public/discover/context/app.js +++ b/src/legacy/core_plugins/kibana/public/discover/angular/context_app.js @@ -18,24 +18,23 @@ */ import _ from 'lodash'; - -import { callAfterBindingsWorkaround } from 'ui/compat'; -import { uiModules } from 'ui/modules'; -import contextAppTemplate from './app.html'; -import './components/action_bar'; -import { getFirstSortableField } from './api/utils/sorting'; +import { getServices, callAfterBindingsWorkaround } from './../kibana_services'; +import contextAppTemplate from './context_app.html'; +import './context/components/action_bar'; +import { getFirstSortableField } from './context/api/utils/sorting'; import { createInitialQueryParametersState, QueryParameterActionsProvider, QUERY_PARAMETER_KEYS, -} from './query_parameters'; +} from './context/query_parameters'; import { createInitialLoadingStatusState, FAILURE_REASONS, LOADING_STATUS, QueryActionsProvider, -} from './query'; -import { timefilter } from 'ui/timefilter'; +} from './context/query'; + +const { uiModules, timefilter } = getServices(); // load directives import '../../../../data/public/legacy'; diff --git a/src/legacy/core_plugins/kibana/public/discover/angular/directives/histogram.tsx b/src/legacy/core_plugins/kibana/public/discover/angular/directives/histogram.tsx index 0dca912653f6c..ab336396b5bed 100644 --- a/src/legacy/core_plugins/kibana/public/discover/angular/directives/histogram.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/angular/directives/histogram.tsx @@ -23,7 +23,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import lightEuiTheme from '@elastic/eui/dist/eui_theme_light.json'; import darkEuiTheme from '@elastic/eui/dist/eui_theme_dark.json'; -import { npStart } from 'ui/new_platform'; import { AnnotationDomainTypes, @@ -44,12 +43,9 @@ import { } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; - -import chrome from 'ui/chrome'; -// @ts-ignore: path dynamic for kibana -import { timezoneProvider } from 'ui/vis/lib/timezone'; import { EuiChartThemeType } from '@elastic/eui/src/themes/charts/themes'; import { Subscription } from 'rxjs'; +import { getServices, timezoneProvider } from '../../kibana_services'; export interface DiscoverHistogramProps { chartData: any; @@ -68,12 +64,12 @@ export class DiscoverHistogram extends Component this.setState({ chartsTheme })); } @@ -145,7 +141,7 @@ export class DiscoverHistogram extends Component diff --git a/src/legacy/core_plugins/kibana/public/discover/angular/directives/no_results.js b/src/legacy/core_plugins/kibana/public/discover/angular/directives/no_results.js index 5f6d32681b50e..b5d3e8a5a01ca 100644 --- a/src/legacy/core_plugins/kibana/public/discover/angular/directives/no_results.js +++ b/src/legacy/core_plugins/kibana/public/discover/angular/directives/no_results.js @@ -32,6 +32,7 @@ import { EuiSpacer, EuiText, } from '@elastic/eui'; +import { getServices } from '../../kibana_services'; // eslint-disable-next-line react/prefer-stateless-function export class DiscoverNoResults extends Component { @@ -39,7 +40,6 @@ export class DiscoverNoResults extends Component { shardFailures: PropTypes.array, timeFieldName: PropTypes.string, queryLanguage: PropTypes.string, - getDocLink: PropTypes.func.isRequired, }; render() { @@ -47,7 +47,6 @@ export class DiscoverNoResults extends Component { shardFailures, timeFieldName, queryLanguage, - getDocLink, } = this.props; let shardFailuresMessage; @@ -226,7 +225,7 @@ export class DiscoverNoResults extends Component { queryStringSyntaxLink: ( { + return { + getServices: () => ({ + docLinks: { + links: { + query: { + luceneQuerySyntax: 'documentation-link', + }, + }, + }, + }), + }; +}); + +beforeEach(() => { + jest.clearAllMocks(); +}); describe('DiscoverNoResults', () => { describe('props', () => { describe('shardFailures', () => { test('renders failures list when there are failures', () => { - const shardFailures = [{ - index: 'A', - shard: '1', - reason: { reason: 'Awful error' }, - }, { - index: 'B', - shard: '2', - reason: { reason: 'Bad error' }, - }]; + const shardFailures = [ + { + index: 'A', + shard: '1', + reason: { reason: 'Awful error' }, + }, + { + index: 'B', + shard: '2', + reason: { reason: 'Bad error' }, + }, + ]; - const component = renderWithIntl( - ''} - /> - ); + const component = renderWithIntl(); expect(component).toMatchSnapshot(); }); @@ -51,12 +65,7 @@ describe('DiscoverNoResults', () => { test(`doesn't render failures list when there are no failures`, () => { const shardFailures = []; - const component = renderWithIntl( - ''} - /> - ); + const component = renderWithIntl(); expect(component).toMatchSnapshot(); }); @@ -64,12 +73,7 @@ describe('DiscoverNoResults', () => { describe('timeFieldName', () => { test('renders time range feedback', () => { - const component = renderWithIntl( - ''} - /> - ); + const component = renderWithIntl(); expect(component).toMatchSnapshot(); }); @@ -78,10 +82,7 @@ describe('DiscoverNoResults', () => { describe('queryLanguage', () => { test('supports lucene and renders doc link', () => { const component = renderWithIntl( - 'documentation-link'} - /> + 'documentation-link'} /> ); expect(component).toMatchSnapshot(); diff --git a/src/legacy/core_plugins/kibana/public/discover/angular/directives/unsupported_index_pattern.js b/src/legacy/core_plugins/kibana/public/discover/angular/directives/unsupported_index_pattern.js index ac26203dafc4a..b1c1c47e39291 100644 --- a/src/legacy/core_plugins/kibana/public/discover/angular/directives/unsupported_index_pattern.js +++ b/src/legacy/core_plugins/kibana/public/discover/angular/directives/unsupported_index_pattern.js @@ -18,7 +18,6 @@ */ import React, { Fragment } from 'react'; - import { EuiCallOut, EuiFlexGroup, diff --git a/src/legacy/core_plugins/kibana/public/discover/index.html b/src/legacy/core_plugins/kibana/public/discover/angular/discover.html similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/index.html rename to src/legacy/core_plugins/kibana/public/discover/angular/discover.html diff --git a/src/legacy/core_plugins/kibana/public/discover/angular/discover.js b/src/legacy/core_plugins/kibana/public/discover/angular/discover.js index 840152fc40ced..ed5049aa912e0 100644 --- a/src/legacy/core_plugins/kibana/public/discover/angular/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/angular/discover.js @@ -18,63 +18,65 @@ */ import _ from 'lodash'; -import { i18n } from '@kbn/i18n'; import React from 'react'; -import angular from 'angular'; import { Subscription } from 'rxjs'; import moment from 'moment'; -import chrome from 'ui/chrome'; import dateMath from '@elastic/datemath'; +import { i18n } from '@kbn/i18n'; +import '../saved_searches/saved_searches'; +import '../components/field_chooser/field_chooser'; // doc table -import '../doc_table'; -import { getSort } from '../doc_table/lib/get_sort'; -import { getSortForSearchSource } from '../doc_table/lib/get_sort_for_search_source'; -import * as columnActions from '../doc_table/actions/columns'; -import * as filterActions from '../doc_table/actions/filter'; - -import 'ui/directives/listen'; -import 'ui/visualize'; -import 'ui/fixed_scroll'; -import 'ui/index_patterns'; -import 'ui/state_management/app_state'; -import { timefilter } from 'ui/timefilter'; -import { hasSearchStategyForIndexPattern, isDefaultTypeIndexPattern } from 'ui/courier'; -import { toastNotifications } from 'ui/notify'; -import { VisProvider } from 'ui/vis'; -import { FilterBarQueryFilterProvider } from 'ui/filter_manager/query_filter'; -import { vislibSeriesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib'; -import { docTitle } from 'ui/doc_title'; -import { intervalOptions } from 'ui/agg_types/buckets/_interval_options'; -import { stateMonitorFactory } from 'ui/state_management/state_monitor_factory'; -import uiRoutes from 'ui/routes'; -import { uiModules } from 'ui/modules'; -import indexTemplate from '../index.html'; -import { StateProvider } from 'ui/state_management/state'; -import { migrateLegacyQuery } from 'ui/utils/migrate_legacy_query'; -import { subscribeWithScope } from 'ui/utils/subscribe_with_scope'; -import { getFilterGenerator } from 'ui/filter_manager'; - -import { getDocLink } from 'ui/documentation_links'; -import '../components/fetch_error'; -import { getPainlessError } from './get_painless_error'; -import { showShareContextMenu, ShareContextMenuExtensionsRegistryProvider } from 'ui/share'; -import { getUnhashableStatesProvider } from 'ui/state_management/state_hashing'; -import { Inspector } from 'ui/inspector'; -import { RequestAdapter } from 'ui/inspector/adapters'; -import { getRequestInspectorStats, getResponseInspectorStats } from 'ui/courier/utils/courier_inspector_utils'; +import './doc_table'; +import { getSort } from './doc_table/lib/get_sort'; +import { getSortForSearchSource } from './doc_table/lib/get_sort_for_search_source'; +import * as columnActions from './doc_table/actions/columns'; +import * as filterActions from './doc_table/actions/filter'; + +import indexTemplate from './discover.html'; import { showOpenSearchPanel } from '../top_nav/show_open_search_panel'; -import { tabifyAggResponse } from 'ui/agg_response/tabify'; -import { showSaveModal } from 'ui/saved_objects/show_saved_object_save_modal'; -import { SavedObjectSaveModal } from 'ui/saved_objects/components/saved_object_save_modal'; -import { getRootBreadcrumbs, getSavedSearchBreadcrumbs } from '../breadcrumbs'; -import { buildVislibDimensions } from 'ui/visualize/loader/pipeline_helpers/build_pipeline'; -import 'ui/capabilities/route_setup'; import { addHelpMenuToAppChrome } from '../components/help_menu/help_menu_util'; +import '../components/fetch_error'; +import { getPainlessError } from './get_painless_error'; +import { + angular, + buildVislibDimensions, + getFilterGenerator, + getRequestInspectorStats, + getResponseInspectorStats, + getServices, + getUnhashableStatesProvider, + hasSearchStategyForIndexPattern, + intervalOptions, + isDefaultTypeIndexPattern, + migrateLegacyQuery, + RequestAdapter, + showSaveModal, + showShareContextMenu, + stateMonitorFactory, + subscribeWithScope, + tabifyAggResponse, + vislibSeriesResponseHandlerProvider, + VisProvider, + SavedObjectSaveModal, +} from '../kibana_services'; + +const { + chrome, + docTitle, + FilterBarQueryFilterProvider, + ShareContextMenuExtensionsRegistryProvider, + StateProvider, + timefilter, + toastNotifications, + uiModules, + uiRoutes, +} = getServices(); +import { getRootBreadcrumbs, getSavedSearchBreadcrumbs } from '../breadcrumbs'; import { extractTimeFilter, changeTimeFilter } from '../../../../data/public'; import { start as data } from '../../../../data/public/legacy'; -import { npStart } from 'ui/new_platform'; + const { savedQueryService } = data.search.services; @@ -151,7 +153,7 @@ uiRoutes return savedSearches.get(savedSearchId) .then((savedSearch) => { if (savedSearchId) { - npStart.core.chrome.recentlyAccessed.add( + chrome.recentlyAccessed.add( savedSearch.getFullPath(), savedSearch.title, savedSearchId); @@ -211,8 +213,6 @@ function discoverController( mode: 'absolute', }); }; - - $scope.getDocLink = getDocLink; $scope.intervalOptions = intervalOptions; $scope.showInterval = false; $scope.minimumVisibleRows = 50; @@ -354,7 +354,7 @@ function discoverController( }), testId: 'openInspectorButton', run() { - Inspector.open(inspectorAdapters, { + getServices().inspector.open(inspectorAdapters, { title: savedSearch.title }); } @@ -401,12 +401,12 @@ function discoverController( }); if (savedSearch.id && savedSearch.title) { - chrome.breadcrumbs.set([{ + chrome.setBreadcrumbs([{ text: discoverBreadcrumbsTitle, href: '#/discover', }, { text: savedSearch.title }]); } else { - chrome.breadcrumbs.set([{ + chrome.setBreadcrumbs([{ text: discoverBreadcrumbsTitle, }]); } diff --git a/src/legacy/core_plugins/kibana/public/discover/doc/index.html b/src/legacy/core_plugins/kibana/public/discover/angular/doc.html similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc/index.html rename to src/legacy/core_plugins/kibana/public/discover/angular/doc.html diff --git a/src/legacy/core_plugins/kibana/public/discover/doc/index.ts b/src/legacy/core_plugins/kibana/public/discover/angular/doc.ts similarity index 71% rename from src/legacy/core_plugins/kibana/public/discover/doc/index.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/doc.ts index b969bd6a48126..e6c890c9a66a2 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc/index.ts +++ b/src/legacy/core_plugins/kibana/public/discover/angular/doc.ts @@ -16,14 +16,25 @@ * specific language governing permissions and limitations * under the License. */ -import uiRoutes from 'ui/routes'; -import { IndexPatterns } from 'ui/index_patterns'; -import { timefilter } from 'ui/timefilter'; +import { getServices, IndexPatterns } from '../kibana_services'; // @ts-ignore -import { getRootBreadcrumbs } from 'plugins/kibana/discover/breadcrumbs'; -// @ts-ignore -import html from './index.html'; -import './doc_directive'; +import { getRootBreadcrumbs } from '../breadcrumbs'; +import html from './doc.html'; +import { Doc } from '../doc/doc'; +const { uiRoutes, uiModules, wrapInI18nContext, timefilter } = getServices(); +uiModules.get('apps/discover').directive('discoverDoc', function(reactDirective: any) { + return reactDirective( + wrapInI18nContext(Doc), + [ + ['id', { watchDepth: 'value' }], + ['index', { watchDepth: 'value' }], + ['indexPatternId', { watchDepth: 'reference' }], + ['indexPatternService', { watchDepth: 'reference' }], + ['esClient', { watchDepth: 'reference' }], + ], + { restrict: 'E' } + ); +}); uiRoutes // the old, pre 8.0 route, no longer used, keep it to stay compatible diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/__tests__/actions/filter.js b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/__tests__/actions/filter.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/__tests__/actions/filter.js rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/__tests__/actions/filter.js diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/__tests__/doc_table.js b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/__tests__/doc_table.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/__tests__/doc_table.js rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/__tests__/doc_table.js diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/__tests__/lib/get_sort.js b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/__tests__/lib/get_sort.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/__tests__/lib/get_sort.js rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/__tests__/lib/get_sort.js diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/__tests__/lib/rows_headers.js b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/__tests__/lib/rows_headers.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/__tests__/lib/rows_headers.js rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/__tests__/lib/rows_headers.js diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/_doc_table.scss b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/_doc_table.scss similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/_doc_table.scss rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/_doc_table.scss diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/_index.scss b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/_index.scss similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/_index.scss rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/_index.scss diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/actions/columns.ts b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/actions/columns.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/actions/columns.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/actions/columns.ts diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/actions/filter.js b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/actions/filter.js similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/actions/filter.js rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/actions/filter.js diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/_index.scss b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/_index.scss similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/_index.scss rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/_index.scss diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/_table_header.scss b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/_table_header.scss similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/_table_header.scss rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/_table_header.scss diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/__snapshots__/tool_bar_pager_buttons.test.tsx.snap b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/__snapshots__/tool_bar_pager_buttons.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/__snapshots__/tool_bar_pager_buttons.test.tsx.snap rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/__snapshots__/tool_bar_pager_buttons.test.tsx.snap diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/__snapshots__/tool_bar_pager_text.test.tsx.snap b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/__snapshots__/tool_bar_pager_text.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/__snapshots__/tool_bar_pager_text.test.tsx.snap rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/__snapshots__/tool_bar_pager_text.test.tsx.snap diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/index.js b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/index.js similarity index 91% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/index.js rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/index.js index e6d638d88bc27..7462de544dbce 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/index.js +++ b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/index.js @@ -16,11 +16,11 @@ * specific language governing permissions and limitations * under the License. */ - -import { uiModules } from 'ui/modules'; +import { getServices } from '../../../../kibana_services'; import { ToolBarPagerText } from './tool_bar_pager_text'; import { ToolBarPagerButtons } from './tool_bar_pager_buttons'; -import { wrapInI18nContext } from 'ui/i18n'; + +const { wrapInI18nContext, uiModules } = getServices(); const app = uiModules.get('kibana'); diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/tool_bar_pager_buttons.test.tsx b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/tool_bar_pager_buttons.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/tool_bar_pager_buttons.test.tsx rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/tool_bar_pager_buttons.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/tool_bar_pager_buttons.tsx b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/tool_bar_pager_buttons.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/tool_bar_pager_buttons.tsx rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/tool_bar_pager_buttons.tsx diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/tool_bar_pager_text.test.tsx b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/tool_bar_pager_text.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/tool_bar_pager_text.test.tsx rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/tool_bar_pager_text.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/tool_bar_pager_text.tsx b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/tool_bar_pager_text.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/pager/tool_bar_pager_text.tsx rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/pager/tool_bar_pager_text.tsx diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header.ts b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header.ts similarity index 93% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header.ts index e054120c08474..f447c54507729 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header.ts +++ b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header.ts @@ -17,10 +17,9 @@ * under the License. */ import { wrapInI18nContext } from 'ui/i18n'; -// @ts-ignore -import { uiModules } from 'ui/modules'; +import { getServices } from '../../../kibana_services'; import { TableHeader } from './table_header/table_header'; -const module = uiModules.get('app/discover'); +const module = getServices().uiModules.get('app/discover'); module.directive('kbnTableHeader', function(reactDirective: any, config: any) { return reactDirective( diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header/helpers.tsx b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header/helpers.tsx similarity index 94% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header/helpers.tsx rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header/helpers.tsx index ddf960091d476..80f963c8ccb3e 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header/helpers.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header/helpers.tsx @@ -16,10 +16,9 @@ * specific language governing permissions and limitations * under the License. */ - -import { IndexPattern } from 'ui/index_patterns'; +import { IndexPattern } from '../../../../kibana_services'; // @ts-ignore -import { shortenDottedString } from '../../../../../common/utils/shorten_dotted_string'; +import { shortenDottedString } from '../../../../../../common/utils/shorten_dotted_string'; export type SortOrder = [string, 'asc' | 'desc']; export interface ColumnProps { diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header/table_header.test.tsx b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header/table_header.test.tsx similarity index 98% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header/table_header.test.tsx rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header/table_header.test.tsx index ea2c65b1b8487..09ba77c7c4999 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header/table_header.test.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header/table_header.test.tsx @@ -23,7 +23,7 @@ import { TableHeader } from './table_header'; // @ts-ignore import { findTestSubject } from '@elastic/eui/lib/test'; import { SortOrder } from './helpers'; -import { IndexPattern, FieldType } from 'ui/index_patterns'; +import { IndexPattern, FieldType } from '../../../../kibana_services'; function getMockIndexPattern() { return ({ diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header/table_header.tsx b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header/table_header.tsx similarity index 91% rename from src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header/table_header.tsx rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header/table_header.tsx index abc8077afb669..71674710ac855 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc_table/components/table_header/table_header.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/components/table_header/table_header.tsx @@ -17,9 +17,8 @@ * under the License. */ import React from 'react'; -import { IndexPattern } from 'ui/index_patterns'; +import { IndexPattern } from '../../../../kibana_services'; // @ts-ignore -import { shortenDottedString } from '../../../../../common/utils/shorten_dotted_string'; import { TableHeaderColumn } from './table_header_column'; import { SortOrder, getDisplayedColumns } from './helpers'; @@ -48,7 +47,7 @@ export function TableHeader({ return ( - + {displayedColumns.map(col => { return ( { return { diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_directive.ts b/src/legacy/core_plugins/kibana/public/discover/angular/doc_viewer.ts similarity index 90% rename from src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_directive.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/doc_viewer.ts index fa6145c45f55f..c13c354528413 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_directive.ts +++ b/src/legacy/core_plugins/kibana/public/discover/angular/doc_viewer.ts @@ -18,8 +18,10 @@ */ // @ts-ignore -import { uiModules } from 'ui/modules'; -import { DocViewer } from './doc_viewer'; +import { getServices } from '../kibana_services'; +import { DocViewer } from '../doc_viewer/doc_viewer'; + +const { uiModules } = getServices(); uiModules.get('apps/discover').directive('docViewer', (reactDirective: any) => { return reactDirective( diff --git a/src/legacy/core_plugins/kibana/public/discover/doc/doc_directive.ts b/src/legacy/core_plugins/kibana/public/discover/angular/index.ts similarity index 58% rename from src/legacy/core_plugins/kibana/public/discover/doc/doc_directive.ts rename to src/legacy/core_plugins/kibana/public/discover/angular/index.ts index 3ee510f47ce5b..5bae0d9d551e5 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc/doc_directive.ts +++ b/src/legacy/core_plugins/kibana/public/discover/angular/index.ts @@ -16,21 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -import { wrapInI18nContext } from 'ui/i18n'; -// @ts-ignore -import { uiModules } from 'ui/modules'; -import { Doc } from './doc'; - -uiModules.get('apps/discover').directive('discoverDoc', function(reactDirective: any) { - return reactDirective( - wrapInI18nContext(Doc), - [ - ['id', { watchDepth: 'value' }], - ['index', { watchDepth: 'value' }], - ['indexPatternId', { watchDepth: 'reference' }], - ['indexPatternService', { watchDepth: 'reference' }], - ['esClient', { watchDepth: 'reference' }], - ], - { restrict: 'E' } - ); -}); +import './discover'; +import './doc'; +import './context'; +import './doc_viewer'; +import './directives'; diff --git a/src/legacy/core_plugins/kibana/public/discover/breadcrumbs.js b/src/legacy/core_plugins/kibana/public/discover/breadcrumbs.ts similarity index 88% rename from src/legacy/core_plugins/kibana/public/discover/breadcrumbs.js rename to src/legacy/core_plugins/kibana/public/discover/breadcrumbs.ts index 1220c99b5ee56..51e0dcba1cad0 100644 --- a/src/legacy/core_plugins/kibana/public/discover/breadcrumbs.js +++ b/src/legacy/core_plugins/kibana/public/discover/breadcrumbs.ts @@ -23,18 +23,18 @@ export function getRootBreadcrumbs() { return [ { text: i18n.translate('kbn.discover.rootBreadcrumb', { - defaultMessage: 'Discover' + defaultMessage: 'Discover', }), - href: '#/discover' - } + href: '#/discover', + }, ]; } -export function getSavedSearchBreadcrumbs($route) { +export function getSavedSearchBreadcrumbs($route: any) { return [ ...getRootBreadcrumbs(), { text: $route.current.locals.savedSearch.id, - } + }, ]; } diff --git a/src/legacy/core_plugins/kibana/public/discover/components/fetch_error/fetch_error.js b/src/legacy/core_plugins/kibana/public/discover/components/fetch_error/fetch_error.js index 670e9446c6e4f..612ca860f8031 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/fetch_error/fetch_error.js +++ b/src/legacy/core_plugins/kibana/public/discover/components/fetch_error/fetch_error.js @@ -16,21 +16,11 @@ * specific language governing permissions and limitations * under the License. */ - -import 'ngreact'; import React, { Fragment } from 'react'; -import { uiModules } from 'ui/modules'; -import { wrapInI18nContext } from 'ui/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { npStart } from 'ui/new_platform'; - -import { - EuiFlexGroup, - EuiFlexItem, - EuiCallOut, - EuiCodeBlock, - EuiSpacer, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiCallOut, EuiCodeBlock, EuiSpacer } from '@elastic/eui'; +import { getServices } from '../../kibana_services'; +const { uiModules, wrapInI18nContext, chrome } = getServices(); const DiscoverFetchError = ({ fetchError }) => { if (!fetchError) { @@ -40,7 +30,7 @@ const DiscoverFetchError = ({ fetchError }) => { let body; if (fetchError.lang === 'painless') { - const managementUrl = npStart.core.chrome.navLinks.get('kibana:management').url; + const managementUrl = chrome.navLinks.get('kibana:management').url; const url = `${managementUrl}/kibana/index_patterns`; body = ( @@ -51,10 +41,12 @@ const DiscoverFetchError = ({ fetchError }) => { in {managementLink}, under the {scriptedFields} tab." values={{ fetchErrorScript: `'${fetchError.script}'`, - scriptedFields: , + scriptedFields: ( + + ), managementLink: ( { defaultMessage="Management > Index Patterns" /> - ) + ), }} />

@@ -75,16 +67,10 @@ const DiscoverFetchError = ({ fetchError }) => { - + {body} - - {fetchError.error} - + {fetchError.error} @@ -96,4 +82,6 @@ const DiscoverFetchError = ({ fetchError }) => { const app = uiModules.get('apps/discover', ['react']); -app.directive('discoverFetchError', reactDirective => reactDirective(wrapInI18nContext(DiscoverFetchError))); +app.directive('discoverFetchError', reactDirective => + reactDirective(wrapInI18nContext(DiscoverFetchError)) +); diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field.js b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field.js index f7469d0142d57..cfcb654077152 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field.js +++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field.js @@ -18,15 +18,15 @@ */ import $ from 'jquery'; +import _ from 'lodash'; import { i18n } from '@kbn/i18n'; +import { getServices } from '../../kibana_services'; import html from './discover_field.html'; -import _ from 'lodash'; import 'ui/directives/css_truncate'; import 'ui/directives/field_name'; import './string_progress_bar'; import detailsHtml from './lib/detail_views/string.html'; -import { capabilities } from 'ui/capabilities'; -import { uiModules } from 'ui/modules'; +const { uiModules, capabilities } = getServices(); const app = uiModules.get('apps/discover'); app.directive('discoverField', function ($compile) { @@ -78,7 +78,7 @@ app.directive('discoverField', function ($compile) { }; - $scope.canVisualize = capabilities.get().visualize.show; + $scope.canVisualize = capabilities.visualize.show; $scope.toggleDisplay = function (field) { if (field.display) { diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search_directive.ts b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search_directive.ts index 8af23caedd78a..2e7dd3e210ef8 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search_directive.ts +++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search_directive.ts @@ -17,10 +17,11 @@ * under the License. */ // @ts-ignore -import { uiModules } from 'ui/modules'; -import { wrapInI18nContext } from 'ui/i18n'; +import { getServices } from '../../kibana_services'; import { DiscoverFieldSearch } from './discover_field_search'; +const { wrapInI18nContext, uiModules } = getServices(); + const app = uiModules.get('apps/discover'); app.directive('discoverFieldSearch', function(reactDirective: any) { diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern_directive.ts b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern_directive.ts index 938d6cc226f2f..5e3f678e388ad 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern_directive.ts +++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_index_pattern_directive.ts @@ -17,10 +17,11 @@ * under the License. */ // @ts-ignore -import { uiModules } from 'ui/modules'; -import { wrapInI18nContext } from 'ui/i18n'; +import { getServices } from '../../kibana_services'; import { DiscoverIndexPattern } from './discover_index_pattern'; +const { wrapInI18nContext, uiModules } = getServices(); + const app = uiModules.get('apps/discover'); app.directive('discoverIndexPatternSelect', function(reactDirective: any) { diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/field_chooser.js b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/field_chooser.js index 3e0172dec1ff4..99a63efc0e0fc 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/field_chooser.js +++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/field_chooser.js @@ -16,20 +16,22 @@ * specific language governing permissions and limitations * under the License. */ - -import 'ui/directives/css_truncate'; +//field_name directive will be replaced very soon import 'ui/directives/field_name'; import './discover_field'; -import 'ui/angular_ui_select'; import './discover_field_search_directive'; import './discover_index_pattern_directive'; import _ from 'lodash'; import $ from 'jquery'; import rison from 'rison-node'; import { fieldCalculator } from './lib/field_calculator'; -import { FieldList } from 'ui/index_patterns'; -import { uiModules } from 'ui/modules'; +import { + getServices, + FieldList +} from '../../kibana_services'; import fieldChooserTemplate from './field_chooser.html'; + +const { uiModules } = getServices(); const app = uiModules.get('apps/discover'); app.directive('discFieldChooser', function ($location, config, $route) { diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/string_progress_bar.js b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/string_progress_bar.js index ae00df6dfbbf8..ca3a47cad5075 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/string_progress_bar.js +++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/string_progress_bar.js @@ -16,13 +16,8 @@ * specific language governing permissions and limitations * under the License. */ - - -import { wrapInI18nContext } from 'ui/i18n'; -import { uiModules } from 'ui/modules'; - import React from 'react'; - +import { getServices } from '../../kibana_services'; import { EuiFlexGroup, EuiFlexItem, @@ -31,6 +26,7 @@ import { EuiToolTip, } from '@elastic/eui'; +const { wrapInI18nContext, uiModules } = getServices(); const module = uiModules.get('discover/field_chooser'); function StringFieldProgressBar(props) { diff --git a/src/legacy/core_plugins/kibana/public/discover/components/help_menu/help_menu.js b/src/legacy/core_plugins/kibana/public/discover/components/help_menu/help_menu.js index 95db1b686f7aa..ad68e55e71622 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/help_menu/help_menu.js +++ b/src/legacy/core_plugins/kibana/public/discover/components/help_menu/help_menu.js @@ -20,7 +20,8 @@ import React, { Fragment, PureComponent } from 'react'; import { EuiButton, EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } from 'ui/documentation_links'; +import { getServices } from '../../kibana_services'; +const { docLinks } = getServices(); export class HelpMenu extends PureComponent { render() { @@ -31,7 +32,7 @@ export class HelpMenu extends PureComponent { diff --git a/src/legacy/core_plugins/kibana/public/discover/components/help_menu/help_menu_util.js b/src/legacy/core_plugins/kibana/public/discover/components/help_menu/help_menu_util.js index aeabff2d97007..58a92193de63e 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/help_menu/help_menu_util.js +++ b/src/legacy/core_plugins/kibana/public/discover/components/help_menu/help_menu_util.js @@ -22,7 +22,7 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { HelpMenu } from './help_menu'; export function addHelpMenuToAppChrome(chrome) { - chrome.helpExtension.set(domElement => { + chrome.setHelpExtension(domElement => { render(, domElement); return () => { unmountComponentAtNode(domElement); diff --git a/src/legacy/core_plugins/kibana/public/discover/context/README.md b/src/legacy/core_plugins/kibana/public/discover/context/README.md new file mode 100644 index 0000000000000..18ba118b4da79 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/context/README.md @@ -0,0 +1,4 @@ +# DISCOVER CONTEXT + +Placeholder for Discover's context functionality, that's currently in [../angular/context](../angular/context). +Once fully de-angularized it should be moved to this location \ No newline at end of file diff --git a/src/legacy/core_plugins/kibana/public/discover/doc/doc.test.tsx b/src/legacy/core_plugins/kibana/public/discover/doc/doc.test.tsx index 6612097620b44..b3efd23ea48d0 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc/doc.test.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/doc/doc.test.tsx @@ -24,6 +24,27 @@ import { ReactWrapper } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; import { Doc, DocProps } from './doc'; +jest.mock('../doc_viewer/doc_viewer', () => ({ + DocViewer: 'test', +})); + +jest.mock('../kibana_services', () => { + return { + getServices: () => ({ + metadata: { + branch: 'test', + }, + getDocViewsSorted: () => { + return []; + }, + }), + }; +}); + +beforeEach(() => { + jest.clearAllMocks(); +}); + // Suppress warnings about "act" until we use React 16.9 /* eslint-disable no-console */ const originalError = console.error; @@ -68,30 +89,30 @@ async function mountDoc(search: () => void, update = false, indexPatternGetter: } describe('Test of of Discover', () => { - it('renders loading msg', async () => { + test('renders loading msg', async () => { const comp = await mountDoc(jest.fn()); expect(findTestSubject(comp, 'doc-msg-loading').length).toBe(1); }); - it('renders IndexPattern notFound msg', async () => { + test('renders IndexPattern notFound msg', async () => { const indexPatternGetter = jest.fn(() => Promise.reject({ savedObjectId: '007' })); const comp = await mountDoc(jest.fn(), true, indexPatternGetter); expect(findTestSubject(comp, 'doc-msg-notFoundIndexPattern').length).toBe(1); }); - it('renders notFound msg', async () => { + test('renders notFound msg', async () => { const search = jest.fn(() => Promise.reject({ status: 404 })); const comp = await mountDoc(search, true); expect(findTestSubject(comp, 'doc-msg-notFound').length).toBe(1); }); - it('renders error msg', async () => { + test('renders error msg', async () => { const search = jest.fn(() => Promise.reject('whatever')); const comp = await mountDoc(search, true); expect(findTestSubject(comp, 'doc-msg-error').length).toBe(1); }); - it('renders elasticsearch hit ', async () => { + test('renders elasticsearch hit ', async () => { const hit = { hits: { total: 1, hits: [{ _id: 1, _source: { test: 1 } }] } }; const search = jest.fn(() => Promise.resolve(hit)); const comp = await mountDoc(search, true); diff --git a/src/legacy/core_plugins/kibana/public/discover/doc/doc.tsx b/src/legacy/core_plugins/kibana/public/discover/doc/doc.tsx index 1f2d2fc532b57..0e0e6ed110ca6 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc/doc.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/doc/doc.tsx @@ -19,11 +19,9 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCallOut, EuiLink, EuiLoadingSpinner, EuiPageContent } from '@elastic/eui'; -import { IndexPatterns } from 'ui/index_patterns'; -import { metadata } from 'ui/metadata'; -import { ElasticSearchHit } from 'ui/registry/doc_views_types'; -import { DocViewer } from '../doc_viewer'; +import { DocViewer } from '../doc_viewer/doc_viewer'; import { ElasticRequestState, useEsDocSearch } from './use_es_doc_search'; +import { IndexPatterns, ElasticSearchHit, getServices } from '../kibana_services'; export interface ElasticSearchResult { hits: { @@ -117,7 +115,9 @@ export function Doc(props: DocProps) { values={{ indexName: props.index }} />{' '} { + return { + getServices: () => ({ + docViewsRegistry: { + getDocViewsSorted: (hit: any) => { + return mockGetDocViewsSorted(hit); + }, + }, + }), + }; +}); beforeEach(() => { emptyDocViews(); + jest.clearAllMocks(); }); test('Render with 3 different tabs', () => { diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer.tsx b/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer.tsx index 1c7aba9bcd7b2..aa737ebd8dcf1 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer.tsx @@ -18,7 +18,7 @@ */ import React from 'react'; import { EuiTabbedContent } from '@elastic/eui'; -import { getDocViewsSorted, DocViewRenderProps } from 'ui/registry/doc_views'; +import { getServices, DocViewRenderProps } from '../kibana_services'; import { DocViewerTab } from './doc_viewer_tab'; /** @@ -28,21 +28,24 @@ import { DocViewerTab } from './doc_viewer_tab'; * a `render` function. */ export function DocViewer(renderProps: DocViewRenderProps) { - const tabs = getDocViewsSorted(renderProps.hit).map(({ title, render, component }, idx) => { - return { - id: title, - name: title, - content: ( - - ), - }; - }); + const { docViewsRegistry } = getServices(); + const tabs = docViewsRegistry + .getDocViewsSorted(renderProps.hit) + .map(({ title, render, component }, idx) => { + return { + id: title, + name: title, + content: ( + + ), + }; + }); if (!tabs.length) { // There there's a minimum of 2 tabs active in Discover. diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_render_tab.test.tsx b/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_render_tab.test.tsx index 3bb59a8dc958c..5fa2d24dfa04c 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_render_tab.test.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_render_tab.test.tsx @@ -19,7 +19,7 @@ import React from 'react'; import { mount } from 'enzyme'; import { DocViewRenderTab } from './doc_viewer_render_tab'; -import { DocViewRenderProps } from 'ui/registry/doc_views'; +import { DocViewRenderProps } from '../kibana_services'; test('Mounting and unmounting DocViewerRenderTab', () => { const unmountFn = jest.fn(); diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_render_tab.tsx b/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_render_tab.tsx index 185ff163dad2a..750ef6b6061e1 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_render_tab.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_render_tab.tsx @@ -17,7 +17,7 @@ * under the License. */ import React, { useRef, useEffect } from 'react'; -import { DocViewRenderFn, DocViewRenderProps } from 'ui/registry/doc_views'; +import { DocViewRenderFn, DocViewRenderProps } from '../kibana_services'; interface Props { render: DocViewRenderFn; diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_tab.tsx b/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_tab.tsx index 0b25421d8aff3..3721ba5818d41 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_tab.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/doc_viewer/doc_viewer_tab.tsx @@ -18,7 +18,7 @@ */ import React from 'react'; import { I18nProvider } from '@kbn/i18n/react'; -import { DocViewRenderProps, DocViewRenderFn } from 'ui/registry/doc_views'; +import { DocViewRenderProps, DocViewRenderFn } from '../kibana_services'; import { DocViewRenderTab } from './doc_viewer_render_tab'; import { DocViewerError } from './doc_viewer_render_error'; diff --git a/src/legacy/core_plugins/kibana/public/discover/doc_viewer/index.ts b/src/legacy/core_plugins/kibana/public/discover/embeddable/constants.ts similarity index 92% rename from src/legacy/core_plugins/kibana/public/discover/doc_viewer/index.ts rename to src/legacy/core_plugins/kibana/public/discover/embeddable/constants.ts index 8ce94f24128df..cdb8a6ad3ad46 100644 --- a/src/legacy/core_plugins/kibana/public/discover/doc_viewer/index.ts +++ b/src/legacy/core_plugins/kibana/public/discover/embeddable/constants.ts @@ -16,7 +16,4 @@ * specific language governing permissions and limitations * under the License. */ - -import './doc_viewer_directive'; - -export * from './doc_viewer'; +export const SEARCH_EMBEDDABLE_TYPE = 'search'; diff --git a/src/legacy/core_plugins/kibana/public/discover/embeddable/index.ts b/src/legacy/core_plugins/kibana/public/discover/embeddable/index.ts index 3138008f3e3a0..beeb6a7338f9d 100644 --- a/src/legacy/core_plugins/kibana/public/discover/embeddable/index.ts +++ b/src/legacy/core_plugins/kibana/public/discover/embeddable/index.ts @@ -20,3 +20,4 @@ export * from './types'; export * from './search_embeddable_factory'; export * from './search_embeddable'; +export { SEARCH_EMBEDDABLE_TYPE } from './constants'; 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 eaec11ff893ed..5f3ebd6d22e24 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 @@ -16,42 +16,38 @@ * specific language governing permissions and limitations * under the License. */ - -// @ts-ignore -import { getFilterGenerator } from 'ui/filter_manager'; -import angular from 'angular'; import _ from 'lodash'; -import { SearchSource } from 'ui/courier'; -import { - getRequestInspectorStats, - getResponseInspectorStats, -} from 'ui/courier/utils/courier_inspector_utils'; -import { IndexPattern } from 'ui/index_patterns'; -import { RequestAdapter } from 'ui/inspector/adapters'; -import { Adapters } from 'ui/inspector/types'; -import { Subscription } from 'rxjs'; import * as Rx from 'rxjs'; +import { Subscription } from 'rxjs'; import { Filter, FilterStateStore } from '@kbn/es-query'; -import chrome from 'ui/chrome'; import { i18n } from '@kbn/i18n'; -import { toastNotifications } from 'ui/notify'; -import { TimeRange } from 'src/plugins/data/public'; import { TExecuteTriggerActions } from 'src/plugins/ui_actions/public'; import { setup as data } from '../../../../data/public/legacy'; -import { Query, onlyDisabledFiltersChanged, getTime } from '../../../../data/public'; +import { getTime, onlyDisabledFiltersChanged, Query } from '../../../../data/public'; import { APPLY_FILTER_TRIGGER, - Embeddable, Container, + Embeddable, } from '../../../../embeddable_api/public/np_ready/public'; -import * as columnActions from '../doc_table/actions/columns'; +import * as columnActions from '../angular/doc_table/actions/columns'; import { SavedSearch } from '../types'; import searchTemplate from './search_template.html'; import { ISearchEmbeddable, SearchInput, SearchOutput } from './types'; -import { SortOrder } from '../doc_table/components/table_header/helpers'; -import { getSortForSearchSource } from '../doc_table/lib/get_sort_for_search_source'; - -const config = chrome.getUiSettingsClient(); +import { SortOrder } from '../angular/doc_table/components/table_header/helpers'; +import { getSortForSearchSource } from '../angular/doc_table/lib/get_sort_for_search_source'; +import { + Adapters, + angular, + getFilterGenerator, + getRequestInspectorStats, + getResponseInspectorStats, + getServices, + IndexPattern, + RequestAdapter, + SearchSource, +} from '../kibana_services'; +import { TimeRange } from '../../../../../../plugins/data/public'; +import { SEARCH_EMBEDDABLE_TYPE } from './constants'; interface SearchScope extends ng.IScope { columns?: string[]; @@ -92,8 +88,6 @@ interface SearchEmbeddableConfig { queryFilter: unknown; } -export const SEARCH_EMBEDDABLE_TYPE = 'search'; - export class SearchEmbeddable extends Embeddable implements ISearchEmbeddable { private readonly savedSearch: SavedSearch; @@ -277,7 +271,7 @@ export class SearchEmbeddable extends Embeddable if (this.abortController) this.abortController.abort(); this.abortController = new AbortController(); - searchSource.setField('size', config.get('discover:sampleSize')); + searchSource.setField('size', getServices().uiSettings.get('discover:sampleSize')); searchSource.setField( 'sort', getSortForSearchSource(this.searchScope.sort, this.searchScope.indexPattern) @@ -319,7 +313,7 @@ export class SearchEmbeddable extends Embeddable // If the fetch was aborted, no need to surface this in the UI if (error.name === 'AbortError') return; - toastNotifications.addError(error, { + getServices().toastNotifications.addError(error, { title: i18n.translate('kbn.embeddable.errorTitle', { defaultMessage: 'Error fetching data', }), diff --git a/src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable_factory.ts b/src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable_factory.ts index d7b51b39e2a16..1939cc7060621 100644 --- a/src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable_factory.ts +++ b/src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable_factory.ts @@ -16,24 +16,21 @@ * specific language governing permissions and limitations * under the License. */ - -import '../doc_table'; -import { capabilities } from 'ui/capabilities'; -import { npStart, npSetup } from 'ui/new_platform'; -import { i18n } from '@kbn/i18n'; -import chrome from 'ui/chrome'; import { IPrivate } from 'ui/private'; -import { TimeRange } from 'src/plugins/data/public'; -import { FilterBarQueryFilterProvider } from 'ui/filter_manager/query_filter'; +import { i18n } from '@kbn/i18n'; import { TExecuteTriggerActions } from 'src/plugins/ui_actions/public'; +import '../angular/doc_table'; +import { getServices } from '../kibana_services'; import { EmbeddableFactory, ErrorEmbeddable, Container, } from '../../../../../../plugins/embeddable/public'; +import { TimeRange } from '../../../../../../plugins/data/public'; import { SavedSearchLoader } from '../types'; -import { SearchEmbeddable, SEARCH_EMBEDDABLE_TYPE } from './search_embeddable'; +import { SearchEmbeddable } from './search_embeddable'; import { SearchInput, SearchOutput } from './types'; +import { SEARCH_EMBEDDABLE_TYPE } from './constants'; export class SearchEmbeddableFactory extends EmbeddableFactory< SearchInput, @@ -55,7 +52,7 @@ export class SearchEmbeddableFactory extends EmbeddableFactory< } public isEditable() { - return capabilities.get().discover.save as boolean; + return getServices().capabilities.discover.save as boolean; } public canCreateNew() { @@ -73,16 +70,18 @@ export class SearchEmbeddableFactory extends EmbeddableFactory< input: Partial & { id: string; timeRange: TimeRange }, parent?: Container ): Promise { - const $injector = await chrome.dangerouslyGetActiveInjector(); + const $injector = await getServices().getInjector(); const $compile = $injector.get('$compile'); const $rootScope = $injector.get('$rootScope'); const searchLoader = $injector.get('savedSearches'); - const editUrl = chrome.addBasePath(`/app/kibana${searchLoader.urlFor(savedObjectId)}`); + const editUrl = await getServices().addBasePath( + `/app/kibana${searchLoader.urlFor(savedObjectId)}` + ); const Private = $injector.get('Private'); - const queryFilter = Private(FilterBarQueryFilterProvider); + const queryFilter = Private(getServices().FilterBarQueryFilterProvider); try { const savedObject = await searchLoader.get(savedObjectId); return new SearchEmbeddable( @@ -92,7 +91,7 @@ export class SearchEmbeddableFactory extends EmbeddableFactory< $compile, editUrl, queryFilter, - editable: capabilities.get().discover.save as boolean, + editable: getServices().capabilities.discover.save as boolean, indexPatterns: _.compact([savedObject.searchSource.getField('index')]), }, input, @@ -110,5 +109,5 @@ export class SearchEmbeddableFactory extends EmbeddableFactory< } } -const factory = new SearchEmbeddableFactory(npStart.plugins.uiActions.executeTriggerActions); -npSetup.plugins.embeddable.registerEmbeddableFactory(factory.type, factory); +const factory = new SearchEmbeddableFactory(getServices().uiActions.executeTriggerActions); +getServices().embeddable.registerEmbeddableFactory(factory.type, factory); diff --git a/src/legacy/core_plugins/kibana/public/discover/embeddable/types.ts b/src/legacy/core_plugins/kibana/public/discover/embeddable/types.ts index bc46cdbe82981..db8d2afc7aff3 100644 --- a/src/legacy/core_plugins/kibana/public/discover/embeddable/types.ts +++ b/src/legacy/core_plugins/kibana/public/discover/embeddable/types.ts @@ -17,13 +17,13 @@ * under the License. */ -import { StaticIndexPattern } from 'ui/index_patterns'; import { TimeRange } from 'src/plugins/data/public'; import { Query } from 'src/legacy/core_plugins/data/public'; import { Filter } from '@kbn/es-query'; import { EmbeddableInput, EmbeddableOutput, IEmbeddable } from 'src/plugins/embeddable/public'; +import { StaticIndexPattern } from '../kibana_services'; import { SavedSearch } from '../types'; -import { SortOrder } from '../doc_table/components/table_header/helpers'; +import { SortOrder } from '../angular/doc_table/components/table_header/helpers'; export interface SearchInput extends EmbeddableInput { timeRange: TimeRange; diff --git a/src/legacy/core_plugins/kibana/public/discover/helpers/register_feature.ts b/src/legacy/core_plugins/kibana/public/discover/helpers/register_feature.ts new file mode 100644 index 0000000000000..eb8c2aec91558 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/helpers/register_feature.ts @@ -0,0 +1,41 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { i18n } from '@kbn/i18n'; +import { + FeatureCatalogueRegistryProvider, + FeatureCatalogueCategory, +} from 'ui/registry/feature_catalogue'; + +export function registerFeature() { + FeatureCatalogueRegistryProvider.register(() => { + return { + id: 'discover', + title: i18n.translate('kbn.discover.discoverTitle', { + defaultMessage: 'Discover', + }), + description: i18n.translate('kbn.discover.discoverDescription', { + defaultMessage: 'Interactively explore your data by querying and filtering raw documents.', + }), + icon: 'discoverApp', + path: '/app/kibana#/discover', + showOnHomePage: true, + category: FeatureCatalogueCategory.DATA, + }; + }); +} diff --git a/src/legacy/core_plugins/kibana/public/discover/index.js b/src/legacy/core_plugins/kibana/public/discover/index.js deleted file mode 100644 index e509936306275..0000000000000 --- a/src/legacy/core_plugins/kibana/public/discover/index.js +++ /dev/null @@ -1,46 +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 './saved_searches/saved_searches'; -import { i18n } from '@kbn/i18n'; - -import './angular/directives'; -import 'ui/collapsible_sidebar'; -import './components/field_chooser/field_chooser'; -import './angular/discover'; -import './doc_table/components/table_row'; -import { FeatureCatalogueRegistryProvider, FeatureCatalogueCategory } from 'ui/registry/feature_catalogue'; -import './doc'; -import './context'; - -FeatureCatalogueRegistryProvider.register(() => { - return { - id: 'discover', - title: i18n.translate('kbn.discover.discoverTitle', { - defaultMessage: 'Discover', - }), - description: i18n.translate('kbn.discover.discoverDescription', { - defaultMessage: 'Interactively explore your data by querying and filtering raw documents.', - }), - icon: 'discoverApp', - path: '/app/kibana#/discover', - showOnHomePage: true, - category: FeatureCatalogueCategory.DATA - }; -}); diff --git a/src/legacy/core_plugins/kibana/public/discover/index.ts b/src/legacy/core_plugins/kibana/public/discover/index.ts new file mode 100644 index 0000000000000..35e48598f07a8 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/index.ts @@ -0,0 +1,32 @@ +/* + * 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 { PluginInitializer, PluginInitializerContext } from 'kibana/public'; +import { npSetup, npStart } from 'ui/new_platform'; +import { DiscoverPlugin, DiscoverSetup, DiscoverStart } from './plugin'; + +// Core will be looking for this when loading our plugin in the new platform +export const plugin: PluginInitializer = ( + initializerContext: PluginInitializerContext +) => { + return new DiscoverPlugin(initializerContext); +}; + +const pluginInstance = plugin({} as PluginInitializerContext); +export const setup = pluginInstance.setup(npSetup.core, npSetup.plugins); +export const start = pluginInstance.start(npStart.core, npStart.plugins); diff --git a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts new file mode 100644 index 0000000000000..dd0674073f442 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts @@ -0,0 +1,121 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import 'ui/collapsible_sidebar'; +import 'ui/directives/listen'; +import 'ui/fixed_scroll'; +import 'ui/directives/css_truncate'; + +import { npStart } from 'ui/new_platform'; +import chromeLegacy from 'ui/chrome'; +import angular from 'angular'; // just used in embeddables and discover controller +import uiRoutes from 'ui/routes'; +// @ts-ignore +import { uiModules } from 'ui/modules'; +import { SearchSource } from 'ui/courier'; +// @ts-ignore +import { StateProvider } from 'ui/state_management/state'; +// @ts-ignore +import { SavedObjectProvider } from 'ui/saved_objects/saved_object'; +import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_registry'; +import { FilterBarQueryFilterProvider } from 'ui/filter_manager/query_filter'; +import { timefilter } from 'ui/timefilter'; +import { ShareContextMenuExtensionsRegistryProvider } from 'ui/share'; +// @ts-ignore +import { IndexPattern, IndexPatterns } from 'ui/index_patterns'; +import { wrapInI18nContext } from 'ui/i18n'; +// @ts-ignore +import { docTitle } from 'ui/doc_title'; +// @ts-ignore +import * as docViewsRegistry from 'ui/registry/doc_views'; + +const services = { + // new plattform + addBasePath: npStart.core.http.basePath.prepend, + capabilities: npStart.core.application.capabilities, + chrome: npStart.core.chrome, + docLinks: npStart.core.docLinks, + eui_utils: npStart.plugins.eui_utils, + inspector: npStart.plugins.inspector, + metadata: npStart.core.injectedMetadata.getLegacyMetadata(), + toastNotifications: npStart.core.notifications.toasts, + uiSettings: npStart.core.uiSettings, + uiActions: npStart.plugins.uiActions, + embeddable: npStart.plugins.embeddable, + // legacy + docTitle, + docViewsRegistry, + FilterBarQueryFilterProvider, + getInjector: () => { + return chromeLegacy.dangerouslyGetActiveInjector(); + }, + SavedObjectRegistryProvider, + SavedObjectProvider, + SearchSource, + ShareContextMenuExtensionsRegistryProvider, + StateProvider, + timefilter, + uiModules, + uiRoutes, + wrapInI18nContext, +}; +export function getServices() { + return services; +} + +// EXPORT legacy static dependencies +export { angular }; +export { buildVislibDimensions } from 'ui/visualize/loader/pipeline_helpers/build_pipeline'; +// @ts-ignore +export { callAfterBindingsWorkaround } from 'ui/compat'; +// @ts-ignore +export { getFilterGenerator } from 'ui/filter_manager'; +export { + getRequestInspectorStats, + getResponseInspectorStats, +} from 'ui/courier/utils/courier_inspector_utils'; +// @ts-ignore +export { hasSearchStategyForIndexPattern, isDefaultTypeIndexPattern } from 'ui/courier'; +// @ts-ignore +export { intervalOptions } from 'ui/agg_types/buckets/_interval_options'; +// @ts-ignore +export { migrateLegacyQuery } from 'ui/utils/migrate_legacy_query'; +// @ts-ignore +export { RequestAdapter } from 'ui/inspector/adapters'; +export { SavedObjectSaveModal } from 'ui/saved_objects/components/saved_object_save_modal'; +export { FieldList } from 'ui/index_patterns'; +export { showSaveModal } from 'ui/saved_objects/show_saved_object_save_modal'; +export { showShareContextMenu } from 'ui/share'; +export { stateMonitorFactory } from 'ui/state_management/state_monitor_factory'; +export { subscribeWithScope } from 'ui/utils/subscribe_with_scope'; +// @ts-ignore +export { timezoneProvider } from 'ui/vis/lib/timezone'; +// @ts-ignore +export { getUnhashableStatesProvider } from 'ui/state_management/state_hashing'; +// @ts-ignore +export { tabifyAggResponse } from 'ui/agg_response/tabify'; +// @ts-ignore +export { vislibSeriesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib'; + +// EXPORT types +export { VisProvider } from 'ui/vis'; +export { StaticIndexPattern, IndexPatterns, IndexPattern, FieldType } from 'ui/index_patterns'; +export { SearchSource } from 'ui/courier'; +export { ElasticSearchHit } from 'ui/registry/doc_views_types'; +export { DocViewRenderProps, DocViewRenderFn } from 'ui/registry/doc_views'; +export { Adapters } from 'ui/inspector/types'; diff --git a/src/legacy/core_plugins/kibana/public/discover/plugin.ts b/src/legacy/core_plugins/kibana/public/discover/plugin.ts new file mode 100644 index 0000000000000..873c429bf705d --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/plugin.ts @@ -0,0 +1,60 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'kibana/public'; +import { IUiActionsStart } from 'src/plugins/ui_actions/public'; +import { registerFeature } from './helpers/register_feature'; +import './kibana_services'; +import { + Start as EmbeddableStart, + Setup as EmbeddableSetup, +} from '../../../../../plugins/embeddable/public'; + +/** + * These are the interfaces with your public contracts. You should export these + * for other plugins to use in _their_ `SetupDeps`/`StartDeps` interfaces. + * @public + */ +export type DiscoverSetup = void; +export type DiscoverStart = void; +interface DiscoverSetupPlugins { + uiActions: IUiActionsStart; + embeddable: EmbeddableSetup; +} +interface DiscoverStartPlugins { + uiActions: IUiActionsStart; + embeddable: EmbeddableStart; +} + +export class DiscoverPlugin implements Plugin { + constructor(initializerContext: PluginInitializerContext) {} + setup(core: CoreSetup, plugins: DiscoverSetupPlugins): DiscoverSetup { + registerFeature(); + require('./angular'); + } + + start(core: CoreStart, plugins: DiscoverStartPlugins): DiscoverStart { + // TODO enable this when possible, seems it broke a functional test: + // dashboard mode Dashboard View Mode Dashboard viewer can paginate on a saved search + // const factory = new SearchEmbeddableFactory(plugins.uiActions.executeTriggerActions); + // plugins.embeddable.registerEmbeddableFactory(factory.type, factory); + } + + stop() {} +} diff --git a/src/legacy/core_plugins/kibana/public/discover/saved_searches/_saved_search.js b/src/legacy/core_plugins/kibana/public/discover/saved_searches/_saved_search.js index 3903dc0845450..9bbc5baf4fc22 100644 --- a/src/legacy/core_plugins/kibana/public/discover/saved_searches/_saved_search.js +++ b/src/legacy/core_plugins/kibana/public/discover/saved_searches/_saved_search.js @@ -17,10 +17,10 @@ * under the License. */ -import 'ui/notify'; -import { uiModules } from 'ui/modules'; import { createLegacyClass } from 'ui/utils/legacy_class'; -import { SavedObjectProvider } from 'ui/saved_objects/saved_object'; +import { getServices } from '../kibana_services'; + +const { uiModules, SavedObjectProvider } = getServices(); const module = uiModules.get('discover/saved_searches', []); @@ -40,7 +40,7 @@ module.factory('SavedSearch', function (Private) { columns: [], hits: 0, sort: [], - version: 1 + version: 1, }, }); @@ -55,7 +55,7 @@ module.factory('SavedSearch', function (Private) { hits: 'integer', columns: 'keyword', sort: 'keyword', - version: 'integer' + version: 'integer', }; // Order these fields to the top, the rest are alphabetical diff --git a/src/legacy/core_plugins/kibana/public/discover/saved_searches/saved_search_register.js b/src/legacy/core_plugins/kibana/public/discover/saved_searches/saved_search_register.js index 8460ccf923cf3..9554642c225fd 100644 --- a/src/legacy/core_plugins/kibana/public/discover/saved_searches/saved_search_register.js +++ b/src/legacy/core_plugins/kibana/public/discover/saved_searches/saved_search_register.js @@ -17,10 +17,10 @@ * under the License. */ -import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_registry'; +import { getServices } from '../kibana_services'; import './saved_searches'; -SavedObjectRegistryProvider.register((savedSearches) => { +getServices().SavedObjectRegistryProvider.register((savedSearches) => { return savedSearches; }); diff --git a/src/legacy/core_plugins/kibana/public/discover/top_nav/open_search_panel.js b/src/legacy/core_plugins/kibana/public/discover/top_nav/open_search_panel.js index f29ebe6a47141..0c3b52fbf0640 100644 --- a/src/legacy/core_plugins/kibana/public/discover/top_nav/open_search_panel.js +++ b/src/legacy/core_plugins/kibana/public/discover/top_nav/open_search_panel.js @@ -19,11 +19,9 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { SavedObjectFinder } from 'ui/saved_objects/components/saved_object_finder'; import rison from 'rison-node'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; - import { EuiButton, EuiFlexGroup, @@ -34,6 +32,7 @@ import { EuiFlyoutBody, EuiTitle, } from '@elastic/eui'; +import { SavedObjectFinder } from 'ui/saved_objects/components/saved_object_finder'; const SEARCH_OBJECT_TYPE = 'search'; diff --git a/src/legacy/core_plugins/kibana/public/discover/top_nav/open_search_panel.test.js b/src/legacy/core_plugins/kibana/public/discover/top_nav/open_search_panel.test.js index 2bec532110379..3531088e3847c 100644 --- a/src/legacy/core_plugins/kibana/public/discover/top_nav/open_search_panel.test.js +++ b/src/legacy/core_plugins/kibana/public/discover/top_nav/open_search_panel.test.js @@ -20,6 +20,14 @@ import React from 'react'; import { shallow } from 'enzyme'; +jest.mock('../kibana_services', () => { + return { + getServices: () => ({ + SavedObjectFinder: jest.fn() + }), + }; +}); + import { OpenSearchPanel, } from './open_search_panel'; diff --git a/src/legacy/core_plugins/kibana/public/discover/types.d.ts b/src/legacy/core_plugins/kibana/public/discover/types.d.ts index f285e94369893..7d8740243ec02 100644 --- a/src/legacy/core_plugins/kibana/public/discover/types.d.ts +++ b/src/legacy/core_plugins/kibana/public/discover/types.d.ts @@ -17,8 +17,8 @@ * under the License. */ -import { SearchSource } from 'ui/courier'; -import { SortOrder } from './doc_table/components/table_header/helpers'; +import { SearchSource } from './kibana_services'; +import { SortOrder } from './angular/doc_table/components/table_header/helpers'; export interface SavedSearch { readonly id: string; diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/expression_types/embeddable_types.ts b/x-pack/legacy/plugins/canvas/canvas_plugin_src/expression_types/embeddable_types.ts index c94b0dcd2bd9d..6efe6bc96dbba 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/expression_types/embeddable_types.ts +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/expression_types/embeddable_types.ts @@ -6,8 +6,8 @@ // @ts-ignore import { MAP_SAVED_OBJECT_TYPE } from '../../../maps/common/constants'; -import { SEARCH_EMBEDDABLE_TYPE } from '../../../../../../src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable'; import { VISUALIZE_EMBEDDABLE_TYPE } from '../../../../../../src/legacy/core_plugins/kibana/public/visualize/embeddable'; +import { SEARCH_EMBEDDABLE_TYPE } from '../../../../../../src/legacy/core_plugins/kibana/public/discover/embeddable/constants'; export const EmbeddableTypes = { map: MAP_SAVED_OBJECT_TYPE, From d1d7d8a86aacdcdb38b27c31e721a8a4b59245a0 Mon Sep 17 00:00:00 2001 From: Chris Davies Date: Fri, 25 Oct 2019 10:19:48 -0400 Subject: [PATCH 16/61] Fix telemetry factory and tests (#49224) --- .../plugins/lens/public/app_plugin/plugin.tsx | 1 - .../lens/public/lens_ui_telemetry/factory.test.ts | 3 +-- .../lens/public/lens_ui_telemetry/factory.ts | 14 ++------------ 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/x-pack/legacy/plugins/lens/public/app_plugin/plugin.tsx b/x-pack/legacy/plugins/lens/public/app_plugin/plugin.tsx index 1f8779bb68b81..b7960b23651c6 100644 --- a/x-pack/legacy/plugins/lens/public/app_plugin/plugin.tsx +++ b/x-pack/legacy/plugins/lens/public/app_plugin/plugin.tsx @@ -72,7 +72,6 @@ export class AppPlugin { setReportManager( new LensReportManager({ storage: new Storage(localStorage), - basePath: core.http.basePath.get(), http: core.http, }) ); diff --git a/x-pack/legacy/plugins/lens/public/lens_ui_telemetry/factory.test.ts b/x-pack/legacy/plugins/lens/public/lens_ui_telemetry/factory.test.ts index 9b65cbefaf799..6e860c594f4a5 100644 --- a/x-pack/legacy/plugins/lens/public/lens_ui_telemetry/factory.test.ts +++ b/x-pack/legacy/plugins/lens/public/lens_ui_telemetry/factory.test.ts @@ -45,7 +45,6 @@ describe('Lens UI telemetry', () => { const fakeManager = new LensReportManager({ http, storage, - basePath: '/basepath', }); setReportManager(fakeManager); }); @@ -84,7 +83,7 @@ describe('Lens UI telemetry', () => { jest.runOnlyPendingTimers(); - expect(http.post).toHaveBeenCalledWith(`/basepath/api/lens/telemetry`, { + expect(http.post).toHaveBeenCalledWith(`/api/lens/telemetry`, { body: JSON.stringify({ events: { '2019-10-23': { diff --git a/x-pack/legacy/plugins/lens/public/lens_ui_telemetry/factory.ts b/x-pack/legacy/plugins/lens/public/lens_ui_telemetry/factory.ts index d264e9c77c463..673910deae339 100644 --- a/x-pack/legacy/plugins/lens/public/lens_ui_telemetry/factory.ts +++ b/x-pack/legacy/plugins/lens/public/lens_ui_telemetry/factory.ts @@ -45,21 +45,11 @@ export class LensReportManager { private storage: Storage; private http: HttpServiceBase; - private basePath: string; private timer: ReturnType; - constructor({ - storage, - http, - basePath, - }: { - storage: Storage; - http: HttpServiceBase; - basePath: string; - }) { + constructor({ storage, http }: { storage: Storage; http: HttpServiceBase }) { this.storage = storage; this.http = http; - this.basePath = basePath; this.readFromStorage(); @@ -96,7 +86,7 @@ export class LensReportManager { this.readFromStorage(); if (Object.keys(this.events).length || Object.keys(this.suggestionEvents).length) { try { - await this.http.post(`${this.basePath}${BASE_API_URL}/telemetry`, { + await this.http.post(`${BASE_API_URL}/telemetry`, { body: JSON.stringify({ events: this.events, suggestionEvents: this.suggestionEvents, From e16a36df3343cbf653ce01f989d7297a1e98add5 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 25 Oct 2019 10:21:56 -0400 Subject: [PATCH 17/61] Add render for empty donut chart. (#48583) --- .../public/components/functional/charts/donut_chart.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart.tsx index 3ae6f349d3997..76c3bd5d4c50d 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart.tsx @@ -25,6 +25,10 @@ export const DonutChart = ({ height, down, up, width }: DonutChartProps) => { colors: { danger, gray }, } = useContext(UptimeSettingsContext); + let upCount = up; + if (up === 0 && down === 0) { + upCount = 1; + } useEffect(() => { if (chartElement.current !== null) { // we must remove any existing paths before painting @@ -50,7 +54,7 @@ export const DonutChart = ({ height, down, up, width }: DonutChartProps) => { .data( // @ts-ignore pie generator expects param of type number[], but only works with // output of d3.entries, which is like Array<{ key: string, value: number }> - pieGenerator(d3.entries({ up, down })) + pieGenerator(d3.entries({ up: upCount, down })) ) .enter() .append('path') @@ -64,7 +68,7 @@ export const DonutChart = ({ height, down, up, width }: DonutChartProps) => { ) .attr('fill', (d: any) => color(d.data.key)); } - }, [chartElement.current, up, down]); + }, [chartElement.current, upCount, down]); return ( From 7af0c478cb889f9b97baa62c61f8a8d971fb011e Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 07:35:36 -0700 Subject: [PATCH 18/61] [npm] Removes rsync (#49285) Amungst one of the first dependencies added to X-Pack and does not appear to still be used. Signed-off-by: Tyler Smalley --- x-pack/package.json | 1 - yarn.lock | 5 ----- 2 files changed, 6 deletions(-) diff --git a/x-pack/package.json b/x-pack/package.json index fa439a2087547..6b3156a30e7ae 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -169,7 +169,6 @@ "react-test-renderer": "^16.8.0", "react-testing-library": "^6.0.0", "redux-test-utils": "0.2.2", - "rsync": "0.6.1", "sass-loader": "^7.3.1", "sass-resources-loader": "^2.0.1", "simple-git": "1.116.0", diff --git a/yarn.lock b/yarn.lock index b949aa07608c9..e9b4ef6588daf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24816,11 +24816,6 @@ rsvp@^4.8.4: resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== -rsync@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/rsync/-/rsync-0.6.1.tgz#3681a0098bd8750448f8bf9da1fee09f7763742b" - integrity sha1-NoGgCYvYdQRI+L+dof7gn3djdCs= - run-async@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" From 0cd5c49954c6d8ffb34ba4d688957c0679eba136 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 07:36:34 -0700 Subject: [PATCH 19/61] [npm] Removes react-select (#49284) Added when X-Pack was closed-source and import/no-extraneous-dependencies was implemented. Does not appear to still be used. Signed-off-by: Tyler Smalley --- x-pack/package.json | 1 - yarn.lock | 13 ++----------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/x-pack/package.json b/x-pack/package.json index 6b3156a30e7ae..2830d2d7e31cf 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -333,7 +333,6 @@ "react-resize-detector": "^4.2.0", "react-reverse-portal": "^1.0.4", "react-router-dom": "^4.3.1", - "react-select": "^1.2.1", "react-shortcuts": "^2.0.0", "react-sticky": "^6.0.3", "react-syntax-highlighter": "^5.7.0", diff --git a/yarn.lock b/yarn.lock index e9b4ef6588daf..68173b3cf941a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7937,7 +7937,7 @@ classnames@2.2.6, classnames@^2.2.3, classnames@^2.2.5, classnames@^2.2.6: resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== -classnames@2.x, classnames@^2.2.4: +classnames@2.x: version "2.2.5" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" integrity sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0= @@ -23073,7 +23073,7 @@ react-hotkeys@2.0.0-pre4: dependencies: prop-types "^15.6.1" -react-input-autosize@^2.1.2, react-input-autosize@^2.2.1: +react-input-autosize@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8" integrity sha512-3+K4CD13iE4lQQ2WlF8PuV5htfmTRLH6MDnfndHM6LuBRszuXnuyIfE7nhSKt8AzRBZ50bu0sAhkNMeS5pxQQA== @@ -23391,15 +23391,6 @@ react-router@^4.3.1: prop-types "^15.6.1" warning "^4.0.1" -react-select@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.2.1.tgz#a2fe58a569eb14dcaa6543816260b97e538120d1" - integrity sha512-vaCgT2bEl+uTyE/uKOEgzE5Dc/wLtzhnBvoHCeuLoJWc4WuadN6WQDhoL42DW+TziniZK2Gaqe/wUXydI3NSaQ== - dependencies: - classnames "^2.2.4" - prop-types "^15.5.8" - react-input-autosize "^2.1.2" - react-select@^2.2.0: version "2.4.4" resolved "https://registry.yarnpkg.com/react-select/-/react-select-2.4.4.tgz#ba72468ef1060c7d46fbb862b0748f96491f1f73" From fa169dacebeb4375daafee9ec1abab67fbdbad51 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 07:37:06 -0700 Subject: [PATCH 20/61] [npm] Removes humps (#49282) Added with the original commit of APM, but is no longer used. Signed-off-by: Tyler Smalley --- package.json | 1 - renovate.json5 | 8 -------- x-pack/package.json | 1 - yarn.lock | 10 ---------- 4 files changed, 20 deletions(-) diff --git a/package.json b/package.json index d64307ade9247..86bf17205a577 100644 --- a/package.json +++ b/package.json @@ -312,7 +312,6 @@ "@types/has-ansi": "^3.0.0", "@types/history": "^4.7.3", "@types/hoek": "^4.1.3", - "@types/humps": "^1.1.2", "@types/jest": "^24.0.18", "@types/joi": "^13.4.2", "@types/jquery": "^3.3.31", diff --git a/renovate.json5 b/renovate.json5 index deb513d57c85e..2d068f55bc61a 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -401,14 +401,6 @@ '@types/history', ], }, - { - groupSlug: 'humps', - groupName: 'humps related packages', - packageNames: [ - 'humps', - '@types/humps', - ], - }, { groupSlug: 'jquery', groupName: 'jquery related packages', diff --git a/x-pack/package.json b/x-pack/package.json index 2830d2d7e31cf..7b685ebd3e0ff 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -266,7 +266,6 @@ "handlebars": "4.3.5", "history": "4.9.0", "history-extra": "^5.0.1", - "humps": "2.0.1", "i18n-iso-countries": "^4.3.1", "icalendar": "0.7.1", "idx": "^2.5.6", diff --git a/yarn.lock b/yarn.lock index 68173b3cf941a..6e1f42218b378 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3451,11 +3451,6 @@ resolved "https://registry.yarnpkg.com/@types/hoek/-/hoek-4.1.3.tgz#d1982d48fb0d2a0e5d7e9d91838264d8e428d337" integrity sha1-0ZgtSPsNKg5dfp2Rg4Jk2OQo0zc= -"@types/humps@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@types/humps/-/humps-1.1.2.tgz#fbcaf596d20ff2ed78f8f511c5d6a943b51101d6" - integrity sha1-+8r1ltIP8u14+PURxdapQ7URAdY= - "@types/indent-string@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/indent-string/-/indent-string-3.0.0.tgz#9ebb391ceda548926f5819ad16405349641b999f" @@ -15155,11 +15150,6 @@ humanize-string@^1.0.2: dependencies: decamelize "^1.0.0" -humps@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/humps/-/humps-2.0.1.tgz#dd02ea6081bd0568dc5d073184463957ba9ef9aa" - integrity sha1-3QLqYIG9BWjcXQcxhEY5V7qe+ao= - hyperlinker@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/hyperlinker/-/hyperlinker-1.0.0.tgz#23dc9e38a206b208ee49bc2d6c8ef47027df0c0e" From 2210c2f50e8b0e212bb1e3b18f1b3282c025698e Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 07:37:44 -0700 Subject: [PATCH 21/61] [npm] Removes dataloader (#49281) Originally added in https://github.com/elastic/kibana/pull/24068, however, it doesn't appear to have ever been used. Signed-off-by: Tyler Smalley --- x-pack/package.json | 1 - yarn.lock | 5 ----- 2 files changed, 6 deletions(-) diff --git a/x-pack/package.json b/x-pack/package.json index 7b685ebd3e0ff..6fe8d0ddb47e3 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -241,7 +241,6 @@ "cytoscape-dagre": "^2.2.2", "d3": "3.5.17", "d3-scale": "1.0.7", - "dataloader": "^1.4.0", "dedent": "^0.7.0", "del": "^5.1.0", "dragselect": "1.13.1", diff --git a/yarn.lock b/yarn.lock index 6e1f42218b378..b01374a570e3d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9691,11 +9691,6 @@ data-urls@^1.0.1: whatwg-mimetype "^2.1.0" whatwg-url "^7.0.0" -dataloader@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-1.4.0.tgz#bca11d867f5d3f1b9ed9f737bd15970c65dff5c8" - integrity sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw== - date-fns@^1.27.2: version "1.29.0" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" From 1461bc4a7c25e6bd529912af33ed986bda55e73f Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 07:38:08 -0700 Subject: [PATCH 22/61] [npm] Removes trunc-html and trunc-text (#49278) Originally added in https://github.com/elastic/kibana/pull/6791 as part of custom notification banners, however it's no longer used. Signed-off-by: Tyler Smalley --- package.json | 2 -- yarn.lock | 42 ------------------------------------------ 2 files changed, 44 deletions(-) diff --git a/package.json b/package.json index 86bf17205a577..91af1a017e91a 100644 --- a/package.json +++ b/package.json @@ -247,8 +247,6 @@ "tinygradient": "0.4.3", "tinymath": "1.2.1", "topojson-client": "3.0.0", - "trunc-html": "1.1.2", - "trunc-text": "1.0.2", "tslib": "^1.9.3", "type-detect": "^4.0.8", "ui-select": "0.19.8", diff --git a/yarn.lock b/yarn.lock index b01374a570e3d..444a1eb1a1e15 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5665,16 +5665,6 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -assignment@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.0.0.tgz#ffd17b21bf5d6b22e777b989681a815456a3dd3e" - integrity sha1-/9F7Ib9dayLnd7mJaBqBVFaj3T4= - -assignment@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/assignment/-/assignment-2.2.0.tgz#f5b5bc2d160d69986e8700cd38f567c0aabe101e" - integrity sha1-9bW8LRYNaZhuhwDNOPVnwKq+EB4= - ast-module-types@^2.3.1, ast-module-types@^2.3.2, ast-module-types@^2.4.0: version "2.5.0" resolved "https://registry.yarnpkg.com/ast-module-types/-/ast-module-types-2.5.0.tgz#44b8bcd51684329a77f2af6b2587df9ea6b4d5ff" @@ -14748,11 +14738,6 @@ hawk@~6.0.2: hoek "4.x.x" sntp "2.x.x" -he@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" - integrity sha1-LAX/rvkLaOhg8/0rVO9YCYknfuI= - he@1.2.0, he@1.2.x, he@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -15623,14 +15608,6 @@ inquirer@^7.0.0: strip-ansi "^5.1.0" through "^2.3.6" -insane@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/insane/-/insane-2.6.1.tgz#c7dcae7b51c20346883b71078fad6ce0483c198f" - integrity sha1-x9yue1HCA0aIO3EHj61s4Eg8GY8= - dependencies: - assignment "2.0.0" - he "0.5.0" - insight@0.10.1: version "0.10.1" resolved "https://registry.yarnpkg.com/insight/-/insight-0.10.1.tgz#a0ecf668484a95d66e9be59644964e719cc83380" @@ -27577,25 +27554,6 @@ trough@^1.0.0: dependencies: glob "^6.0.4" -trunc-html@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/trunc-html/-/trunc-html-1.1.2.tgz#1e97d51f67d470b67662b1a670e6d0ea7a8edafe" - integrity sha1-HpfVH2fUcLZ2YrGmcObQ6nqO2v4= - dependencies: - assignment "2.2.0" - insane "2.6.1" - trunc-text "1.0.1" - -trunc-text@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.1.tgz#58f876d8ac59b224b79834bb478b8656e69622b5" - integrity sha1-WPh22KxZsiS3mDS7R4uGVuaWIrU= - -trunc-text@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.2.tgz#b582bb3ddea9c9adc25017d737c48ebdd2157406" - integrity sha1-tYK7Pd6pya3CUBfXN8SOvdIVdAY= - ts-debounce@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ts-debounce/-/ts-debounce-1.0.0.tgz#e433301744ba75fe25466f7f23e1382c646aae6a" From 9b69d2988ac144b084fcc4458a47bd2bcec2b1bf Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 07:38:41 -0700 Subject: [PATCH 23/61] [npm] Remove checksum (#49277) Used in Gulp when X-Pack was closed source and no longer used. Signed-off-by: Tyler Smalley --- x-pack/package.json | 1 - yarn.lock | 14 -------------- 2 files changed, 15 deletions(-) diff --git a/x-pack/package.json b/x-pack/package.json index 6fe8d0ddb47e3..59d546d2833d4 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -122,7 +122,6 @@ "base64url": "^3.0.1", "chalk": "^2.4.2", "chance": "1.0.18", - "checksum": "0.1.1", "cheerio": "0.22.0", "commander": "3.0.0", "copy-webpack-plugin": "^5.0.4", diff --git a/yarn.lock b/yarn.lock index 444a1eb1a1e15..fba1f0ccab548 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7732,13 +7732,6 @@ check-more-types@2.24.0: resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA= -checksum@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/checksum/-/checksum-0.1.1.tgz#dc6527d4c90be8560dbd1ed4cecf3297d528e9e9" - integrity sha1-3GUn1MkL6FYNvR7Uzs8yl9Uo6ek= - dependencies: - optimist "~0.3.5" - cheerio@0.22.0: version "0.22.0" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" @@ -20781,13 +20774,6 @@ optimist@^0.6.1, optimist@~0.6.1: minimist "~0.0.1" wordwrap "~0.0.2" -optimist@~0.3.5: - version "0.3.7" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9" - integrity sha1-yQlBrVnkJzMokjB00s8ufLxuwNk= - dependencies: - wordwrap "~0.0.2" - optionator@^0.8.1, optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" From cc67942f39583ed934a232821e4ee59281299206 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 07:39:10 -0700 Subject: [PATCH 24/61] [npm] Remove babel-plugin-mock-imports and gulp-multi-process (#49276) * [npm] Remove babel-plugin-mock-imports Originally added as part of https://github.com/elastic/kibana/pull/22695, however, it doesn't appear to have ever actually been used. * [npm] Removes gulp-multi-process Signed-off-by: Tyler Smalley --- src/dev/license_checker/config.ts | 3 -- x-pack/package.json | 2 - yarn.lock | 61 ------------------------------- 3 files changed, 66 deletions(-) diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index 727c51f704431..fbd16d95ded1c 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -106,8 +106,5 @@ export const LICENSE_OVERRIDES = { // TODO can be removed once we upgrade the use of walk dependency past or equal to v2.3.14 'walk@2.3.9': ['MIT'], - // TODO remove this once we upgrade past or equal to v1.0.2 - 'babel-plugin-mock-imports@1.0.1': ['MIT'], - '@elastic/node-ctags@1.0.2': ['Nuclide software'], }; diff --git a/x-pack/package.json b/x-pack/package.json index 59d546d2833d4..8bb3c683fa290 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -115,7 +115,6 @@ "axios": "^0.19.0", "babel-jest": "^24.9.0", "babel-plugin-inline-react-svg": "^1.1.0", - "babel-plugin-mock-imports": "^1.0.1", "babel-plugin-require-context-hook": "npm:babel-plugin-require-context-hook-babel7@1.0.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "base64-js": "^1.3.1", @@ -142,7 +141,6 @@ "graphql-codegen-typescript-server": "^0.18.2", "gulp": "4.0.2", "gulp-mocha": "^7.0.2", - "gulp-multi-process": "1.3.1", "hapi": "^17.5.3", "jest": "^24.9.0", "jest-cli": "^24.9.0", diff --git a/yarn.lock b/yarn.lock index fba1f0ccab548..5b82466674428 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5748,55 +5748,6 @@ async-settle@^1.0.0: dependencies: async-done "^1.2.2" -async.queue@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/async.queue/-/async.queue-0.5.2.tgz#8d5d90812e1481066bc0904e8cc1712b17c3bd7c" - integrity sha1-jV2QgS4UgQZrwJBOjMFxKxfDvXw= - dependencies: - async.util.queue "0.5.2" - -async.util.arrayeach@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/async.util.arrayeach/-/async.util.arrayeach-0.5.2.tgz#58c4e98028d55d69bfb05aeb3af44e0a555a829c" - integrity sha1-WMTpgCjVXWm/sFrrOvROClVagpw= - -async.util.isarray@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/async.util.isarray/-/async.util.isarray-0.5.2.tgz#e62dac8f2636f65875dcf7521c2d24d0dfb2bbdf" - integrity sha1-5i2sjyY29lh13PdSHC0k0N+yu98= - -async.util.map@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/async.util.map/-/async.util.map-0.5.2.tgz#e588ef86e0b3ab5f027d97af4d6835d055ca69d6" - integrity sha1-5YjvhuCzq18CfZevTWg10FXKadY= - -async.util.noop@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/async.util.noop/-/async.util.noop-0.5.2.tgz#bdd62b97cb0aa3f60b586ad148468698975e58b9" - integrity sha1-vdYrl8sKo/YLWGrRSEaGmJdeWLk= - -async.util.onlyonce@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz#b8e6fc004adc923164d79e32f2813ee465c24ff2" - integrity sha1-uOb8AErckjFk154y8oE+5GXCT/I= - -async.util.queue@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/async.util.queue/-/async.util.queue-0.5.2.tgz#57f65abe1a3cdf273d31abd28ab95425f8222ee5" - integrity sha1-V/Zavho83yc9MavSirlUJfgiLuU= - dependencies: - async.util.arrayeach "0.5.2" - async.util.isarray "0.5.2" - async.util.map "0.5.2" - async.util.noop "0.5.2" - async.util.onlyonce "0.5.2" - async.util.setimmediate "0.5.2" - -async.util.setimmediate@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/async.util.setimmediate/-/async.util.setimmediate-0.5.2.tgz#2812ebabf2a58027758d4bc7793d1ccfaf10255f" - integrity sha1-KBLrq/KlgCd1jUvHeT0cz68QJV8= - async@1.x, async@^1.4.2, async@^1.5.2, async@~1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -6225,11 +6176,6 @@ babel-plugin-minify-type-constructors@^0.4.3: dependencies: babel-helper-is-void-0 "^0.4.3" -babel-plugin-mock-imports@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-mock-imports/-/babel-plugin-mock-imports-1.0.1.tgz#1476ed4de911347d344fc81caab4beced80804b1" - integrity sha512-Nu4unCGKeqOfLlfnLPnv/pEHancdAGTqFqyArZ27gsKIiKxeZvMr87IHB8BxhMu3Bfc8fA8bx7hWt32aZbEwpQ== - babel-plugin-named-asset-import@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.3.tgz#9ba2f3ac4dc78b042651654f07e847adfe50667c" @@ -14345,13 +14291,6 @@ gulp-mocha@^7.0.2: supports-color "^7.0.0" through2 "^3.0.1" -gulp-multi-process@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/gulp-multi-process/-/gulp-multi-process-1.3.1.tgz#e12aa818e4c234357ad99d5caff8df8a18f46e9e" - integrity sha512-okxYy3mxUkekM0RNjkBg8OPuzpnD2yXMAdnGOaQPSJ2wzBdE9R9pkTV+tzPZ65ORK7b57YUc6s+gROA4+EIOLg== - dependencies: - async.queue "^0.5.2" - gulp-rename@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/gulp-rename/-/gulp-rename-1.4.0.tgz#de1c718e7c4095ae861f7296ef4f3248648240bd" From cc0ef60a883416167c6b51d6e57c58dde32bb747 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 07:39:26 -0700 Subject: [PATCH 25/61] [npm] Removes ansicolors (#49274) Originally used in the functional test runners pro runner, it is no longer used. Signed-off-by: Tyler Smalley --- x-pack/package.json | 1 - yarn.lock | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/x-pack/package.json b/x-pack/package.json index 8bb3c683fa290..2e218fbef67a1 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -111,7 +111,6 @@ "@types/xml-crypto": "^1.4.0", "@types/xml2js": "^0.4.5", "abab": "^1.0.4", - "ansicolors": "0.3.2", "axios": "^0.19.0", "babel-jest": "^24.9.0", "babel-plugin-inline-react-svg": "^1.1.0", diff --git a/yarn.lock b/yarn.lock index 5b82466674428..6f1c757e7878d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5077,16 +5077,16 @@ ansi@^0.3.0, ansi@~0.3.1: resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21" integrity sha1-DELU+xcWDVqa8eSEus4cZpIsGyE= -ansicolors@0.3.2, ansicolors@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= - ansicolors@~0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef" integrity sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8= +ansicolors@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" + integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= + any-base@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" From a56d2d8b8582c207cdea516819c00954c2f638d3 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 07:39:53 -0700 Subject: [PATCH 26/61] [npm] Removes @slack/client (#49273) Originally added in https://github.com/elastic/kibana/pull/19236 as part of the notification service, however it's no longer used. Signed-off-by: Tyler Smalley --- x-pack/package.json | 1 - yarn.lock | 109 +------------------------------------------- 2 files changed, 1 insertion(+), 109 deletions(-) diff --git a/x-pack/package.json b/x-pack/package.json index 2e218fbef67a1..c2749dd517a2e 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -206,7 +206,6 @@ "@mapbox/mapbox-gl-draw": "^1.1.1", "@samverschueren/stream-to-observable": "^0.3.0", "@scant/router": "^0.1.0", - "@slack/client": "^4.8.0", "@slack/webhook": "^5.0.0", "@turf/boolean-contains": "6.0.1", "angular-resource": "1.7.8", diff --git a/yarn.lock b/yarn.lock index 6f1c757e7878d..f5a9465bc794d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2418,35 +2418,6 @@ resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== -"@slack/client@^4.8.0": - version "4.8.0" - resolved "https://registry.yarnpkg.com/@slack/client/-/client-4.8.0.tgz#265606f1cebae1d72f3fdd2cdf7cf1510783dde4" - integrity sha512-c4PKsRMtTp3QVYg+6cNqqxbU/50gnYfMlZgPCGUuMDMm9mkx50y0PEuERcVyLIe5j61imrhQx9DoNIfybEhTTw== - dependencies: - "@types/form-data" "^2.2.1" - "@types/is-stream" "^1.1.0" - "@types/loglevel" "^1.5.3" - "@types/node" ">=6.0.0" - "@types/p-cancelable" "^0.3.0" - "@types/p-queue" "^2.3.1" - "@types/p-retry" "^1.0.1" - "@types/retry" "^0.10.2" - "@types/ws" "^5.1.1" - axios "^0.18.0" - eventemitter3 "^3.0.0" - finity "^0.5.4" - form-data "^2.3.1" - is-stream "^1.1.0" - loglevel "^1.6.1" - object.entries "^1.0.4" - object.getownpropertydescriptors "^2.0.3" - object.values "^1.0.4" - p-cancelable "^0.3.0" - p-queue "^2.3.0" - p-retry "^2.0.0" - retry "^0.12.0" - ws "^5.2.0" - "@slack/types@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@slack/types/-/types-1.0.0.tgz#1dc7a63b293c4911e474197585c3feda012df17a" @@ -3308,13 +3279,6 @@ resolved "https://registry.yarnpkg.com/@types/file-saver/-/file-saver-2.0.0.tgz#cbb49815a5e1129d5f23836a98d65d93822409af" integrity sha512-dxdRrUov2HVTbSRFX+7xwUPlbGYVEZK6PrSqClg2QPos3PNe0bCajkDDkDeeC1znjSH03KOEqVbXpnJuWa2wgQ== -"@types/form-data@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-2.2.1.tgz#ee2b3b8eaa11c0938289953606b745b738c54b1e" - integrity sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ== - dependencies: - "@types/node" "*" - "@types/fs-extra@5.0.4": version "5.0.4" resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.0.4.tgz#b971134d162cc0497d221adde3dbb67502225599" @@ -3473,13 +3437,6 @@ resolved "https://registry.yarnpkg.com/@types/is-glob/-/is-glob-4.0.0.tgz#fb8a2bff539025d4dcd6d5efe7689e03341b876d" integrity sha512-zC/2EmD8scdsGIeE+Xg7kP7oi9VP90zgMQtm9Cr25av4V+a+k8slQyiT60qSw8KORYrOKlPXfHwoa1bQbRzskQ== -"@types/is-stream@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@types/is-stream/-/is-stream-1.1.0.tgz#b84d7bb207a210f2af9bed431dc0fbe9c4143be1" - integrity sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg== - dependencies: - "@types/node" "*" - "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -3617,11 +3574,6 @@ resolved "https://registry.yarnpkg.com/@types/log-symbols/-/log-symbols-2.0.0.tgz#7919e2ec3c8d13879bfdcab310dd7a3f7fc9466d" integrity sha512-YJhbp0sz3egFFKl3BcCNPQKzuGFOP4PACcsifhK6ROGnJUW9ViYLuLybQ9GQZm7Zejy3tkGuiXYMq3GiyGkU4g== -"@types/loglevel@^1.5.3": - version "1.5.3" - resolved "https://registry.yarnpkg.com/@types/loglevel/-/loglevel-1.5.3.tgz#adfce55383edc5998a2170ad581b3e23d6adb5b8" - integrity sha512-TzzIZihV+y9kxSg5xJMkyIkaoGkXi50isZTtGHObNHRqAAwjGNjSCNPI7AUAv0tZUKTq9f2cdkCUd/2JVZUTrA== - "@types/lru-cache@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.0.tgz#57f228f2b80c046b4a1bd5cac031f81f207f4f03" @@ -3718,7 +3670,7 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@10.12.27", "@types/node@8.5.8", "@types/node@>=6.0.0", "@types/node@>=8.9.0", "@types/node@^10.12.27", "@types/node@^12.0.2": +"@types/node@*", "@types/node@10.12.27", "@types/node@8.5.8", "@types/node@>=8.9.0", "@types/node@^10.12.27", "@types/node@^12.0.2": version "10.12.27" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.27.tgz#eb3843f15d0ba0986cc7e4d734d2ee8b50709ef8" integrity sha512-e9wgeY6gaY21on3ve0xAjgBVjGDWq/xUteK0ujsE53bUoxycMkqfnkUgMt6ffZtykZ5X12Mg3T7Pw4TRCObDKg== @@ -3761,23 +3713,6 @@ dependencies: "@types/node" "*" -"@types/p-cancelable@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@types/p-cancelable/-/p-cancelable-0.3.0.tgz#3e4fcc54a3dfd81d0f5b93546bb68d0df50553bb" - integrity sha512-sP+9Ivnpil7cdmvr5O+145aXm65YX8Y+Lrul1ojdYz6yaE05Dqonn6Z9v5eqJCQ0UeSGcTRtepMlZDh9ywdKgw== - -"@types/p-queue@^2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@types/p-queue/-/p-queue-2.3.1.tgz#2fb251e46e884e31c4bd1bf58f0e188972353ff4" - integrity sha512-JyO7uMAtkcMMULmsTQ4t/lCC8nxirTtweGG1xAFNNIAoC1RemmeIxq8PiKghuEy99XdbS6Lwx4zpbXUjfeSSAA== - -"@types/p-retry@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/p-retry/-/p-retry-1.0.1.tgz#2302bc3da425014208c8a9b68293d37325124785" - integrity sha512-HgQPG9kkUb4EpTeUv2taH2nBZsVUb5aOTSw3X2YozcTG1ttmGcLaLKx1MbAz1evVfUEDTCAPmdz2HiFztIyWrw== - dependencies: - "@types/retry" "*" - "@types/papaparse@^4.5.11": version "4.5.11" resolved "https://registry.yarnpkg.com/@types/papaparse/-/papaparse-4.5.11.tgz#dcd4f64da55f768c2e2cf92ccac1973c67a73890" @@ -3977,11 +3912,6 @@ "@types/tough-cookie" "*" form-data "^2.5.0" -"@types/retry@*", "@types/retry@^0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.10.2.tgz#bd1740c4ad51966609b058803ee6874577848b37" - integrity sha512-LqJkY4VQ7S09XhI7kA3ON71AxauROhSv74639VsNXC9ish4IWHnIi98if+nP1MxQV3RMPqXSCYgpPsDHjlg9UQ== - "@types/selenium-webdriver@^4.0.3": version "4.0.3" resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.0.3.tgz#388f12c464cc1fff5d4c84cb372f19b9ab9b5c81" @@ -4202,14 +4132,6 @@ resolved "https://registry.yarnpkg.com/@types/write-pkg/-/write-pkg-3.1.0.tgz#f58767f4fb9a6a3ad8e95d3e9cd1f2d026ceab26" integrity sha512-JRGsPEPCrYqTXU0Cr+Yu7esPBE2yvH7ucOHr+JuBy0F59kglPvO5gkmtyEvf3P6dASSkScvy/XQ6SC1QEBFDuA== -"@types/ws@^5.1.1": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-5.1.2.tgz#f02d3b1cd46db7686734f3ce83bdf46c49decd64" - integrity sha512-NkTXUKTYdXdnPE2aUUbGOXE1XfMK527SCvU/9bj86kyFF6kZ9ZnOQ3mK5jADn98Y2vEUD/7wKDgZa7Qst2wYOg== - dependencies: - "@types/events" "*" - "@types/node" "*" - "@types/xml-crypto@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@types/xml-crypto/-/xml-crypto-1.4.0.tgz#b586e4819f6bdd0571a3faa9a8098049d5c3cc5a" @@ -12599,11 +12521,6 @@ fined@^1.0.1: object.pick "^1.2.0" parse-filepath "^1.0.1" -finity@^0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/finity/-/finity-0.5.4.tgz#f2a8a9198e8286467328ec32c8bfcc19a2229c11" - integrity sha512-3l+5/1tuw616Lgb0QBimxfdd2TqaDGpfCBpfX6EqtFmqUV3FtQnVEX4Aa62DagYEqnsTIjZcTfbq9msDbXYgyA== - first-chunk-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70" @@ -18471,11 +18388,6 @@ logform@^2.1.1: ms "^2.1.1" triple-beam "^1.3.0" -loglevel@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" - integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po= - loglevel@^1.6.4: version "1.6.4" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.4.tgz#f408f4f006db8354d0577dcf6d33485b3cb90d56" @@ -20974,23 +20886,11 @@ p-map@^3.0.0: dependencies: aggregate-error "^3.0.0" -p-queue@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-2.4.2.tgz#03609826682b743be9a22dba25051bd46724fc34" - integrity sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng== - p-reduce@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= -p-retry@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-2.0.0.tgz#b97f1f4d6d81a3c065b2b40107b811e995c1bfba" - integrity sha512-ZbCuzAmiwJ45q4evp/IG9D+5MUllGSUeCWwPt3j/tdYSi1KPkSD+46uqmAA1LhccDhOXv8kYZKNb8x78VflzfA== - dependencies: - retry "^0.12.0" - p-retry@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" @@ -30108,13 +30008,6 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== - dependencies: - async-limiter "~1.0.0" - ws@^6.1.0: version "6.2.0" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.0.tgz#13806d9913b2a5f3cbb9ba47b563c002cbc7c526" From 7ecf5ac9357f26abc6e51e6baac52e0fbe35234b Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 07:40:27 -0700 Subject: [PATCH 27/61] [npm] Removes stream-to-observable (#49272) Added in https://github.com/elastic/kibana/pull/18885 as part of the RxJS 6 upgrade and used in the screenshot stictcher, however it is not longer used. Signed-off-by: Tyler Smalley --- x-pack/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/package.json b/x-pack/package.json index c2749dd517a2e..79796cd9be30e 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -204,7 +204,6 @@ "@kbn/interpreter": "1.0.0", "@kbn/ui-framework": "1.0.0", "@mapbox/mapbox-gl-draw": "^1.1.1", - "@samverschueren/stream-to-observable": "^0.3.0", "@scant/router": "^0.1.0", "@slack/webhook": "^5.0.0", "@turf/boolean-contains": "6.0.1", From 909d28fe386a71506bcfa1d9c14799ba7be956e1 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Fri, 25 Oct 2019 15:59:31 +0100 Subject: [PATCH 28/61] [ML] Fixing edit buttons in advanced wizard summary (#49324) --- .../components/advanced_view/detector_list.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_view/detector_list.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_view/detector_list.tsx index b82cc9b9c24bc..d11ef8164169a 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_view/detector_list.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_view/detector_list.tsx @@ -108,9 +108,11 @@ export const DetectorList: FC = ({ isActive, onEditJob, onDeleteJob }) => detectorToString(d) )} - - - + {isActive && ( + + + + )} {d.detector_description !== undefined && ( From 9acc18095bde9d4e4159cff156003ff1d275ff98 Mon Sep 17 00:00:00 2001 From: Brandon Kobel Date: Fri, 25 Oct 2019 08:23:09 -0700 Subject: [PATCH 29/61] Fixing kibana.yml doc comments for elasticsearch.ssl.certificate/key (#49262) --- config/kibana.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/kibana.yml b/config/kibana.yml index 9525a6423d90a..47482f9e6d59f 100644 --- a/config/kibana.yml +++ b/config/kibana.yml @@ -50,7 +50,8 @@ #server.ssl.key: /path/to/your/server.key # Optional settings that provide the paths to the PEM-format SSL certificate and key files. -# These files validate that your Elasticsearch backend uses the same key files. +# These files are used to verify the identity of Kibana to Elasticsearch and are required when +# xpack.ssl.verification_mode in Elasticsearch is set to either certificate or full. #elasticsearch.ssl.certificate: /path/to/your/client.crt #elasticsearch.ssl.key: /path/to/your/client.key From 8499cfd0f900d57b1ba6ee6ed43698f8e43239ff Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Fri, 25 Oct 2019 17:53:45 +0200 Subject: [PATCH 30/61] ensure loading order (#49316) --- src/legacy/core_plugins/kibana/public/home/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/home/index.js b/src/legacy/core_plugins/kibana/public/home/index.js index 829d1ef8f0ba4..8a8680eeba47c 100644 --- a/src/legacy/core_plugins/kibana/public/home/index.js +++ b/src/legacy/core_plugins/kibana/public/home/index.js @@ -36,12 +36,12 @@ const homeTitle = i18n.translate('kbn.home.breadcrumbs.homeTitle', { defaultMess function getRoute() { return { template, - controller($scope) { - const { chrome, addBasePath, getFeatureCatalogueRegistryProvider } = getServices(); - getFeatureCatalogueRegistryProvider().then(catalogue => { - $scope.directories = catalogue.inTitleOrder; - $scope.$digest(); - }); + resolve: { + directories: () => getServices().getFeatureCatalogueRegistryProvider().then(catalogue => catalogue.inTitleOrder) + }, + controller($scope, $route) { + const { chrome, addBasePath } = getServices(); + $scope.directories = $route.current.locals.directories; $scope.recentlyAccessed = chrome.recentlyAccessed.get().map(item => { item.link = addBasePath(item.link); return item; From 91a5664b4f591c5244fe6b04c47809f62959e347 Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Fri, 25 Oct 2019 12:09:41 -0400 Subject: [PATCH 31/61] [Lens] Text updates (#48964) * [Lens] Text updates * Update per comments * Update text for datapanel * Fix tests --- .../editor_frame/chart_switch.tsx | 8 +-- .../editor_frame/suggestion_panel.tsx | 33 +++++---- .../change_indexpattern.tsx | 14 +++- .../public/indexpattern_plugin/datapanel.tsx | 26 ++++--- .../public/indexpattern_plugin/field_item.tsx | 14 ++-- .../indexpattern_plugin/indexpattern.test.ts | 4 +- .../operations/definitions/count.tsx | 2 +- .../operations/definitions/date_histogram.tsx | 2 +- .../metric_expression.tsx | 4 +- .../public/xy_visualization_plugin/types.ts | 8 +-- .../xy_config_panel.tsx | 68 +++++++++++-------- .../xy_visualization_plugin/xy_expression.tsx | 6 +- .../xy_visualization.test.ts | 18 ++--- .../xy_visualization.tsx | 6 +- 14 files changed, 122 insertions(+), 91 deletions(-) diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/chart_switch.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/chart_switch.tsx index 26db1224eb352..2e95aa10bf4db 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/chart_switch.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/chart_switch.tsx @@ -52,8 +52,8 @@ function VisualizationSummary(props: Props) { if (!visualization) { return ( <> - {i18n.translate('xpack.lens.configPanel.chooseVisualization', { - defaultMessage: 'Choose a visualization', + {i18n.translate('xpack.lens.configPanel.selectVisualization', { + defaultMessage: 'Select a visualization', })} ); @@ -201,8 +201,8 @@ export function ChartSwitch(props: Props) { anchorPosition="downLeft" > - {i18n.translate('xpack.lens.configPanel.chooseVisualization', { - defaultMessage: 'Choose a visualization', + {i18n.translate('xpack.lens.configPanel.selectVisualization', { + defaultMessage: 'Select a visualization', })} diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.tsx index 7d1f400f484e1..e2f9bd84560de 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.tsx @@ -259,20 +259,27 @@ export function SuggestionPanel({ {stagedPreview && ( - { - trackUiEvent('suggestion_confirmed'); - dispatch({ - type: 'SUBMIT_SUGGESTION', - }); - }} - > - {i18n.translate('xpack.lens.sugegstion.confirmSuggestionLabel', { - defaultMessage: 'Reload suggestions', + + > + { + trackUiEvent('suggestion_confirmed'); + dispatch({ + type: 'SUBMIT_SUGGESTION', + }); + }} + > + {i18n.translate('xpack.lens.sugegstion.refreshSuggestionLabel', { + defaultMessage: 'Refresh', + })} + + )} diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/change_indexpattern.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/change_indexpattern.tsx index dc42b97cce08d..4d9bc6276d52a 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/change_indexpattern.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/change_indexpattern.tsx @@ -5,8 +5,15 @@ */ import _ from 'lodash'; +import { i18n } from '@kbn/i18n'; import React, { useState } from 'react'; -import { EuiButtonEmpty, EuiPopover, EuiSelectable, EuiButtonEmptyProps } from '@elastic/eui'; +import { + EuiButtonEmpty, + EuiPopover, + EuiPopoverTitle, + EuiSelectable, + EuiButtonEmptyProps, +} from '@elastic/eui'; import { EuiSelectableProps } from '@elastic/eui/src/components/selectable/selectable'; import { IndexPatternRef } from './types'; import { trackUiEvent } from '../lens_ui_telemetry'; @@ -62,6 +69,11 @@ export function ChangeIndexPattern({ ownFocus >
+ + {i18n.translate('xpack.lens.indexPattern.changeIndexPatternTitle', { + defaultMessage: 'Change index pattern', + })} + } @@ -441,31 +441,35 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({ {paginatedFields.length === 0 && (

- - {showEmptyFields - ? i18n.translate('xpack.lens.indexPatterns.hiddenFieldsLabel', { + {showEmptyFields + ? localState.typeFilter.length || localState.nameFilter.length + ? i18n.translate('xpack.lens.indexPatterns.noFilteredFieldsLabel', { defaultMessage: - 'No fields have data with the current filters. You can show fields without data using the filters above.', + 'No fields match the current filters. Try changing your filters or time range.', }) : i18n.translate('xpack.lens.indexPatterns.noFieldsLabel', { - defaultMessage: 'No fields in {title} can be visualized.', - values: { title: currentIndexPattern.title }, - })} - + defaultMessage: 'No fields exist in this index pattern.', + }) + : i18n.translate('xpack.lens.indexPatterns.emptyFieldsWithDataLabel', { + defaultMessage: + 'No fields have data with the current filters and time range. Try changing your filters or time range.', + })}

+ {(!showEmptyFields || localState.typeFilter.length || localState.nameFilter.length) && ( { - trackUiEvent('show_empty_fields_clicked'); + trackUiEvent('indexpattern_show_all_fields_clicked'); clearLocalState(); onToggleEmptyFields(true); }} > {i18n.translate('xpack.lens.indexPatterns.showAllFields.buttonText', { - defaultMessage: 'Show All Fields', + defaultMessage: 'Show all fields', })} )} diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/field_item.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/field_item.tsx index 41a4bd3549dc1..79a3ac4137f88 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/field_item.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/field_item.tsx @@ -174,10 +174,8 @@ export function FieldItem(props: FieldItemProps) { togglePopover(); } }} - aria-label={i18n.translate('xpack.lens.indexPattern.fieldStatsButtonAriaLabel', { - defaultMessage: - 'Click or press Enter for information about {fieldName}. Or, drag field into visualization.', - values: { fieldName: field.name }, + aria-label={i18n.translate('xpack.lens.indexPattern.fieldStatsButtonLabel', { + defaultMessage: 'Click for a field preview. Or, drag and drop to visualize.', })} > @@ -188,10 +186,8 @@ export function FieldItem(props: FieldItemProps) { {i18n.translate('xpack.lens.indexPattern.fieldStatsNoData', { - defaultMessage: 'No data to display', + defaultMessage: 'No data to display.', })}
); diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/indexpattern.test.ts b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/indexpattern.test.ts index 845cfa29d5724..b4f01078f1f78 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/indexpattern.test.ts +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/indexpattern.test.ts @@ -240,7 +240,7 @@ describe('IndexPattern Data Source', () => { columnOrder: ['col1', 'col2'], columns: { col1: { - label: 'Count of Documents', + label: 'Count of records', dataType: 'number', isBucketed: false, @@ -272,7 +272,7 @@ describe('IndexPattern Data Source', () => { metricsAtAllLevels=false partialRows=false includeFormatHints=true - aggConfigs={lens_auto_date aggConfigs='[{\\"id\\":\\"col1\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"schema\\":\\"metric\\",\\"params\\":{}},{\\"id\\":\\"col2\\",\\"enabled\\":true,\\"type\\":\\"date_histogram\\",\\"schema\\":\\"segment\\",\\"params\\":{\\"field\\":\\"timestamp\\",\\"useNormalizedEsInterval\\":true,\\"interval\\":\\"1d\\",\\"drop_partials\\":false,\\"min_doc_count\\":0,\\"extended_bounds\\":{}}}]'} | lens_rename_columns idMap='{\\"col-0-col1\\":{\\"label\\":\\"Count of Documents\\",\\"dataType\\":\\"number\\",\\"isBucketed\\":false,\\"operationType\\":\\"count\\",\\"id\\":\\"col1\\"},\\"col-1-col2\\":{\\"label\\":\\"Date\\",\\"dataType\\":\\"date\\",\\"isBucketed\\":true,\\"operationType\\":\\"date_histogram\\",\\"sourceField\\":\\"timestamp\\",\\"params\\":{\\"interval\\":\\"1d\\"},\\"id\\":\\"col2\\"}}'" + aggConfigs={lens_auto_date aggConfigs='[{\\"id\\":\\"col1\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"schema\\":\\"metric\\",\\"params\\":{}},{\\"id\\":\\"col2\\",\\"enabled\\":true,\\"type\\":\\"date_histogram\\",\\"schema\\":\\"segment\\",\\"params\\":{\\"field\\":\\"timestamp\\",\\"useNormalizedEsInterval\\":true,\\"interval\\":\\"1d\\",\\"drop_partials\\":false,\\"min_doc_count\\":0,\\"extended_bounds\\":{}}}]'} | lens_rename_columns idMap='{\\"col-0-col1\\":{\\"label\\":\\"Count of records\\",\\"dataType\\":\\"number\\",\\"isBucketed\\":false,\\"operationType\\":\\"count\\",\\"id\\":\\"col1\\"},\\"col-1-col2\\":{\\"label\\":\\"Date\\",\\"dataType\\":\\"date\\",\\"isBucketed\\":true,\\"operationType\\":\\"date_histogram\\",\\"sourceField\\":\\"timestamp\\",\\"params\\":{\\"interval\\":\\"1d\\"},\\"id\\":\\"col2\\"}}'" `); }); }); diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/count.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/count.tsx index 68a36787ec189..94cb17b340c36 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/count.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/count.tsx @@ -9,7 +9,7 @@ import { OperationDefinition } from '.'; import { ParameterlessIndexPatternColumn, BaseIndexPatternColumn } from './column_types'; const countLabel = i18n.translate('xpack.lens.indexPattern.countOf', { - defaultMessage: 'Count of documents', + defaultMessage: 'Count of records', }); export type CountIndexPatternColumn = ParameterlessIndexPatternColumn< diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/date_histogram.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/date_histogram.tsx index 89c4899bb8e56..e5c00542df7d3 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/date_histogram.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/date_histogram.tsx @@ -16,7 +16,7 @@ import { IndexPattern } from '../../types'; type PropType = C extends React.ComponentType ? P : unknown; const autoInterval = 'auto'; -const supportedIntervals = ['M', 'w', 'd', 'h']; +const supportedIntervals = ['M', 'w', 'd', 'h', 'm']; const defaultCustomInterval = supportedIntervals[2]; // Add ticks to EuiRange component props diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_expression.tsx b/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_expression.tsx index 68de585771a79..407c754284671 100644 --- a/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_expression.tsx @@ -76,8 +76,8 @@ export const getMetricChartRenderer = ( formatFactory: FormatFactory ): IInterpreterRenderFunction => ({ name: 'lens_metric_chart_renderer', - displayName: 'Metric Chart', - help: 'Metric Chart Renderer', + displayName: 'Metric chart', + help: 'Metric chart renderer', validate: () => {}, reuseDomNode: true, render: async (domNode: Element, config: MetricChartProps, _handlers: unknown) => { diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/types.ts b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/types.ts index de81cc208070a..f81eb9d72d6ae 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/types.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/types.ts @@ -241,7 +241,7 @@ export const visualizationTypes: VisualizationType[] = [ icon: 'visBarHorizontal', largeIcon: chartBarHorizontalSVG, label: i18n.translate('xpack.lens.xyVisualization.barHorizontalLabel', { - defaultMessage: 'Horizontal Bar', + defaultMessage: 'Horizontal bar', }), }, { @@ -249,7 +249,7 @@ export const visualizationTypes: VisualizationType[] = [ icon: 'visBarVerticalStacked', largeIcon: chartBarStackedSVG, label: i18n.translate('xpack.lens.xyVisualization.stackedBarLabel', { - defaultMessage: 'Stacked Bar', + defaultMessage: 'Stacked bar', }), }, { @@ -257,7 +257,7 @@ export const visualizationTypes: VisualizationType[] = [ icon: 'visBarHorizontalStacked', largeIcon: chartBarHorizontalStackedSVG, label: i18n.translate('xpack.lens.xyVisualization.stackedBarHorizontalLabel', { - defaultMessage: 'Stacked Horizontal Bar', + defaultMessage: 'Stacked horizontal bar', }), }, { @@ -281,7 +281,7 @@ export const visualizationTypes: VisualizationType[] = [ icon: 'visAreaStacked', largeIcon: chartAreaStackedSVG, label: i18n.translate('xpack.lens.xyVisualization.stackedAreaLabel', { - defaultMessage: 'Stacked Area', + defaultMessage: 'Stacked area', }), }, ]; diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_config_panel.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_config_panel.tsx index f285cb90f225a..f59b1520dbbb4 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_config_panel.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_config_panel.tsx @@ -20,6 +20,7 @@ import { EuiSpacer, EuiButtonEmpty, EuiPopoverFooter, + EuiToolTip, } from '@elastic/eui'; import { State, SeriesType, LayerConfig, visualizationTypes } from './types'; import { VisualizationProps, OperationMetadata } from '../types'; @@ -235,7 +236,7 @@ export function XYConfigPanel(props: VisualizationProps) { ) { ))} - { - trackUiEvent('xy_layer_added'); - const usedSeriesTypes = _.uniq(state.layers.map(layer => layer.seriesType)); - setState({ - ...state, - layers: [ - ...state.layers, - newLayerState( - usedSeriesTypes.length === 1 ? usedSeriesTypes[0] : state.preferredSeriesType, - frame.addNewLayer() - ), - ], - }); - }} - iconType="plusInCircleFilled" - /> + + + { + trackUiEvent('xy_layer_added'); + const usedSeriesTypes = _.uniq(state.layers.map(layer => layer.seriesType)); + setState({ + ...state, + layers: [ + ...state.layers, + newLayerState( + usedSeriesTypes.length === 1 ? usedSeriesTypes[0] : state.preferredSeriesType, + frame.addNewLayer() + ), + ], + }); + }} + iconType="plusInCircleFilled" + /> + + ); } diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_expression.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_expression.tsx index 4529179debd26..3871abcd53c1e 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_expression.tsx @@ -98,9 +98,9 @@ export const getXyChartRenderer = (dependencies: { timeZone: string; }): IInterpreterRenderFunction => ({ name: 'lens_xy_chart_renderer', - displayName: 'XY Chart', + displayName: 'XY chart', help: i18n.translate('xpack.lens.xyChart.renderer.help', { - defaultMessage: 'X/Y Chart Renderer', + defaultMessage: 'X/Y chart renderer', }), validate: () => {}, reuseDomNode: true, @@ -238,7 +238,7 @@ export function XYChart({ data, args, formatFactory, timeZone }: XYChartRenderPr const rows = data.tables[layerId].rows.map(row => { const newRow: typeof row = {}; - // Remap data to { 'Count of documents': 5 } + // Remap data to { 'Count of records': 5 } Object.keys(row).forEach(key => { if (columnToLabelMap[key]) { newRow[columnToLabelMap[key]] = row[key]; diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_visualization.test.ts b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_visualization.test.ts index 4b03c6c346ce5..db28e76f82946 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_visualization.test.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_visualization.test.ts @@ -47,7 +47,7 @@ describe('xy_visualization', () => { it('should show mixed xy chart when multilple series types', () => { const desc = xyVisualization.getDescription(mixedState('bar', 'line')); - expect(desc.label).toEqual('Mixed XY Chart'); + expect(desc.label).toEqual('Mixed XY chart'); }); it('should show the preferredSeriesType if there are no layers', () => { @@ -56,7 +56,7 @@ describe('xy_visualization', () => { // 'test-file-stub' is a hack, but it at least means we aren't using // a standard icon here. expect(desc.icon).toEqual('test-file-stub'); - expect(desc.label).toEqual('Bar Chart'); + expect(desc.label).toEqual('Bar chart'); }); it('should show mixed horizontal bar chart when multiple horizontal bar types', () => { @@ -64,23 +64,23 @@ describe('xy_visualization', () => { mixedState('bar_horizontal', 'bar_horizontal_stacked') ); - expect(desc.label).toEqual('Mixed Horizontal Bar Chart'); + expect(desc.label).toEqual('Mixed horizontal bar chart'); }); it('should show bar chart when bar only', () => { const desc = xyVisualization.getDescription(mixedState('bar_horizontal', 'bar_horizontal')); - expect(desc.label).toEqual('Horizontal Bar Chart'); + expect(desc.label).toEqual('Horizontal bar chart'); }); it('should show the chart description if not mixed', () => { - expect(xyVisualization.getDescription(mixedState('area')).label).toEqual('Area Chart'); - expect(xyVisualization.getDescription(mixedState('line')).label).toEqual('Line Chart'); + expect(xyVisualization.getDescription(mixedState('area')).label).toEqual('Area chart'); + expect(xyVisualization.getDescription(mixedState('line')).label).toEqual('Line chart'); expect(xyVisualization.getDescription(mixedState('area_stacked')).label).toEqual( - 'Stacked Area Chart' + 'Stacked area chart' ); expect(xyVisualization.getDescription(mixedState('bar_horizontal_stacked')).label).toEqual( - 'Stacked Horizontal Bar Chart' + 'Stacked horizontal bar chart' ); }); }); @@ -119,7 +119,7 @@ describe('xy_visualization', () => { "position": "right", }, "preferredSeriesType": "bar_stacked", - "title": "Empty XY Chart", + "title": "Empty XY chart", } `); }); diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_visualization.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_visualization.tsx index b56e0d9deb55e..5ba77cb39d5f8 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_visualization.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_visualization.tsx @@ -54,7 +54,7 @@ function getDescription(state?: State) { ? visualizationType.label : isHorizontalChart(state.layers) ? i18n.translate('xpack.lens.xyVisualization.mixedBarHorizontalLabel', { - defaultMessage: 'Mixed Horizontal Bar', + defaultMessage: 'Mixed horizontal bar', }) : i18n.translate('xpack.lens.xyVisualization.mixedLabel', { defaultMessage: 'Mixed XY', @@ -70,7 +70,7 @@ export const xyVisualization: Visualization = { getDescription(state) { const { icon, label } = getDescription(state); const chartLabel = i18n.translate('xpack.lens.xyVisualization.chartLabel', { - defaultMessage: '{label} Chart', + defaultMessage: '{label} chart', values: { label }, }); @@ -93,7 +93,7 @@ export const xyVisualization: Visualization = { initialize(frame, state) { return ( state || { - title: 'Empty XY Chart', + title: 'Empty XY chart', legend: { isVisible: true, position: Position.Right }, preferredSeriesType: defaultSeriesType, layers: [ From fcc9ea369a09949af28ef0e4863ec0ed2ba87816 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 09:22:14 -0700 Subject: [PATCH 32/61] [npm] Removes unused dependencies (#49287) * [npm] Remove mochawesome-report-generator * [npm] Remove babel-plugin-transform-react-remove-prop-types * [npm] Removing popper.js * [npm] Remove stream-stream * [npm] Remove react-redux-request Signed-off-by: Tyler Smalley --- package.json | 1 - x-pack/package.json | 4 ---- yarn.lock | 20 +++----------------- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 91af1a017e91a..04ce14a9f3692 100644 --- a/package.json +++ b/package.json @@ -237,7 +237,6 @@ "rxjs": "^6.2.1", "script-loader": "0.7.2", "semver": "^5.5.0", - "stream-stream": "^1.2.6", "style-it": "^2.1.3", "style-loader": "0.23.1", "symbol-observable": "^1.2.0", diff --git a/x-pack/package.json b/x-pack/package.json index 79796cd9be30e..09511d88f073b 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -115,7 +115,6 @@ "babel-jest": "^24.9.0", "babel-plugin-inline-react-svg": "^1.1.0", "babel-plugin-require-context-hook": "npm:babel-plugin-require-context-hook-babel7@1.0.0", - "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "base64-js": "^1.3.1", "base64url": "^3.0.1", "chalk": "^2.4.2", @@ -151,7 +150,6 @@ "mocha-multi-reporters": "^1.1.7", "mochawesome": "^4.1.0", "mochawesome-merge": "^2.0.1", - "mochawesome-report-generator": "^4.0.1", "mustache": "^2.3.0", "mutation-observer": "^1.0.3", "node-fetch": "^2.6.0", @@ -301,7 +299,6 @@ "pluralize": "3.1.0", "pngjs": "3.4.0", "polished": "^1.9.2", - "popper.js": "^1.14.3", "postcss-prefix-selector": "^1.7.2", "prop-types": "^15.6.0", "proper-lockfile": "^3.2.0", @@ -321,7 +318,6 @@ "react-monaco-editor": "~0.27.0", "react-portal": "^3.2.0", "react-redux": "^5.1.1", - "react-redux-request": "^1.5.6", "react-resize-detector": "^4.2.0", "react-reverse-portal": "^1.0.4", "react-router-dom": "^4.3.1", diff --git a/yarn.lock b/yarn.lock index f5a9465bc794d..8d57c549c96d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6157,7 +6157,7 @@ babel-plugin-transform-property-literals@^6.9.4: dependencies: esutils "^2.0.2" -babel-plugin-transform-react-remove-prop-types@0.4.24, babel-plugin-transform-react-remove-prop-types@^0.4.24: +babel-plugin-transform-react-remove-prop-types@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== @@ -19372,7 +19372,7 @@ mochawesome-merge@^2.0.1: uuid "^3.3.2" yargs "^12.0.5" -mochawesome-report-generator@^4.0.0, mochawesome-report-generator@^4.0.1: +mochawesome-report-generator@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/mochawesome-report-generator/-/mochawesome-report-generator-4.0.1.tgz#0a010d1ecf379eb26ba05300feb59e2665076080" integrity sha512-hQbmQt8/yCT68GjrQFat+Diqeuka3haNllexYfja1+y0hpwi3yCJwFpQCdWK9ezzcXL3Nu80f2I6SZeyspwsqg== @@ -21655,7 +21655,7 @@ polished@^3.3.1: dependencies: "@babel/runtime" "^7.4.5" -popper.js@^1.14.1, popper.js@^1.14.3, popper.js@^1.14.7: +popper.js@^1.14.1, popper.js@^1.14.7: version "1.15.0" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.15.0.tgz#5560b99bbad7647e9faa475c6b8056621f5a4ff2" integrity sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA== @@ -23052,15 +23052,6 @@ react-reconciler@^0.20.1: prop-types "^15.6.2" scheduler "^0.13.6" -react-redux-request@^1.5.6: - version "1.5.6" - resolved "https://registry.yarnpkg.com/react-redux-request/-/react-redux-request-1.5.6.tgz#8c514dc88264d225e113b4b54a265064e8020651" - integrity sha512-mzdG41GSLwynFI7DII3XNJxkABLD++I3Q1zlZWpcqycWSzWSYkjPUEz7M8r6aIIMzruANHQZX+asulvoaiwFRg== - dependencies: - lodash.get "^4.4.2" - lodash.isequal "^4.5.0" - prop-types "^15.6.1" - react-redux@^5.0.6, react-redux@^5.0.7: version "5.0.7" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8" @@ -26030,11 +26021,6 @@ stream-spigot@~2.1.2: dependencies: readable-stream "~1.1.0" -stream-stream@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/stream-stream/-/stream-stream-1.2.6.tgz#a9ae071c64c11b8584f52973f7715e37e5144c43" - integrity sha1-qa4HHGTBG4WE9Slz93FeN+UUTEM= - stream-to-observable@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe" From b24e44c5b8d32deeb32a53e0e09d5bb0b695be66 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 09:23:04 -0700 Subject: [PATCH 33/61] Removes unused babel-plugin-inline-react-svg package (#49271) Signed-off-by: Tyler Smalley --- package.json | 1 - x-pack/package.json | 1 - yarn.lock | 55 ++------------------------------------------- 3 files changed, 2 insertions(+), 55 deletions(-) diff --git a/package.json b/package.json index 04ce14a9f3692..d5d4799d48c9f 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,6 @@ "**/typescript": "3.5.3", "**/graphql-toolkit/lodash": "^4.17.13", "**/isomorphic-git/**/base64-js": "^1.2.1", - "**/babel-plugin-inline-react-svg/svgo/js-yaml": "^3.13.1", "**/image-diff/gm/debug": "^2.6.9" }, "workspaces": { diff --git a/x-pack/package.json b/x-pack/package.json index 09511d88f073b..34cda1640f8df 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -113,7 +113,6 @@ "abab": "^1.0.4", "axios": "^0.19.0", "babel-jest": "^24.9.0", - "babel-plugin-inline-react-svg": "^1.1.0", "babel-plugin-require-context-hook": "npm:babel-plugin-require-context-hook-babel7@1.0.0", "base64-js": "^1.3.1", "base64url": "^3.0.1", diff --git a/yarn.lock b/yarn.lock index 8d57c549c96d3..da1f7c38b75f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5970,17 +5970,6 @@ babel-plugin-emotion@^9.2.11: source-map "^0.5.7" touch "^2.0.1" -babel-plugin-inline-react-svg@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-inline-react-svg/-/babel-plugin-inline-react-svg-1.1.0.tgz#b39519c78249b3fcf895b541c38b485a2b11b0be" - integrity sha512-Y/tBMi7Jh7Jh+DGcSNsY9/RW33nvcR067HFK0Dp+03jpidil1sJAffBdajK72xn3tbwMsgFLJubxW5xpQLJytA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/parser" "^7.0.0" - lodash.isplainobject "^4.0.6" - resolve "^1.10.0" - svgo "^0.7.2" - babel-plugin-istanbul@^5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.1.tgz#7981590f1956d75d67630ba46f0c22493588c893" @@ -7753,13 +7742,6 @@ circular-json@^0.5.5: resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.9.tgz#932763ae88f4f7dead7a0d09c8a51a4743a53b1d" integrity sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ== -clap@^1.0.9: - version "1.2.3" - resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.3.tgz#4f36745b32008492557f46412d66d50cb99bce51" - integrity sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA== - dependencies: - chalk "^1.1.3" - class-extend@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/class-extend/-/class-extend-0.1.2.tgz#8057a82b00f53f82a5d62c50ef8cffdec6fabc34" @@ -8063,13 +8045,6 @@ coa@^2.0.2: chalk "^2.4.1" q "^1.1.2" -coa@~1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd" - integrity sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0= - dependencies: - q "^1.1.2" - code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -9121,14 +9096,6 @@ csso@^3.5.1: dependencies: css-tree "1.0.0-alpha.29" -csso@~2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85" - integrity sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U= - dependencies: - clap "^1.0.9" - source-map "^0.5.3" - cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": version "0.3.2" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b" @@ -16972,7 +16939,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@3.13.1, js-yaml@3.x, js-yaml@^3.10.0, js-yaml@^3.13.1, js-yaml@^3.4.6, js-yaml@^3.5.1, js-yaml@^3.5.4, js-yaml@^3.9.0, js-yaml@~3.13.0, js-yaml@~3.13.1, js-yaml@~3.7.0: +js-yaml@3.13.1, js-yaml@3.x, js-yaml@^3.10.0, js-yaml@^3.13.1, js-yaml@^3.4.6, js-yaml@^3.5.1, js-yaml@^3.5.4, js-yaml@^3.9.0, js-yaml@~3.13.0, js-yaml@~3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -24820,7 +24787,7 @@ sass-resources-loader@^2.0.1: glob "^7.1.1" loader-utils "^1.0.4" -sax@>=0.6.0, sax@^1.2.1, sax@^1.2.4, sax@~1.2.1, sax@~1.2.4: +sax@>=0.6.0, sax@^1.2.1, sax@^1.2.4, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -26529,19 +26496,6 @@ svg-to-pdfkit@^0.1.7: dependencies: pdfkit ">=0.8.1" -svgo@^0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" - integrity sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U= - dependencies: - coa "~1.0.1" - colors "~1.1.2" - csso "~2.3.1" - js-yaml "~3.7.0" - mkdirp "~0.5.1" - sax "~1.2.1" - whet.extend "~0.9.9" - svgo@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.2.2.tgz#0253d34eccf2aed4ad4f283e11ee75198f9d7316" @@ -29694,11 +29648,6 @@ whatwg-url@^7.0.0: tr46 "^1.0.1" webidl-conversions "^4.0.2" -whet.extend@~0.9.9: - version "0.9.9" - resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" - integrity sha1-+HfVv2SMl+WqVC+twW1qJZucEaE= - which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" From 373320a3a0603a901e61803d5899c2395432701a Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 25 Oct 2019 09:38:13 -0700 Subject: [PATCH 34/61] [npm] Removes react-clipboard.js and redux-test-utils (#49283) * [npm] Removes react-clipboard.js Added in the original commit of APM, but does not appear to still be used. * [npm] Remove redux-test-utils Signed-off-by: Tyler Smalley --- x-pack/package.json | 2 -- yarn.lock | 24 +----------------------- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/x-pack/package.json b/x-pack/package.json index 34cda1640f8df..089ce24b9a4ff 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -161,7 +161,6 @@ "react-hooks-testing-library": "^0.3.8", "react-test-renderer": "^16.8.0", "react-testing-library": "^6.0.0", - "redux-test-utils": "0.2.2", "sass-loader": "^7.3.1", "sass-resources-loader": "^2.0.1", "simple-git": "1.116.0", @@ -307,7 +306,6 @@ "react": "^16.8.0", "react-apollo": "^2.1.4", "react-beautiful-dnd": "^8.0.7", - "react-clipboard.js": "^1.1.2", "react-datetime": "^2.14.0", "react-dom": "^16.8.0", "react-dropzone": "^4.2.9", diff --git a/yarn.lock b/yarn.lock index da1f7c38b75f0..7de969ffae168 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7895,15 +7895,6 @@ cli-width@^2.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= -clipboard@^1.6.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-1.7.1.tgz#360d6d6946e99a7a1fef395e42ba92b5e9b5a16b" - integrity sha1-Ng1taUbpmnof7zleQrqStem1oWs= - dependencies: - good-listener "^1.2.2" - select "^1.1.2" - tiny-emitter "^2.0.0" - clipboard@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.4.tgz#836dafd66cf0fea5d71ce5d5b0bf6e958009112d" @@ -21962,7 +21953,7 @@ prop-types@15.6.1: loose-envify "^1.3.1" object-assign "^4.1.1" -prop-types@15.7.2, prop-types@15.x, prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@15.7.2, prop-types@15.x, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -22592,14 +22583,6 @@ react-clientside-effect@^1.2.0: "@babel/runtime" "^7.0.0" shallowequal "^1.1.0" -react-clipboard.js@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/react-clipboard.js/-/react-clipboard.js-1.1.3.tgz#86feeb49364553ecd15aea91c75aa142532a60e0" - integrity sha512-97IKPinjiuFIBrCXqhNvKCBJFrSS1mmV5LVALE9djkweau26UWpR5VueYB3Eo3b2vfPtbyt0QUw06YOGdC0rpw== - dependencies: - clipboard "^1.6.1" - prop-types "^15.5.0" - react-color@^2.13.8: version "2.14.1" resolved "https://registry.yarnpkg.com/react-color/-/react-color-2.14.1.tgz#db8ad4f45d81e74896fc2e1c99508927c6d084e0" @@ -23670,11 +23653,6 @@ redux-saga@^0.16.0: resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-0.16.2.tgz#993662e86bc945d8509ac2b8daba3a8c615cc971" integrity sha512-iIjKnRThI5sKPEASpUvySemjzwqwI13e3qP7oLub+FycCRDysLSAOwt958niZW6LhxfmS6Qm1BzbU70w/Koc4w== -redux-test-utils@0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/redux-test-utils/-/redux-test-utils-0.2.2.tgz#593213f30173c5908f72315f08b705e1606094fe" - integrity sha512-+YsUHpzZJ7G85wYgllmGLJ75opIlWrCuKThaVTsHW5xLOrzaLE4abQ3AbYcHkx/vFOReG2D8XUwMfGnFKH8hGw== - redux-thunk@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.2.0.tgz#e615a16e16b47a19a515766133d1e3e99b7852e5" From c7a1c895b4b08a472f48e20aaac9bac95f8861c9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 25 Oct 2019 09:41:21 -0700 Subject: [PATCH 35/61] Update dependency @elastic/charts to ^13.5.8 (#49327) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index d5d4799d48c9f..7aaf2573cc8de 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "dependencies": { "@babel/core": "^7.5.5", "@babel/register": "^7.5.5", - "@elastic/charts": "^13.5.7", + "@elastic/charts": "^13.5.8", "@elastic/datemath": "5.0.2", "@elastic/ems-client": "1.0.5", "@elastic/eui": "14.7.0", diff --git a/yarn.lock b/yarn.lock index 7de969ffae168..a3752df9b024c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1064,10 +1064,10 @@ debug "^3.1.0" lodash.once "^4.1.1" -"@elastic/charts@^13.5.7": - version "13.5.7" - resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-13.5.7.tgz#97ba458059613efd542ae68d7d2da059aac38484" - integrity sha512-8ibgrEJD3fpoLurB/DnNaWRmMGxAPHdtvCiPl1saPIjvlmGlrUNlXMneVgsPLqerNT0vuJDgqfQHHQcef/S2Hw== +"@elastic/charts@^13.5.8": + version "13.5.8" + resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-13.5.8.tgz#ae26371e373d79cb7fe5e7394711013e1416cb81" + integrity sha512-wXz5vVKwdbOhNZwRyd1py9YdVOGHmMJ4K+PERMIJ4VwAfjHimN1qieIVAKun9vfomt/j25tDhF3Kxq3XA9W0+g== dependencies: "@types/d3-shape" "^1.3.1" classnames "^2.2.6" From 58dbb130dc3e3b1971837a6587ea538596824a67 Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Fri, 25 Oct 2019 12:42:31 -0400 Subject: [PATCH 36/61] [task manager] Kibana should start without task manager (#48568) * [task manager] Kibana should not fail to start without task manager * Check for task manager in maps * Lower log level * Update task registration --- x-pack/legacy/plugins/lens/index.ts | 1 + .../plugins/lens/server/usage/collectors.ts | 6 +++++- x-pack/legacy/plugins/lens/server/usage/task.ts | 17 ++++++++++++++--- x-pack/legacy/plugins/maps/index.js | 3 ++- .../maps_telemetry/maps_usage_collector.js | 7 ++++++- .../server/maps_telemetry/telemetry_task.js | 15 ++++++++++++++- x-pack/legacy/plugins/oss_telemetry/index.js | 2 +- .../visualizations/get_usage_collector.ts | 6 +++++- .../oss_telemetry/server/lib/tasks/index.ts | 7 ++++++- 9 files changed, 54 insertions(+), 10 deletions(-) diff --git a/x-pack/legacy/plugins/lens/index.ts b/x-pack/legacy/plugins/lens/index.ts index a8984bd80fb1c..20f92ebbe0654 100644 --- a/x-pack/legacy/plugins/lens/index.ts +++ b/x-pack/legacy/plugins/lens/index.ts @@ -18,6 +18,7 @@ export const lens: LegacyPluginInitializer = kibana => { return new kibana.Plugin({ id: PLUGIN_ID, configPrefix: `xpack.${PLUGIN_ID}`, + // task_manager could be required, but is only used for telemetry require: ['kibana', 'elasticsearch', 'xpack_main', 'interpreter', 'data'], publicDir: resolve(__dirname, 'public'), diff --git a/x-pack/legacy/plugins/lens/server/usage/collectors.ts b/x-pack/legacy/plugins/lens/server/usage/collectors.ts index 9a58026002ade..94a7c8e0d85c1 100644 --- a/x-pack/legacy/plugins/lens/server/usage/collectors.ts +++ b/x-pack/legacy/plugins/lens/server/usage/collectors.ts @@ -89,7 +89,11 @@ async function isTaskManagerReady(server: Server) { } async function getLatestTaskState(server: Server) { - const taskManager = server.plugins.task_manager!; + const taskManager = server.plugins.task_manager; + + if (!taskManager) { + return null; + } try { const result = await taskManager.fetch({ diff --git a/x-pack/legacy/plugins/lens/server/usage/task.ts b/x-pack/legacy/plugins/lens/server/usage/task.ts index 8fc6c8cbefe8a..3cb857a453e1d 100644 --- a/x-pack/legacy/plugins/lens/server/usage/task.ts +++ b/x-pack/legacy/plugins/lens/server/usage/task.ts @@ -45,7 +45,13 @@ export function initializeLensTelemetry(core: CoreSetup, { server }: { server: S } function registerLensTelemetryTask(core: CoreSetup, { server }: { server: Server }) { - const taskManager = server.plugins.task_manager!; + const taskManager = server.plugins.task_manager; + + if (!taskManager) { + server.log(['debug', 'telemetry'], `Task manager is not available`); + return; + } + taskManager.registerTaskDefinitions({ [TELEMETRY_TASK_TYPE]: { title: 'Lens telemetry fetch task', @@ -62,6 +68,11 @@ function scheduleTasks(server: Server) { status: { plugin: { kbnServer: KbnServer } }; }).status.plugin; + if (!taskManager) { + server.log(['debug', 'telemetry'], `Task manager is not available`); + return; + } + kbnServer.afterPluginsInit(() => { // The code block below can't await directly within "afterPluginsInit" // callback due to circular dependency The server isn't "ready" until @@ -71,14 +82,14 @@ function scheduleTasks(server: Server) { // function block. (async () => { try { - await taskManager!.schedule({ + await taskManager.schedule({ id: TASK_ID, taskType: TELEMETRY_TASK_TYPE, state: { byDate: {}, suggestionsByDate: {}, saved: {}, runs: 0 }, params: {}, }); } catch (e) { - server.log(['warning', 'telemetry'], `Error scheduling task, received ${e.message}`); + server.log(['debug', 'telemetry'], `Error scheduling task, received ${e.message}`); } })(); }); diff --git a/x-pack/legacy/plugins/maps/index.js b/x-pack/legacy/plugins/maps/index.js index 076fae1bb5882..3bb9d48741ab9 100644 --- a/x-pack/legacy/plugins/maps/index.js +++ b/x-pack/legacy/plugins/maps/index.js @@ -23,7 +23,8 @@ import _ from 'lodash'; export function maps(kibana) { return new kibana.Plugin({ - require: ['kibana', 'elasticsearch', 'xpack_main', 'tile_map', 'task_manager'], + // task_manager could be required, but is only used for telemetry + require: ['kibana', 'elasticsearch', 'xpack_main', 'tile_map'], id: APP_ID, configPrefix: 'xpack.maps', publicDir: resolve(__dirname, 'public'), diff --git a/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_usage_collector.js b/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_usage_collector.js index 5f6361a16aa00..c0ac5a781b796 100644 --- a/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_usage_collector.js +++ b/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_usage_collector.js @@ -9,7 +9,7 @@ import { TASK_ID, scheduleTask, registerMapsTelemetryTask } from './telemetry_ta export function initTelemetryCollection(server) { registerMapsTelemetryTask(server); - scheduleTask(server, server.plugins.task_manager); + scheduleTask(server); registerMapsUsageCollector(server); } @@ -21,6 +21,11 @@ async function isTaskManagerReady(server) { async function fetch(server) { let docs; const taskManager = server.plugins.task_manager; + + if (!taskManager) { + return null; + } + try { ({ docs } = await taskManager.fetch({ query: { diff --git a/x-pack/legacy/plugins/maps/server/maps_telemetry/telemetry_task.js b/x-pack/legacy/plugins/maps/server/maps_telemetry/telemetry_task.js index 521c5ae71e14b..3702bc8e29539 100644 --- a/x-pack/legacy/plugins/maps/server/maps_telemetry/telemetry_task.js +++ b/x-pack/legacy/plugins/maps/server/maps_telemetry/telemetry_task.js @@ -10,7 +10,14 @@ const TELEMETRY_TASK_TYPE = 'maps_telemetry'; export const TASK_ID = `Maps-${TELEMETRY_TASK_TYPE}`; -export function scheduleTask(server, taskManager) { +export function scheduleTask(server) { + const taskManager = server.plugins.task_manager; + + if (!taskManager) { + server.log(['debug', 'telemetry'], `Task manager is not available`); + return; + } + const { kbnServer } = server.plugins.xpack_main.status.plugin; kbnServer.afterPluginsInit(() => { @@ -36,6 +43,12 @@ export function scheduleTask(server, taskManager) { export function registerMapsTelemetryTask(server) { const taskManager = server.plugins.task_manager; + + if (!taskManager) { + server.log(['debug', 'telemetry'], `Task manager is not available`); + return; + } + taskManager.registerTaskDefinitions({ [TELEMETRY_TASK_TYPE]: { title: 'Maps telemetry fetch task', diff --git a/x-pack/legacy/plugins/oss_telemetry/index.js b/x-pack/legacy/plugins/oss_telemetry/index.js index 01bbd9359783a..eeee9e18f9112 100644 --- a/x-pack/legacy/plugins/oss_telemetry/index.js +++ b/x-pack/legacy/plugins/oss_telemetry/index.js @@ -11,7 +11,7 @@ import { PLUGIN_ID } from './constants'; export const ossTelemetry = (kibana) => { return new kibana.Plugin({ id: PLUGIN_ID, - require: ['elasticsearch', 'xpack_main', 'task_manager'], + require: ['elasticsearch', 'xpack_main'], configPrefix: 'xpack.oss_telemetry', init(server) { diff --git a/x-pack/legacy/plugins/oss_telemetry/server/lib/collectors/visualizations/get_usage_collector.ts b/x-pack/legacy/plugins/oss_telemetry/server/lib/collectors/visualizations/get_usage_collector.ts index 2bbecf99b97c3..63640c87f80a6 100644 --- a/x-pack/legacy/plugins/oss_telemetry/server/lib/collectors/visualizations/get_usage_collector.ts +++ b/x-pack/legacy/plugins/oss_telemetry/server/lib/collectors/visualizations/get_usage_collector.ts @@ -14,7 +14,11 @@ async function isTaskManagerReady(server: HapiServer) { } async function fetch(server: HapiServer) { - const taskManager = server.plugins.task_manager!; + const taskManager = server.plugins.task_manager; + + if (!taskManager) { + return null; + } let docs; try { diff --git a/x-pack/legacy/plugins/oss_telemetry/server/lib/tasks/index.ts b/x-pack/legacy/plugins/oss_telemetry/server/lib/tasks/index.ts index de3a17a79afb6..eaa8cc7405821 100644 --- a/x-pack/legacy/plugins/oss_telemetry/server/lib/tasks/index.ts +++ b/x-pack/legacy/plugins/oss_telemetry/server/lib/tasks/index.ts @@ -11,6 +11,11 @@ import { visualizationsTaskRunner } from './visualizations/task_runner'; export function registerTasks(server: HapiServer) { const taskManager = server.plugins.task_manager; + if (!taskManager) { + server.log(['debug', 'telemetry'], `Task manager is not available`); + return; + } + taskManager.registerTaskDefinitions({ [VIS_TELEMETRY_TASK]: { title: 'X-Pack telemetry calculator for Visualizations', @@ -43,7 +48,7 @@ export function scheduleTasks(server: HapiServer) { state: { stats: {}, runs: 0 }, }); } catch (e) { - server.log(['warning', 'telemetry'], `Error scheduling task, received ${e.message}`); + server.log(['debug', 'telemetry'], `Error scheduling task, received ${e.message}`); } })(); }); From 9da6c0705985a79b4c04aea501a8429da21841bc Mon Sep 17 00:00:00 2001 From: Brian Seeders Date: Fri, 25 Oct 2019 12:57:46 -0400 Subject: [PATCH 37/61] Re-add pipeline for flaky test runner job (#48781) * Revert "Revert "Add pipeline for flaky test runner job (#46740)"" This reverts commit 7d96a13fad5337f262743b51d5bdd6103d2c51a4. Also reconcile changes to Jenkinsfile since original revert happened * Fix param parsing and add missed change * Add missing variable --- .ci/Jenkinsfile_flaky | 113 ++++++ Jenkinsfile | 322 ++---------------- src/dev/ci_setup/setup_env.sh | 6 + src/dev/precommit_hook/casing_check_config.js | 3 +- ...enkins_build_kbn_tp_sample_panel_action.sh | 9 + test/scripts/jenkins_ci_group.sh | 5 +- vars/kibanaPipeline.groovy | 251 ++++++++++++++ vars/runbld.groovy | 11 + 8 files changed, 425 insertions(+), 295 deletions(-) create mode 100644 .ci/Jenkinsfile_flaky create mode 100755 test/scripts/jenkins_build_kbn_tp_sample_panel_action.sh create mode 100644 vars/kibanaPipeline.groovy create mode 100644 vars/runbld.groovy diff --git a/.ci/Jenkinsfile_flaky b/.ci/Jenkinsfile_flaky new file mode 100644 index 0000000000000..3f77243da2c1b --- /dev/null +++ b/.ci/Jenkinsfile_flaky @@ -0,0 +1,113 @@ +#!/bin/groovy + +library 'kibana-pipeline-library' +kibanaLibrary.load() + +// Looks like 'oss:ciGroup:1' or 'oss:firefoxSmoke' +def JOB_PARTS = params.CI_GROUP.split(':') +def IS_XPACK = JOB_PARTS[0] == 'xpack' +def JOB = JOB_PARTS[1] +def CI_GROUP = JOB_PARTS.size() > 2 ? JOB_PARTS[2] : '' + +def worker = getWorkerFromParams(IS_XPACK, JOB, CI_GROUP) + +def workerFailures = [] + +currentBuild.displayName += trunc(" ${params.GITHUB_OWNER}:${params.branch_specifier}", 24) +currentBuild.description = "${params.CI_GROUP}
Executions: ${params.NUMBER_EXECUTIONS}" + +// Note: If you increase agent count, it will execute NUMBER_EXECUTIONS per agent. It will not divide them up amongst the agents +// e.g. NUMBER_EXECUTIONS = 25, agentCount = 4 results in 100 total executions +def agentCount = 1 + +stage("Kibana Pipeline") { + timeout(time: 180, unit: 'MINUTES') { + timestamps { + ansiColor('xterm') { + def agents = [:] + for(def agentNumber = 1; agentNumber <= agentCount; agentNumber++) { + agents["agent-${agentNumber}"] = { + catchError { + kibanaPipeline.withWorkers('flaky-test-runner', { + if (!IS_XPACK) { + kibanaPipeline.buildOss() + if (CI_GROUP == '1') { + runbld "./test/scripts/jenkins_build_kbn_tp_sample_panel_action.sh" + } + } else { + kibanaPipeline.buildXpack() + } + }, getWorkerMap(agentNumber, params.NUMBER_EXECUTIONS.toInteger(), worker, workerFailures))() + } + } + } + + parallel(agents) + + currentBuild.description += ", Failures: ${workerFailures.size()}" + + if (workerFailures.size() > 0) { + print "There were ${workerFailures.size()} test suite failures." + print "The executions that failed were:" + print workerFailures.join("\n") + print "Please check 'Test Result' and 'Pipeline Steps' pages for more info" + } + } + } + } +} + +def getWorkerFromParams(isXpack, job, ciGroup) { + if (!isXpack) { + if (job == 'firefoxSmoke') { + return kibanaPipeline.getPostBuildWorker('firefoxSmoke', { runbld './test/scripts/jenkins_firefox_smoke.sh' }) + } else if(job == 'visualRegression') { + return kibanaPipeline.getPostBuildWorker('visualRegression', { runbld './test/scripts/jenkins_visual_regression.sh' }) + } else { + return kibanaPipeline.getOssCiGroupWorker(ciGroup) + } + } + + if (job == 'firefoxSmoke') { + return kibanaPipeline.getPostBuildWorker('xpack-firefoxSmoke', { runbld './test/scripts/jenkins_xpack_firefox_smoke.sh' }) + } else if(job == 'visualRegression') { + return kibanaPipeline.getPostBuildWorker('xpack-visualRegression', { runbld './test/scripts/jenkins_xpack_visual_regression.sh' }) + } else { + return kibanaPipeline.getXpackCiGroupWorker(ciGroup) + } +} + +def getWorkerMap(agentNumber, numberOfExecutions, worker, workerFailures, maxWorkers = 14) { + def workerMap = [:] + def numberOfWorkers = Math.min(numberOfExecutions, maxWorkers) + + for(def i = 1; i <= numberOfWorkers; i++) { + def workerExecutions = numberOfExecutions/numberOfWorkers + (i <= numberOfExecutions%numberOfWorkers ? 1 : 0) + + workerMap["agent-${agentNumber}-worker-${i}"] = { workerNumber -> + for(def j = 0; j < workerExecutions; j++) { + print "Execute agent-${agentNumber} worker-${workerNumber}: ${j}" + withEnv(["JOB=agent-${agentNumber}-worker-${workerNumber}-${j}"]) { + catchError { + try { + worker(workerNumber) + } catch (ex) { + workerFailures << "agent-${agentNumber} worker-${workerNumber}-${j}" + throw ex + } + } + } + } + } + } + + return workerMap +} + +def trunc(str, length) { + if (str.size() >= length) { + return str.take(length) + "..." + } + + return str; +} diff --git a/Jenkinsfile b/Jenkinsfile index fca814b265295..4820de9876737 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,6 +1,7 @@ #!/bin/groovy library 'kibana-pipeline-library' +kibanaLibrary.load() stage("Kibana Pipeline") { // This stage is just here to help the BlueOcean UI a little bit timeout(time: 180, unit: 'MINUTES') { @@ -8,301 +9,42 @@ stage("Kibana Pipeline") { // This stage is just here to help the BlueOcean UI a ansiColor('xterm') { catchError { parallel([ - 'kibana-intake-agent': legacyJobRunner('kibana-intake'), - 'x-pack-intake-agent': legacyJobRunner('x-pack-intake'), - 'kibana-oss-agent': withWorkers('kibana-oss-tests', { buildOss() }, [ - 'oss-ciGroup1': getOssCiGroupWorker(1), - 'oss-ciGroup2': getOssCiGroupWorker(2), - 'oss-ciGroup3': getOssCiGroupWorker(3), - 'oss-ciGroup4': getOssCiGroupWorker(4), - 'oss-ciGroup5': getOssCiGroupWorker(5), - 'oss-ciGroup6': getOssCiGroupWorker(6), - 'oss-ciGroup7': getOssCiGroupWorker(7), - 'oss-ciGroup8': getOssCiGroupWorker(8), - 'oss-ciGroup9': getOssCiGroupWorker(9), - 'oss-ciGroup10': getOssCiGroupWorker(10), - 'oss-ciGroup11': getOssCiGroupWorker(11), - 'oss-ciGroup12': getOssCiGroupWorker(12), - 'oss-firefoxSmoke': getPostBuildWorker('firefoxSmoke', { runbld './test/scripts/jenkins_firefox_smoke.sh' }), - // 'oss-visualRegression': getPostBuildWorker('visualRegression', { runbld './test/scripts/jenkins_visual_regression.sh' }), + 'kibana-intake-agent': kibanaPipeline.legacyJobRunner('kibana-intake'), + 'x-pack-intake-agent': kibanaPipeline.legacyJobRunner('x-pack-intake'), + 'kibana-oss-agent': kibanaPipeline.withWorkers('kibana-oss-tests', { kibanaPipeline.buildOss() }, [ + 'oss-ciGroup1': kibanaPipeline.getOssCiGroupWorker(1), + 'oss-ciGroup2': kibanaPipeline.getOssCiGroupWorker(2), + 'oss-ciGroup3': kibanaPipeline.getOssCiGroupWorker(3), + 'oss-ciGroup4': kibanaPipeline.getOssCiGroupWorker(4), + 'oss-ciGroup5': kibanaPipeline.getOssCiGroupWorker(5), + 'oss-ciGroup6': kibanaPipeline.getOssCiGroupWorker(6), + 'oss-ciGroup7': kibanaPipeline.getOssCiGroupWorker(7), + 'oss-ciGroup8': kibanaPipeline.getOssCiGroupWorker(8), + 'oss-ciGroup9': kibanaPipeline.getOssCiGroupWorker(9), + '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-visualRegression': kibanaPipeline.getPostBuildWorker('visualRegression', { runbld './test/scripts/jenkins_visual_regression.sh' }), ]), - 'kibana-xpack-agent': withWorkers('kibana-xpack-tests', { buildXpack() }, [ - 'xpack-ciGroup1': getXpackCiGroupWorker(1), - 'xpack-ciGroup2': getXpackCiGroupWorker(2), - 'xpack-ciGroup3': getXpackCiGroupWorker(3), - 'xpack-ciGroup4': getXpackCiGroupWorker(4), - 'xpack-ciGroup5': getXpackCiGroupWorker(5), - 'xpack-ciGroup6': getXpackCiGroupWorker(6), - 'xpack-ciGroup7': getXpackCiGroupWorker(7), - 'xpack-ciGroup8': getXpackCiGroupWorker(8), - 'xpack-ciGroup9': getXpackCiGroupWorker(9), - 'xpack-ciGroup10': getXpackCiGroupWorker(10), - 'xpack-firefoxSmoke': getPostBuildWorker('xpack-firefoxSmoke', { runbld './test/scripts/jenkins_xpack_firefox_smoke.sh' }), - // 'xpack-visualRegression': getPostBuildWorker('xpack-visualRegression', { runbld './test/scripts/jenkins_xpack_visual_regression.sh' }), + 'kibana-xpack-agent': kibanaPipeline.withWorkers('kibana-xpack-tests', { kibanaPipeline.buildXpack() }, [ + 'xpack-ciGroup1': kibanaPipeline.getXpackCiGroupWorker(1), + 'xpack-ciGroup2': kibanaPipeline.getXpackCiGroupWorker(2), + 'xpack-ciGroup3': kibanaPipeline.getXpackCiGroupWorker(3), + 'xpack-ciGroup4': kibanaPipeline.getXpackCiGroupWorker(4), + 'xpack-ciGroup5': kibanaPipeline.getXpackCiGroupWorker(5), + 'xpack-ciGroup6': kibanaPipeline.getXpackCiGroupWorker(6), + 'xpack-ciGroup7': kibanaPipeline.getXpackCiGroupWorker(7), + '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-visualRegression': kibanaPipeline.getPostBuildWorker('xpack-visualRegression', { runbld './test/scripts/jenkins_xpack_visual_regression.sh' }), ]), ]) } - node('flyweight') { - // If the build doesn't have a result set by this point, there haven't been any errors and it can be marked as a success - // The e-mail plugin for the infra e-mail depends upon this being set - currentBuild.result = currentBuild.result ?: 'SUCCESS' - - sendMail() - } + kibanaPipeline.sendMail() } } } } - -def withWorkers(name, preWorkerClosure = {}, workerClosures = [:]) { - return { - jobRunner('tests-xl', true) { - try { - doSetup() - preWorkerClosure() - - def nextWorker = 1 - def worker = { workerClosure -> - def workerNumber = nextWorker - nextWorker++ - - return { - workerClosure(workerNumber) - } - } - - def workers = [:] - workerClosures.each { workerName, workerClosure -> - workers[workerName] = worker(workerClosure) - } - - parallel(workers) - } finally { - catchError { - uploadAllGcsArtifacts(name) - } - - catchError { - runbldJunit() - } - - catchError { - publishJunit() - } - - catchError { - runErrorReporter() - } - } - } - } -} - -def getPostBuildWorker(name, closure) { - return { workerNumber -> - def kibanaPort = "61${workerNumber}1" - def esPort = "61${workerNumber}2" - def esTransportPort = "61${workerNumber}3" - - withEnv([ - "CI_WORKER_NUMBER=${workerNumber}", - "TEST_KIBANA_HOST=localhost", - "TEST_KIBANA_PORT=${kibanaPort}", - "TEST_KIBANA_URL=http://elastic:changeme@localhost:${kibanaPort}", - "TEST_ES_URL=http://elastic:changeme@localhost:${esPort}", - "TEST_ES_TRANSPORT_PORT=${esTransportPort}", - "IS_PIPELINE_JOB=1", - ]) { - closure() - } - } -} - -def getOssCiGroupWorker(ciGroup) { - return getPostBuildWorker("ciGroup" + ciGroup, { - withEnv([ - "CI_GROUP=${ciGroup}", - "JOB=kibana-ciGroup${ciGroup}", - ]) { - runbld "./test/scripts/jenkins_ci_group.sh" - } - }) -} - -def getXpackCiGroupWorker(ciGroup) { - return getPostBuildWorker("xpack-ciGroup" + ciGroup, { - withEnv([ - "CI_GROUP=${ciGroup}", - "JOB=xpack-kibana-ciGroup${ciGroup}", - ]) { - runbld "./test/scripts/jenkins_xpack_ci_group.sh" - } - }) -} - -def legacyJobRunner(name) { - return { - parallel([ - "${name}": { - withEnv([ - "JOB=${name}", - ]) { - jobRunner('linux && immutable', false) { - try { - runbld('.ci/run.sh', true) - } finally { - catchError { - uploadAllGcsArtifacts(name) - } - catchError { - publishJunit() - } - catchError { - runErrorReporter() - } - } - } - } - } - ]) - } -} - -def jobRunner(label, useRamDisk, closure) { - node(label) { - if (useRamDisk) { - // 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}' - """ - } - } - - def scmVars = checkout scm - - withEnv([ - "CI=true", - "HOME=${env.JENKINS_HOME}", - "PR_SOURCE_BRANCH=${env.ghprbSourceBranch ?: ''}", - "PR_TARGET_BRANCH=${env.ghprbTargetBranch ?: ''}", - "PR_AUTHOR=${env.ghprbPullAuthorLogin ?: ''}", - "TEST_BROWSER_HEADLESS=1", - "GIT_BRANCH=${scmVars.GIT_BRANCH}", - ]) { - withCredentials([ - string(credentialsId: 'vault-addr', variable: 'VAULT_ADDR'), - string(credentialsId: 'vault-role-id', variable: 'VAULT_ROLE_ID'), - string(credentialsId: 'vault-secret-id', variable: 'VAULT_SECRET_ID'), - ]) { - // scm is configured to check out to the ./kibana directory - dir('kibana') { - closure() - } - } - } - } -} - -// TODO what should happen if GCS, Junit, or email publishing fails? Unstable build? Failed build? - -def uploadGcsArtifact(workerName, pattern) { - def storageLocation = "gs://kibana-ci-artifacts/jobs/${env.JOB_NAME}/${BUILD_NUMBER}/${workerName}" // TODO - // def storageLocation = "gs://kibana-pipeline-testing/jobs/pipeline-test/${BUILD_NUMBER}/${workerName}" - - googleStorageUpload( - credentialsId: 'kibana-ci-gcs-plugin', - bucket: storageLocation, - pattern: pattern, - sharedPublicly: true, - showInline: true, - ) -} - -def uploadAllGcsArtifacts(workerName) { - def ARTIFACT_PATTERNS = [ - 'target/kibana-*', - 'target/junit/**/*', - 'test/**/screenshots/**/*.png', - 'test/functional/failure_debug/html/*.html', - 'x-pack/test/**/screenshots/**/*.png', - 'x-pack/test/functional/failure_debug/html/*.html', - 'x-pack/test/functional/apps/reporting/reports/session/*.pdf', - ] - - ARTIFACT_PATTERNS.each { pattern -> - uploadGcsArtifact(workerName, pattern) - } -} - -def publishJunit() { - junit(testResults: 'target/junit/**/*.xml', allowEmptyResults: true, keepLongStdio: true) -} - -def sendMail() { - sendInfraMail() - sendKibanaMail() -} - -def sendInfraMail() { - catchError { - step([ - $class: 'Mailer', - notifyEveryUnstableBuild: true, - recipients: 'infra-root+build@elastic.co', - sendToIndividuals: false - ]) - } -} - -def sendKibanaMail() { - catchError { - def buildStatus = buildUtils.getBuildStatus() - - if(params.NOTIFY_ON_FAILURE && buildStatus != 'SUCCESS' && buildStatus != 'ABORTED') { - emailext( - to: 'build-kibana@elastic.co', - subject: "${env.JOB_NAME} - Build # ${env.BUILD_NUMBER} - ${buildStatus}", - body: '${SCRIPT,template="groovy-html.template"}', - mimeType: 'text/html', - ) - } - } -} - -def runbld(script, enableJunitProcessing = false) { - def extraConfig = enableJunitProcessing ? "" : "--config ${env.WORKSPACE}/kibana/.ci/runbld_no_junit.yml" - - sh "/usr/local/bin/runbld -d '${pwd()}' ${extraConfig} ${script}" -} - -def runbldJunit() { - sh "/usr/local/bin/runbld -d '${pwd()}' ${env.WORKSPACE}/kibana/test/scripts/jenkins_runbld_junit.sh" -} - -def bash(script) { - sh "#!/bin/bash\n${script}" -} - -def doSetup() { - runbld "./test/scripts/jenkins_setup.sh" -} - -def buildOss() { - runbld "./test/scripts/jenkins_build_kibana.sh" -} - -def buildXpack() { - runbld "./test/scripts/jenkins_xpack_build_kibana.sh" -} - -def runErrorReporter() { - bash """ - source src/dev/ci_setup/setup_env.sh - node scripts/report_failed_tests - """ -} diff --git a/src/dev/ci_setup/setup_env.sh b/src/dev/ci_setup/setup_env.sh index 3b239bd3ff731..805b77365e624 100644 --- a/src/dev/ci_setup/setup_env.sh +++ b/src/dev/ci_setup/setup_env.sh @@ -2,6 +2,10 @@ set -e +if [[ "$CI_ENV_SETUP" ]]; then + return 0 +fi + installNode=$1 dir="$(pwd)" @@ -152,3 +156,5 @@ if [[ -d "$ES_DIR" && -f "$ES_JAVA_PROP_PATH" ]]; then echo "Setting JAVA_HOME=$HOME/.java/$ES_BUILD_JAVA" export JAVA_HOME=$HOME/.java/$ES_BUILD_JAVA fi + +export CI_ENV_SETUP=true diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index 9829de2fd3920..edd818e1b42de 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -43,8 +43,9 @@ export const IGNORE_FILE_GLOBS = [ 'x-pack/docs/**/*', 'src/legacy/ui/public/assets/fonts/**/*', 'packages/kbn-utility-types/test-d/**/*', - 'Jenkinsfile', + '**/Jenkinsfile*', 'Dockerfile*', + 'vars/*', // Files in this directory must match a pre-determined name in some cases. 'x-pack/legacy/plugins/canvas/.storybook/*', diff --git a/test/scripts/jenkins_build_kbn_tp_sample_panel_action.sh b/test/scripts/jenkins_build_kbn_tp_sample_panel_action.sh new file mode 100755 index 0000000000000..4b16e3b32fefd --- /dev/null +++ b/test/scripts/jenkins_build_kbn_tp_sample_panel_action.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +source src/dev/ci_setup/setup_env.sh + +cd test/plugin_functional/plugins/kbn_tp_sample_panel_action; +if [[ ! -d "target" ]]; then + checks-reporter-with-killswitch "Build kbn_tp_sample_panel_action" yarn build; +fi +cd -; diff --git a/test/scripts/jenkins_ci_group.sh b/test/scripts/jenkins_ci_group.sh index 6deddd5a59152..274cca695b535 100755 --- a/test/scripts/jenkins_ci_group.sh +++ b/test/scripts/jenkins_ci_group.sh @@ -22,10 +22,7 @@ fi checks-reporter-with-killswitch "Functional tests / Group ${CI_GROUP}" yarn run grunt "run:functionalTests_ciGroup${CI_GROUP}"; if [ "$CI_GROUP" == "1" ]; then - # build kbn_tp_sample_panel_action - cd test/plugin_functional/plugins/kbn_tp_sample_panel_action; - checks-reporter-with-killswitch "Build kbn_tp_sample_panel_action" yarn build; - cd -; + source test/scripts/jenkins_build_kbn_tp_sample_panel_action.sh yarn run grunt run:pluginFunctionalTestsRelease --from=source; yarn run grunt run:interpreterFunctionalTestsRelease; fi diff --git a/vars/kibanaPipeline.groovy b/vars/kibanaPipeline.groovy new file mode 100644 index 0000000000000..e8d7cc03edad0 --- /dev/null +++ b/vars/kibanaPipeline.groovy @@ -0,0 +1,251 @@ +def withWorkers(name, preWorkerClosure = {}, workerClosures = [:]) { + return { + jobRunner('tests-xl', true) { + try { + doSetup() + preWorkerClosure() + + def nextWorker = 1 + def worker = { workerClosure -> + def workerNumber = nextWorker + nextWorker++ + + return { + workerClosure(workerNumber) + } + } + + def workers = [:] + workerClosures.each { workerName, workerClosure -> + workers[workerName] = worker(workerClosure) + } + + parallel(workers) + } finally { + catchError { + uploadAllGcsArtifacts(name) + } + + catchError { + runbld.junit() + } + + catchError { + publishJunit() + } + + catchError { + runErrorReporter() + } + } + } + } +} + +def getPostBuildWorker(name, closure) { + return { workerNumber -> + def kibanaPort = "61${workerNumber}1" + def esPort = "61${workerNumber}2" + def esTransportPort = "61${workerNumber}3" + + withEnv([ + "CI_WORKER_NUMBER=${workerNumber}", + "TEST_KIBANA_HOST=localhost", + "TEST_KIBANA_PORT=${kibanaPort}", + "TEST_KIBANA_URL=http://elastic:changeme@localhost:${kibanaPort}", + "TEST_ES_URL=http://elastic:changeme@localhost:${esPort}", + "TEST_ES_TRANSPORT_PORT=${esTransportPort}", + "IS_PIPELINE_JOB=1", + ]) { + closure() + } + } +} + +def getOssCiGroupWorker(ciGroup) { + return getPostBuildWorker("ciGroup" + ciGroup, { + withEnv([ + "CI_GROUP=${ciGroup}", + "JOB=kibana-ciGroup${ciGroup}", + ]) { + runbld "./test/scripts/jenkins_ci_group.sh" + } + }) +} + +def getXpackCiGroupWorker(ciGroup) { + return getPostBuildWorker("xpack-ciGroup" + ciGroup, { + withEnv([ + "CI_GROUP=${ciGroup}", + "JOB=xpack-kibana-ciGroup${ciGroup}", + ]) { + runbld "./test/scripts/jenkins_xpack_ci_group.sh" + } + }) +} + +def legacyJobRunner(name) { + return { + parallel([ + "${name}": { + withEnv([ + "JOB=${name}", + ]) { + jobRunner('linux && immutable', false) { + try { + runbld('.ci/run.sh', true) + } finally { + catchError { + uploadAllGcsArtifacts(name) + } + catchError { + publishJunit() + } + catchError { + runErrorReporter() + } + } + } + } + } + ]) + } +} + +def jobRunner(label, useRamDisk, closure) { + node(label) { + if (useRamDisk) { + // 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}' + """ + } + } + + def scmVars = checkout scm + + withEnv([ + "CI=true", + "HOME=${env.JENKINS_HOME}", + "PR_SOURCE_BRANCH=${env.ghprbSourceBranch ?: ''}", + "PR_TARGET_BRANCH=${env.ghprbTargetBranch ?: ''}", + "PR_AUTHOR=${env.ghprbPullAuthorLogin ?: ''}", + "TEST_BROWSER_HEADLESS=1", + "GIT_BRANCH=${scmVars.GIT_BRANCH}", + ]) { + withCredentials([ + string(credentialsId: 'vault-addr', variable: 'VAULT_ADDR'), + string(credentialsId: 'vault-role-id', variable: 'VAULT_ROLE_ID'), + string(credentialsId: 'vault-secret-id', variable: 'VAULT_SECRET_ID'), + ]) { + // scm is configured to check out to the ./kibana directory + dir('kibana') { + closure() + } + } + } + } +} + +// TODO what should happen if GCS, Junit, or email publishing fails? Unstable build? Failed build? + +def uploadGcsArtifact(workerName, pattern) { + def storageLocation = "gs://kibana-ci-artifacts/jobs/${env.JOB_NAME}/${BUILD_NUMBER}/${workerName}" // TODO + + googleStorageUpload( + credentialsId: 'kibana-ci-gcs-plugin', + bucket: storageLocation, + pattern: pattern, + sharedPublicly: true, + showInline: true, + ) +} + +def uploadAllGcsArtifacts(workerName) { + def ARTIFACT_PATTERNS = [ + 'target/kibana-*', + 'target/junit/**/*', + 'test/**/screenshots/**/*.png', + 'test/functional/failure_debug/html/*.html', + 'x-pack/test/**/screenshots/**/*.png', + 'x-pack/test/functional/failure_debug/html/*.html', + 'x-pack/test/functional/apps/reporting/reports/session/*.pdf', + ] + + ARTIFACT_PATTERNS.each { pattern -> + uploadGcsArtifact(workerName, pattern) + } +} + +def publishJunit() { + junit(testResults: 'target/junit/**/*.xml', allowEmptyResults: true, keepLongStdio: true) +} + +def sendMail() { + // If the build doesn't have a result set by this point, there haven't been any errors and it can be marked as a success + // The e-mail plugin for the infra e-mail depends upon this being set + currentBuild.result = currentBuild.result ?: 'SUCCESS' + + def buildStatus = buildUtils.getBuildStatus() + if (buildStatus != 'SUCCESS' && buildStatus != 'ABORTED') { + node('flyweight') { + sendInfraMail() + sendKibanaMail() + } + } +} + +def sendInfraMail() { + catchError { + step([ + $class: 'Mailer', + notifyEveryUnstableBuild: true, + recipients: 'infra-root+build@elastic.co', + sendToIndividuals: false + ]) + } +} + +def sendKibanaMail() { + catchError { + def buildStatus = buildUtils.getBuildStatus() + if(params.NOTIFY_ON_FAILURE && buildStatus != 'SUCCESS' && buildStatus != 'ABORTED') { + emailext( + to: 'build-kibana@elastic.co', + subject: "${env.JOB_NAME} - Build # ${env.BUILD_NUMBER} - ${buildStatus}", + body: '${SCRIPT,template="groovy-html.template"}', + mimeType: 'text/html', + ) + } + } +} + +def bash(script) { + sh "#!/bin/bash\n${script}" +} + +def doSetup() { + runbld "./test/scripts/jenkins_setup.sh" +} + +def buildOss() { + runbld "./test/scripts/jenkins_build_kibana.sh" +} + +def buildXpack() { + runbld "./test/scripts/jenkins_xpack_build_kibana.sh" +} + +def runErrorReporter() { + bash """ + source src/dev/ci_setup/setup_env.sh + node scripts/report_failed_tests + """ +} + +return this diff --git a/vars/runbld.groovy b/vars/runbld.groovy new file mode 100644 index 0000000000000..501e2421ca65b --- /dev/null +++ b/vars/runbld.groovy @@ -0,0 +1,11 @@ +def call(script, enableJunitProcessing = false) { + def extraConfig = enableJunitProcessing ? "" : "--config ${env.WORKSPACE}/kibana/.ci/runbld_no_junit.yml" + + sh "/usr/local/bin/runbld -d '${pwd()}' ${extraConfig} ${script}" +} + +def junit() { + sh "/usr/local/bin/runbld -d '${pwd()}' ${env.WORKSPACE}/kibana/test/scripts/jenkins_runbld_junit.sh" +} + +return this From a4d2638d48e72b17443d96827b9e69664ce2e16e Mon Sep 17 00:00:00 2001 From: Tim Schnell Date: Fri, 25 Oct 2019 12:27:11 -0500 Subject: [PATCH 38/61] [skip ci] Function Reference Docs Update (#48791) * setting up function reference pattern * adding functions A-F * grammar fixes * Apply suggestions from code review Co-Authored-By: Catherine Liu * more review updates --- .../canvas/canvas-function-reference.asciidoc | 568 ++++++++++++++++++ 1 file changed, 568 insertions(+) diff --git a/docs/canvas/canvas-function-reference.asciidoc b/docs/canvas/canvas-function-reference.asciidoc index df4b17e905772..2b437728b2d01 100644 --- a/docs/canvas/canvas-function-reference.asciidoc +++ b/docs/canvas/canvas-function-reference.asciidoc @@ -25,6 +25,32 @@ A † denotes an argument can be passed multiple times. Returns `true` if all of the conditions are met. See also <>. +*Expression syntax* +[source,js] +---- +all {neq “foo”} {neq “bar”} {neq “fizz”} +all condition={gt 10} condition={lt 20} +---- + +*Code example* +[source,text] +---- +filters +| demodata +| math "mean(percent_uptime)" +| formatnumber "0.0%" +| metric "Average uptime" + metricFont={ + font size=48 family="'Open Sans', Helvetica, Arial, sans-serif" + color={ + if {all {gte 0} {lt 0.8}} then="red" else="green" + } + align="center" lHeight=48 + } +| render +---- +This sets the color of the metric text to `”red”` if the context passed into `metric` is greater than or equal to 0 and less than 0.8. Otherwise, the color is set to `"green"`. + *Accepts:* `null` [cols="3*^<"] @@ -47,6 +73,24 @@ Alias: `condition` Converts between core types, including `string`, `number`, `null`, `boolean`, and `date`, and renames columns. See also <> and <>. +*Expression syntax* +[source,js] +---- +alterColumn “cost” type=”string” +alterColumn column=”@timestamp” name=”foo” +---- + +*Code example* +[source,text] +---- +filters +| demodata +| alterColumn “time” name=”time_in_ms” type=”number” +| table +| render +---- +This renames the `time` column to `time_in_ms` and converts the type of the column’s values from `date` to `number`. + *Accepts:* `datatable` [cols="3*^<"] @@ -77,6 +121,27 @@ Alias: `column` Returns `true` if at least one of the conditions is met. See also <>. +*Expression syntax* +[source,js] +---- +any {eq “foo”} {eq “bar”} {eq “fizz”} +any condition={lte 10} condition={gt 30} +---- + +*Code example* +[source,text] +---- +filters +| demodata +| filterrows { + getCell "project" | any {eq "elasticsearch"} {eq "kibana"} {eq "x-pack"} + } +| pointseries color="project" size="max(price)" +| pie +| render +---- +This filters out any rows that don’t contain `“elasticsearch”`, `“kibana”` or `“x-pack”` in the `project` field. + *Accepts:* `null` [cols="3*^<"] @@ -99,6 +164,28 @@ Alias: `condition` Creates a `datatable` with a single value. See also <>. +*Expression syntax* +[source,js] +---- +as +as “foo” +as name=”bar” +---- + +*Code example* +[source,text] +---- +filters +| demodata +| ply by="project" fn={math "count(username)" | as "num_users"} fn={math "mean(price)" | as "price"} +| pointseries x="project" y="num_users" size="price" color="project" +| plot +| render +---- +`as` casts any primitive value (`string`, `number`, `date`, `null`) into a `datatable` with a single row and a single column with the given name (or defaults to `"value"` if no name is provided). This is useful when piping a primitive value into a function that only takes `datatable` as an input. + +In the example above, `ply` expects each `fn` subexpression to return a `datatable` in order to merge the results of each `fn` back into a `datatable`, but using a `math` aggregation in the subexpressions returns a single `math` value, which is then cast into a `datatable` using `as`. + *Accepts:* `string`, `boolean`, `number`, `null` [cols="3*^<"] @@ -123,6 +210,21 @@ Default: `"value"` Retrieves Canvas workpad asset objects to provide as argument values. Usually images. +*Expression syntax* +[source,js] +---- +asset "asset-52f14f2b-fee6-4072-92e8-cd2642665d02" +asset id="asset-498f7429-4d56-42a2-a7e4-8bf08d98d114" +---- + +*Code example* +[source,text] +---- +image dataurl={asset "asset-c661a7cc-11be-45a1-a401-d7592ea7917a"} mode="contain" +| render +---- +The image asset stored with the ID `“asset-c661a7cc-11be-45a1-a401-d7592ea7917a”` is passed into the `dataurl` argument of the `image` function to display the stored asset. + *Accepts:* `null` [cols="3*^<"] @@ -145,6 +247,27 @@ Alias: `id` Configures the axis of a visualization. Only used with <>. +*Expression syntax* +[source,js] +---- +axisConfig show=false +axisConfig position=”right” min=0 max=10 tickSize=1 +---- + +*Code example* +[source,text] +---- +filters +| demodata +| pointseries x="size(cost)" y="project" color="project" +| plot defaultStyle={seriesStyle bars=0.75 horizontalBars=true} + legend=false + xaxis={axisConfig position="top" min=0 max=400 tickSize=100} + yaxis={axisConfig position="right"} +| render +---- +This sets the `x-axis` to display on the top of the chart and sets the range of values to `0-400` with ticks displayed at `100` intervals. The `y-axis` is configured to display on the `right`. + *Accepts:* `null` [cols="3*^<"] @@ -188,6 +311,34 @@ Default: `true` Builds a `case` (including a condition/result) to pass to the <> function. +*Expression syntax* +[source,js] +---- +case 0 then=”red” +case when=5 then=”yellow” +case if={lte 50} then=”green” +---- + +*Code example* +[source,text] +---- +math "random()" +| progress shape="gauge" label={formatnumber "0%"} + font={font size=24 family="'Open Sans', Helvetica, Arial, sans-serif" align="center" + color={ + switch {case if={lte 0.5} then="green"} + {case if={all {gt 0.5} {lte 0.75}} then="orange"} + default="red" + }} + valueColor={ + switch {case if={lte 0.5} then="green"} + {case if={all {gt 0.5} {lte 0.75}} then="orange"} + default="red" + } +| render +---- +This sets the color of the progress indicator and the color of the label to `"green"` if the value is less than or equal to `0.5`, `"orange"` if the value is greater than `0.5` and less than or equal to `0.75`, and `"red"` if `none` of the case conditions are met. + *Accepts:* `any` [cols="3*^<"] @@ -229,6 +380,24 @@ Clears the _context_, and returns `null`. Includes or excludes columns from a data table. If you specify both, this will exclude first. +*Expression syntax* +[source,js] +---- +columns include=”@timestamp, projects, cost” +columns exclude=”username, country, age” +---- + +*Code example* +[source,text] +---- +filters +| demodata +| columns include="price, cost, state, project" +| table +| render +---- +This only keeps the `price`, `cost`, `state`, and `project` columns from the `demodata` data source and removes all other columns. + *Accepts:* `datatable` [cols="3*^<"] @@ -257,6 +426,31 @@ Compares the _context_ to specified value to determine `true` or `false`. Usually used in combination with <> or <>. This only works with primitive types, such as `number`, `string`, and `boolean`. See also <>, <>, <>, <>, <>, and <>. +*Expression syntax* +[source,js] +---- +compare “neq” to=”elasticsearch” +compare op=”lte” to=100 +---- + +*Code example* +[source,text] +---- +filters +| demodata +| mapColumn project + fn=${getCell project | + switch + {case if={compare eq to=kibana} then=kibana} + {case if={compare eq to=elasticsearch} then=elasticsearch} + default="other" + } +| pointseries size="size(cost)" color="project" +| pie +| render +---- +This maps all `project` values that aren’t `“kibana”` and `“elasticsearch”` to `“other”`. Alternatively, you can use the individual comparator functions instead of compare. See <>, <>, <>, <>, <>, and <>. + *Accepts:* `string`, `number`, `boolean`, `null` [cols="3*^<"] @@ -287,6 +481,35 @@ Alias: `this`, `b` Creates an object used for styling an element's container, including background, border, and opacity. +*Expression syntax* +[source,js] +---- +containerStyle backgroundColor=”red”’ +containerStyle borderRadius=”50px” +containerStyle border=”1px solid black” +containerStyle padding=”5px” +containerStyle opacity=”0.5” +containerStyle overflow=”hidden” +containerStyle backgroundImage={asset id=asset-f40d2292-cf9e-4f2c-8c6f-a504a25e949c} + backgroundRepeat="no-repeat" + backgroundSize="cover" +---- + +*Code example* +[source,text] +---- +shape "star" fill="#E61D35" maintainAspect=true +| render + containerStyle={ + containerStyle backgroundColor="#F8D546" + borderRadius="200px" + border="4px solid #05509F" + padding="0px" + opacity="0.9" + overflow="hidden" + } +---- + *Accepts:* `null` [cols="3*^<"] @@ -346,6 +569,22 @@ Default: `"hidden"` Returns whatever you pass into it. This can be useful when you need to use the _context_ as an argument to a function as a sub-expression. +*Expression syntax* +[source,js] +---- +context +---- + +*Code example* +[source,text] +---- +date +| formatdate "LLLL" +| markdown "Last updated: " {context} +| render +---- +Using the `context` function allows us to pass the output, or _context_, of the previous function as a value to an argument in the next function. Here we get the formatted date string from the previous function and pass it as `content` for the markdown element. + *Accepts:* `any` *Returns:* Original _context_ @@ -356,6 +595,26 @@ _context_ as an argument to a function as a sub-expression. Creates a `datatable` from CSV input. +*Expression syntax* +[source,js] +---- +csv “fruit, stock + kiwi, 10 + Banana, 5” +---- + +*Code example* +[source,text] +---- +csv "fruit,stock + kiwi,10 + banana,5" +| pointseries color=fruit size=stock +| pie +| render +---- +This is useful for quickly mocking data. + *Accepts:* `null` [cols="3*^<"] @@ -390,6 +649,30 @@ Alias: `data` Returns the current time, or a time parsed from a `string`, as milliseconds since epoch. +*Expression syntax* +[source,js] +---- +date +date value=1558735195 +date “2019-05-24T21:59:55+0000” +date “01/31/2019” format=”MM/DD/YYYY” +---- + +*Code example* +[source,text] +---- +date +| formatdate "LLL" +| markdown {context} + font={font family="Arial, sans-serif" size=30 align="left" + color="#000000" + weight="normal" + underline=false + italic=false} +| render +---- +Using `date` without passing any arguments will return the current date and time. + *Accepts:* `null` [cols="3*^<"] @@ -418,6 +701,24 @@ using the `format` argument. Must be an ISO8601 string or you must provide the f A mock data set that includes project CI times with usernames, countries, and run phases. +*Expression syntax* +[source,js] +---- +demodata +demodata “ci” +demodata type=”shirts” +---- + +*Code example* +[source,text] +---- +filters +| demodata +| table +| render +---- +`demodata` is a mock data set that you can use to start playing around in Canvas. + *Accepts:* `filter` [cols="3*^<"] @@ -442,6 +743,23 @@ Default: `"ci"` Executes multiple sub-expressions, then returns the original _context_. Use for running functions that produce an action or side effect without changing the original _context_. +*Expression syntax* +[source,js] +---- +do fn={something cool} +---- + +*Code example* +[source,text] +---- +filters +| demodata +| do fn={something cool} +| table +| render +---- +`do` should be used to invoke a function that produces as a side effect without changing the `context`. + *Accepts:* `any` [cols="3*^<"] @@ -464,6 +782,22 @@ Aliases: `expression`, `exp`, `fn`, `function` Configures a dropdown filter control element. +*Expression syntax* +[source,js] +---- +dropdownControl valueColumn=project filterColumn=project +dropdownControl valueColumn=agent filterColumn=agent.keyword filterGroup=group1 +---- + +*Code example* +[source,text] +---- +demodata +| dropdownControl valueColumn=project filterColumn=project +| render +---- +This creates a dropdown filter element. It requires a data source and uses the unique values from the given `valueColumn` (i.e. `project`) and applies the filter to the `project` column. Note: `filterColumn` should point to a keyword type field for Elasticsearch data sources. + *Accepts:* `datatable` [cols="3*^<"] @@ -496,6 +830,33 @@ Configures a dropdown filter control element. Returns whether the _context_ is equal to the argument. +*Expression syntax* +[source,js] +---- +eq true +eq null +eq 10 +eq “foo” +---- + +*Code example* +[source,text] +---- +filters +| demodata +| mapColumn project + fn=${getCell project | + switch + {case if={eq kibana} then=kibana} + {case if={eq elasticsearch} then=elasticsearch} + default="other" + } +| pointseries size="size(cost)" color="project" +| pie +| render +---- +This changes all values in the project column that don’t equal `“kibana”` or `“elasticsearch”` to `“other”`. + *Accepts:* `boolean`, `number`, `string`, `null` [cols="3*^<"] @@ -518,6 +879,28 @@ Alias: `value` Queries {es} for the number of hits matching the specified query. +*Expression syntax* +[source,js] +---- +escount index=”logstash-*” +escount "currency:\"EUR\"" index=”kibana_sample_data_ecommerce” +escount query="response:404" index=”kibana_sample_data_logs” +---- + +*Code example* +[source,text] +---- +filters +| escount "Cancelled:true" index="kibana_sample_data_flights" +| math "value" +| progress shape="semicircle" + label={formatnumber 0,0} + font={font size=24 family="'Open Sans', Helvetica, Arial, sans-serif" color="#000000" align=center} + max={filters | escount index="kibana_sample_data_flights"} +| render +---- +The first `escount` expression retrieves the number of flights that were cancelled. The second `escount` expression retrieves the total number of flights. + *Accepts:* `filter` [cols="3*^<"] @@ -549,6 +932,34 @@ Default: `_all` Queries {es} for raw documents. Specify the fields you want to retrieve, especially if you are asking for a lot of rows. +*Expression syntax* +[source,js] +---- +esdocs index=”logstash-*” +esdocs "currency:\"EUR\"" index=”kibana_sample_data_ecommerce” +esdocs query="response:404" index=”kibana_sample_data_logs” +esdocs index=”kibana_sample_data_flights” count=100 +esdocs index="kibana_sample_data_flights" sort="AvgTicketPrice, asc" +---- + +*Code example* +[source,text] +---- +filters +| esdocs index="kibana_sample_data_ecommerce" + fields="customer_gender, taxful_total_price, order_date" + sort="order_date, asc" + count=10000 +| mapColumn "order_date" + fn={getCell "order_date" | date {context} | rounddate "YYYY-MM-DD"} +| alterColumn "order_date" type="date" +| pointseries x="order_date" y="sum(taxful_total_price)" color="customer_gender" +| plot defaultStyle={seriesStyle lines=3} + palette={palette "#7ECAE3" "#003A4D" gradient=true} +| render +---- +This retrieves the latest 10000 documents data from the `kibana_sample_data_ecommerce` index sorted by `order_date` in ascending order and only requests the `customer_gender`, `taxful_total_price`, and `order_date` fields. + *Accepts:* `filter` [cols="3*^<"] @@ -593,6 +1004,21 @@ Default: `"_all"` Queries {es} using {es} SQL. +*Expression syntax* +[source,js] +---- +essql query=”SELECT * FROM \”logstash*\”” +essql “SELECT * FROM \”apm*\”” count=10000 +---- + +*Code example* +[source,text] +---- +filters +| essql query="SELECT Carrier, FlightDelayMin, AvgTicketPrice FROM \"kibana_sample_data_flights\"" +---- +This retrieves the `Carrier`, `FlightDelayMin`, and `AvgTicketPrice` fields from the “kibana_sample_data_flights” index. + *Accepts:* `filter` [cols="3*^<"] @@ -627,6 +1053,26 @@ Default: `UTC` Creates a filter that matches a given column to an exact value. +*Expression syntax* +[source,js] +---- +exactly “state” value=”running” +exactly “age” value=50 filterGroup=”group2” +exactly column=“project” value=”beats” +---- + +*Code example* +[source,text] +---- +filters +| exactly column=project value=elasticsearch +| demodata +| pointseries x=project y="mean(age)" +| plot defaultStyle={seriesStyle bars=1} +| render +---- +The `exactly` filter here is added to existing filters retrieved by the `filters` function and further filters down the data to only have `”elasticsearch”` data. The `exactly` filter only applies to this one specific element and will not affect other elements in the workpad. + *Accepts:* `filter` [cols="3*^<"] @@ -664,6 +1110,29 @@ capitalization. Filters rows in a `datatable` based on the return value of a sub-expression. +*Expression syntax* +[source,js] +---- +filterrows {getCell “project” | eq “kibana”} +filterrows fn={getCell “age” | gt 50} +---- + +*Code example* +[source,text] +---- +filters +| demodata +| filterrows {getCell "country" | any {eq "IN"} {eq "US"} {eq "CN"}} +| mapColumn "@timestamp" + fn={getCell "@timestamp" | rounddate "YYYY-MM"} +| alterColumn "@timestamp" type="date" +| pointseries x="@timestamp" y="mean(cost)" color="country" +| plot defaultStyle={seriesStyle points="2" lines="1"} + palette={palette "#01A4A4" "#CC6666" "#D0D102" "#616161" "#00A1CB" "#32742C" "#F18D05" "#113F8C" "#61AE24" "#D70060" gradient=false} +| render +---- +This uses `filterrows` to only keep data from India (`IN`), the United States (`US`), and China (`CN`). + *Accepts:* `datatable` [cols="3*^<"] @@ -688,6 +1157,34 @@ and a `false` value removes it. Aggregates element filters from the workpad for use elsewhere, usually a data source. +*Expression syntax* +[source,js] +---- +filters +filters group=”timefilter1” +filters group=”timefilter2” group=”dropdownfilter1” ungrouped=true +---- + +*Code example* +[source,text] +---- +filters group=group2 ungrouped=true +| demodata +| pointseries x="project" y="size(cost)" color="project" +| plot defaultStyle={seriesStyle bars=0.75} legend=false + font={ + font size=14 + family="'Open Sans', Helvetica, Arial, sans-serif" + align="left" + color="#FFFFFF" + weight="lighter" + underline=true + italic=true + } +| render +---- +`filters` sets the existing filters as context and accepts `group` parameter to create filter groups. + *Accepts:* `null` [cols="3*^<"] @@ -718,6 +1215,38 @@ Default: `false` Creates a font style. +*Expression syntax* +[source,js] +---- +font size=12 +font family=Arial +font align=middle +font color=pink +font weight=lighter +font underline=true +font italic=false +font lHeight=32 +---- + +*Code example* +[source,text] +---- +filters +| demodata +| pointseries x="project" y="size(cost)" color="project" +| plot defaultStyle={seriesStyle bars=0.75} legend=false + font={ + font size=14 + family="'Open Sans', Helvetica, Arial, sans-serif" + align="left" + color="#FFFFFF" + weight="lighter" + underline=true + italic=true + } +| render +---- + *Accepts:* `null` [cols="3*^<"] @@ -781,6 +1310,25 @@ Default: `"normal"` Formats an ISO8601 date string or a date in milliseconds since epoch using MomentJS. See https://momentjs.com/docs/#/displaying/. +*Expression syntax* +[source,js] +---- +formatdate format=”YYYY-MM-DD” +formatdate “MM/DD/YYYY” +---- + +*Code example* +[source,text] +---- +filters +| demodata +| mapColumn "time" fn={getCell time | formatdate "MMM 'YY"} +| pointseries x="time" y="sum(price)" color="state" +| plot defaultStyle={seriesStyle points=5} +| render +---- +This transforms the dates in the `time` field into strings that look like `“Jan ‘19”`, `“Feb ‘19”`, etc. using a MomentJS format. + *Accepts:* `number`, `string` [cols="3*^<"] @@ -803,6 +1351,26 @@ Alias: `format` Formats a `number` into a formatted `string` using NumeralJS. See http://numeraljs.com/#format. +*Expression syntax* +[source,js] +---- +formatnumber format=”$0,0.00” +fortmatnumber “0.0a” +---- + +*Code example* +[source,text] +---- +filters +| demodata +| math "mean(percent_uptime)" +| progress shape="gauge" + label={formatnumber "0%"} + font={font size=24 family="'Open Sans', Helvetica, Arial, sans-serif" color="#000000" align="center"} +| render +---- +The `formatnumber` subexpression receives the same `context` as the `progress` function, which is the output of the `math` function. It formats the value into a percentage. + *Accepts:* `number` [cols="3*^<"] From 467dfcc577a8c1d71f690748df19a65fe888232c Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Fri, 25 Oct 2019 18:37:34 +0100 Subject: [PATCH 39/61] [ML] Fixing advanced detector field selects enablement (#49348) --- .../advanced_detector_modal.tsx | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_detector_modal/advanced_detector_modal.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_detector_modal/advanced_detector_modal.tsx index 6ddfdb22feda8..b9e9df77d35e3 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_detector_modal/advanced_detector_modal.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_detector_modal/advanced_detector_modal.tsx @@ -83,7 +83,7 @@ export const AdvancedDetectorModal: FC = ({ createExcludeFrequentOption(detector.excludeFrequent) ); const [descriptionOption, setDescriptionOption] = useState(detector.description || ''); - const [fieldsEnabled, setFieldsEnabled] = useState(true); + const [splitFieldsEnabled, setSplitFieldsEnabled] = useState(true); const [excludeFrequentEnabled, setExcludeFrequentEnabled] = useState(true); const [fieldOptionEnabled, setFieldOptionEnabled] = useState(true); const { descriptionPlaceholder, setDescriptionPlaceholder } = useDetectorPlaceholder(detector); @@ -139,20 +139,22 @@ export const AdvancedDetectorModal: FC = ({ const partitionField = getField(partitionFieldOption.label); if (agg !== null) { - setFieldsEnabled(true); setCurrentFieldOptions(agg); if (isFieldlessAgg(agg) && eventRateField !== undefined) { + setSplitFieldsEnabled(true); setFieldOption(emptyOption); setFieldOptionEnabled(false); field = eventRateField; } else { + setSplitFieldsEnabled(field !== null); setFieldOptionEnabled(true); - // only enable exclude frequent if there is a by or over selected - setExcludeFrequentEnabled(byField !== null || overField !== null); } + // only enable exclude frequent if there is a by or over selected + setExcludeFrequentEnabled(byField !== null || overField !== null); } else { - setFieldsEnabled(false); + setSplitFieldsEnabled(false); + setFieldOptionEnabled(false); } const dtr: RichDetector = { @@ -179,7 +181,7 @@ export const AdvancedDetectorModal: FC = ({ useEffect(() => { const agg = getAgg(aggOption.label); - setFieldsEnabled(aggOption.label !== ''); + setSplitFieldsEnabled(aggOption.label !== ''); if (agg !== null) { setFieldOptionEnabled(isFieldlessAgg(agg) === false); @@ -202,7 +204,7 @@ export const AdvancedDetectorModal: FC = ({ function saveEnabled() { return ( - fieldsEnabled && + splitFieldsEnabled && (fieldOptionEnabled === false || (fieldOptionEnabled === true && fieldOption.label !== '')) ); } @@ -216,7 +218,7 @@ export const AdvancedDetectorModal: FC = ({ @@ -230,7 +232,7 @@ export const AdvancedDetectorModal: FC = ({ selectedOptions={createSelectedOptions(fieldOption, currentFieldOptions)} onChange={onOptionChange(setFieldOption)} isClearable={true} - isDisabled={fieldsEnabled === false || fieldOptionEnabled === false} + isDisabled={fieldOptionEnabled === false} /> @@ -245,7 +247,7 @@ export const AdvancedDetectorModal: FC = ({ selectedOptions={createSelectedOptions(byFieldOption, splitFieldOptions)} onChange={onOptionChange(setByFieldOption)} isClearable={true} - isDisabled={fieldsEnabled === false} + isDisabled={splitFieldsEnabled === false} /> @@ -257,7 +259,7 @@ export const AdvancedDetectorModal: FC = ({ selectedOptions={createSelectedOptions(overFieldOption, splitFieldOptions)} onChange={onOptionChange(setOverFieldOption)} isClearable={true} - isDisabled={fieldsEnabled === false} + isDisabled={splitFieldsEnabled === false} /> @@ -269,7 +271,7 @@ export const AdvancedDetectorModal: FC = ({ selectedOptions={createSelectedOptions(partitionFieldOption, splitFieldOptions)} onChange={onOptionChange(setPartitionFieldOption)} isClearable={true} - isDisabled={fieldsEnabled === false} + isDisabled={splitFieldsEnabled === false} /> @@ -278,10 +280,13 @@ export const AdvancedDetectorModal: FC = ({ @@ -393,10 +398,13 @@ function createDefaultDescription(dtr: RichDetector) { // if the options list only contains one option and nothing has been selected, set // selectedOptions list to be an empty array function createSelectedOptions( - option: EuiComboBoxOptionProps, + selectedOption: EuiComboBoxOptionProps, options: EuiComboBoxOptionProps[] ): EuiComboBoxOptionProps[] { - return options.length === 1 && options[0].label !== option.label ? [] : [option]; + return (options.length === 1 && options[0].label !== selectedOption.label) || + selectedOption.label === '' + ? [] + : [selectedOption]; } function comboBoxOptionsSort(a: EuiComboBoxOptionProps, b: EuiComboBoxOptionProps) { From 4e8878d5dab3be10af6273280831c563f1232489 Mon Sep 17 00:00:00 2001 From: Steph Milovic Date: Fri, 25 Oct 2019 13:55:30 -0500 Subject: [PATCH 40/61] [SIEM] N-flow ecs bug fix (#49266) --- .../elastic_adapter.test.ts.snap | 1366 +++++++++++++++++ .../lib/network/elastic_adapter.test.ts | 30 + .../lib/network/elasticsearch_adapter.ts | 7 +- 3 files changed, 1400 insertions(+), 3 deletions(-) create mode 100644 x-pack/legacy/plugins/siem/server/lib/network/__snapshots__/elastic_adapter.test.ts.snap diff --git a/x-pack/legacy/plugins/siem/server/lib/network/__snapshots__/elastic_adapter.test.ts.snap b/x-pack/legacy/plugins/siem/server/lib/network/__snapshots__/elastic_adapter.test.ts.snap new file mode 100644 index 0000000000000..50454fcb6b351 --- /dev/null +++ b/x-pack/legacy/plugins/siem/server/lib/network/__snapshots__/elastic_adapter.test.ts.snap @@ -0,0 +1,1366 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Network Top N flow elasticsearch_adapter with FlowTarget=source Unhappy Path - No geo data getNetworkTopNFlow 1`] = ` +Object { + "edges": Array [ + Object { + "cursor": Object { + "tiebreaker": null, + "value": "1.1.1.1", + }, + "node": Object { + "_id": "1.1.1.1", + "network": Object { + "bytes_in": 11276023407, + "bytes_out": 1025631, + }, + "source": Object { + "autonomous_system": Object { + "name": "Level 3 Parent, LLC", + "number": 3356, + }, + "destination_ips": 345345, + "domain": Array [ + "test.1.net", + ], + "flows": 1234567, + "ip": "1.1.1.1", + "location": null, + }, + }, + }, + Object { + "cursor": Object { + "tiebreaker": null, + "value": "2.2.2.2", + }, + "node": Object { + "_id": "2.2.2.2", + "network": Object { + "bytes_in": 5469323342, + "bytes_out": 2811441, + }, + "source": Object { + "autonomous_system": Object { + "name": "Level 3 Parent, LLC", + "number": 3356, + }, + "destination_ips": 345345, + "domain": Array [ + "test.2.net", + ], + "flows": 1234567, + "ip": "2.2.2.2", + "location": Object { + "flowTarget": "source", + "geo": Object { + "city_name": "Philadelphia", + "continent_name": "North America", + "country_iso_code": "US", + "location": Object { + "lat": 39.9359, + "lon": -75.1534, + }, + "region_iso_code": "US-PA", + "region_name": "Pennsylvania", + }, + }, + }, + }, + }, + Object { + "cursor": Object { + "tiebreaker": null, + "value": "3.3.3.3", + }, + "node": Object { + "_id": "3.3.3.3", + "network": Object { + "bytes_in": 3807671322, + "bytes_out": 4494034, + }, + "source": Object { + "autonomous_system": Object { + "name": "Level 3 Parent, LLC", + "number": 3356, + }, + "destination_ips": 345345, + "domain": Array [ + "test.3.com", + "test.3-duplicate.com", + ], + "flows": 1234567, + "ip": "3.3.3.3", + "location": Object { + "flowTarget": "source", + "geo": Object { + "city_name": "Philadelphia", + "continent_name": "North America", + "country_iso_code": "US", + "location": Object { + "lat": 39.9359, + "lon": -75.1534, + }, + "region_iso_code": "US-PA", + "region_name": "Pennsylvania", + }, + }, + }, + }, + }, + Object { + "cursor": Object { + "tiebreaker": null, + "value": "4.4.4.4", + }, + "node": Object { + "_id": "4.4.4.4", + "network": Object { + "bytes_in": 166517626, + "bytes_out": 3194782, + }, + "source": Object { + "autonomous_system": Object { + "name": "Level 3 Parent, LLC", + "number": 3356, + }, + "destination_ips": 345345, + "domain": Array [ + "test.4.com", + ], + "flows": 1234567, + "ip": "4.4.4.4", + "location": Object { + "flowTarget": "source", + "geo": Object { + "city_name": "Philadelphia", + "continent_name": "North America", + "country_iso_code": "US", + "location": Object { + "lat": 39.9359, + "lon": -75.1534, + }, + "region_iso_code": "US-PA", + "region_name": "Pennsylvania", + }, + }, + }, + }, + }, + Object { + "cursor": Object { + "tiebreaker": null, + "value": "5.5.5.5", + }, + "node": Object { + "_id": "5.5.5.5", + "network": Object { + "bytes_in": 104785026, + "bytes_out": 1838597, + }, + "source": Object { + "autonomous_system": Object { + "name": "Level 3 Parent, LLC", + "number": 3356, + }, + "destination_ips": 345345, + "domain": Array [ + "test.5.com", + ], + "flows": 1234567, + "ip": "5.5.5.5", + "location": Object { + "flowTarget": "source", + "geo": Object { + "city_name": "Philadelphia", + "continent_name": "North America", + "country_iso_code": "US", + "location": Object { + "lat": 39.9359, + "lon": -75.1534, + }, + "region_iso_code": "US-PA", + "region_name": "Pennsylvania", + }, + }, + }, + }, + }, + Object { + "cursor": Object { + "tiebreaker": null, + "value": "6.6.6.6", + }, + "node": Object { + "_id": "6.6.6.6", + "network": Object { + "bytes_in": 28804250, + "bytes_out": 482982, + }, + "source": Object { + "autonomous_system": Object { + "name": "Level 3 Parent, LLC", + "number": 3356, + }, + "destination_ips": 345345, + "domain": Array [ + "test.6.com", + ], + "flows": 1234567, + "ip": "6.6.6.6", + "location": Object { + "flowTarget": "source", + "geo": Object { + "city_name": "Philadelphia", + "continent_name": "North America", + "country_iso_code": "US", + "location": Object { + "lat": 39.9359, + "lon": -75.1534, + }, + "region_iso_code": "US-PA", + "region_name": "Pennsylvania", + }, + }, + }, + }, + }, + Object { + "cursor": Object { + "tiebreaker": null, + "value": "7.7.7.7", + }, + "node": Object { + "_id": "7.7.7.7", + "network": Object { + "bytes_in": 23032363, + "bytes_out": 400623, + }, + "source": Object { + "autonomous_system": Object { + "name": "Level 3 Parent, LLC", + "number": 3356, + }, + "destination_ips": 345345, + "domain": Array [ + "test.7.com", + ], + "flows": 1234567, + "ip": "7.7.7.7", + "location": Object { + "flowTarget": "source", + "geo": Object { + "city_name": "Philadelphia", + "continent_name": "North America", + "country_iso_code": "US", + "location": Object { + "lat": 39.9359, + "lon": -75.1534, + }, + "region_iso_code": "US-PA", + "region_name": "Pennsylvania", + }, + }, + }, + }, + }, + Object { + "cursor": Object { + "tiebreaker": null, + "value": "8.8.8.8", + }, + "node": Object { + "_id": "8.8.8.8", + "network": Object { + "bytes_in": 21424889, + "bytes_out": 344357, + }, + "source": Object { + "autonomous_system": Object { + "name": "Level 3 Parent, LLC", + "number": 3356, + }, + "destination_ips": 345345, + "domain": Array [ + "test.8.com", + ], + "flows": 1234567, + "ip": "8.8.8.8", + "location": Object { + "flowTarget": "source", + "geo": Object { + "city_name": "Philadelphia", + "continent_name": "North America", + "country_iso_code": "US", + "location": Object { + "lat": 39.9359, + "lon": -75.1534, + }, + "region_iso_code": "US-PA", + "region_name": "Pennsylvania", + }, + }, + }, + }, + }, + Object { + "cursor": Object { + "tiebreaker": null, + "value": "9.9.9.9", + }, + "node": Object { + "_id": "9.9.9.9", + "network": Object { + "bytes_in": 19205000, + "bytes_out": 355663, + }, + "source": Object { + "autonomous_system": Object { + "name": "Level 3 Parent, LLC", + "number": 3356, + }, + "destination_ips": 345345, + "domain": Array [ + "test.9.com", + ], + "flows": 1234567, + "ip": "9.9.9.9", + "location": Object { + "flowTarget": "source", + "geo": Object { + "city_name": "Philadelphia", + "continent_name": "North America", + "country_iso_code": "US", + "location": Object { + "lat": 39.9359, + "lon": -75.1534, + }, + "region_iso_code": "US-PA", + "region_name": "Pennsylvania", + }, + }, + }, + }, + }, + Object { + "cursor": Object { + "tiebreaker": null, + "value": "10.10.10.10", + }, + "node": Object { + "_id": "10.10.10.10", + "network": Object { + "bytes_in": 11407633, + "bytes_out": 199360, + }, + "source": Object { + "autonomous_system": Object { + "name": "Level 3 Parent, LLC", + "number": 3356, + }, + "destination_ips": 345345, + "domain": Array [ + "test.10.com", + ], + "flows": 1234567, + "ip": "10.10.10.10", + "location": Object { + "flowTarget": "source", + "geo": Object { + "city_name": "Philadelphia", + "continent_name": "North America", + "country_iso_code": "US", + "location": Object { + "lat": 39.9359, + "lon": -75.1534, + }, + "region_iso_code": "US-PA", + "region_name": "Pennsylvania", + }, + }, + }, + }, + }, + ], + "inspect": Object { + "dsl": Array [ + "{ + \\"mockTopNFlowQueryDsl\\": \\"mockTopNFlowQueryDsl\\" +}", + ], + "response": Array [ + "{ + \\"took\\": 122, + \\"timed_out\\": false, + \\"_shards\\": { + \\"total\\": 11, + \\"successful\\": 11, + \\"skipped\\": 0, + \\"failed\\": 0 + }, + \\"hits\\": { + \\"max_score\\": null, + \\"hits\\": [] + }, + \\"aggregations\\": { + \\"top_n_flow_count\\": { + \\"value\\": 545 + }, + \\"source\\": { + \\"buckets\\": [ + { + \\"key\\": \\"1.1.1.1\\", + \\"flows\\": { + \\"value\\": 1234567 + }, + \\"destination_ips\\": { + \\"value\\": 345345 + }, + \\"bytes_in\\": { + \\"value\\": 11276023407 + }, + \\"bytes_out\\": { + \\"value\\": 1025631 + }, + \\"location\\": { + \\"doc_count\\": 14, + \\"top_geo\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [] + } + } + }, + \\"autonomous_system\\": { + \\"doc_count\\": 14, + \\"top_as\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"as\\": { + \\"number\\": 3356, + \\"organization\\": { + \\"name\\": \\"Level 3 Parent, LLC\\" + } + } + } + } + } + ] + } + } + }, + \\"domain\\": { + \\"buckets\\": [ + { + \\"key\\": \\"test.1.net\\" + } + ] + } + }, + { + \\"key\\": \\"2.2.2.2\\", + \\"flows\\": { + \\"value\\": 1234567 + }, + \\"destination_ips\\": { + \\"value\\": 345345 + }, + \\"bytes_in\\": { + \\"value\\": 5469323342 + }, + \\"bytes_out\\": { + \\"value\\": 2811441 + }, + \\"location\\": { + \\"doc_count\\": 14, + \\"top_geo\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"geo\\": { + \\"continent_name\\": \\"North America\\", + \\"region_iso_code\\": \\"US-PA\\", + \\"city_name\\": \\"Philadelphia\\", + \\"country_iso_code\\": \\"US\\", + \\"region_name\\": \\"Pennsylvania\\", + \\"location\\": { + \\"lon\\": -75.1534, + \\"lat\\": 39.9359 + } + } + } + } + } + ] + } + } + }, + \\"autonomous_system\\": { + \\"doc_count\\": 14, + \\"top_as\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"as\\": { + \\"number\\": 3356, + \\"organization\\": { + \\"name\\": \\"Level 3 Parent, LLC\\" + } + } + } + } + } + ] + } + } + }, + \\"domain\\": { + \\"buckets\\": [ + { + \\"key\\": \\"test.2.net\\" + } + ] + } + }, + { + \\"key\\": \\"3.3.3.3\\", + \\"flows\\": { + \\"value\\": 1234567 + }, + \\"destination_ips\\": { + \\"value\\": 345345 + }, + \\"bytes_in\\": { + \\"value\\": 3807671322 + }, + \\"bytes_out\\": { + \\"value\\": 4494034 + }, + \\"location\\": { + \\"doc_count\\": 14, + \\"top_geo\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"geo\\": { + \\"continent_name\\": \\"North America\\", + \\"region_iso_code\\": \\"US-PA\\", + \\"city_name\\": \\"Philadelphia\\", + \\"country_iso_code\\": \\"US\\", + \\"region_name\\": \\"Pennsylvania\\", + \\"location\\": { + \\"lon\\": -75.1534, + \\"lat\\": 39.9359 + } + } + } + } + } + ] + } + } + }, + \\"autonomous_system\\": { + \\"doc_count\\": 14, + \\"top_as\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"as\\": { + \\"number\\": 3356, + \\"organization\\": { + \\"name\\": \\"Level 3 Parent, LLC\\" + } + } + } + } + } + ] + } + } + }, + \\"domain\\": { + \\"buckets\\": [ + { + \\"key\\": \\"test.3.com\\" + }, + { + \\"key\\": \\"test.3-duplicate.com\\" + } + ] + } + }, + { + \\"key\\": \\"4.4.4.4\\", + \\"flows\\": { + \\"value\\": 1234567 + }, + \\"destination_ips\\": { + \\"value\\": 345345 + }, + \\"bytes_in\\": { + \\"value\\": 166517626 + }, + \\"bytes_out\\": { + \\"value\\": 3194782 + }, + \\"location\\": { + \\"doc_count\\": 14, + \\"top_geo\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"geo\\": { + \\"continent_name\\": \\"North America\\", + \\"region_iso_code\\": \\"US-PA\\", + \\"city_name\\": \\"Philadelphia\\", + \\"country_iso_code\\": \\"US\\", + \\"region_name\\": \\"Pennsylvania\\", + \\"location\\": { + \\"lon\\": -75.1534, + \\"lat\\": 39.9359 + } + } + } + } + } + ] + } + } + }, + \\"autonomous_system\\": { + \\"doc_count\\": 14, + \\"top_as\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"as\\": { + \\"number\\": 3356, + \\"organization\\": { + \\"name\\": \\"Level 3 Parent, LLC\\" + } + } + } + } + } + ] + } + } + }, + \\"domain\\": { + \\"buckets\\": [ + { + \\"key\\": \\"test.4.com\\" + } + ] + } + }, + { + \\"key\\": \\"5.5.5.5\\", + \\"flows\\": { + \\"value\\": 1234567 + }, + \\"destination_ips\\": { + \\"value\\": 345345 + }, + \\"bytes_in\\": { + \\"value\\": 104785026 + }, + \\"bytes_out\\": { + \\"value\\": 1838597 + }, + \\"location\\": { + \\"doc_count\\": 14, + \\"top_geo\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"geo\\": { + \\"continent_name\\": \\"North America\\", + \\"region_iso_code\\": \\"US-PA\\", + \\"city_name\\": \\"Philadelphia\\", + \\"country_iso_code\\": \\"US\\", + \\"region_name\\": \\"Pennsylvania\\", + \\"location\\": { + \\"lon\\": -75.1534, + \\"lat\\": 39.9359 + } + } + } + } + } + ] + } + } + }, + \\"autonomous_system\\": { + \\"doc_count\\": 14, + \\"top_as\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"as\\": { + \\"number\\": 3356, + \\"organization\\": { + \\"name\\": \\"Level 3 Parent, LLC\\" + } + } + } + } + } + ] + } + } + }, + \\"domain\\": { + \\"buckets\\": [ + { + \\"key\\": \\"test.5.com\\" + } + ] + } + }, + { + \\"key\\": \\"6.6.6.6\\", + \\"flows\\": { + \\"value\\": 1234567 + }, + \\"destination_ips\\": { + \\"value\\": 345345 + }, + \\"bytes_in\\": { + \\"value\\": 28804250 + }, + \\"bytes_out\\": { + \\"value\\": 482982 + }, + \\"location\\": { + \\"doc_count\\": 14, + \\"top_geo\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"geo\\": { + \\"continent_name\\": \\"North America\\", + \\"region_iso_code\\": \\"US-PA\\", + \\"city_name\\": \\"Philadelphia\\", + \\"country_iso_code\\": \\"US\\", + \\"region_name\\": \\"Pennsylvania\\", + \\"location\\": { + \\"lon\\": -75.1534, + \\"lat\\": 39.9359 + } + } + } + } + } + ] + } + } + }, + \\"autonomous_system\\": { + \\"doc_count\\": 14, + \\"top_as\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"as\\": { + \\"number\\": 3356, + \\"organization\\": { + \\"name\\": \\"Level 3 Parent, LLC\\" + } + } + } + } + } + ] + } + } + }, + \\"domain\\": { + \\"doc_count_error_upper_bound\\": 0, + \\"sum_other_doc_count\\": 31, + \\"buckets\\": [ + { + \\"key\\": \\"test.6.com\\" + } + ] + } + }, + { + \\"key\\": \\"7.7.7.7\\", + \\"flows\\": { + \\"value\\": 1234567 + }, + \\"destination_ips\\": { + \\"value\\": 345345 + }, + \\"bytes_in\\": { + \\"value\\": 23032363 + }, + \\"bytes_out\\": { + \\"value\\": 400623 + }, + \\"location\\": { + \\"doc_count\\": 14, + \\"top_geo\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"geo\\": { + \\"continent_name\\": \\"North America\\", + \\"region_iso_code\\": \\"US-PA\\", + \\"city_name\\": \\"Philadelphia\\", + \\"country_iso_code\\": \\"US\\", + \\"region_name\\": \\"Pennsylvania\\", + \\"location\\": { + \\"lon\\": -75.1534, + \\"lat\\": 39.9359 + } + } + } + } + } + ] + } + } + }, + \\"autonomous_system\\": { + \\"doc_count\\": 14, + \\"top_as\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"as\\": { + \\"number\\": 3356, + \\"organization\\": { + \\"name\\": \\"Level 3 Parent, LLC\\" + } + } + } + } + } + ] + } + } + }, + \\"domain\\": { + \\"doc_count_error_upper_bound\\": 0, + \\"sum_other_doc_count\\": 0, + \\"buckets\\": [ + { + \\"key\\": \\"test.7.com\\" + } + ] + } + }, + { + \\"key\\": \\"8.8.8.8\\", + \\"flows\\": { + \\"value\\": 1234567 + }, + \\"destination_ips\\": { + \\"value\\": 345345 + }, + \\"bytes_in\\": { + \\"value\\": 21424889 + }, + \\"bytes_out\\": { + \\"value\\": 344357 + }, + \\"location\\": { + \\"doc_count\\": 14, + \\"top_geo\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"geo\\": { + \\"continent_name\\": \\"North America\\", + \\"region_iso_code\\": \\"US-PA\\", + \\"city_name\\": \\"Philadelphia\\", + \\"country_iso_code\\": \\"US\\", + \\"region_name\\": \\"Pennsylvania\\", + \\"location\\": { + \\"lon\\": -75.1534, + \\"lat\\": 39.9359 + } + } + } + } + } + ] + } + } + }, + \\"autonomous_system\\": { + \\"doc_count\\": 14, + \\"top_as\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"as\\": { + \\"number\\": 3356, + \\"organization\\": { + \\"name\\": \\"Level 3 Parent, LLC\\" + } + } + } + } + } + ] + } + } + }, + \\"domain\\": { + \\"buckets\\": [ + { + \\"key\\": \\"test.8.com\\" + } + ] + } + }, + { + \\"key\\": \\"9.9.9.9\\", + \\"flows\\": { + \\"value\\": 1234567 + }, + \\"destination_ips\\": { + \\"value\\": 345345 + }, + \\"bytes_in\\": { + \\"value\\": 19205000 + }, + \\"bytes_out\\": { + \\"value\\": 355663 + }, + \\"location\\": { + \\"doc_count\\": 14, + \\"top_geo\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"geo\\": { + \\"continent_name\\": \\"North America\\", + \\"region_iso_code\\": \\"US-PA\\", + \\"city_name\\": \\"Philadelphia\\", + \\"country_iso_code\\": \\"US\\", + \\"region_name\\": \\"Pennsylvania\\", + \\"location\\": { + \\"lon\\": -75.1534, + \\"lat\\": 39.9359 + } + } + } + } + } + ] + } + } + }, + \\"autonomous_system\\": { + \\"doc_count\\": 14, + \\"top_as\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"as\\": { + \\"number\\": 3356, + \\"organization\\": { + \\"name\\": \\"Level 3 Parent, LLC\\" + } + } + } + } + } + ] + } + } + }, + \\"domain\\": { + \\"buckets\\": [ + { + \\"key\\": \\"test.9.com\\" + } + ] + } + }, + { + \\"key\\": \\"10.10.10.10\\", + \\"flows\\": { + \\"value\\": 1234567 + }, + \\"destination_ips\\": { + \\"value\\": 345345 + }, + \\"bytes_in\\": { + \\"value\\": 11407633 + }, + \\"bytes_out\\": { + \\"value\\": 199360 + }, + \\"location\\": { + \\"doc_count\\": 14, + \\"top_geo\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"geo\\": { + \\"continent_name\\": \\"North America\\", + \\"region_iso_code\\": \\"US-PA\\", + \\"city_name\\": \\"Philadelphia\\", + \\"country_iso_code\\": \\"US\\", + \\"region_name\\": \\"Pennsylvania\\", + \\"location\\": { + \\"lon\\": -75.1534, + \\"lat\\": 39.9359 + } + } + } + } + } + ] + } + } + }, + \\"autonomous_system\\": { + \\"doc_count\\": 14, + \\"top_as\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"as\\": { + \\"number\\": 3356, + \\"organization\\": { + \\"name\\": \\"Level 3 Parent, LLC\\" + } + } + } + } + } + ] + } + } + }, + \\"domain\\": { + \\"buckets\\": [ + { + \\"key\\": \\"test.10.com\\" + } + ] + } + }, + { + \\"key\\": \\"11.11.11.11\\", + \\"flows\\": { + \\"value\\": 1234567 + }, + \\"destination_ips\\": { + \\"value\\": 345345 + }, + \\"bytes_in\\": { + \\"value\\": 11393327 + }, + \\"bytes_out\\": { + \\"value\\": 195914 + }, + \\"location\\": { + \\"doc_count\\": 14, + \\"top_geo\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"geo\\": { + \\"continent_name\\": \\"North America\\", + \\"region_iso_code\\": \\"US-PA\\", + \\"city_name\\": \\"Philadelphia\\", + \\"country_iso_code\\": \\"US\\", + \\"region_name\\": \\"Pennsylvania\\", + \\"location\\": { + \\"lon\\": -75.1534, + \\"lat\\": 39.9359 + } + } + } + } + } + ] + } + } + }, + \\"autonomous_system\\": { + \\"doc_count\\": 14, + \\"top_as\\": { + \\"hits\\": { + \\"total\\": { + \\"value\\": 14, + \\"relation\\": \\"eq\\" + }, + \\"max_score\\": 1, + \\"hits\\": [ + { + \\"_index\\": \\"filebeat-8.0.0-2019.06.19-000005\\", + \\"_type\\": \\"_doc\\", + \\"_id\\": \\"dd4fa2d4bd-692279846149410\\", + \\"_score\\": 1, + \\"_source\\": { + \\"source\\": { + \\"as\\": { + \\"number\\": 3356, + \\"organization\\": { + \\"name\\": \\"Level 3 Parent, LLC\\" + } + } + } + } + } + ] + } + } + }, + \\"domain\\": { + \\"buckets\\": [ + { + \\"key\\": \\"test.11.com\\" + } + ] + } + } + ] + } + } +}", + ], + }, + "pageInfo": Object { + "activePage": 0, + "fakeTotalCount": 50, + "showMorePagesIndicator": true, + }, + "totalCount": 545, +} +`; diff --git a/x-pack/legacy/plugins/siem/server/lib/network/elastic_adapter.test.ts b/x-pack/legacy/plugins/siem/server/lib/network/elastic_adapter.test.ts index c3bcfafac8757..542a2a0108a9a 100644 --- a/x-pack/legacy/plugins/siem/server/lib/network/elastic_adapter.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/network/elastic_adapter.test.ts @@ -96,6 +96,36 @@ describe('Network Top N flow elasticsearch_adapter with FlowTarget=source', () = }); }); + describe('Unhappy Path - No geo data', () => { + const mockCallWithRequest = jest.fn(); + const mockNoGeoDataResponse = cloneDeep(mockResponse); + // sometimes bad things happen to good ecs + mockNoGeoDataResponse.aggregations[ + FlowTargetSourceDest.source + ].buckets[0].location.top_geo.hits.hits = []; + mockCallWithRequest.mockResolvedValue(mockNoGeoDataResponse); + const mockFramework: FrameworkAdapter = { + version: 'mock', + callWithRequest: mockCallWithRequest, + exposeStaticDir: jest.fn(), + getIndexPatternsService: jest.fn(), + getSavedObjectsService: jest.fn(), + registerGraphQLEndpoint: jest.fn(), + }; + jest.doMock('../framework', () => ({ + callWithRequest: mockCallWithRequest, + })); + + test('getNetworkTopNFlow', async () => { + const EsNetworkTopNFlow = new ElasticsearchNetworkAdapter(mockFramework); + const data: NetworkTopNFlowData = await EsNetworkTopNFlow.getNetworkTopNFlow( + mockRequest as FrameworkRequest, + mockOptions + ); + expect(data).toMatchSnapshot(); + }); + }); + describe('No pagination', () => { const mockNoPaginationResponse = cloneDeep(mockResponse); mockNoPaginationResponse.aggregations.top_n_flow_count.value = 10; diff --git a/x-pack/legacy/plugins/siem/server/lib/network/elasticsearch_adapter.ts b/x-pack/legacy/plugins/siem/server/lib/network/elasticsearch_adapter.ts index 5a871a3f9c9b4..eff5fba0c54d5 100644 --- a/x-pack/legacy/plugins/siem/server/lib/network/elasticsearch_adapter.ts +++ b/x-pack/legacy/plugins/siem/server/lib/network/elasticsearch_adapter.ts @@ -193,19 +193,20 @@ const getGeoItem = (result: NetworkTopNFlowBuckets): GeoItem | null => : null; const getAsItem = (result: NetworkTopNFlowBuckets): AutonomousSystemItem | null => - result.autonomous_system.top_as.hits.hits.length > 0 + result.autonomous_system.top_as.hits.hits.length > 0 && + result.autonomous_system.top_as.hits.hits[0]._source ? { number: getOr( null, `autonomous_system.top_as.hits.hits[0]._source.${ - Object.keys(result.location.top_geo.hits.hits[0]._source)[0] + Object.keys(result.autonomous_system.top_as.hits.hits[0]._source)[0] }.as.number`, result ), name: getOr( '', `autonomous_system.top_as.hits.hits[0]._source.${ - Object.keys(result.location.top_geo.hits.hits[0]._source)[0] + Object.keys(result.autonomous_system.top_as.hits.hits[0]._source)[0] }.as.organization.name`, result ), From 243a9815e3685631f85c27c5c8ea1524c883cc30 Mon Sep 17 00:00:00 2001 From: gchaps <33642766+gchaps@users.noreply.github.com> Date: Fri, 25 Oct 2019 11:59:01 -0700 Subject: [PATCH 41/61] [DOCS] Adds docs for API Keys UI (#49135) * [DOCS] Adds docs for API Keys UI * [DOCS] Incorporates review comments into API keys doc * [DOCS] Fixes typo --- .../api-keys/images/api-key-invalidate.png | Bin 0 -> 129223 bytes .../security/api-keys/images/api-keys.png | Bin 0 -> 111824 bytes docs/user/security/api-keys/index.asciidoc | 86 ++++++++++++++++++ docs/user/security/index.asciidoc | 2 + 4 files changed, 88 insertions(+) create mode 100755 docs/user/security/api-keys/images/api-key-invalidate.png create mode 100755 docs/user/security/api-keys/images/api-keys.png create mode 100644 docs/user/security/api-keys/index.asciidoc diff --git a/docs/user/security/api-keys/images/api-key-invalidate.png b/docs/user/security/api-keys/images/api-key-invalidate.png new file mode 100755 index 0000000000000000000000000000000000000000..c925679ab24bc64565b780203a05bf0d1183ee24 GIT binary patch literal 129223 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 $&blZvHHdhp|(U$!7gmduOC7f`) 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%0A7E z`ItF0P>wVI2Te6C`X{^aJSqjvY^PbPD33Wxd2EqCphuriPCuYb$RCt;HI~z{I~Di_ zW`Q}RJL-2E%1GD1B`CPsFLei86Lulj%m(`vP@M}Q2#euZMosC-W&GyvaqEu7D(Ils z4JaEGFdATiWFkdOqwK5FnJJbujn>ooInW0+n$svb*|37Ktx4B+Wv^xS&R z=ddG>E+(DY*SIy9DSlyEZAhMI38|z5W=_w@-*MgR-=O7AbB*>^5}C290{6%*4=?1L zJ`E<**CtV3z&tsZ>!ieKgJ-Yr+O#bOA02Iwmt~I+)@6T2bVB&ChiWU9EcwX@e_Q>_ z$g2=YZ&43hqdH z*u{aF0t*HO>6>ckk(H7%-QbV(nwEa`HxRR-cr{g-ob^&pMosUO=-3OEI|=qpzbdQ( zCQ`)In6BoUIgZTAe+UjA)15fXa|@Ph7UR~OsU=jZa>hl;6g|R1d_}#kXfzDretI~f zhWcNSXshkj_vAus{%&H2e`w2;>vx+>3)IH=c@4+@g&?>=>9l-5i$&B{u`vw~0f6K+nrL??=X7scmmT_(wdw-8N0r{S`JH=Bi45 zlSH)$P5s{)mUitoyj0k`_Dthd_q$^qJskw_!2xnd=*qJlXUV98!ZARgL+0s#wvh z?O9V0dot{u0S_6+v6^(ouhem*F9yjMAl;5r_2UQ4Ej|mbYNiXSC1UC3xCwSoc<&s< z$Z=pBSyo3&|2>oQHdnNe-+Ul*BK8`&R9ARvsbT{OW7^LDFwCr6AHm)3HC zyVUe_VdJfr%#YkPwa)mxiuzRv!&?T;@mUP$8`|Z?HilJ5y!uke0*|Qr)!3KoQNvZo z9Vy51M%IKaDP{k^T)P0wEt~59NwrIx-qa7Ml~~se-YEY2iJK_@cgM%%d8tN5YE4HQ z+~|ywosUc%^-2={QLa^muuvusk7PBoFZ7!5Z2wH#Uk|e(41=pL(~X|K@H$6X-V{os zx5uJTv$g<^=8IqU+6wPeYl+G(9e?WGSI|mVPZm?j0UaGpB16udo;1&}+p9f0ko7sN zzk4T#)cw&2m`S?8#><&xxjQ?T3u@eixV?8pV{9PSLL@?Vw;|n$a%T;d=UtQpRf=>;+*|j%fx|hXFrz zc6P%0&#+IvL^D@E_jW<2H~cdko17F^Opl~BDF5-f{-;&>;{<7Ek(W8UChvKQZ`k0ekVX*s#-<8mP{Z?4+M7N(+Nh23$`E)3=7E1sIpPSO z3*x5sQk*6$z3V!0zJ$U}j^fPU6>^#IX_;^`_(o$Q(A5whwvw&DieH>Pq^k1i)Qy-> zQVjml<#$tyOi1~geWO>a8^!&}y6w;ri*M=FEJB*6Ew}9Q(j-!$d6e!H6h}kSMDvj` zdSF0~)saM$JK9bc7+NSO(fCL5;n*}WGdP>r(RJ-@4dbU~#^;7^bFc3B?>$>HJ5ND7 zei#F1pBC9=UHBkFN216cWGIT5-?Bbk<0-f?d04r$Gwh_GSA%xy{^q>5`(zB8X) z;H-+edr7{8DnYM6{rT=dZ&kGkOk$)dZ1yn&;gf^x+2IUEd3V#T{8}DOfwtsExOkJ3 zhEPr58Lr6>F38e?KW}o?0pn$=MlR=HGrQH$o7JHNldy+0i^K+ZC&nw$cLpj`E5zsK z8F^YD0~1X=hC>pYl^fPJZr|e`G|q6}o<7a1Qlx*XY@=}UEK;fa0(U8fE9&A``z}SvV)Ge?v!QP)w2*Z6OM-p@D=+egvbLLjVG6% zmsTj9!F&I*!~n?WMRkYA>)Iplm3i&Q|Dam+lj}OPJN)h^eb{+=@)inrxJ`~80zmU6 zu3M*1rg7+7GdV>H-ePg3IhDJ|w}lkA{vq{krB_uu(MXKcHO=<-d;?r@^PeR26oJZS zJ*A4YUTu}v9B~>yP|7R1Ay}1}t~1RU6J;Ho7-0(jt96FI(`tjS2n~Xj3lPlzBDNq{ zvwK|Y_2zIQ)$ze8Zs_#O_TQ}Aa69Hd?36UotEi?g^Yz0*uDwq&O@6`!z3zU0$qz>o zTW>j%PTWV#j+y`cWOrBA0t~BayNJ#({~A4;8LIuzSG%4hmT5z@nS`_z#n~gw*bh-} zh`!UU{)_eWq;#xK_#rX49Ai0z)waCkI1Sgc{gB0RGh0NXiKezVUzO_Xpq?9){gE*0 zy5>Tb+bj?WY9eoJ*riLm%Z-jF_lFCwcJIC|kBnv&$5rgZ?yVNS3~AJz7I$Q{MQW%! z49+Mgi-^9qO&q+GUQk;f9XmL_2WBTs!nnV%S+a0zB=YH%?XSNg*me(Dm$j^Jtl)QM zNgoakUfKUj6h#2@m4ERekE_9%etgXdKX3M}b0&092sUF^RuST5UpTq;Adh?E(~5$_ zT={(w95NsDO|Fd~N&#h&ntS(rAPH@R%Lm#LoX ze1&NV3w@KhvxT!sELZ+G{PvYPGxjEsM+>|W1~~?samii2*K5tu%-D;BfuCC;${k+6 z>zN+W>J^E;)-WXlm`8@ef{%ya6JLYb)SYHQ|3%G~wx$==$A5RUru_vJk+KwH-)Qer zjGnbOK_THIrGn@P^u^gF0kx+iMLwgVMuIcaNA#-h8+)E1HRT@HU$jK?^(RyeHA)EDO|^M20ma7Mf}i$d&RHP!J2 zdz9O4_;GoTQXkU)B+iG}H2+mH1AD87uUOjpgzYfbN&c`RlcWlT+vMG!{g(!G>Rd@j znyc&+Zh6jJIIOv3(ew|^$9iAwKOe|%HyT{+mGO%Qr3vnf2`KrVKPUYebQwcEETSqX zq!3Y^eZe^%589d+Ynz{THC7~#P6@K5e4KuoDk*h#6?cT8iJq=&roN{DquqB5QY;%! z^G!pNaXs6mPIwD`MXS%pA|R zp{W4cP7Ft@_Pm_e@rJ0~{gStizum0;I9mwOV{m*!FpTz$U_Qdr#R{V}**CtF0a|=s z+{C8P^enZObmLqDR^3$0Km<2o}SWUM-V~yM)6}_g# zmv5nb+HM?zw=gUL)gBKSdGN*)cC>}zi?-s`VZfnC4uoL9($<%>$iRK=lHpf%SF!6T zLW#9(z#(LY_+qwKp#(Kqj8v$*?TY`*}V;kjrqBz zAH+U*t661o2noBk*6i;M!|`=5#%tIYPE2H2yY8l4=bz7@^}R5|a&&37U!ZVkTv8J_ z#t52Luc)fFNmJ=FYPSCBWxk9K8F3l)5i2_MzKMjFzk8$7QnK;yXbnjk)uTDmhnk8X z%~PE7o+D=j5Ig-%I$ohf!>P z1SlME&DlxlOqCZKo!aIZ{yPkj@2qfdvHN-U`??W(w_OG$)pEfK){*@5L<`m0?J+go zI;@>=Q)*pYMhhkLs5rcJ`*%@ET3>{w{DqpspN&@APbh^am(73PFVZY)eR);VRxSp9 zqd(-bWw|_!pBZOx6dQjAd*eIgvZEbO_WCBm9!2qJuL(5Y%i!BA&YGB+LJZCML2oX7 z5^L@5-|5#D!e;;2?#;cQb%ZLcjJu6deEB&Q?Xf;rO?ZNAD4bT#IUNiYPb-Mqc|P*} zIV*{yOP-`ymZzN=2n|mq&bC zV9m5pyf15~-v+S+h?JYgRo2X$bgtsj)~G%N1kviL7vbXKDG(;EDtp>#PizlqVVQZ}_o`B9hf0R?O9GS(_wGKDs zsIhP~^1t!eBNtDX=v;Ss5&~yHeo$8L?wLSd5qMu{aebn6^z{)1_3#OuJvHW|T$^9V zb(Xc|+9i5P7_{u@Ys|$# zCVC_!iTokKl^!DjmNaO7M@jhbYn--e#A^Lz0TiD*rI%JZ`b`sQJ+3=mX0EQD z%&2}hC^YILPACu=bYU-YT}rq>3!Gllq`I2}TyN|EX)hT-Ha}T3uP;oNG|wabXheI- z#fNSbrJ57AB>4XCB@){mGq0|32>PeU%hVg)R5sq8E@h7wjuC01Mo9AT_qoqN`nh%A zcXK!ns=s(-4FFfC^wn$D895PLnylo4za4MZx^%7BCM3He-?PRu{F8k{$Q;Uz5)&l5M>Sghm5I6oVpB%ziGOeqgxAHg7YzztqDJu8 zOE-%SHcZb64$g!s7eQxpDq8_JR(c5RO5cQa;U4Si$Qy!x3GG?$Y;0zUg6!OwbgjC( zw=>5F7~fI!sV1$wisXo@%LsCfp2_Q<5d3f$WiJ>(>Tn~`M~2vRb%`27$28+nq>|J6m9!GtMolZ<(v{Z)x< zsR|3p$XE&YlMnf>odkPnpWR$-rEB*L@qfI>C`HxulA1gY^~)@IbU0ckOfrz}TQ*1T z&EZNcqaQXno6alZGYUyiH?Vm;6J7tK)OKP-3z)wZ`Be`A1!5MH>RulX?WXb&HrPw9 zF3N*ubaO~?fd$Hwx`WKB=d{l8Z(?)wO&)){E)2iXjZ<)tgnAo4R!x>vkr7A;w08j)iiRsU8~0Pu>w3{Urs`v4)2+fUgmaS! z9Al5WkKR|z)xZk+y|2s&=F9am<2V2%*s+Xo{7yB}WF}eT4M6JsIUCZN;8s&%XQa0i zxLYH9KM$i#eIn!clPD2#L!>x+lDOy<_R+mHMq^(;Zkgw!i%TvFC@Tx}@_HtoGqjQd zJNzHPeD=6j%vF8zSt&7kqk90mdis26#eeS5NHpEwXx(>R8m5^MiW~YNr<-#e!SAor zN(|!ciJJFP@jLD}>Ld6a$djmX@Xf`$pzoZx^j@LTpQJZGhVcKJ!&&?zf@SS68SQ7L zgxTGh=JzAAK8!_`#++!7ypB+*^TZ4fI`-^LGbyn6t`0^zV8gWg9TTJcc~5t1D|*G- zNRMnbm&#V9&gz@{{qSbvPQU)Jf1zA$Z&&WAj1j_>Y=js60nyY}bJj-U|r zJ?1}oZhNirZ)-LOetXjHzZl%l9y)_q4EVOEc05GqDzW|Ar4OZX&FP5>rSrUi@d2%R z=$!m=h0Cqk!8ECa`vI5UCB=CxZVzYo&{lwH74K3t2?2|3$qbG-jC*_{khpIB zTeJcle{~QiheP+M`;lxTexD2x+A3oH1g#DxJWxxW3g7ZSjq#wsCoZZO4Ft_BJCcSh z-A+Nn79xV*Dh+mDD5Y2HJZbSKX_L0lZKMcl9g()*Dd=)wdpDgf1`$>s8j-&E%~@@j z+a7H#Dfa96AGG+LgwQ>BKEJNDkCXLz_q=tlD{kwp3d8!C_nmJam@1Hkb++i!zh_93pW92*{R!={r;lKf1r>* z@a2=1hUU$h26PLw@;|K#A^_51ZD8sn%j23M--otXv@N@2o1~Q=BL-lnGTdj$Ec|`L zu=wjs(=MW)2-v8Yzh5yTP>0QfqAQQBlN94p?!Ssjn3f?`+hh>1vXAF2cvx81vl#A+ znT+gd3L{J)aNF&YE{>CV|MuUIE(vAO9ixtqrlI}rTb6c8p^ANyqaXy?`mNiw(9A(` zZ@ynmJpw^GCiWl3hfN47r1+_s%opd#U*ITWR!tJ=c)%zC;&zFXjP0;bKW_ORUDOe; z|1f}4ippGv!OgU5cnw-#SbiK3JxY8o>5n>si(QiEU?^FI6bz*?%{#P=fBQ)&Y=TT% zyI9XF2T{8WG$g!t0+Vk7Ge9FcG+Cx3+wd!XGxvNd`ksmN?|Ob9le>LLS(aQVZ3uDN z&e*E*2i`N8RS#R>%pXfm26t`^mC^-{Ad3SxY~E;vVUtEAN7$tE?IHWd=UeUKvn4o8 z)O$J++f-mj#&tt7Eg*E)M5Zq084ko!uVoHcWq|;f>&@Zrub9Fg4vN#=Y@bKv&aIJa z4Bc+SZfuTf704wp+tIBmC0}+CcrtQ-a{A$`r=}CL&;EzkQ%)8~NKsS&-a`vypYHW` zzcu$vl{tAk<2oixSEb@k%R_u-3u;`$G%K0G$YBT-)n1-me=I3Ew=c!z?nE za0${){dF#NS&;=Hwf1G+#FEP=;}yPYwgnyEx_4W5${hO=Bd|v*wGU`Tf6J8^N{_$p zuF^du0J-fF*GhE9No!Sw*+Wk#ld;p?+t0Ff#p5HkNsg6M+v9IDkcVaxz0a!(ETko* z#s6odKt;7DE$%RH02kdr3n&?*B!|$yx;5sX%Bh0gtsL8YCegH^Lh~(FZLRl|Q059R zQ!OQ+U$~EEj;UiD)m`eQ=OCPdUZ#PQ=fb6%|0+rU9T7sL%k@pZX5t@=Q%}FjpP9jj z?xh=x^0Ta)FU0BQdHEI@R5aM3T9ptN4S%P0n@yyBYA$;Fgn}aC-Uw{G(#0Lq2pTLU z$<@D%m>RzKEy0h%;qOo>oTFm)izdnF)Xf)njRh#nM+4<}%H(c-i%sBO;{^zEpWG5r z>17_z7qbkWBgQ+Ns~rKX)dOT)jKdJe>HIjhFA@o8Z}a=>i=6LrWzKAb1g^**#-Y~R zqmJJh10CiHK#FphO!S_-sjM~i^vziVri383H1LR27e2uqp9FPZ0Raw~yT<2OIsR1A z#H7N}357coRkW*nQfGMs|Q@t>dF!^moC&3HD*U+4cF z>c+g)@$)((60*%HWN@-nAp4cSWheM}xvWlv1ts&~L^fi(`2!`U#vpu!r-}_W#;|kZ zht;LM`IMA8e*z!UuJsf?Q%yBF=Djac_LW=KvU4LiS$&<3CX}D+RMx!HpKDOd@W*r0 z-y$lcZ9+9whWPbV|I25lptn-dp&lIcB2U$4(@Qm`vE7L ziR>1>I>oZCls>j1inBa_nrSSy0Qtl^ z%B4%+ueQ>E^iMBfY4(nJV22?3NYzqK|J;Ga44mY%)RWKb5_DlHy6X!dWmyqq^-7lQ zHfwf-*hU{j9BJLPQX+|p{r*+R?$=`*VBr?`hilSn3{&pU?FoUWzYNHkt}^CE?cX>I z={~M{8fr0FXuH1G_U6=S^nqph{$d#P+HH_0HYFuwt&cPD>6XWA*88WDn?WQG`T$Kf z0a;_BZ;4RG{+#%93BTm@`I#7E@PsOl=Qn?vOdPlSmh^8lJJEx-m1^HuX z5M_}l_>O&Q^ABWu;b1YzBssmsd(BHf^)SkO?t{R;diN!+T-8*xZ@yYg=JAF$^d9*b zr9V;qwBQ&awcX?HGFsukq&FXnCqHlgE~)ITN12=b9*&bl@K-6|3Yyi`b{cR=B7WT% zgJ;i@x+1QhKEJx0*l>U8RJW}7!pEWCHmNX7u_$uT_kJh=I-dLALGsIH$-=g_%~wzq zAzluYrvIJ?0^m7ik?so9+zpVH6%f%r`g7yXJ0*VE1{m5frjCihjEaeW(jq&O5FCN5 zF}xS9k2sg{*osEChtlobk3EQ>$U{8wktu=;As#HJ-5oW(Z_>*q&a7ro};K9 z+wB(PQCRoob!C#(M$NP?C5ufZ)lbiP<6G_Rzl0jywt2vKf&FGvUjx$7syA;BCL+19 z8H`kbPF-^|m{tmH6hiE@7$Hs?Zc{YcHk#?rTi4}F1P8K%(h^U)Qa)X}nd-c%U(7qS$=4>7k_aZ+ z_AGYC#)CY>e5K_ZxnHpX?X1{?{%*&d{K7f4IlpeNy{1?igyBkY6I6X)wZP zFucjj+(SV=d*VrLGZ*uPT}NcXaY}bhjBHP84MaNVFol!f^M1`dt45ONuv-XQ|2G%r z?7*n|i@7sTTx@Hwc&u$RG9}cU>b5^v=6;g-hv9bxAg>psdEd3-_bY5A@hoM!${~S) z&|H7qpm<)Ew$;Nb)aVp#5_*Auy!ZvrQq!?O&iL6`qlB*S&51SdX6FZeo%g{z zo}m~xX{OcszqIQp#C;w@>2Z0sSj|dwfRcv8CV2*=Dw;~S4VVSWVm282FR=){h;TvM z4CU#+=4t$vf*yy8#hZ068E`~J>)>F1N%oX)zn&oAfgkwo^&;87PI^T{Uo z3LOs(nB3KF8~pknjt%>MG=aS#NL8}ugj|p>F-Y?PI4r`6PWiBHxuz!PM=EYg*hCPf z@tnCXBRuF}9u*iEzHNyxup2i)R46{)a`FyeF*T0d=hXyL&$P@~0pXB6yxr3d3~5O{ zv80!%<-O^6NDzKQ%(^IFM(EA5_>+Z$&k7RB?_UhMVEi~;UQ?bJe`BFIK{cJ;L-?#& z4LD!_-&#XQ1QEozqIn0x15w$gvU)M(6TNVOKpN;a%~hKDr4_;UFsMS@bt~@}P2ZvB+l|ewWb$m#M@U0wS?9u~v`o)PY`e-v zszjus2=xWwG6=PsLhIKQ&#lGV06VFX>3(ufIHHjy&`q%uNcMZe&CN>jjX2Mq`q-kP z9g_>~&CSsXF;*?_P8Jr18-19A-(ANuXb_vT-m1RGJ*A*bwHbRels1_9)?@Bifc+SN zUgVFWUPXJ-lF#%{8dX$eb#$-ZxEZv2u69GLA9P74G9*f5m8L6R_=vrm^K0RA8IMBj z47=r?xIo{)Hs1~09~`h*Y@U<554yw)wMz;*f?%lgncpPCj5$LIi2ne?psVuvim3d9 zcuxoTAVq}kI*HqO;nm>BKajx-OBo;GVcuiGJ@#;FJ~Y4bT}N3G8+nI}@794&oHLi2 z7oK)tuu!Pq%PqjkZZ79Ne;q=|1TWZ=U|Nn~TX_2#$HpeXQlMiwP(^QzVO~ZDevGy_BWto;sY3bAW8JAU{v*mP)eOdevafD(uI;rv@vCjYY zZ__I)wirk~#`v9qxH?@odiS8$~;U)?85< z(9P4>ypmEg@;j<2KjN{BY+!c&{csFf^5xYbJ#N7N_QJ8==D!LrPwa;tt%Ux=-vjBc zy%5Ac$z1-1S)(w{@9(QpURu2@EMk)iD2@Y^W=MT)FsMkU%_IzrjCv(M+uS#Kb2+)nX;iEs16B?0)?X}GI^O_^=nLzMbes}=wi6D&cPa9VD1^7R zS}2eY<~aXWYaT9TEeBl$L3gONt3b)XPF>Rw37LSj83- zJue9CL{H^7u>?kVCt(fswD1b--?!wgEA-%7@pLZ44|w(_76M**FzrKI4l! zd`>~|Q{)kZdyc^B`v)L-dG2jD4eqFd&8lZ<0IuB96tqCx{P784+^&2)|Er=$Q%X5l z(Z1VpN-%=6EWH69QKSvV-HzXAuuSkIu5K>Yiye|@=&gP@?dWGF3^Y-T!$K2ZTM6F+ z^{=u%2Z1k7_Z|JTPTuA;ifqgdgP0j?uu@g{(=p)$J1+uj#=*HqNJg!AQPHDQ++Ep( zE*Zl=!);NoZDyuks7GxR5lP^T10KNr_0);}ga`g#gBysJd1^16h= zne_LE<~-eh7i!`&90U#D8z`$YNb-~sb~WU{>F22N>&I?MAL%KMfq@fcDRb{QvO7^^ z{2e<_IYbA$)l;$nKm(e;U?Su5)^Lci+2BBjlu5kL>jt<8nDjb&3yDDYfydNU5L@Mn!z32i+qim^ zb9%blgAP6M6l zwr7Qp;H__inbB4uGqBVfV3eNcNF&c1;?K@S$#cDaH@Ob}#?3&JQfpVd_x^dGED`*# z#}ut?kVDE!&eg=ON#^pDu0zj3wI}UsFY59a|6W zMf=puSZx;CPRbm6D^B;6L|X<|+FdI!>siBVmc<^-)1Y?~NVvfbz!kz_3VNY#`(#|V zoBxDR2N)rbL?p7OsoIC=J?|obB-3p4Cm8wPjPPx-I2h?XyWn%#T&Cu=;S*C65`vQeSqBXx%GVXjt>_Rg!<1Q0$|eSWblVCe=XtJ^@)m~0}1c3Z4IU= zi8uE(BeVS^TBByGI##G`RfCxNJOpPO%M$aI#Mi1{n)>D_>jp6d>xq{E zY;)FN^pSdoSbzOX+yqha(LBhnZ|r}R6T$nwI9jn4>P(`u*G#mi(a6;`tTPGAH|eUC z2J?S@{pymS?P~Co|EXR2m80c+UYwI}wgJ&~Jum;=az2(%_(76JR_Oa}N4qffNy8D8 zHD_f5xz=~-1Gb<5F^8EA=fCH|@!uAPS$ea-Z*>Gz= zsN+|W`&2oNoWlE+5FOhw zzvXqGAAEl{vBA)>#Is8>%qYp5fvLoRE_`?4mm!nSEMUl*m`6{@I*ctTyr zrp0ULgyBe413l*60z^?mC|2%QdJ`_@%hgYj_~;BLHRO1D6WtdSzljX9alInAi^kv^ zTg~-+Af`F7*BOd;b!Qb=TS*X7<3*Zj_0mZD+RONSu|sy(evNb5=M z6%dkuOZBL%|!{!~4t=$E>Qm|E@_Xc;H_fKuTNOJED%)pmlM=d zUgp(g_`X-JkHj$- zjsu^t#fH`?``H>4vZ7e6dQ~H`bYK@c$(6Ia+#`6E6gJ+(p;Ghr*w>)N%`79z|Df>l z5410_+V}d=c^StOQ^#$?Y*)rp?w9>;3gG9pI5X_oEBDK4mGOE#t!9&kC5F`|3!^Gd^HB<}fI(a^F}Vbqvj{vo<=}Z_#NxZNqwu#VpMps^|wD^tRGg^g z{qSm;RLfFCe%1`!%rUYbYWx=zopWAMm^41UN-?AEEHvOeA2y%MdW*`(Yh`KvKx<7j z{awT9a5hgCNKmV8P2~7zWPB3GNj!S zW0fuybsSMchsegY#k#8*-Nhf#p`n>h-w!ad*wqw9c(tD>a=I|szzE)xG24<@AhuQf zTD{e4oNp-EGWB8NcWE`u6iHf2c75k+#?=ge!NrDRI`s@0TPwu>*WQ~)L;b)1!!2(V zp-n1VyW$;12!l%HT|&j!jY<+@sWg_c6$vTYP?nJtnK8z`Goezp$vVt13^BGb7&F7H zzo*aV{`|i6J@+5?x&Qc`bKmDXb51$(GOwQ3^Yy$Q*W>GJK{Cm<4A+RZc&m5rhWqyIyYV+>*q!J%=mm6a*uz_- zs(-g~)q2GTVuWyT}*HmN$ozZZ8%h_yB?dOY`M+t~aKJuE-AGsl2 z+cibJytCZbHf6g9lCd?#VTs+PnyE79Tlw?;af*q#H^xaYdTUv1=0z9cw9qyu6oEIE zOV#rt^_jw=C%F#KMyhRzG5JZK9RoqLfNjNTDLheZZuSbOuqd&)OVPy zB0g;D(U$7xu5KecY=*wo;Tep8uY`5pQ+Fvy)x`aDj`AvH{0wh}exk1bnr*Q^h1g(- zG`7iu4Oiq{3xaB_kL$S(pM8{9KPw7X^F4UcEMkW(mhw4jzE(NLAmFK@QRkDC{9ok0 z0G&7gcx|qwz=7_lcW>&m0dzAf z33#V*sM75S17m6QckbUdF$s%FU76I~e?9MBut7UE&l$ziln+8wflB9>#0iYNCS5p} z5%A8Ak*O;~kT)b#s9v(lzlTx=9=nh zTi%Z!gb*2tK=qO34i(E||Cm0I1VzL@=__~HYkxI)N@2;cTCKA6HAa~-*8)|TU3x1O zFtvz~?G=~VwM(WD>W)IxU`hAcYs}7@6;NP*mPQKjrU zTZNVQlmg_(N_2p_9d@kQrpCA1TW%o*M=3O5rSWEff=I_gP=aE%k72l@4*gVg3xXf+ zxoc3bI!4pE_6AMEnf>rYwdnqkT6zZ(e_JgQv}6ZAz&v3@$J+*}-^~koe{-rum};Os zDQvIy!GyDccz?-u5AHi(?EWcmiw)f|&Ddzr3`PubEcf8W84i0_KDH8Tm3U7~`c`NKo9ldd z1#fdEUrit0%$?1-l=f7Xm#*DgHM!*JTB*uq_klz@cJ zp2|%Q_+TY(sOMgr@%9)=hBN2QBk7dU%hdY6y)+?FcChGuTpji=N*&?e;3L{2n(L*Y z0!~Ky%N?N?s%F=6fw5{YI`6HHWNm+icDuck_h;${BV3O$5hX4}SvN8vuZ3r{qtCAwf7Z60f7|e2s|}0ORl<1?inx8X@Z*{*SPbIQ3x6XHSI1~) z_kvdf^E(GUTm*!=-(1<^`i6!sSX5Z?HhqjAy67K)+0lHWf8kE zW#+%~7Ws2^Cuh3qaGJSmkA!fPI!^3y<@JW;^K6=RgZlfu*ZTS@8-xz3*%Z*pMC}8( zBwDJhOUCigYr;1dgk}x=P1kNy(Al!Jap}pHN@JwbnQ8KD7u`<9do!qB3GJ#zpR#+= z2uMwBAG?{D>Wx6v{GcllJZ2&Jp7Ctspwa#~ZK^MOd}$=BH^l_Md-N@hq((1oRm^q7kBor@;9^+nc2J z50l>UA5 z?74p7`tYL*+KUTe<9QYt#zdm^?VPHcLcId>oMjo;1YV6*4pWdlAJtB};*r@!{3y4YIiZP{1EW}YCYJ=)n=4C@( zAl+uTU`}-i;81Tvpw?9A8ylxeI?#KZ{jE~VM$%V8wo6-&c`V6wQcD}CX6U@6zy@x3zXqh)bns@d=4!& z;T$cZwS4G`=<$2^-MYSXT2M>rz+3U%baKSW!L0r8*o?H@-k^-<&3wrn(4!XW*u{Fmcue7wgP~&f8VG_yJaNfgC+`6=Fy;S zaCC1c$~d+p_wGV+^740(il#fDCeEn>hnE;P4_Ttg*OhWac6eF`OJFk8tF-Z zks3^!Lk)Dwya-3O`*v2pa;@?5P?jWUx>U_IpbG+rc%5_5A?s9z^Nel&RaGam$N8Kp z^x*Igl#0QqPpXuz*C5*>(~v#QYuPCk_DbWx?9!MTt+ce?p~@Mj%jaB0Z-=naMeb5b#Q zW`rxZ8Kdr zEh{+V?=#~$FGj7Bp!qFlZv>G600Iltl{jmUrnOK@v_OyB` zNdBV^&4Zipog1UNIMM`y7-3DBH1QtLeQxhj8XZ1;%&PWd$fWS90-|iI$evm?xA1f2 zyG7Zjh)mmY$!aLI04>_4N+9(wbkF9V`51Q1QuMHiJ||ed)Ee0SMnPyYEWfBWpWmF_ z!XKW{Eb37u829UJlh2&YtPnqW!iUl^*L?7%fz?q*#3qKxQhGw^?YJl9BOG_*=W!wP zV^y>^Ple*!YxlA}uCA94AFl6xnQ1(R1dwFapW%!kBE3^~mDu3C`^sRCFYR$*y0`W~ zmJf7YbMY}HUlofk&j_c^uQ>%SIQvD@5Heg8f{)RX{AT0+Y2_6;VDc82=}??nrVtXH zRi0h-Le3W7dUrCU3l|n+zwk1tk-2Ur6Xf8RKC8iNIA6_0^J;eVnoBFweWk%6aI*2q zoW6`OB_&Mx0(`h3K-0W`NdxT_4x$<5Cm2%L)FSjP%J=4?~>ct=3>;M~23Zci=w{A362n#qp8r>u8BQj0`bX*kuB7}-D$ zhE&B&@gGcB#{uR3F-|Y>E$#{5!DCeI5yIa6rpVcpT#U#acFQ7W{w1ov+sz)K;C9H| z%(cv%iHKMMRuisSZcddpmX4mg8_lzb3UT5DF>RHw$oau5@jQm)_9CFKNzSOb%eeoy zT>)i&r9FPTdZy>G1o4y3wXeer;&kcN%l>A25xu*myD|+Mm{k`_0)*Z@YYvD_O6|~y zpf!lSmDqAHn7BpB?#1Z1kKkKd(tN63of{1mZZrky{WSEQ=5J+^Q!W&3HX`?CnGWew zSlUe$X-fy%cQ8oT_a|%QtP^ZA4C-8$R_=>+sSIm|g|GFW01wJ4Zl?%n$Ruc~oah)E|8M!cbr@!x; z)%P)X*}44yd;s8*38W7Vgm>CE;dc^0Z8f%8DX6LkG6FP{%q@c+a$4daCi}~t&RtPr zHcJv%dWz65gts+6B{q0dsQa&B1-hJxNb^|vEa>UXzDW(D;4GATYV{o=YUTVBkk&-3G@2>vE|jER`~ zQ~yF2TTGxqLS4pS9fO)$4$W~!`01sK7%maPd+NcaaH{bwQL&1#G^%}4a=G)KF%CCD zYoB3jxYqevq*gE=+XelXS;-9|s zSwNcU_gs?|D}rM5=0iUC#1sU~HI84B8(2}x^j;LU-H>{Ca`zc^X5>tjn zN;}qCtIA0C>ED@r;{#Y(3B9L)s-5ofnG>mvDdQxkx?66QNAZ+l^L6J}&$54=e(Hd@SbZIU5QaeK&aF0grv_c0 zfrYj8*+Taejp0JTHu3^`+0JsgD+AwtdHUBP3j0j_=Wf&|o~C1n1;e8clghLD+B!*x zXuV&|eo%uuXLP(5V9b5{>oMFkpkQMLsg)5M14Ty!+k@Eg9*fhhw~^vv)%v#Pu65Vl zTcFJ3iQV2W$wKCCRLHe7ZjY|t(Dk7ZRt10o1BB>S`)4EeU=+>m_#L>?^;wrr+O1i0 z!vDhA(>4-`j!`4aI!cYz(oU3>^w3Z9&eIOl%w{_*lafT4N*W~i5a-rYqW5oq;0huV zmGyxzhavIyx~sKkr!F$K+hEGLs}$o^=jNaF*0K!U`2xm;p_7gkGh64p<~4>cu5P4N z*Sz{(#ZOzd;QQzKO9N6HCJ(3CrbVO{SuGFtL z3w82}!Fw|C>*ESs@b24G+Y9e*%NZErttgz#ww(kBYMR{Jv!hD-X6yt`@ED1x7uWj~ z2^q{9YeA$P^Q^82wKHekCNy6DSlLm8iZ+g&TrA@lm?0C`e8f8y>m)DMhJP*DAB%^Y z=kudml?y%RNa>9XdczFKcJ-7WdW_w5eZf`NpS@1qxinoc@4rz2=$b^tS>kSn-r~t9 zvOmvEVAGuxF!Z}aPm{k&W^|$I<}))P2ui>l$)h>St;KU_SROlH_|J^8N${cURDSeP z7&k^>^Qn|zo_|ao&buF`+859p?f~?^4W8Al)2mpCx4xQ*e4fjEZN1?m2XcSeUiO_= zug?vR@)v*UQB@XD+ERWqgF0-N^|->
Evj7_xv+r{3n&&`uXuR>8vvr4;R%Zk59 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 W@L#6w-MIQtT{vfXw&2XQ$o~a}k!3aj literal 0 HcmV?d00001 diff --git a/docs/user/security/api-keys/index.asciidoc b/docs/user/security/api-keys/index.asciidoc new file mode 100644 index 0000000000000..c00f58cf598e3 --- /dev/null +++ b/docs/user/security/api-keys/index.asciidoc @@ -0,0 +1,86 @@ +[role="xpack"] +[[api-keys]] +=== API Keys + + +API keys enable you to create secondary credentials so that you can send +requests on behalf of the user. Secondary credentials have +the same or lower access rights. + +For example, if you extract data from an {es} cluster on a daily +basis, you might create an API key tied to your credentials, +configure it with minimum access, +and then put the API credentials into a cron job. +Or, you might create API keys to automate ingestion of new data from +remote sources, without a live user interaction. + +You can create API keys from the {kib} Console. To view and invalidate +API keys, use *Management > Security > API Keys*. + +[role="screenshot"] +image:user/security/api-keys/images/api-keys.png["API Keys UI"] + +[float] +[[api-keys-service]] +=== {es} API key service + +The {es} API key service is automatically enabled when you configure +{ref}/configuring-tls.html#tls-http[TLS on the HTTP interface]. +This ensures that clients are unable to send API keys in clear-text. + +When HTTPS connections are not enabled between {kib} and {es}, +you cannot create or manage API keys, and you get an error message. +For more information, see the +{ref}/security-api-create-api-key.html[{es} API key documentation], +or contact your system administrator. + +[float] +[[api-keys-security-privileges]] +=== Security privileges + +You must have the `manage_security`, `manage_api_key`, or the `manage_own_api_key` +cluster privileges to use API keys in {kib}. You can manage roles in +*Management > Security > Roles*, or use the <>. + + +[float] +[[create-api-key]] +=== Create an API key +You can {ref}/security-api-create-api-key.html[create an API key] from +the Kibana Console. For example: + +[source,js] +POST /_security/api_key +{ + "name": "my_api_key", + "expiration": "1d" +} + +This creates an API key with the name `my_api_key` that +expires after one day. API key names must be globally unique. +An expiration date is optional and follows {ref}/common-options.html#time-units[{es} time unit format]. +When an expiration is not provided, the API key does not expire. + +[float] +[[view-api-keys]] +=== View and invalidate API keys +The *API Keys* UI lists your API keys, including the name, date created, +and expiration date. If an API key expires, its status changes from `Active` to `Expired`. + +If you have `manage_security` or `manage_api_key` permissions, +you can view the API keys of all users, and see which API key was +created by which user in which realm. +If you have only the `manage_own_api_key` permission, you see only a list of your own keys. + +You can invalidate API keys individually or in bulk. +Invalidated keys are deleted in batch after seven days. + +[role="screenshot"] +image:user/security/api-keys/images/api-key-invalidate.png["API Keys invalidate"] + +You cannot modify an API key. If you need additional privileges, +you must create a new key with the desired configuration and invalidate the old key. + + + + diff --git a/docs/user/security/index.asciidoc b/docs/user/security/index.asciidoc index 7b7e38d610843..f57d1bcd3bc2a 100644 --- a/docs/user/security/index.asciidoc +++ b/docs/user/security/index.asciidoc @@ -36,3 +36,5 @@ cause Kibana's authorization to behave unexpectedly. include::authorization/index.asciidoc[] include::authorization/kibana-privileges.asciidoc[] +include::api-keys/index.asciidoc[] + From e0cf748a1dff029c599c292f4b52b4ff51e410d9 Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Fri, 25 Oct 2019 12:46:09 -0700 Subject: [PATCH 42/61] [Reporting] Fix scroll timeout logging bug (#49111) * [Reporting] Fix scroll timeout logging bug * test cancellation token * test time out --- .../reporting/common/cancellation_token.ts | 12 +- .../csv/server/lib/__tests__/hit_iterator.ts | 136 ++++++++++++++++++ .../csv/server/lib/hit_iterator.js | 71 --------- .../csv/server/lib/hit_iterator.ts | 97 +++++++++++++ x-pack/legacy/plugins/reporting/types.d.ts | 7 + 5 files changed, 248 insertions(+), 75 deletions(-) create mode 100644 x-pack/legacy/plugins/reporting/export_types/csv/server/lib/__tests__/hit_iterator.ts delete mode 100644 x-pack/legacy/plugins/reporting/export_types/csv/server/lib/hit_iterator.js create mode 100644 x-pack/legacy/plugins/reporting/export_types/csv/server/lib/hit_iterator.ts diff --git a/x-pack/legacy/plugins/reporting/common/cancellation_token.ts b/x-pack/legacy/plugins/reporting/common/cancellation_token.ts index 11425c3002d97..c03f9ee7328cb 100644 --- a/x-pack/legacy/plugins/reporting/common/cancellation_token.ts +++ b/x-pack/legacy/plugins/reporting/common/cancellation_token.ts @@ -7,11 +7,11 @@ import { isFunction } from 'lodash'; export class CancellationToken { - private isCancelled: boolean; + private _isCancelled: boolean; private _callbacks: Function[]; constructor() { - this.isCancelled = false; + this._isCancelled = false; this._callbacks = []; } @@ -20,7 +20,7 @@ export class CancellationToken { throw new Error('Expected callback to be a function'); } - if (this.isCancelled) { + if (this._isCancelled) { callback(); return; } @@ -29,7 +29,11 @@ export class CancellationToken { }; public cancel = () => { - this.isCancelled = true; + this._isCancelled = true; this._callbacks.forEach(callback => callback()); }; + + public isCancelled() { + return this._isCancelled; + } } diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/__tests__/hit_iterator.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/__tests__/hit_iterator.ts new file mode 100644 index 0000000000000..c439c2bbf60eb --- /dev/null +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/__tests__/hit_iterator.ts @@ -0,0 +1,136 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; +import sinon from 'sinon'; +import { CancellationToken } from '../../../../../common/cancellation_token'; +import { Logger, ScrollConfig } from '../../../../../types'; +import { createHitIterator } from '../hit_iterator'; + +const mockLogger = { + error: new Function(), + debug: new Function(), + warning: new Function(), +} as Logger; +const debugLogStub = sinon.stub(mockLogger, 'debug'); +const warnLogStub = sinon.stub(mockLogger, 'warning'); +const errorLogStub = sinon.stub(mockLogger, 'error'); +const mockCallEndpoint = sinon.stub(); +const mockSearchRequest = {}; +const mockConfig: ScrollConfig = { duration: '2s', size: 123 }; +let realCancellationToken = new CancellationToken(); +let isCancelledStub: sinon.SinonStub; + +describe('hitIterator', function() { + beforeEach(() => { + debugLogStub.resetHistory(); + warnLogStub.resetHistory(); + errorLogStub.resetHistory(); + mockCallEndpoint.resetHistory(); + mockCallEndpoint.resetBehavior(); + mockCallEndpoint.resolves({ _scroll_id: '123blah', hits: { hits: ['you found me'] } }); + mockCallEndpoint.onCall(11).resolves({ _scroll_id: '123blah', hits: {} }); + + isCancelledStub = sinon.stub(realCancellationToken, 'isCancelled'); + isCancelledStub.returns(false); + }); + + afterEach(() => { + realCancellationToken = new CancellationToken(); + }); + + it('iterates hits', async () => { + // Begin + const hitIterator = createHitIterator(mockLogger); + const iterator = hitIterator( + mockConfig, + mockCallEndpoint, + mockSearchRequest, + realCancellationToken + ); + + while (true) { + const { done: iterationDone, value: hit } = await iterator.next(); + if (iterationDone) { + break; + } + expect(hit).to.be('you found me'); + } + + expect(mockCallEndpoint.callCount).to.be(13); + expect(debugLogStub.callCount).to.be(13); + expect(warnLogStub.callCount).to.be(0); + expect(errorLogStub.callCount).to.be(0); + }); + + it('stops searches after cancellation', async () => { + // Setup + isCancelledStub.onFirstCall().returns(false); + isCancelledStub.returns(true); + + // Begin + const hitIterator = createHitIterator(mockLogger); + const iterator = hitIterator( + mockConfig, + mockCallEndpoint, + mockSearchRequest, + realCancellationToken + ); + + while (true) { + const { done: iterationDone, value: hit } = await iterator.next(); + if (iterationDone) { + break; + } + expect(hit).to.be('you found me'); + } + + expect(mockCallEndpoint.callCount).to.be(3); + expect(debugLogStub.callCount).to.be(3); + expect(warnLogStub.callCount).to.be(1); + expect(errorLogStub.callCount).to.be(0); + + expect(warnLogStub.firstCall.lastArg).to.be( + 'Any remaining scrolling searches have been cancelled by the cancellation token.' + ); + }); + + it('handles time out', async () => { + // Setup + mockCallEndpoint.onCall(2).resolves({ status: 404 }); + + // Begin + const hitIterator = createHitIterator(mockLogger); + const iterator = hitIterator( + mockConfig, + mockCallEndpoint, + mockSearchRequest, + realCancellationToken + ); + + let errorThrown = false; + try { + while (true) { + const { done: iterationDone, value: hit } = await iterator.next(); + if (iterationDone) { + break; + } + expect(hit).to.be('you found me'); + } + } catch (err) { + expect(err).to.eql( + new Error('Expected _scroll_id in the following Elasticsearch response: {"status":404}') + ); + errorThrown = true; + } + + expect(mockCallEndpoint.callCount).to.be(4); + expect(debugLogStub.callCount).to.be(4); + expect(warnLogStub.callCount).to.be(0); + expect(errorLogStub.callCount).to.be(1); + expect(errorThrown).to.be(true); + }); +}); diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/hit_iterator.js b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/hit_iterator.js deleted file mode 100644 index 5ad6182568721..0000000000000 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/hit_iterator.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; - -async function parseResponse(request) { - const response = await request; - if (!response._scroll_id) { - throw new Error(i18n.translate('xpack.reporting.exportTypes.csv.hitIterator.expectedScrollIdErrorMessage', { - defaultMessage: 'Expected {scrollId} in the following Elasticsearch response: {response}', - values: { response: JSON.stringify(response), scrollId: '_scroll_id' } - })); - } - - if (!response.hits) { - throw new Error(i18n.translate('xpack.reporting.exportTypes.csv.hitIterator.expectedHitsErrorMessage', { - defaultMessage: 'Expected {hits} in the following Elasticsearch response: {response}', - values: { response: JSON.stringify(response), hits: 'hits' } - })); - } - - return { - scrollId: response._scroll_id, - hits: response.hits.hits - }; -} - -export function createHitIterator(logger) { - return async function* hitIterator(scrollSettings, callEndpoint, searchRequest, cancellationToken) { - logger.debug('executing search request'); - function search(index, body) { - return parseResponse(callEndpoint('search', { - index, - body, - scroll: scrollSettings.duration, - size: scrollSettings.size - })); - } - - function scroll(scrollId) { - logger.debug('executing scroll request'); - return parseResponse(callEndpoint('scroll', { - scrollId, - scroll: scrollSettings.duration - })); - } - - function clearScroll(scrollId) { - logger.debug('executing clearScroll request'); - return callEndpoint('clearScroll', { - scrollId: [ scrollId ] - }); - } - - let { scrollId, hits } = await search(searchRequest.index, searchRequest.body); - try { - while(hits.length && !cancellationToken.isCancelled) { - for(const hit of hits) { - yield hit; - } - - ({ scrollId, hits } = await scroll(scrollId)); - } - } finally { - await clearScroll(scrollId); - } - }; -} diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/hit_iterator.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/hit_iterator.ts new file mode 100644 index 0000000000000..68836c01369e3 --- /dev/null +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/hit_iterator.ts @@ -0,0 +1,97 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { SearchParams, SearchResponse } from 'elasticsearch'; + +import { i18n } from '@kbn/i18n'; +import { CancellationToken, ScrollConfig, Logger } from '../../../../types'; + +async function parseResponse(request: SearchResponse) { + const response = await request; + if (!response || !response._scroll_id) { + throw new Error( + i18n.translate('xpack.reporting.exportTypes.csv.hitIterator.expectedScrollIdErrorMessage', { + defaultMessage: 'Expected {scrollId} in the following Elasticsearch response: {response}', + values: { response: JSON.stringify(response), scrollId: '_scroll_id' }, + }) + ); + } + + if (!response.hits) { + throw new Error( + i18n.translate('xpack.reporting.exportTypes.csv.hitIterator.expectedHitsErrorMessage', { + defaultMessage: 'Expected {hits} in the following Elasticsearch response: {response}', + values: { response: JSON.stringify(response), hits: 'hits' }, + }) + ); + } + + return { + scrollId: response._scroll_id, + hits: response.hits.hits, + }; +} + +export function createHitIterator(logger: Logger) { + return async function* hitIterator( + scrollSettings: ScrollConfig, + callEndpoint: Function, + searchRequest: SearchParams, + cancellationToken: CancellationToken + ) { + logger.debug('executing search request'); + function search(index: string | boolean | string[] | undefined, body: object) { + return parseResponse( + callEndpoint('search', { + index, + body, + scroll: scrollSettings.duration, + size: scrollSettings.size, + }) + ); + } + + function scroll(scrollId: string | undefined) { + logger.debug('executing scroll request'); + return parseResponse( + callEndpoint('scroll', { + scrollId, + scroll: scrollSettings.duration, + }) + ); + } + + function clearScroll(scrollId: string | undefined) { + logger.debug('executing clearScroll request'); + return callEndpoint('clearScroll', { + scrollId: [scrollId], + }); + } + + try { + let { scrollId, hits } = await search(searchRequest.index, searchRequest.body); + try { + while (hits && hits.length && !cancellationToken.isCancelled()) { + for (const hit of hits) { + yield hit; + } + + ({ scrollId, hits } = await scroll(scrollId)); + + if (cancellationToken.isCancelled()) { + logger.warning( + 'Any remaining scrolling searches have been cancelled by the cancellation token.' + ); + } + } + } finally { + await clearScroll(scrollId); + } + } catch (err) { + logger.error(err); + throw err; + } + }; +} diff --git a/x-pack/legacy/plugins/reporting/types.d.ts b/x-pack/legacy/plugins/reporting/types.d.ts index 62f8286cdf364..731d0f084a718 100644 --- a/x-pack/legacy/plugins/reporting/types.d.ts +++ b/x-pack/legacy/plugins/reporting/types.d.ts @@ -112,6 +112,11 @@ export interface QueueConfig { timeout: number; } +export interface ScrollConfig { + duration: string; + size: number; +} + export interface ElementPosition { boundingClientRect: { // modern browsers support x/y, but older ones don't @@ -248,5 +253,7 @@ export interface ExportTypesRegistry { register: (exportTypeDefinition: ExportTypeDefinition) => void; } +export { CancellationToken } from './common/cancellation_token'; + // Prefer to import this type using: `import { LevelLogger } from 'relative/path/server/lib';` export { LevelLogger as Logger } from './server/lib/level_logger'; From 9bd8f74ff8795c9c5581968fa256ab140ce0ea7f Mon Sep 17 00:00:00 2001 From: gchaps <33642766+gchaps@users.noreply.github.com> Date: Fri, 25 Oct 2019 13:27:55 -0700 Subject: [PATCH 43/61] [DOCS] Updates Snapshot docs to include retention (#49007) * [DOCS] Updates Snapshot docs to include retention * [DOCS] Creates tutorial for snapshot & restore * [DOCS] Incorporates review comments for Snapshot doc * [DOCS] Fixes typo * [DOCS] Adds x-pack label --- .../images/create-policy-example.png | Bin 0 -> 219430 bytes .../images/snapshot-retention.png | Bin 0 -> 219515 bytes .../snapshot-restore/index.asciidoc | 228 +++++++++++++----- 3 files changed, 170 insertions(+), 58 deletions(-) create mode 100755 docs/management/snapshot-restore/images/create-policy-example.png create mode 100755 docs/management/snapshot-restore/images/snapshot-retention.png diff --git a/docs/management/snapshot-restore/images/create-policy-example.png b/docs/management/snapshot-restore/images/create-policy-example.png new file mode 100755 index 0000000000000000000000000000000000000000..e871c925f5fd525a708f838d989611d914a39360 GIT binary patch literal 219430 zcmeEuc|6qX`*)pAX<@V>d!0xnDY6eLl@Ka>wj(4>mLZI7)X7p5MaZ5CSx5F=nV76o zwz1AM27|#EgE7X;JonW3e$RQHzn(vz*X#Kie~j_@+@E{7?(2GA@Aq}j)9WVs0=va_ zZ`ra%z~Jhon_ITx3Bk}jrs8UX!Kvv@UB09|FUJ~_=ktbPm0Qt)7|g(&ZE{+9?k9+ zkc@`(`xW~sy1lP&$uHOu*n=l~iN~n%8N|!{=XdQ(w3>$j%()0*G>Bp=(D%sx=RYzA zBlOV?0!Ir@cI2NwmHypo`;y&1x5=P=|G6xlAN#KX{NLXM zGfq=A`lro%wvpsSsd%r%e@3$K(SqyE_EPb(UVQ$qenmj9D$Wp@JrEQ4eY5tee+}oJ z2RDs7`0B_8;oe9z9r0$+Yv|x$i6R6x=y4V1cfa_brt>Ws1g2Me;L^ydc!CYBZ9-u{ z=@Qr0SS(#62lAy?h|*HT>_op3jcIxBzNh6&^FMbQ1pB~Mp@ADMXPg&%OYaV+x_tDr z5d6lqG^@JjXk{)jt#B(v;)Q#8a(L|?tH|v}mJty~mj4>(+K-9*>OC=TUG_=*eQrIr z!j{G3FI3I&N2AEHR%u?+=@=(wKX`6>zb>w1^ib9PabaMkyr1Lzw$*H{;o=Zt??AiB zR3G`2aTOvinNt$Ib%Rh4+{%ocP;jD^sW^44M6{>;-rAbhDF5ruExY>%i$_~}gGK`zp)A2wL5>`ciaV@w>(U@3fFZz z4e7KhM#T@1!wP#W$h2K0cJ{CCzTBiv?B7!fV=qB{ zJJ%5Y=Ot1xat-&VG*LQ#_vmTOA+4TxH>@Kki^$9^uJ>DI5(>bz0^-%-vYi6hzZ<=3 z<%4jjfYUt*b!@MJT31$N|ABK*zF&P_ywV>^cXqweU)89T%Yl)wN z@&C7p@=$~hjI&&d)T4PeF9udZusC2(!iviOZD%}|$ZT+RvcCZz^uxjymY|Coj>|!0 zxIrUP5Dj9>dtOk3CYxR+E9tHHwGVU zo1H$GFERGeq<-AK{JHI6mc3T7|>C;{z+KDLE?1N zWVH9Cm?Q&*ICr7US>~8YGnv5U1kB*5XzzJiG1@7rdS|hz`iX`WA3~|mlp){2pLY5I z&W~kyU%q^q_%2R&mqMI}74S(qlGbTCyqRm%SoV(GJf%QI2s z(0gyT7^f)7O8DAQBz46nun`bR)c7nTguc)mpQR-mmivVoJT-tb(@ltxH2?XaH&@O= z33{!?!}@Vj2YR$o_O+2y^#xNOi(4>RA!36?HVH*1bNq*@JZy)`T#atg2p4QxjWob! zMb&MjW*|)^O2``;y|Z=V=!QW0zuVl_IxziMM><_~=A?%OlfyT-2h7$%F%^wd=kAZ4 z>({DrQh#H@p2QilnnKqK4=mQz+pg2G?mK2GzswK&w&+WTO6aV=aqN`?-8g2PI`QfH z9U;-oEWfotjj%{NpIITN=`I_{$)AI`{_apF)yWd&Z~z~~8h1%s?TsWDr%Ar#uPmuq zo?AK}7u8aTYLe1nKR7?bC1Qv<$&R}Obylv{%uE=eX~m}es}N7~xrKDUHKtQb_*0$B zm7hLcc--=cPqKkj8H1~$_K{`zB9#iiE^X%L1>a$hJsGVba6joeF_)+Q-GvL5C3d1g zI-~Oa`N3BQKb?fsO(anyQMIR6sN5UY4G5Zv)pM`0nzNhGJJ)7bFJ^f=v5ew{W@~rM zh}a?Eua*1?Om7OfAxvB?To5{8oWHzjImuC1j8k*)VXNpP0%_qfinY*ZQta|h9wGxj zD!{Qy-KGo{6KCBrjjPPD65hCC!kICIS@P19m0tYT;J`0ialkUr<=EBT9wzE1Hl3;L zGEZ(QFjEYNYU6R=}>4_igNW$d2L*Yy-1`0OVtkXUADcdGo^6EYko}jpvTaU z0~UIsnPxUZl7G9;e&I-R@IzUnq)6YM#>1Ng-8EzJdulMG`3(Iwp&z96 zc9Cb4n=w`yjlEWH)b945v~8R+2Ywqt@*8y-J0y`K|oqW!CK}9n4%*hA|g>K<#!^e&C>gT zm4~g*kW5>?zI@j*(Q0%uBn{5mK-~QN-XNhR*)ddd2V?{KOq6cqlV)4(S=ft1eYmUl z`i#@hPQExaOukSxC*pt5_-;SV@ABxOu1G@`SO|#xv1&lIR)l>+7?5 zFP%RBwLLIYdZ3@kY>J+U2rjx#{QJeXKv;zML4A`_qL!9O+(a5Kh}5 zI}(e^v8Lh<)PVEj-&m~$qR|}9wQBG485{15u;qNWa7QFtg^a^oz(3sjxP{mqH}bvP z-cz9bPB)&WLK#E}lH{)K3<#h|%}I_OU#Kz~7T?Fm*dHCuvV`y3HV(u1?7y^6Vw$p(PUQKl*X*#K3b$z z5ovOnCOfb&T!~R+RsH@rf;_4z)Bl;XA4TozXvX0x?xWSRCeL8E%ut7vMbvvlk*deY ztMn(|nz{PK%{`|L7pp7Ci0h3zvitnhj%_2jb|%Sf`!QE~Z=j%`uC2DfeE2Yi`B+5F`L4^A& zS;5fu$=LeEUA%a;hG#rX$7*K|`I>h+qYs$sWNeJFlhXUmlE^wUbj6nZyo|)P*NS&> zI`@Z4k9eV+8j7p&L2?T^vFc^6J{L`!Ow)gb!;T)XmJ}{gKij=r*nQi(LAmr-{9g+$ z+6@dB7;jW!#Z`1pHL%x$HJWuG5%^&4;|i2+li%nW|9P+W>#((XjrKo1-1Mg6AJ+%q zL!0|C!hE%RL{1wQRC!{FsF^h zgI11dMZJnBi$cpNY7NUmZCqSD+vhM$y^;a3hKm{SI3VdI2@ZgK(TC(GZUd%qLS~o~R z9f5F^yfy%UG3jLQM`uiA%!uQyX(wxRTU5m57!h*FHTW6fYLBMr5sJL_rKXi-dGyl0 zqwxxpo$?S!o^hI#RM7hOZ|`S`iO5q?(r|MGxsj2efHpFdMAJcV~Ex{^%I>YEI*Kl;3EG^$NZ1)BZ@kqWHtQL+V-QD>MGoP_6No z*{38&DgqI!m1^-9LITZ!Bf@Vo+sPlwsFb6z&|@o$^j?#!;4y9D2*q<}@PhC8ktH@h zSo&+H>JnUC=UzWHA8WnQE=Zev7G3i7R}Qj_UTR26Jr`)$BQ#)^d#$(^b2fD2nKy2H zym#aNr%x_h67wsFfnyV_hCQddH23|W1}}(1pdXOxMK&=mMkMufW60;Lh>7#3X*v^g zz5XKh@qXHC3$_|+0E1K*j(bU1W`y=IiQ!dwGNZ?+m8OdWy~QKx2l1g)wombw*llIa zoK)eG`o*@2BX-lJ>mT05?UBpy2~uZl?nx-lHq}^t<~{ixbL??tm&ahW;5U*#Hm6u3 zb{hflEKX;7{oBL`=YWG*zU`wim?I91hDqG3Q#xb?TmMkwWkmd!7e~7& z*WqsPa(+Ie<9m*$qO|EWVlE}KefLaR$qFi#7#MQjESDo%hxgaduNVCyv`SMxpePDo zs}*^l$#TyQoU6rTN!B*$NF}I0iPO6HY8t>(0Rgcb$B83I6VjB#NqGmz8#k@iN$PY_R|PFz=kv@AB|*#hgq zq4TmJJF~(#m&<-z2Y4&8ez8gITBedLWsUSn(?M4YBB;z)PUA`khorgGNK2!e!M3v@ zLOsXU&rC!~CoGIh2hP)64yD3=9E!p|ZeB0z!uqwx%Mx>Y?0q1Uq?3dGA`agm?Pf^o;<=h-3$(tX)X^l!ob+Cn$OVLC|zZLdrzxS;%^ml+wA7mvtEn zR&_OVDy{-jO1k!Ez{^%&A3RYvP^2IVRQ&`r!L!>ZEL9tbI`K51M*cWeS=LYKsP z)2UD$QGJuzdPFZOf)_AX8`>iF<&#BB#R7B5zQh$}?1@#GztqoTSL+gw>2M7aa>I>I zH~z8O1U*AhB|WUBcUQ~EnSWUr3*!V{TR-aeEKE#8iCqUbnt+pAYE8fFX zRcY==Y=eg0}|xf~OpB_i8QE=9-jXXW5KnTY0$p|w{Pqn;r%#CCE^(!x(P zdA*Sz3(GDZt&+7Bbc0xuK2;v;RDs5A`yBtc5!i#lj!C#YL*1prPDtEJ6J=eiM1FCi zWF;0Sgq28_Mtu9+{tXK8Ci!>g6jwaAeZXC&47q%ev?{p+8JqZV#*?pEp7ybEZA4rn zDg$o4xk2$dR-FLz{)m`opI11 zvid!&+5mb?7{H}q&q73{gE!lk=&v0O?cF6E9}CG_MrK`!HLPM{C1Tr%(}`C8{APKa z+EGGsZ6ukORFuI!A-SP;aBt-7lvTvmZMuScgioFF`)Xs?aAH%_|NinONtl>|$qkHo zhXzJ&F^v(n`XgW=$hOBRBq|mciQU0(D246O@ueMV^B5sT&v%Wg*IYT=F0QQoJ<;_O83U^7XkGQZZQo3}PKx0XN3Wp?4q zLg)I$*fqWaSmo*}DWwN@t;_Ei*LnrBH{QC;NJUXo^oDdo9Uw6xil^yo{e@O22sP}R zuE+HnlGseLeF{G{;25NmWJymU1h?6cBc0Gq##J7t3thz51UIG*U9Y}sIh1746h)?0 zHY`S_`DFgNv>1l!bQmNxJ{T@r@*!B2d&)N@#X&a^)=eQy&rru{u}n1^WKF`wu?`)2 zZPtSh(ROU4-IZ90j7nq9Fxl?<>;cU>zh+&MTmM$#l$C=qTgqbof1ATZd8=c#4sMXY zCR9>kWf=lk!2;Z2UMk*EnX~E-pJ9v#5TZ!7887_m;X55(Qm$bR9NY+7f%_D%c0F2z zp_*&^sG->bSw)!dYwyj_)dZx~+{xjLr?@+@wnc6Z_3TO<;W*vzGhG`RXFKZ#5hk?@ zW`!)fr&ykKlce@DCWE{rKs-LAIiIE^I3fQBZV4(ySQxEz^afCrv&o!l8n1-mavk2` z%1@*AS`8;p?cdUwq|mv69}>uCw5*6KcQm#JY;N#y#(~ky)Uz+}ieo{n45xv)0WCJC zKq3>9Av)q1Vl%iXmh9kf@meduvz8zTuSA4k?;tZtZWB4l4kxC9qxA|^J^Bc7`3!@G z$@7<654g<@dcF2fqv;^mX>ws=zw!pLPXKF1%cs?k`M^fD9E0cuR0$xAOUprYx2!9A z{Noz1v0VXUfu@6R6d=FLD;42s#N+sbi?jZYBURtwZ-VA#-6Ecg8#&6>xwMzL6wV}Y z>W%#y+5%Bz*8EDa|1rpJQpXQAMEy90sbF7MbglX&7PP&g<6FOmxOri$prK}ep&N;% z<{+m--yoantX_-oKYF|n#Hodaus_GoxOTkSP4KsSgzPM?b{qGEBI|>^@T2TUMb!E? z_N>X&X(8>D!;tc3_FDaQ>W@ept#ct<_EHAk(*mG1>?60JwGKElV#DeC+si^og$WvR z{UxSXhmXeg8`K~t2lbjX9K15kI_vP;+dt$cFX=@g6IN5(vZiv1k-wl&K@xz4=X|G& zTqxxDZLgi<2kp*G4GbAvvH&jh$Q;2?Rz>_*i4B`!9!<` zdl=DOv?#ucJB^Z07q8GVRf7EoRq!Ma3}u*lT1z|=;{*$=8pcksh(|9L4tkVZLb=PG zs2o5E9d^s)-``B0YC@Uc4TxMJ*FzsPqcE|FtE2U-%-{s>dw`>i5Nt!AYz3^De(Ig*kw% zw~j+Tj@Und4@UQA2sGXMt2dGyr^_+7Zmhd4A47V$k-@-YhkSww-%#ABL@6at#=I{! zuUIE;G*NeD>D?4wwO%Rdl#N(PQ?A+IUaz(JVb={#2w1JNjkQL&QY?~hv8Fikd0HfB z^pql2*^|KOH^aI#>Nl-V6gD(wrWk@*Q0S90Nj0BUAd&8Ej(RpLFT7qTcg%3P9O@1L z!zquu;@p6SK}JcHmSQ1r(`O|HmTOkX!81gy#uYsaek|#ulJIv^LxBbmlAfg*MXlO~;V{A`NtYEM3(fUV_xH?+mTX=J6WcnFJI3h7C&<$>k* z0)C^JAwkx4_iY?9-6XEIQFPrLOxch4r12iM)yb;RX3AnPy)5{`IhUEzZw;3_D@gt$ zvu@-D^9#@&fZd2k(>J2d?QV1oIpKvv#$gLb8yT+JWUnTsRX)K?2u)w5;G!I`jGiF7 zEP+F>s}n5l^rR;?U?StzkGS`L`0hk(=?#cnpXfYd6GzSru9uTv?<6e*;EjWgNmVP= zcz-wR>XJ2%!|y*sTCf<;R6H3W69##?0=}M$KCoioykH6#iz=avT_)-3Cq$Ey8@lqgX=X|b$WUQOMUiLA9|g3pkRKeHR1P?xo>Af>sh4H@aEh^4=p;d6J5Y3-W{2L zQX$k&yG3RmtoGDx9=|+m+wVAVR&lh2d~;-J6Zm-3lHe>sIvFeIp{!F5vaSb*l1bVJ zQ75u$m+Jr*;WYX6MqqFcd@mbBcnIH}^!MIIxKTrPX2GFMY^JiDo&V(xL#m#bRO-ft z=)jsUY^uP5_zj(!r=5#f?)7SBJ4}xbRk)kgys_W#JQ9_Q_mvL$M##GObLek&0OTDp z@lDl%uWs`2^s+pvBoQQY3-d&@zWL1B#FjHiujy~TKR#Uu)D>p96!mI1tv+p^8z?yA zh2LDlR^v@13y%%xK*Khl=3UI#U+v4Iz5y!6Qt0+o_iX?O3GU5=K?9FCgdqdIszANI zeQ@VdMuGKl>X(|PQz`KSZKKqqi+9e<&_CNaYE36QCOm?-Tg-`6HCK$uX9P^;y*#Qn znqXoSjMtYKF6&33qKSc?o_WBI` zrcdDG3WZUudi^a^o@5Pv$^egd5&matt)_BG_$kWayt+vM7asLKkwz9REeISsb7o-; z0)p@}2^CFh9Gi&`?Oh~)eHUw7g3eHce?5d^=>)H(yIiJxb0Wy#e8T2tGl{7%6t-5W zPBW4WfP}Vas%LXX-Ku!FhA(+))fz+E8@1wYOOp<~R_407_yUHI;%fqMFa^g71l+A& zMqSh^b@+P&1f@8jylJrz6%`)Dr#3?KV@Y0Ddq6>k;j8WwPG`P?ud3j3w5bUDwcaXy zFayljXPd*>fwj@);Z@ig!c+nZ*u%|miOL5Fwk6dxVWXv$QFSkW3lgB)&;WynzKu|kB?(LCB z(POZrzQXb{k$2jXI=juVIgSz148ZFqBvPbTDAGI%%4L+TZhk-DyDYInxd(!gA{?_x zvGd9C@e{<7D7drELv>W7U%bTx6FOK;fLq=5ooIJw9Ef@j7-oV3wG)I;nAZ3UhEr&R zXTX?y_T*D3>{`$f3I!ibecX?djIYwtBUm|hvgolmk+^L?x)=aq6#63Bi&B}GBdZKx zZb8s(JNOIMj?e)?+EPodGzzxUuY{_St5_)$vNApOKi=}R5qTQD?(!j}2d{M>@g`x* zc>&%mOpOd`LTn0s{qERI1|uBI%@1ZGr-zH2Y@x!mTVu>qo*DMbIuji~bQGKHrZHlC zcXin-W;4wDDDN9AqXbxPHMGh?DI8_S_)+osmQCRtky&6-h<3Gl@HI$+sWTW%4gRx- ztOc^q22@k5j{w%IaUr(!?)QlXJhr(>TuMxJgD^M_k5~<5Furcok+Y~7RfZawmuN(N zX)-$y^Vy%l3UZMo_nO=s8b{N)^D<|TQ)nT{nw~kuk*Jg6s`qy)HubA5z+1`EC>tr1 zTa)t9E1NIwM>+b4bIeS%-}NW_(u^L?@kU#0TYVY|qMMCgZipajS%HA21C)2nRysLg zCOvNA@WyN=c5(S^8%(8{g=Z1R=%W#OX{x4G3q2BFtSSn?jC(XG)+|lj)4+fH{w}Pf zj2KuQOf@pO*`D{YnJp|P9fTM$kirp$G$@qCM(U$dDu-`jy$+pPxl=Eo@8pzRW{Bo+ zLF1$^_v0&ABXtpAte3=Y;7AC=e{wb3Ef)tAny5$E3?Wi8ltvVR<7@^JO_hf+6M&e zF-kh!O<{jYq#LJlybw|W;x%P@m?BgRDzN>LKalhys8Ml43R&$AjSg4E=i8c?YmOSt z{sF-1=N5THfpb0Qaf@Q}=B=Yhq=I$nVY@K2v3s22qS#rFpxNXD))jYe+)akJ7;MfP zr=ADqe2fF{(j#@nf;l$|4LTP0mH8s}F;@3v1MPVt--5|hCQ2U^VJDiXN~cNyuJ zLfpJ8@yab|orsBNw5_3HY*`pa>mpAl{gG zf~{9$g5T4Knp-+LSi7c;If}P=C#koIGw-XoBq#WDJwIfF%rgJwQGHolw~3>Gy<%;Z zzeRN6Wm5EHd~3FIiPKG9BG{BgS-lAG$-U6qJc**RNtG8mqs~Fkkt>G;-G^iveC4BZv-~*=0=|j<55VAmi3o~S!F^VJeXtW&sc&YJtS1!bTSp2HVgWR4=iGA ztE+X0?<+7O0nS4;aOWP9xT(n#xsF$x8%Vb9%KtVpo~R}6ITv3kxenCB!WHf!OsOfgpq8&`<0ESX&U&x1$;X0s#jRM>rcJ6(6aa> zW1$2nSkPPDfG3loK43q0r`FcgAzPypD>uqtfwgOQwF;kAz5~_{k0g&@MzC9K^ryC;~M zhm778VB>c zxXxziE^pY(4zf8Fj4O6G@XcI|jiY$=W*iF3#rN?Y8y&DF%EaWk;b$Dq*lM!LF1+4`OjOp?jm21z5B@jreUlAciGYj>{C!*`Rt| zzn=p=FK`Fp5W`;S`}%GAOG00ya@4uI`>(``*~>DTy@_wXeQ0-bXGllE^r9f0%vC0E zo?8dL-gp-e(+6-8AL_6hDEI@*sb64bZY72u0pDABiceylC%rePGaeRZ1q`m_;c1Pr zXSiwP!m8T6Rq}BFvI%TT_=S9&k5OjTp15Q)bxJzD&vF3+OW{)Li2y|T&Gk?E-dLuk z!v|}f28)IRL-CHG+A

{U6;Kz9XV;$s4N{XQ5e8SHn5CTN_m~auwPdr|c>|v^6*) zxz2Vz-AK2NDiLu%>e^n zS!CZHG~CR~T(p^`{Dq->$bwJT0yxQ?9u12)8hbxQ=lp`VapHo1sTL2Z@vufiF(OvJ zzzCA*3rJ;CPQb&Svf@qOo7~9*iX#|nCb21 z7`_^jx{o;ZEXt80c!v<5q$BsZkI!d`-K&W6@2~q(m~Lb ztNEiwR3N|ukg5j|szH6X`XMP5%`kM;at)~`xL2x^s4pR;!(1shZ0>PJGF4!OGjoSB zQPv;-fR&0{DROC;np-T5lOTZ~941HA`jRa-)~Y>N0ld;6JL_d+&{Eg1gxW{JLogR)!CZa{XuT20S0VVD1$f0&3a zT`*01Y0U=>s`(%yhJy?=->#bW9g`J)r#tRi@G}6{aAA&A52sHLAGNP`8*w)FG_uS) zvA?*$H}k+_*Q&4AFBinRqjS|C#EjN**GXT;eX`&W#rV8Z3VUoTJ?s09%q>(cJQu*M1WyYXA*t6*(TJcPqhu_qqDCD`>sPjU z+|$92r3`wN_F1&$JViH43F@S4;{CV*y_e>Obia{^E?3h9;hhvXsV#XHL8d4J2Pjqj zp1VXcy{T(@QmrCG)g$OG51;}8$m+KKU;Q3o>+pPnvitI@3Q1W`c_=fV7$qIn(aEZH zY!)mxX;Wu+`L;v~-m6iYUwqBOM}T6N8M?@PmhITL)RyLDF~=eIWQahtHorDNu#92qCvQwf zfYl7`i$$G)xO9?#SsT3AgdZJc#X(>WY{v&O8o#Z7L+eovnCxbZ6OL}4^D!TKktc+! zeWePGew@k7UX&J`f}lJX|(vOeGbbkNq5|%}Qtz zVx7fAWMMYr=`7A6H630J5rB3>fC~Y-R8sJ|c=b1AHX}wOs%}a$6Z6?^TIDt1PoFIT z#n|eu_d3}z%(XZ-_VHKsgRz+U25R~GAz_7E2YWQAe-)7ffddZE7%G0o69jiEFdgPV zh1QgqHHNGl*zt;|F}Z4I)m#jm?JX;Qun2IF4Ruz%R8n&#%}3B#&2#LKL+HZuBFq8Z zKALZBVW$Kz#!X#R`?5EWrp?%UFm7Bf3v!&{8>e-Lmv9eGNlsw15Vs93e;JqS(IjtH z;N%=|oOmPDSM`q{T+75He_G)OCYaE}@bi5I#-l|)Rm}8J*yh5w46fM+6`4rM&|11ePGaltfWDqbB zZ{G^IYT{{PWKc?TwF=v_+QbGj$9Ua6HQdrBsLl}t5!Msq*Fn-{tx~0vPTN*>CLE5w zNzGc{)UppS>$$KBu&U!UMm4nUnfLlWeb@1x?+S5(j-e_tr);Z2k}>L1^$~kSB5`{&S7puTXcA;q4DM`qrc z#uNK%;3PC4z2hnOu$kI&HcnDjrh=kMr=S}{2Z&!1Oirx&i>cld191OViuCBBM5cbB zC2H3=mHN{6wGisNWEK_xHFUa$Z~TQIiK5oe&YNUV@0F0So3rk0hp43%winDdt_|yg zff=r?v$d1~lUYjO@VSOkLH&#n$ltQs4IpqW=5z6w1Xf(@LZ1~V{>#0VA*RDwDW6ms z(>WEV*Q6(?^+&q@hK&#pg>C?CcotNX$P`k*QUN3gz?)6`C)FlC%Y_NCZrWLlM=1l; z?#x@zicLV$Kc+TZ1@)Y2LWbU$Q};61k=U9~jX`g22UC958MzC)5~6y}>$?(p_kyig zv+^oFz1~(=8K{usRLZ{0pgK36Y$(Y+jm-6|V<~%{zeI<8Z#QkeT;O+y;cmoeF3UNqaUyWIiTs-quZTH#qDeJ@KPO6 zfw46F@DcHCjACc4Y$$a2m;<`$)V4_;c|aPe#~NkB6VPQlX7~nRFB-g>0Zr>t$OXcw zj68)ze}V}Z=2fDpm)wlgx;dXlq7MPFBAO|1 zk54Sg(I%H;HFRyXo8;jLTrFKeBZ~Ub*9^1%IZ9dpiSAUkWmcS`UE;uNS4o`1nFZd<8wLbPtN160vn z%F16#7<4ydJ5=E1a`#^jLXJUi$uMn zxkN_amv@u`D^0uf7>J-zfL(iiUq37GkG9H;5<#9?ikM2owWM)F+VrOXg0I8rqr;yMuLfqSyT|Lg|8%qG6`T-Fe9`FITKcpsdeF{R z$0}F-YvV?$2{Fy9+1N5DNgrq=?`kU7K>cb*?XBv!ty{;#cOB^5JT$SFTL8gL5)o}CUX|3UxkIJv++plJIsAhuKF%Y=avJnC0qe&c_JS6-d% zJXRI>;}aIWs`kLdGSBkPkAv0HvA9REwl}e%>VrC7(;cnwdJuHAN?Wj6 z5P53Yk8GC#|G@j>bqb=Y_&}>_9)y#BK)^`gPByUceC-CiVS^>bD@)Mm(T4#0*SB{p zXN(8f8Hh(cgTt6*4LD&%oBa;K>~8P26!QE^{8ramEIFw0#eC*<3x9z7fH5582_g}A zedDysoecl5!^8WV-#(^u8}o3odIVn4k!SNJn1spSqd?7}+$MB7*~d%P!5-+M)KM&- zAjHaH;OuJo2Zso}BU~=FM=d}Al+u=V!g7)^fUS+El)B*^?G$vqzmXH`ay5Uh`}Il? zUcKSxg;8!C07TG_1$FnwdimY1jS7Pg38N&T?!A*P53N!#H!aZg!|N;Nr^~>&bLo) z%){>AUI)Bs6R4{&`+8|o7!+u_?oZCWvhtjHK* zh+T08tbVCC8k++)dIW)cDA_Kq>Er^CE?X&87=_PRb;{UHD^a(_Lwn<>YJ^SsRVnNE z>aF+ePUwWTbuG=hZELB-ja%np_Q%M1k8wXeCe~A%1VI60(Kk{%5aTnu4g|CvM1gwEUIc5L(Zbf2`dRwrlR?>Y`hHf?-A3Tp&Fr0T&zj6~SzLKj0X#2youwO40jJz;6G zk6Sw(oLo{Zt2YR!6hq6IqyQM_I1<~yr1K;wL9a%(31a?fUOaK)@`BT(0m z)yC89l%WoMY|0TmG$>-Yc;kEIJ?8yau81afV0XHPe66KFw3awxq9!w%RSn3*^uV>i z_R4W-Q*GS3l(_PA^5nXue`TQi1R4JQZ7UHYt$%E^R+sZ7p`Be_zcewaISRz9b7TH2 z`)qP~AJS2)RVQm-u?NTJd8XHD6agk)ns8|}am0SzX zzf1;VvTxfh*uBz}f`1a`%d98e8l|a{wkS!_6Z2Wm(F5Q(%rW^<5*w2^N~^JI^=tB# zPFQvFm;)t$aq@#Ln{fp{(x zirS!(^N))pBJ3U)OcO#_LvzfH6IW zUS6Q4G*c@b)yWP1PJk(c?EQIZ|INQ2eNJ4>lYg|z!-y3C3Uc;@vYNzhNenA3+#>UI z!v?Q`U#I5!@BO-7E*W7=Ppf|*AmSJlI79n^21P?6=*DrXphyKwT1?G7NmV^ABM^{< zt8*%lUkB;>Z~y1s6lJ#vAWB}t3j$tC1eE3+TGM^wIrt4aSj2qkv^;qNBKE6yKL5ER zfDo)Z56CE+$ID&3>ilQoYC1Oge@~w$@2VKRWu71uMu0U-j{iI;vl~sn=---XB}a|0 z+eWY1*yNpE>hZ$qY|=35kAEHc8`9$~qz4GDM4*icRs&u;HWI=U!%^L7YEj$w2uJeH zvV3$7+oOD^iyttukY9E)5A=v%dB&FiIUfj?`2X)ofISW4vIzg2vo*S}7E^Mil?&jkkHy!-#m1J82)-3 z4i}f*t?d})?8#NCsF|XBTazzjw?E%@@f}5Xk3b2_RKSc|PZQX7u`g{$

ch<9G> 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

^fRCT7NOVJ&F-( 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�r|i^hfvJ+e{h*=*5~oOe7hV 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

7>+J`eD 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 literal 0 HcmV?d00001 diff --git a/docs/management/snapshot-restore/index.asciidoc b/docs/management/snapshot-restore/index.asciidoc index f309b2c17e0ed..f19aaa122675e 100644 --- a/docs/management/snapshot-restore/index.asciidoc +++ b/docs/management/snapshot-restore/index.asciidoc @@ -11,11 +11,11 @@ you can restore a snapshot from the repository. You’ll find *Snapshot and Restore* under *Management > Elasticsearch*. With this UI, you can: -* <> -* <> -* <> -* <> -* <> +* Register a repository for storing your snapshots +* View a list of your snapshots and drill down into details +* Restore data into your cluster from a snapshot +* Create a policy to automate snapshot creation and deletion +* Delete a snapshot to free storage space [role="screenshot"] image:management/snapshot-restore/images/snapshot_list.png["Snapshot list"] @@ -27,28 +27,34 @@ more detailed information. [float] [[kib-snapshot-register-repository]] === Register a repository +A repository is where your snapshots live. You must register a snapshot +repository before you can perform snapshot and restore operations. + +If you don't have a repository, Kibana walks you through the process of +registering one. +{kib} supports three repository types +out of the box: shared file system, read-only URL, and source-only. +For more information on these repositories and their settings, +see {ref}/modules-snapshots.html#snapshots-repositories[Repositories]. +To use other repositories, such as S3, see +{ref}/modules-snapshots.html#_repository_plugins[Repository plugins]. -The *Repositories* view provides an overview of your repositories. -Click a repository name to view its type, number of snapshots, and settings, and also to verify status. + +Once you create a repository, it is listed in the *Repositories* +view. +Click a repository name to view its type, number of snapshots, and settings, +and to verify status. [role="screenshot"] image:management/snapshot-restore/images/repository_list.png["Repository list"] -If you don't have a repository, you're prompted to register one. -{es} supports three repository types -out of the box: shared file system, read-only URL, and source-only. -For more information on these repositories and their settings, -see {ref}/modules-snapshots.html#snapshots-repositories[Repositories]. For an example, -see <>. - -To use other repositories, such as S3, you can install plugins. See -{ref}/modules-snapshots.html#_repository_plugins[Repository plugins]. [float] [[kib-view-snapshot]] === View your snapshots -The *Snapshots* view gives an overview of your snapshots. You can drill down +A snapshot is a backup taken from a running {es} cluster. You'll find an overview of +your snapshots in the *Snapshots* view, and you can drill down into each snapshot for further investigation. [role="screenshot"] @@ -68,18 +74,25 @@ the new data. [[kib-restore-snapshot]] === Restore a snapshot -The *Restore* wizard walks you through the process of restoring a snapshot -into a running cluster. To get started, go to the *Snapshots* view, find the -snapshot, and click the restore icon in the *Actions* column. +The information stored in a snapshot is not tied to a specific +cluster or a cluster name. This enables you to +restore a snapshot made from one cluster to another cluster. You might +use the restore operation to: -You’re presented -options for the restore, including which +* Recover data lost due to a failure +* Migrate a current Elasticsearch cluster to a new version +* Move data from one cluster to another cluster + +To get started, go to the *Snapshots* view, find the +snapshot, and click the restore icon in the *Actions* column. +The Restore wizard presents +options for the restore operation, including which indices to restore and whether to modify the index settings. You can restore an existing index only if it’s closed and has the same number of shards as the index in the snapshot. Once you initiate the restore, you're navigated to the *Restore Status* view, -where you can track the progress. +where you can track the current state for each shard in the snapshot. [role="screenshot"] image:management/snapshot-restore/images/snapshot-restore.png["Snapshot details"] @@ -89,23 +102,28 @@ image:management/snapshot-restore/images/snapshot-restore.png["Snapshot details" [[kib-snapshot-policy]] === Create a snapshot lifecycle policy -You can create policies to schedule automatic snapshots of your cluster. -{ref}/snapshot-lifecycle-management-api.html[Snapshot lifecycle policies] are related -to {ref}/index-lifecycle-management.html[index lifecycle policies]. -However, where an index lifecycle policy applies to a single index, -a snapshot lifecycle policy can span multiple indices. - -For an overview of your policies, open the *Policies* view. -You can drill down into each policy to examine its settings and last successful and failed run. - -If you don’t have any policies, use the *Create policy* wizard. -You’ll define the snapshots and repository, when to take snapshots, and -the settings, such as which indices the snapshot should contain. +Use a {ref}/snapshot-lifecycle-management-api.html[snapshot lifecycle policy] +to automate the creation and deletion +of cluster snapshots. Taking automatic snapshots: + +* Ensures your {es} indices and clusters are backed up on a regular basis +* Ensures a recent and relevant snapshot is available if a situation +arises where a cluster needs to be recovered +* Allows you to manage your snapshots in {kib}, instead of using a +third-party tool + +If you don’t have any snapshot policies, follow the +*Create policy* wizard. It walks you through defining +when and where to take snapshots, the settings you want, +and how long to retain snapshots. [role="screenshot"] -image:management/snapshot-restore/images/create-policy.png["Snapshot details"] +image:management/snapshot-restore/images/snapshot-retention.png["Snapshot details"] + +An overview of your policies is on the *Policies* view. +You can drill down into each policy to examine its settings and last successful and failed run. -You can perform the following actions on a policy: +You can perform the following actions on a snapshot policy: * *Run* a policy immediately without waiting for the scheduled time. This action is useful before an upgrade or before performing maintenance on indices. @@ -113,6 +131,9 @@ This action is useful before an upgrade or before performing maintenance on indi * *Delete* a policy to prevent any future snapshots from being taken. This action does not cancel any currently ongoing snapshots or remove any previously taken snapshots. +[role="screenshot"] +image:management/snapshot-restore/images/create-policy.png["Snapshot details"] + [float] [[kib-delete-snapshot]] === Delete a snapshot @@ -123,16 +144,25 @@ Find the snapshot in the *Snapshots* view and click the trash icon in the and then click *Delete snapshots*. [[snapshot-repositories-example]] -[float] -=== Example: Register a shared file system repository -This example shows how to register a shared file system repository -and store snapshots. +[role="xpack"] +[[snapshot-restore-tutorial]] +=== Tutorial: Snapshot and Restore -[float] -==== Register the repository location -You must register the location of the repository in the `path.repo` setting on +Ready to try *Snapshot and Restore*? In this tutorial, you'll learn to: + +* Register a repository +* Add snapshots to the repository +* Create a snapshot lifecycle policy +* Restore a snapshot + +==== Before you begin + +This example shows you how to register a shared file system repository +and store snapshots. +Before you begin, you must register the location of the repository in the +{ref}/modules-snapshots.html#_shared_file_system_repository[path.repo] setting on your master and data nodes. You can do this in one of two ways: * Edit your `elasticsearch.yml` to include the `path.repo` setting. @@ -142,30 +172,26 @@ your master and data nodes. You can do this in one of two ways: `bin/elasticsearch -E path.repo=/tmp/es-backups` [float] -==== Register the repository +[[register-repo-example]] +==== Register a repository Use *Snapshot and Restore* to register the repository where your snapshots will live. . Go to *Management > Elasticsearch > Snapshot and Restore*. -. Open the *Repositories* view. -. Click *Register a repository*. +. Click *Register a repository* in either the introductory message or *Repository view*. . Enter a name for your repository, for example, `my_backup`. -. Set *Repository type* to Shared file system. +. Select *Shared file system*. + [role="screenshot"] image:management/snapshot-restore/images/register_repo.png["Register repository"] . Click *Next*. -. In *Location*, enter the path to the snapshot repository, `/tmp/es-backups`. -. In *Chunk size*, enter 100mb so that snapshot files are not bigger than that size. -. Use the defaults for all other fields. -. Click *Register*. +. In *File system location*, enter the path to the snapshot repository, `/tmp/es-backups`. +. In *Chunk size*, enter `100mb` so that snapshot files are not bigger than that size. +. Use the defaults for all other fields, and then click *Register*. + Your new repository is listed on the *Repositories* view. -+ -. Click the respository and inspect its details. -+ The repository currently doesn’t have any snapshots. @@ -174,19 +200,105 @@ The repository currently doesn’t have any snapshots. Use the {ref}//modules-snapshots.html#snapshots-take-snapshot[snapshot API] to create a snapshot. . Go to *Dev Tools > Console*. -. Create the snapshot. +. Create the snapshot: ++ +[source,js] +PUT /_snapshot/my_backup/2019-04-25_snapshot?wait_for_completion=true + In this example, the snapshot name is `2019-04-25_snapshot`. You can also use {ref}//date-math-index-names.html[date math expression] for the snapshot name. + [role="screenshot"] image:management/snapshot-restore/images/create_snapshot.png["Create snapshot"] -+ -. Open *Snapshot and Restore*. + +. Return to *Snapshot and Restore*. + Your new snapshot is available in the *Snapshots* view. +[[create-policy-example]] +==== Create a snapshot lifecycle policy + +Now you'll automate the creation and deletion of snapshots +using the repository created in the previous example. + +. Open the *Policies* view. +. Click *Create a policy*. ++ +[role="screenshot"] +image:management/snapshot-restore/images/create-policy-example.png["Create policy wizard"] + +. As you walk through the wizard, enter the following values: ++ +|=== +|*Logistics* | + +|Policy name +|`daily-snapshots` + +|Snapshot name +|`` + +|Schedule +|Every day at 1:30 a.m. + +|Repository +|`my_backup` + +|*Snapshot settings* | +|Indices +|Select the indices to back up. By default, all indices, including system indices, are backed up. +|All other settings +|Use the defaults. +|*Snapshot retention* | + +|Expiration +|`30 days` + +|Snapshots to retain +|Minimum count: `5`, Maximum count: `50` +|=== + +. Review your input, and then click *Create policy*. ++ +Your new policy is listed in the *Policies* view, and you see a summary of its details. + +[[restore-snapshot-example]] +==== Restore a snapshot +Finally, you'll restore indices from an existing snapshot. + +. In the *Snapshots* view, find the snapshot you want to restore, for example `2019-04-25_snapshot`. +. Click the restore icon in the *Actions* column. +. As you walk through the wizard, enter the following values: ++ +|=== +|*Logistics* | + +|Indices +|Toggle to choose specific indices to restore, or leave in place to restore all indices. + +|Rename indices +|Toggle to give your restored indices new names, or leave in place to restore under original index names. + +|All other fields +|Use the defaults. + +|*Index settings* | + +|Modify index settings +|Toggle to overwrite index settings when they are restored, +or leave in place to keep existing settings. + +|Reset index settings +|Toggle to reset index settings back to the default when they are restored, +or leave in place to keep existing settings. +|=== + +. Review your restore settings, and then click *Restore snapshot*. ++ +The operation loads for a few seconds, +and then you’re navigated to *Restore Status*, +where you can monitor the status of your restored indices. From ed07fb4c065b0128de3eaf50b4837edc0bd44c7b Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Fri, 25 Oct 2019 16:32:59 -0400 Subject: [PATCH 44/61] [Expressions] [Lens] Implement a loading state and error state in the ExpressionRenderer (#48841) * Add loading indicator to Lens workspace panel * [Expressions] [Lens] Handle loading and errors in ExpressionRenderer * Using loading$ observable and improve tests * Using CSS and to handle layout of expression renderer Added TODO for using chart loader when area is completely empty * Improve error handling and simplify code * Fix cleanup behavior * Fix double render and prevent error cases in xy chart * Fix context for use in dashboards * Remove className from expression rendere component * Improve handling of additional interpreter args * More layout fixes - Hide chart if Empty not Loading - Fix relative positioning for progress bar since className is no longer passed (super hacky) --- src/legacy/core_plugins/expressions/index.ts | 1 + .../expressions/public/index.scss | 13 + .../np_ready/public/_expression_renderer.scss | 20 ++ .../public/np_ready/public/_index.scss | 1 + .../public/np_ready/public/execute.ts | 14 +- .../public/expression_renderer.test.tsx | 141 +++++++++ .../np_ready/public/expression_renderer.tsx | 110 +++++-- .../public/np_ready/public/index.ts | 2 +- .../public/np_ready/public/loader.test.ts | 108 ++++++- .../public/np_ready/public/loader.ts | 118 +++++--- .../np_ready/public/{mocks.ts => mocks.tsx} | 3 +- .../public/np_ready/public/plugin.ts | 5 +- .../public/np_ready/public/render.test.ts | 77 ++++- .../public/np_ready/public/render.ts | 76 +++-- .../public/np_ready/public/types.ts | 11 +- .../expression.tsx | 20 +- .../editor_frame/_expression_renderer.scss | 7 +- .../editor_frame/_suggestion_panel.scss | 13 +- .../_workspace_panel_wrapper.scss | 1 + .../editor_frame/suggestion_panel.tsx | 53 ++-- .../editor_frame/workspace_panel.test.tsx | 277 +++++++----------- .../editor_frame/workspace_panel.tsx | 82 ++++-- .../embeddable/embeddable.test.tsx | 20 -- .../embeddable/expression_wrapper.tsx | 25 +- .../metric_expression.tsx | 12 +- .../xy_visualization_plugin/xy_expression.tsx | 21 +- 26 files changed, 832 insertions(+), 399 deletions(-) create mode 100644 src/legacy/core_plugins/expressions/public/index.scss create mode 100644 src/legacy/core_plugins/expressions/public/np_ready/public/_expression_renderer.scss create mode 100644 src/legacy/core_plugins/expressions/public/np_ready/public/_index.scss create mode 100644 src/legacy/core_plugins/expressions/public/np_ready/public/expression_renderer.test.tsx rename src/legacy/core_plugins/expressions/public/np_ready/public/{mocks.ts => mocks.tsx} (97%) diff --git a/src/legacy/core_plugins/expressions/index.ts b/src/legacy/core_plugins/expressions/index.ts index b10e9a8dd5442..4ba9a74795d4c 100644 --- a/src/legacy/core_plugins/expressions/index.ts +++ b/src/legacy/core_plugins/expressions/index.ts @@ -34,6 +34,7 @@ export default function DataExpressionsPlugin(kibana: any) { init: (server: Legacy.Server) => ({}), uiExports: { injectDefaultVars: () => ({}), + styleSheetPaths: resolve(__dirname, 'public/index.scss'), }, }; diff --git a/src/legacy/core_plugins/expressions/public/index.scss b/src/legacy/core_plugins/expressions/public/index.scss new file mode 100644 index 0000000000000..6efc552bf319b --- /dev/null +++ b/src/legacy/core_plugins/expressions/public/index.scss @@ -0,0 +1,13 @@ +// Import the EUI global scope so we can use EUI constants +@import 'src/legacy/ui/public/styles/_styling_constants'; + +/* Expressions plugin styles */ + +// Prefix all styles with "exp" to avoid conflicts. +// Examples +// expChart +// expChart__legend +// expChart__legend--small +// expChart__legend-isLoading + +@import './np_ready/public/index'; diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/_expression_renderer.scss b/src/legacy/core_plugins/expressions/public/np_ready/public/_expression_renderer.scss new file mode 100644 index 0000000000000..4f030384ed883 --- /dev/null +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/_expression_renderer.scss @@ -0,0 +1,20 @@ +.expExpressionRenderer { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; +} + +.expExpressionRenderer__expression { + width: 100%; + height: 100%; +} + +.expExpressionRenderer-isEmpty, +.expExpressionRenderer-hasError { + .expExpressionRenderer__expression { + display: none; + } +} diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/_index.scss b/src/legacy/core_plugins/expressions/public/np_ready/public/_index.scss new file mode 100644 index 0000000000000..b9df491cd6e79 --- /dev/null +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/_index.scss @@ -0,0 +1 @@ +@import './expression_renderer'; diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/execute.ts b/src/legacy/core_plugins/expressions/public/np_ready/public/execute.ts index b4b11588b91bf..8043e0fb6e3f9 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/execute.ts +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/execute.ts @@ -61,6 +61,7 @@ export class ExpressionDataHandler { this.promise = interpreter.interpretAst(this.ast, params.context || defaultContext, { getInitialContext, inspectorAdapters: this.inspectorAdapters, + abortSignal: this.abortController.signal, }); } @@ -69,7 +70,18 @@ export class ExpressionDataHandler { }; getData = async () => { - return await this.promise; + try { + return await this.promise; + } catch (e) { + return { + type: 'error', + error: { + type: e.type, + message: e.message, + stack: e.stack, + }, + }; + } }; getExpression = () => { diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/expression_renderer.test.tsx b/src/legacy/core_plugins/expressions/public/np_ready/public/expression_renderer.test.tsx new file mode 100644 index 0000000000000..26db8753e6403 --- /dev/null +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/expression_renderer.test.tsx @@ -0,0 +1,141 @@ +/* + * 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 React from 'react'; +import { Subject } from 'rxjs'; +import { share } from 'rxjs/operators'; +import { ExpressionRendererImplementation } from './expression_renderer'; +import { ExpressionLoader } from './loader'; +import { mount } from 'enzyme'; +import { EuiProgress } from '@elastic/eui'; + +jest.mock('./loader', () => { + return { + ExpressionLoader: jest.fn().mockImplementation(() => { + return {}; + }), + loader: jest.fn(), + }; +}); + +describe('ExpressionRenderer', () => { + it('starts to load, resolves, and goes back to loading', () => { + const dataSubject = new Subject(); + const data$ = dataSubject.asObservable().pipe(share()); + const renderSubject = new Subject(); + const render$ = renderSubject.asObservable().pipe(share()); + const loadingSubject = new Subject(); + const loading$ = loadingSubject.asObservable().pipe(share()); + + (ExpressionLoader as jest.Mock).mockImplementation(() => { + return { + render$, + data$, + loading$, + update: jest.fn(), + }; + }); + + const instance = mount(); + + loadingSubject.next(); + instance.update(); + + expect(instance.find(EuiProgress)).toHaveLength(1); + + renderSubject.next(1); + + instance.update(); + + expect(instance.find(EuiProgress)).toHaveLength(0); + + instance.setProps({ expression: 'something new' }); + loadingSubject.next(); + instance.update(); + + expect(instance.find(EuiProgress)).toHaveLength(1); + + renderSubject.next(1); + instance.update(); + + expect(instance.find(EuiProgress)).toHaveLength(0); + }); + + it('should display an error message when the expression fails', () => { + const dataSubject = new Subject(); + const data$ = dataSubject.asObservable().pipe(share()); + const renderSubject = new Subject(); + const render$ = renderSubject.asObservable().pipe(share()); + const loadingSubject = new Subject(); + const loading$ = loadingSubject.asObservable().pipe(share()); + + (ExpressionLoader as jest.Mock).mockImplementation(() => { + return { + render$, + data$, + loading$, + update: jest.fn(), + }; + }); + + const instance = mount(); + + dataSubject.next('good data'); + renderSubject.next({ + type: 'error', + error: { message: 'render error' }, + }); + instance.update(); + + expect(instance.find(EuiProgress)).toHaveLength(0); + expect(instance.find('[data-test-subj="expression-renderer-error"]')).toHaveLength(1); + }); + + it('should display a custom error message if the user provides one', () => { + const dataSubject = new Subject(); + const data$ = dataSubject.asObservable().pipe(share()); + const renderSubject = new Subject(); + const render$ = renderSubject.asObservable().pipe(share()); + const loadingSubject = new Subject(); + const loading$ = loadingSubject.asObservable().pipe(share()); + + (ExpressionLoader as jest.Mock).mockImplementation(() => { + return { + render$, + data$, + loading$, + update: jest.fn(), + }; + }); + + const renderErrorFn = jest.fn().mockReturnValue(null); + + const instance = mount( + + ); + + renderSubject.next({ + type: 'error', + error: { message: 'render error' }, + }); + instance.update(); + + expect(renderErrorFn).toHaveBeenCalledWith('render error'); + }); +}); diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/expression_renderer.tsx b/src/legacy/core_plugins/expressions/public/np_ready/public/expression_renderer.tsx index 9edb5f098ba2e..8359663610f29 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/expression_renderer.tsx +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/expression_renderer.tsx @@ -17,49 +17,49 @@ * under the License. */ -import { useRef, useEffect } from 'react'; +import { useRef, useEffect, useState } from 'react'; import React from 'react'; -import { ExpressionAST, IExpressionLoaderParams, IInterpreterResult } from './types'; -import { IExpressionLoader, ExpressionLoader } from './loader'; +import classNames from 'classnames'; +import { EuiLoadingChart, EuiProgress } from '@elastic/eui'; +import { ExpressionAST, IExpressionLoaderParams, IInterpreterErrorResult } from './types'; +import { ExpressionLoader } from './loader'; // Accept all options of the runner as props except for the // dom element which is provided by the component itself export interface ExpressionRendererProps extends IExpressionLoaderParams { - className: string; dataAttrs?: string[]; expression: string | ExpressionAST; - /** - * If an element is specified, but the response of the expression run can't be rendered - * because it isn't a valid response or the specified renderer isn't available, - * this callback is called with the given result. - */ - onRenderFailure?: (result: IInterpreterResult) => void; + renderError?: (error?: string | null) => React.ReactElement | React.ReactElement[]; +} + +interface State { + isEmpty: boolean; + isLoading: boolean; + error: null | Error; } export type ExpressionRenderer = React.FC; -export const createRenderer = (loader: IExpressionLoader): ExpressionRenderer => ({ - className, +const defaultState: State = { + isEmpty: true, + isLoading: false, + error: null, +}; + +export const ExpressionRendererImplementation = ({ dataAttrs, expression, - onRenderFailure, + renderError, ...options }: ExpressionRendererProps) => { const mountpoint: React.MutableRefObject = useRef(null); const handlerRef: React.MutableRefObject = useRef(null); + const [state, setState] = useState({ ...defaultState }); + // Re-fetch data automatically when the inputs change useEffect(() => { - if (mountpoint.current) { - if (!handlerRef.current) { - handlerRef.current = loader(mountpoint.current, expression, options); - } else { - handlerRef.current.update(expression, options); - } - handlerRef.current.data$.toPromise().catch(result => { - if (onRenderFailure) { - onRenderFailure(result); - } - }); + if (handlerRef.current) { + handlerRef.current.update(expression, options); } }, [ expression, @@ -67,8 +67,66 @@ export const createRenderer = (loader: IExpressionLoader): ExpressionRenderer => options.context, options.variables, options.disableCaching, - mountpoint.current, ]); - return
; + // Initialize the loader only once + useEffect(() => { + if (mountpoint.current && !handlerRef.current) { + handlerRef.current = new ExpressionLoader(mountpoint.current, expression, options); + + handlerRef.current.loading$.subscribe(() => { + if (!handlerRef.current) { + return; + } + setState(prevState => ({ ...prevState, isLoading: true })); + }); + handlerRef.current.render$.subscribe((item: number | IInterpreterErrorResult) => { + if (!handlerRef.current) { + return; + } + if (typeof item !== 'number') { + setState(() => ({ + ...defaultState, + isEmpty: false, + error: item.error, + })); + } else { + setState(() => ({ + ...defaultState, + isEmpty: false, + })); + } + }); + } + }, [mountpoint.current]); + + useEffect(() => { + // We only want a clean up to run when the entire component is unloaded, not on every render + return function cleanup() { + if (handlerRef.current) { + handlerRef.current.destroy(); + handlerRef.current = null; + } + }; + }, []); + + const classes = classNames('expExpressionRenderer', { + 'expExpressionRenderer-isEmpty': state.isEmpty, + 'expExpressionRenderer-hasError': !!state.error, + }); + + return ( +
+ {state.isEmpty ? : null} + {state.isLoading ? : null} + {!state.isLoading && state.error ? ( + renderError ? ( + renderError(state.error.message) + ) : ( +
{state.error.message}
+ ) + ) : null} +
+
+ ); }; diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/index.ts b/src/legacy/core_plugins/expressions/public/np_ready/public/index.ts index 428b431d298ad..2ff71a6df60cf 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/index.ts +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/index.ts @@ -22,7 +22,7 @@ import { ExpressionsPublicPlugin } from './plugin'; export * from './plugin'; export { ExpressionRenderer, ExpressionRendererProps } from './expression_renderer'; -export { IInterpreterRenderFunction } from './types'; +export { IInterpreterRenderFunction, IInterpreterRenderHandlers } from './types'; export function plugin(initializerContext: PluginInitializerContext) { return new ExpressionsPublicPlugin(initializerContext); diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/loader.test.ts b/src/legacy/core_plugins/expressions/public/np_ready/public/loader.test.ts index df695c039e02e..36917bf4e8384 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/loader.test.ts +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/loader.test.ts @@ -19,6 +19,7 @@ import { first } from 'rxjs/operators'; import { loader, ExpressionLoader } from './loader'; +import { ExpressionDataHandler } from './execute'; import { fromExpression } from '@kbn/interpreter/common'; import { IInterpreterRenderHandlers } from './types'; import { Observable } from 'rxjs'; @@ -48,27 +49,37 @@ jest.mock('./services', () => { }; }); +jest.mock('./execute', () => { + const actual = jest.requireActual('./execute'); + return { + ExpressionDataHandler: jest + .fn() + .mockImplementation((...args) => new actual.ExpressionDataHandler(...args)), + execute: jest.fn().mockReturnValue(actual.execute), + }; +}); + describe('execute helper function', () => { - it('returns ExpressionDataHandler instance', () => { + it('returns ExpressionLoader instance', () => { const response = loader(element, '', {}); expect(response).toBeInstanceOf(ExpressionLoader); }); }); -describe('ExpressionDataHandler', () => { +describe('ExpressionLoader', () => { const expressionString = ''; describe('constructor', () => { it('accepts expression string', () => { - const expressionDataHandler = new ExpressionLoader(element, expressionString, {}); - expect(expressionDataHandler.getExpression()).toEqual(expressionString); + const expressionLoader = new ExpressionLoader(element, expressionString, {}); + expect(expressionLoader.getExpression()).toEqual(expressionString); }); it('accepts expression AST', () => { const expressionAST = fromExpression(expressionString) as ExpressionAST; - const expressionDataHandler = new ExpressionLoader(element, expressionAST, {}); - expect(expressionDataHandler.getExpression()).toEqual(expressionString); - expect(expressionDataHandler.getAst()).toEqual(expressionAST); + const expressionLoader = new ExpressionLoader(element, expressionAST, {}); + expect(expressionLoader.getExpression()).toEqual(expressionString); + expect(expressionLoader.getAst()).toEqual(expressionAST); }); it('creates observables', () => { @@ -117,9 +128,86 @@ describe('ExpressionDataHandler', () => { expect(response).toBe(2); }); - it('cancel() aborts request', () => { - const expressionDataHandler = new ExpressionLoader(element, expressionString, {}); - expressionDataHandler.cancel(); + it('cancels the previous request when the expression is updated', () => { + const cancelMock = jest.fn(); + + (ExpressionDataHandler as jest.Mock).mockImplementationOnce(() => ({ + getData: () => true, + cancel: cancelMock, + })); + + const expressionLoader = new ExpressionLoader(element, expressionString, {}); + expressionLoader.update('new', {}); + + expect(cancelMock).toHaveBeenCalledTimes(1); + }); + + it('does not send an observable message if a request was aborted', () => { + const cancelMock = jest.fn(); + + const getData = jest + .fn() + .mockResolvedValueOnce({ + type: 'error', + error: { + name: 'AbortError', + }, + }) + .mockResolvedValueOnce({ + type: 'real', + }); + + (ExpressionDataHandler as jest.Mock).mockImplementationOnce(() => ({ + getData, + cancel: cancelMock, + })); + (ExpressionDataHandler as jest.Mock).mockImplementationOnce(() => ({ + getData, + cancel: cancelMock, + })); + + const expressionLoader = new ExpressionLoader(element, expressionString, {}); + + expect.assertions(2); + expressionLoader.data$.subscribe({ + next(data) { + expect(data).toEqual({ + type: 'real', + }); + }, + error() { + expect(false).toEqual('Should not be called'); + }, + }); + + expressionLoader.update('new expression', {}); + + expect(getData).toHaveBeenCalledTimes(2); + }); + + it('sends an observable error if the data fetching failed', () => { + const cancelMock = jest.fn(); + + const getData = jest.fn().mockResolvedValue('rejected'); + + (ExpressionDataHandler as jest.Mock).mockImplementationOnce(() => ({ + getData, + cancel: cancelMock, + })); + + const expressionLoader = new ExpressionLoader(element, expressionString, {}); + + expect.assertions(2); + expressionLoader.data$.subscribe({ + next(data) { + expect(data).toEqual('Should not be called'); + }, + error(error) { + expect(error.message).toEqual('Could not fetch data'); + }, + }); + + expect(getData).toHaveBeenCalledTimes(1); }); it('inspect() returns correct inspector adapters', () => { diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/loader.ts b/src/legacy/core_plugins/expressions/public/np_ready/public/loader.ts index b07b0048bfd52..709fbc78a9b52 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/loader.ts +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/loader.ts @@ -18,11 +18,11 @@ */ import { Observable, Subject } from 'rxjs'; -import { first, share } from 'rxjs/operators'; +import { share } from 'rxjs/operators'; import { Adapters, InspectorSession } from '../../../../../../plugins/inspector/public'; -import { execute, ExpressionDataHandler } from './execute'; +import { ExpressionDataHandler } from './execute'; import { ExpressionRenderHandler } from './render'; -import { RenderId, Data, IExpressionLoaderParams, ExpressionAST } from './types'; +import { Data, IExpressionLoaderParams, ExpressionAST } from './types'; import { getInspector } from './services'; export class ExpressionLoader { @@ -32,12 +32,12 @@ export class ExpressionLoader { events$: ExpressionRenderHandler['events$']; loading$: Observable; - private dataHandler!: ExpressionDataHandler; + private dataHandler: ExpressionDataHandler | undefined; private renderHandler: ExpressionRenderHandler; private dataSubject: Subject; private loadingSubject: Subject; private data: Data; - private params: IExpressionLoaderParams; + private params: IExpressionLoaderParams = {}; constructor( element: HTMLElement, @@ -63,76 +63,108 @@ export class ExpressionLoader { this.render(data); }); - this.params = { - searchContext: { type: 'kibana_context' }, - extraHandlers: params.extraHandlers, - }; + this.setParams(params); - this.execute(expression, params); + this.loadData(expression, this.params); } - destroy() {} + destroy() { + this.dataSubject.complete(); + this.loadingSubject.complete(); + this.renderHandler.destroy(); + if (this.dataHandler) { + this.dataHandler.cancel(); + } + } cancel() { - this.dataHandler.cancel(); + if (this.dataHandler) { + this.dataHandler.cancel(); + } } - getExpression(): string { - return this.dataHandler.getExpression(); + getExpression(): string | undefined { + if (this.dataHandler) { + return this.dataHandler.getExpression(); + } } - getAst(): ExpressionAST { - return this.dataHandler.getAst(); + getAst(): ExpressionAST | undefined { + if (this.dataHandler) { + return this.dataHandler.getAst(); + } } getElement(): HTMLElement { return this.renderHandler.getElement(); } - openInspector(title: string): InspectorSession { - return getInspector().open(this.inspect(), { - title, - }); + openInspector(title: string): InspectorSession | undefined { + const inspector = this.inspect(); + if (inspector) { + return getInspector().open(inspector, { + title, + }); + } } - inspect(): Adapters { - return this.dataHandler.inspect(); + inspect(): Adapters | undefined { + if (this.dataHandler) { + return this.dataHandler.inspect(); + } } - update(expression?: string | ExpressionAST, params?: IExpressionLoaderParams): Promise { - const promise = this.render$.pipe(first()).toPromise(); - if (params && params.searchContext && this.params.searchContext) { - this.params.searchContext = _.defaults( - {}, - params.searchContext, - this.params.searchContext - ) as any; - } + update(expression?: string | ExpressionAST, params?: IExpressionLoaderParams): void { + this.setParams(params); - this.loadingSubject.next(); if (expression) { - this.execute(expression, this.params); + this.loadData(expression, this.params); } else { this.render(this.data); } - return promise; } - private execute = async ( + private loadData = async ( expression: string | ExpressionAST, - params?: IExpressionLoaderParams - ): Promise => { + params: IExpressionLoaderParams + ): Promise => { + this.loadingSubject.next(); if (this.dataHandler) { this.dataHandler.cancel(); } - this.dataHandler = execute(expression, params); - this.data = await this.dataHandler.getData(); - this.dataSubject.next(this.data); - return this.data; + this.setParams(params); + this.dataHandler = new ExpressionDataHandler(expression, params); + const data = await this.dataHandler.getData(); + this.dataSubject.next(data); }; - private async render(data: Data): Promise { - return this.renderHandler.render(data, this.params.extraHandlers); + private render(data: Data): void { + this.loadingSubject.next(); + this.renderHandler.render(data, this.params.extraHandlers); + } + + private setParams(params?: IExpressionLoaderParams) { + if (!params || !Object.keys(params).length) { + return; + } + + if (params.searchContext && this.params.searchContext) { + this.params.searchContext = _.defaults( + {}, + params.searchContext, + this.params.searchContext + ) as any; + } + if (params.extraHandlers && this.params) { + this.params.extraHandlers = params.extraHandlers; + } + + if (!Object.keys(this.params).length) { + this.params = { + ...params, + searchContext: { type: 'kibana_context', ...(params.searchContext || {}) }, + }; + } } } diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/mocks.ts b/src/legacy/core_plugins/expressions/public/np_ready/public/mocks.tsx similarity index 97% rename from src/legacy/core_plugins/expressions/public/np_ready/public/mocks.ts rename to src/legacy/core_plugins/expressions/public/np_ready/public/mocks.tsx index 6569e8d8d1ec5..1a2f473f4c9a1 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/mocks.ts +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/mocks.tsx @@ -17,6 +17,7 @@ * under the License. */ +import React from 'react'; import { ExpressionsSetup, ExpressionsStart, plugin as pluginInitializer } from '.'; /* eslint-disable */ import { coreMock } from '../../../../../../core/public/mocks'; @@ -44,7 +45,7 @@ const createExpressionsSetupMock = (): ExpressionsSetup => { function createExpressionsStartMock(): ExpressionsStart { return { - ExpressionRenderer: jest.fn(() => null), + ExpressionRenderer: jest.fn(props => <>), execute: jest.fn(), loader: jest.fn(), render: jest.fn(), diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/plugin.ts b/src/legacy/core_plugins/expressions/public/np_ready/public/plugin.ts index 5a0eecc51ef19..ec70248694990 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/plugin.ts +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/plugin.ts @@ -34,7 +34,7 @@ import { } from '../../../../../../plugins/inspector/public'; import { IInterpreter } from './types'; import { setInterpreter, setInspector, setRenderersRegistry } from './services'; -import { createRenderer } from './expression_renderer'; +import { ExpressionRendererImplementation } from './expression_renderer'; import { ExpressionLoader, loader } from './loader'; import { ExpressionDataHandler, execute } from './execute'; import { ExpressionRenderHandler, render } from './render'; @@ -77,17 +77,16 @@ export class ExpressionsPublicPlugin } public start(core: CoreStart, { inspector }: ExpressionsStartDeps) { - const ExpressionRenderer = createRenderer(loader); setInspector(inspector); return { execute, render, loader, + ExpressionRenderer: ExpressionRendererImplementation, ExpressionDataHandler, ExpressionRenderHandler, ExpressionLoader, - ExpressionRenderer, }; } diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/render.test.ts b/src/legacy/core_plugins/expressions/public/np_ready/public/render.test.ts index cf606b8fabec2..9d555f9760ee7 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/render.test.ts +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/render.test.ts @@ -20,6 +20,8 @@ import { render, ExpressionRenderHandler } from './render'; import { Observable } from 'rxjs'; import { IInterpreterRenderHandlers } from './types'; +import { getRenderersRegistry } from './services'; +import { first } from 'rxjs/operators'; const element: HTMLElement = {} as HTMLElement; @@ -31,10 +33,11 @@ jest.mock('./services', () => { }, }, }; + return { - getRenderersRegistry: () => ({ - get: (id: string) => renderers[id], - }), + getRenderersRegistry: jest.fn(() => ({ + get: jest.fn((id: string) => renderers[id]), + })), }; }); @@ -46,8 +49,6 @@ describe('render helper function', () => { }); describe('ExpressionRenderHandler', () => { - const data = { type: 'render', as: 'test' }; - it('constructor creates observers', () => { const expressionRenderHandler = new ExpressionRenderHandler(element); expect(expressionRenderHandler.events$).toBeInstanceOf(Observable); @@ -61,27 +62,71 @@ describe('ExpressionRenderHandler', () => { }); describe('render()', () => { - it('throws if invalid data is provided', async () => { + it('sends an observable error and keeps it open if invalid data is provided', async () => { const expressionRenderHandler = new ExpressionRenderHandler(element); - await expect(expressionRenderHandler.render({})).rejects.toThrow(); + const promise1 = expressionRenderHandler.render$.pipe(first()).toPromise(); + expressionRenderHandler.render(false); + await expect(promise1).resolves.toEqual({ + type: 'error', + error: { + message: 'invalid data provided to the expression renderer', + }, + }); + + const promise2 = expressionRenderHandler.render$.pipe(first()).toPromise(); + expressionRenderHandler.render(false); + await expect(promise2).resolves.toEqual({ + type: 'error', + error: { + message: 'invalid data provided to the expression renderer', + }, + }); }); - it('throws if renderer does not exist', async () => { + it('sends an observable error if renderer does not exist', async () => { const expressionRenderHandler = new ExpressionRenderHandler(element); - await expect( - expressionRenderHandler.render({ type: 'render', as: 'something' }) - ).rejects.toThrow(); + const promise = expressionRenderHandler.render$.pipe(first()).toPromise(); + expressionRenderHandler.render({ type: 'render', as: 'something' }); + await expect(promise).resolves.toEqual({ + type: 'error', + error: { + message: `invalid renderer id 'something'`, + }, + }); }); - it('returns a promise', () => { + it('sends an observable error if the rendering function throws', async () => { + (getRenderersRegistry as jest.Mock).mockReturnValueOnce({ get: () => true }); + (getRenderersRegistry as jest.Mock).mockReturnValueOnce({ + get: () => ({ + render: () => { + throw new Error('renderer error'); + }, + }), + }); + const expressionRenderHandler = new ExpressionRenderHandler(element); - expect(expressionRenderHandler.render(data)).toBeInstanceOf(Promise); + const promise = expressionRenderHandler.render$.pipe(first()).toPromise(); + expressionRenderHandler.render({ type: 'render', as: 'something' }); + await expect(promise).resolves.toEqual({ + type: 'error', + error: { + message: 'renderer error', + }, + }); }); - it('resolves a promise once rendering is complete', async () => { + it('sends a next observable once rendering is complete', () => { const expressionRenderHandler = new ExpressionRenderHandler(element); - const response = await expressionRenderHandler.render(data); - expect(response).toBe(1); + expect.assertions(1); + return new Promise(resolve => { + expressionRenderHandler.render$.subscribe(renderCount => { + expect(renderCount).toBe(1); + resolve(); + }); + + expressionRenderHandler.render({ type: 'render', as: 'test' }); + }); }); }); }); diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/render.ts b/src/legacy/core_plugins/expressions/public/np_ready/public/render.ts index 96f56a4b36202..f67b4c2d8e272 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/render.ts +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/render.ts @@ -19,7 +19,7 @@ import { Observable } from 'rxjs'; import * as Rx from 'rxjs'; -import { share, first } from 'rxjs/operators'; +import { share } from 'rxjs/operators'; import { event, RenderId, Data, IInterpreterRenderHandlers } from './types'; import { getRenderersRegistry } from './services'; @@ -33,19 +33,22 @@ export class ExpressionRenderHandler { private element: HTMLElement; private destroyFn?: any; private renderCount: number = 0; + private renderSubject: Rx.Subject; + private eventsSubject: Rx.Subject; + private updateSubject: Rx.Subject; private handlers: IInterpreterRenderHandlers; constructor(element: HTMLElement) { this.element = element; - const eventsSubject = new Rx.Subject(); - this.events$ = eventsSubject.asObservable().pipe(share()); + this.eventsSubject = new Rx.Subject(); + this.events$ = this.eventsSubject.asObservable().pipe(share()); - const renderSubject = new Rx.Subject(); - this.render$ = renderSubject.asObservable().pipe(share()); + this.renderSubject = new Rx.Subject(); + this.render$ = this.renderSubject.asObservable().pipe(share()); - const updateSubject = new Rx.Subject(); - this.update$ = updateSubject.asObservable().pipe(share()); + this.updateSubject = new Rx.Subject(); + this.update$ = this.updateSubject.asObservable().pipe(share()); this.handlers = { onDestroy: (fn: any) => { @@ -53,39 +56,68 @@ export class ExpressionRenderHandler { }, done: () => { this.renderCount++; - renderSubject.next(this.renderCount); + this.renderSubject.next(this.renderCount); }, reload: () => { - updateSubject.next(null); + this.updateSubject.next(null); }, update: params => { - updateSubject.next(params); + this.updateSubject.next(params); }, event: data => { - eventsSubject.next(data); + this.eventsSubject.next(data); }, }; } - render = async (data: Data, extraHandlers: IExpressionRendererExtraHandlers = {}) => { - if (!data || data.type !== 'render' || !data.as) { - throw new Error('invalid data provided to expression renderer'); + render = (data: Data, extraHandlers: IExpressionRendererExtraHandlers = {}) => { + if (!data || typeof data !== 'object') { + this.renderSubject.next({ + type: 'error', + error: { + message: 'invalid data provided to the expression renderer', + }, + }); + return; } - if (!getRenderersRegistry().get(data.as)) { - throw new Error(`invalid renderer id '${data.as}'`); + if (data.type !== 'render' || !data.as) { + if (data.type === 'error') { + this.renderSubject.next(data); + } else { + this.renderSubject.next({ + type: 'error', + error: { message: 'invalid data provided to the expression renderer' }, + }); + } + return; } - const promise = this.render$.pipe(first()).toPromise(); - - getRenderersRegistry() - .get(data.as) - .render(this.element, data.value, { ...this.handlers, ...extraHandlers }); + if (!getRenderersRegistry().get(data.as)) { + this.renderSubject.next({ + type: 'error', + error: { message: `invalid renderer id '${data.as}'` }, + }); + return; + } - return promise; + try { + // Rendering is asynchronous, completed by handlers.done() + getRenderersRegistry() + .get(data.as) + .render(this.element, data.value, { ...this.handlers, ...extraHandlers }); + } catch (e) { + this.renderSubject.next({ + type: 'error', + error: { type: e.type, message: e.message }, + }); + } }; destroy = () => { + this.renderSubject.complete(); + this.eventsSubject.complete(); + this.updateSubject.complete(); if (this.destroyFn) { this.destroyFn(); } 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 09aaa363c9492..0390440298c55 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 @@ -52,16 +52,25 @@ export interface IExpressionLoaderParams { export interface IInterpreterHandlers { getInitialContext: IGetInitialContext; inspectorAdapters?: Adapters; + abortSignal?: AbortSignal; } -export interface IInterpreterResult { +export interface IInterpreterErrorResult { + type: 'error'; + error: { message: string; name: string; stack: string }; +} + +export interface IInterpreterSuccessResult { type: string; as?: string; value?: unknown; error?: unknown; } +export type IInterpreterResult = IInterpreterSuccessResult & IInterpreterErrorResult; + export interface IInterpreterRenderHandlers { + // Done increments the number of rendering successes done: () => void; onDestroy: (fn: () => void) => void; reload: () => void; diff --git a/x-pack/legacy/plugins/lens/public/datatable_visualization_plugin/expression.tsx b/x-pack/legacy/plugins/lens/public/datatable_visualization_plugin/expression.tsx index 23b49ecc168cc..e350e36b3bdc0 100644 --- a/x-pack/legacy/plugins/lens/public/datatable_visualization_plugin/expression.tsx +++ b/x-pack/legacy/plugins/lens/public/datatable_visualization_plugin/expression.tsx @@ -11,7 +11,10 @@ import { EuiBasicTable } from '@elastic/eui'; import { ExpressionFunction } from '../../../../../../src/plugins/expressions/common'; import { KibanaDatatable } from '../../../../../../src/legacy/core_plugins/interpreter/public'; import { LensMultiTable } from '../types'; -import { IInterpreterRenderFunction } from '../../../../../../src/legacy/core_plugins/expressions/public'; +import { + IInterpreterRenderFunction, + IInterpreterRenderHandlers, +} from '../../../../../../src/legacy/core_plugins/expressions/public'; import { FormatFactory } from '../../../../../../src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities'; import { VisualizationContainer } from '../visualization_container'; @@ -113,8 +116,19 @@ export const getDatatableRenderer = ( help: '', validate: () => {}, reuseDomNode: true, - render: async (domNode: Element, config: DatatableProps, _handlers: unknown) => { - ReactDOM.render(, domNode); + render: async ( + domNode: Element, + config: DatatableProps, + handlers: IInterpreterRenderHandlers + ) => { + ReactDOM.render( + , + domNode, + () => { + handlers.done(); + } + ); + handlers.onDestroy(() => ReactDOM.unmountComponentAtNode(domNode)); }, }); diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_expression_renderer.scss b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_expression_renderer.scss index 5d181b9c06da8..8f8dc2323b0b7 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_expression_renderer.scss +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_expression_renderer.scss @@ -1,11 +1,12 @@ .lnsExpressionRenderer { + position: relative; width: 100%; height: 100%; display: flex; overflow-x: hidden; padding: $euiSize; -} -.lnsExpressionRenderer > * { - flex: 1; + > .expExpressionRenderer { + position: static; // Let the progress indicator position itself against the outer parent + } } diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_suggestion_panel.scss b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_suggestion_panel.scss index 0e89bbe2da968..cb4ca425afc84 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_suggestion_panel.scss +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_suggestion_panel.scss @@ -16,6 +16,7 @@ } .lnsSuggestionPanel__button { + position: relative; // Let the expression progress indicator position itself against the button flex: 0 0 auto; width: $lnsSuggestionWidth !important; // sass-lint:disable-line no-important height: $lnsSuggestionHeight; @@ -45,16 +46,22 @@ .lnsSuggestionPanel__chartWrapper { display: flex; - height: $lnsSuggestionHeight - $euiSize; + height: 100%; + width: 100%; pointer-events: none; - margin: 0 $euiSizeS; + padding: $euiSizeS; + + > .expExpressionRenderer { + position: static; // Let the progress indicator position itself against the button + } } .lnsSuggestionPanel__chartWrapper--withLabel { - height: $lnsSuggestionHeight - $euiSizeL; + height: calc(100% - #{$euiSizeL}); } .lnsSuggestionPanel__buttonLabel { + @include euiTextTruncate; @include euiFontSizeXS; display: block; font-weight: $euiFontWeightBold; diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_workspace_panel_wrapper.scss b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_workspace_panel_wrapper.scss index 7811df93ba8ce..3ef387eca1e8b 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_workspace_panel_wrapper.scss +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_workspace_panel_wrapper.scss @@ -22,6 +22,7 @@ align-items: stretch; justify-content: stretch; overflow: auto; + position: relative; > * { flex: 1 1 100%; diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.tsx index e2f9bd84560de..6aee215d11591 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.tsx @@ -63,38 +63,33 @@ const PreviewRenderer = ({ expression: string; ExpressionRendererComponent: ExpressionRenderer; }) => { - const [expressionError, setExpressionError] = useState(false); - - useEffect(() => { - setExpressionError(false); - }, [expression]); - - return expressionError ? ( -
- -
- ) : ( - { - // eslint-disable-next-line no-console - console.error(`Failed to render preview: `, e); - setExpressionError(true); - }} - /> + > + { + return ( +
+ +
+ ); + }} + /> +
); }; diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/workspace_panel.test.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/workspace_panel.test.tsx index ddb82565e4b8b..9cf59f69c0cc2 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/workspace_panel.test.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/workspace_panel.test.tsx @@ -392,190 +392,135 @@ describe('workspace_panel', () => { expect(expressionRendererMock).toHaveBeenCalledTimes(2); }); - describe('expression failures', () => { - it('should show an error message if the expression fails to parse', () => { - mockDatasource.toExpression.mockReturnValue('|||'); - mockDatasource.getLayers.mockReturnValue(['first']); - const framePublicAPI = createMockFramePublicAPI(); - framePublicAPI.datasourceLayers = { - first: mockDatasource.publicAPIMock, - }; - - instance = mount( - 'vis' }, - }} - visualizationState={{}} - dispatch={() => {}} - ExpressionRenderer={expressionRendererMock} - core={coreMock.createSetup()} - /> - ); - - expect(instance.find('[data-test-subj="expression-failure"]').first()).toBeTruthy(); - expect(instance.find(expressionRendererMock)).toHaveLength(0); - }); - - it('should show an error message if the expression fails to render', async () => { - mockDatasource.toExpression.mockReturnValue('datasource'); - mockDatasource.getLayers.mockReturnValue(['first']); - const framePublicAPI = createMockFramePublicAPI(); - framePublicAPI.datasourceLayers = { - first: mockDatasource.publicAPIMock, - }; - expressionRendererMock = jest.fn(({ onRenderFailure }) => { - Promise.resolve().then(() => onRenderFailure!({ type: 'error' })); - return ; - }); - - instance = mount( - 'vis' }, - }} - visualizationState={{}} - dispatch={() => {}} - ExpressionRenderer={expressionRendererMock} - core={coreMock.createSetup()} - /> - ); - - // "wait" for the expression to execute - await waitForPromises(); + it('should show an error message if the expression fails to parse', () => { + mockDatasource.toExpression.mockReturnValue('|||'); + mockDatasource.getLayers.mockReturnValue(['first']); + const framePublicAPI = createMockFramePublicAPI(); + framePublicAPI.datasourceLayers = { + first: mockDatasource.publicAPIMock, + }; - instance.update(); + instance = mount( + 'vis' }, + }} + visualizationState={{}} + dispatch={() => {}} + ExpressionRenderer={expressionRendererMock} + core={coreMock.createSetup()} + /> + ); - expect(instance.find('EuiFlexItem[data-test-subj="expression-failure"]')).toHaveLength(1); - expect(instance.find(expressionRendererMock)).toHaveLength(0); - }); + expect(instance.find('[data-test-subj="expression-failure"]').first()).toBeTruthy(); + expect(instance.find(expressionRendererMock)).toHaveLength(0); + }); - it('should not attempt to run the expression again if it does not change', async () => { - mockDatasource.toExpression.mockReturnValue('datasource'); - mockDatasource.getLayers.mockReturnValue(['first']); - const framePublicAPI = createMockFramePublicAPI(); - framePublicAPI.datasourceLayers = { - first: mockDatasource.publicAPIMock, - }; - expressionRendererMock = jest.fn(({ onRenderFailure }) => { - Promise.resolve().then(() => onRenderFailure!({ type: 'error' })); - return ; - }); + it('should not attempt to run the expression again if it does not change', async () => { + mockDatasource.toExpression.mockReturnValue('datasource'); + mockDatasource.getLayers.mockReturnValue(['first']); + const framePublicAPI = createMockFramePublicAPI(); + framePublicAPI.datasourceLayers = { + first: mockDatasource.publicAPIMock, + }; - instance = mount( - 'vis' }, - }} - visualizationState={{}} - dispatch={() => {}} - ExpressionRenderer={expressionRendererMock} - core={coreMock.createSetup()} - /> - ); + instance = mount( + 'vis' }, + }} + visualizationState={{}} + dispatch={() => {}} + ExpressionRenderer={expressionRendererMock} + core={coreMock.createSetup()} + /> + ); - // "wait" for the expression to execute - await waitForPromises(); + // "wait" for the expression to execute + await waitForPromises(); - instance.update(); + instance.update(); - expect(expressionRendererMock).toHaveBeenCalledTimes(1); + expect(expressionRendererMock).toHaveBeenCalledTimes(1); - instance.update(); + instance.update(); - expect(expressionRendererMock).toHaveBeenCalledTimes(1); - }); + expect(expressionRendererMock).toHaveBeenCalledTimes(1); + }); - it('should attempt to run the expression again if changes after an error', async () => { - mockDatasource.toExpression.mockReturnValue('datasource'); - mockDatasource.getLayers.mockReturnValue(['first']); - const framePublicAPI = createMockFramePublicAPI(); - framePublicAPI.datasourceLayers = { - first: mockDatasource.publicAPIMock, - }; - expressionRendererMock = jest.fn(({ onRenderFailure }) => { - Promise.resolve().then(() => onRenderFailure!({ type: 'error' })); - return ; - }); + it('should attempt to run the expression again if it changes', async () => { + mockDatasource.toExpression.mockReturnValue('datasource'); + mockDatasource.getLayers.mockReturnValue(['first']); + const framePublicAPI = createMockFramePublicAPI(); + framePublicAPI.datasourceLayers = { + first: mockDatasource.publicAPIMock, + }; - instance = mount( - 'vis' }, - }} - visualizationState={{}} - dispatch={() => {}} - ExpressionRenderer={expressionRendererMock} - core={coreMock.createSetup()} - /> - ); + instance = mount( + 'vis' }, + }} + visualizationState={{}} + dispatch={() => {}} + ExpressionRenderer={expressionRendererMock} + core={coreMock.createSetup()} + /> + ); - // "wait" for the expression to execute - await waitForPromises(); + // "wait" for the expression to execute + await waitForPromises(); - instance.update(); + instance.update(); - expect(expressionRendererMock).toHaveBeenCalledTimes(1); + expect(expressionRendererMock).toHaveBeenCalledTimes(1); - expressionRendererMock.mockImplementation(_ => { - return ; - }); + expressionRendererMock.mockImplementation(_ => { + return ; + }); - instance.setProps({ visualizationState: {} }); - instance.update(); + instance.setProps({ visualizationState: {} }); + instance.update(); - expect(expressionRendererMock).toHaveBeenCalledTimes(2); + expect(expressionRendererMock).toHaveBeenCalledTimes(2); - expect(instance.find(expressionRendererMock)).toHaveLength(1); - }); + expect(instance.find(expressionRendererMock)).toHaveLength(1); }); describe('suggestions from dropping in workspace panel', () => { diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/workspace_panel.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/workspace_panel.tsx index 1fb1af46f6f0d..d72bf541fd43e 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/workspace_panel.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/workspace_panel.tsx @@ -8,15 +8,14 @@ import React, { useState, useEffect, useMemo, useContext } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { - EuiCodeBlock, EuiFlexGroup, EuiFlexItem, + EuiIcon, EuiImage, EuiText, EuiBetaBadge, EuiButtonEmpty, } from '@elastic/eui'; -import { toExpression } from '@kbn/interpreter/common'; import { CoreStart, CoreSetup } from 'src/core/public'; import { ExpressionRenderer } from '../../../../../../../src/legacy/core_plugins/expressions/public'; import { Action } from './state_management'; @@ -92,7 +91,10 @@ export function InnerWorkspacePanel({ return suggestions.find(s => s.visualizationId === activeVisualizationId) || suggestions[0]; }, [dragDropContext.dragging]); - const [expressionError, setExpressionError] = useState(undefined); + const [localState, setLocalState] = useState({ + expressionBuildError: undefined as string | undefined, + expandError: false, + }); const activeVisualization = activeVisualizationId ? visualizationMap[activeVisualizationId] @@ -107,7 +109,8 @@ export function InnerWorkspacePanel({ framePublicAPI, }); } catch (e) { - setExpressionError(e.toString()); + // Most likely an error in the expression provided by a datasource or visualization + setLocalState(s => ({ ...s, expressionBuildError: e.toString() })); } }, [ activeVisualization, @@ -178,8 +181,11 @@ export function InnerWorkspacePanel({ function renderVisualization() { useEffect(() => { // reset expression error if component attempts to run it again - if (expressionError) { - setExpressionError(undefined); + if (expression && localState.expressionBuildError) { + setLocalState(s => ({ + ...s, + expressionBuildError: undefined, + })); } }, [expression]); @@ -187,37 +193,63 @@ export function InnerWorkspacePanel({ return renderEmptyWorkspace(); } - if (expressionError) { + if (localState.expressionBuildError) { return ( - + + + + - {/* TODO word this differently because expressions should not be exposed at this level */} - {expression && ( - - {toExpression(expression)} - - )} - - {JSON.stringify(expressionError, null, 2)} - + {localState.expressionBuildError} ); - } else { - return ( + } + + return ( +
{ - setExpressionError(e); + renderError={(errorMessage?: string | null) => { + return ( + + + + + + + + {errorMessage ? ( + + { + setLocalState(prevState => ({ + ...prevState, + expandError: !prevState.expandError, + })); + }} + > + {i18n.translate('xpack.lens.editorFrame.expandRenderingErrorButton', { + defaultMessage: 'Show details of error', + })} + + + {localState.expandError ? errorMessage : null} + + ) : null} + + ); }} /> - ); - } +
+ ); } return ( diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/embeddable.test.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/embeddable.test.tsx index 96624764bb8ca..d728457b7e3a3 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/embeddable.test.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/embeddable.test.tsx @@ -10,7 +10,6 @@ import { Query } from 'src/legacy/core_plugins/data/public'; import { ExpressionRendererProps } from 'src/legacy/core_plugins/expressions/public'; import { Filter } from '@kbn/es-query'; import { Document } from '../../persistence'; -import { act } from 'react-dom/test-utils'; jest.mock('../../../../../../../src/legacy/ui/public/inspector', () => ({ isAvailable: false, @@ -61,25 +60,6 @@ describe('embeddable', () => { expect(expressionRenderer.mock.calls[0][0]!.expression).toEqual(savedVis.expression); }); - it('should display error if expression renderering fails', () => { - const embeddable = new Embeddable( - expressionRenderer, - { - editUrl: '', - editable: true, - savedVis, - }, - { id: '123' } - ); - embeddable.render(mountpoint); - - act(() => { - expressionRenderer.mock.calls[0][0]!.onRenderFailure!({ type: 'error' }); - }); - - expect(mountpoint.innerHTML).toContain("Visualization couldn't be displayed"); - }); - it('should re-render if new input is pushed', () => { const timeRange: TimeRange = { from: 'now-15d', to: 'now' }; const query: Query = { language: 'kquery', query: '' }; diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/expression_wrapper.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/expression_wrapper.tsx index daf5e0c8d0dca..bd7588fcfedae 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/expression_wrapper.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/expression_wrapper.tsx @@ -5,7 +5,7 @@ */ import _ from 'lodash'; -import React, { useState, useEffect } from 'react'; +import React from 'react'; import { I18nProvider } from '@kbn/i18n/react'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -31,16 +31,9 @@ export function ExpressionWrapper({ expression, context, }: ExpressionWrapperProps) { - const [expressionError, setExpressionError] = useState(undefined); - useEffect(() => { - // reset expression error if component attempts to run it again - if (expressionError) { - setExpressionError(undefined); - } - }, [expression, context]); return ( - {expression === '' || expressionError ? ( + {expression === '' ? ( @@ -55,14 +48,12 @@ export function ExpressionWrapper({ ) : ( - { - setExpressionError(e); - }} - searchContext={{ ...context, type: 'kibana_context' }} - /> +
+ +
)}
); diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_expression.tsx b/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_expression.tsx index 407c754284671..e70a10576106c 100644 --- a/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_expression.tsx @@ -8,7 +8,10 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { ExpressionFunction } from 'src/legacy/core_plugins/interpreter/types'; import { FormatFactory } from 'ui/visualize/loader/pipeline_helpers/utilities'; -import { IInterpreterRenderFunction } from '../../../../../../src/legacy/core_plugins/expressions/public/expressions'; +import { + IInterpreterRenderFunction, + IInterpreterRenderHandlers, +} from '../../../../../../src/legacy/core_plugins/expressions/public/expressions'; import { MetricConfig } from './types'; import { LensMultiTable } from '../types'; import { AutoScale } from './auto_scale'; @@ -80,8 +83,11 @@ export const getMetricChartRenderer = ( help: 'Metric chart renderer', validate: () => {}, reuseDomNode: true, - render: async (domNode: Element, config: MetricChartProps, _handlers: unknown) => { - ReactDOM.render(, domNode); + render: (domNode: Element, config: MetricChartProps, handlers: IInterpreterRenderHandlers) => { + ReactDOM.render(, domNode, () => { + handlers.done(); + }); + handlers.onDestroy(() => ReactDOM.unmountComponentAtNode(domNode)); }, }); diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_expression.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_expression.tsx index 3871abcd53c1e..f55cd8f99a213 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_expression.tsx @@ -20,6 +20,7 @@ import { } from '@elastic/charts'; import { I18nProvider } from '@kbn/i18n/react'; import { ExpressionFunction } from 'src/legacy/core_plugins/interpreter/types'; +import { IInterpreterRenderHandlers } from 'src/legacy/core_plugins/expressions/public'; import { EuiIcon, EuiText, IconType, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; @@ -104,12 +105,14 @@ export const getXyChartRenderer = (dependencies: { }), validate: () => {}, reuseDomNode: true, - render: async (domNode: Element, config: XYChartProps, _handlers: unknown) => { + render: (domNode: Element, config: XYChartProps, handlers: IInterpreterRenderHandlers) => { + handlers.onDestroy(() => ReactDOM.unmountComponentAtNode(domNode)); ReactDOM.render( , - domNode + domNode, + () => handlers.done() ); }, }); @@ -121,16 +124,18 @@ function getIconForSeriesType(seriesType: SeriesType): IconType { const MemoizedChart = React.memo(XYChart); export function XYChartReportable(props: XYChartRenderProps) { - const [isReady, setIsReady] = useState(false); + const [state, setState] = useState({ + isReady: false, + }); // It takes a cycle for the XY chart to render. This prevents // reporting from printing a blank chart placeholder. useEffect(() => { - setIsReady(true); + setState({ isReady: true }); }, []); return ( - + ); @@ -229,7 +234,11 @@ export function XYChart({ data, args, formatFactory, timeZone }: XYChartRenderPr }, index ) => { - if (!data.tables[layerId] || data.tables[layerId].rows.length === 0) { + if ( + !data.tables[layerId] || + data.tables[layerId].rows.length === 0 || + data.tables[layerId].rows.every(row => typeof row[xAccessor] === 'undefined') + ) { return; } From 7003c2c6d62ee48e6a6d82f013dac5ac73bbf93e Mon Sep 17 00:00:00 2001 From: Michael Marcialis Date: Fri, 25 Oct 2019 17:43:10 -0400 Subject: [PATCH 45/61] [SIEM] Map Docs Link & Intrinsic Ratios (#49267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * rough out markup and intrinsic ratio poc * reorganize comps * media queries for aspect ratios * disable ratio when error; add translations * unit tests, translations & cleanup * update copy per ben’s suggestions * snapshots and translations * move paddingSize prop inline * change panel selector * fix FormattedMessage id * update snapshots --- .../__snapshots__/embeddable.test.tsx.snap | 11 ++ .../embeddable_header.test.tsx.snap | 9 ++ .../__snapshots__/embedded_map.test.tsx.snap | 25 +++- ...ndex_patterns_missing_prompt.test.tsx.snap | 56 +++++---- .../embeddables/embeddable.test.tsx | 29 +++++ .../components/embeddables/embeddable.tsx | 25 ++++ .../embeddables/embeddable_header.test.tsx | 74 ++++++++++++ .../embeddables/embeddable_header.tsx | 43 +++++++ .../components/embeddables/embedded_map.tsx | 92 +++++++++++---- .../index_patterns_missing_prompt.tsx | 109 ++++++++---------- .../components/embeddables/translations.ts | 24 ++-- .../siem/public/pages/network/network.tsx | 5 +- .../translations/translations/ja-JP.json | 3 +- .../translations/translations/zh-CN.json | 3 +- 14 files changed, 375 insertions(+), 133 deletions(-) create mode 100644 x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/embeddable.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/embeddable_header.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/embeddables/embeddable.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/embeddables/embeddable.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/embeddables/embeddable_header.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/embeddables/embeddable_header.tsx diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/embeddable.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/embeddable.test.tsx.snap new file mode 100644 index 0000000000000..f343316d88c46 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/embeddable.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Embeddable it renders 1`] = ` + + +

+ Test content +

+
+
+`; diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/embeddable_header.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/embeddable_header.test.tsx.snap new file mode 100644 index 0000000000000..e88693b292a5d --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/embeddable_header.test.tsx.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EmbeddableHeader it renders 1`] = ` + + + +`; diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/embedded_map.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/embedded_map.test.tsx.snap index 1f23686adca0e..bf0dfd9417875 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/embedded_map.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/embedded_map.test.tsx.snap @@ -1,19 +1,34 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`EmbeddedMap renders correctly against snapshot 1`] = ` - + + + + + Map configuration help + + + } > - + - - - + + `; diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/index_patterns_missing_prompt.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/index_patterns_missing_prompt.test.tsx.snap index 1aa3b087ac0d0..fb896059460b9 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/index_patterns_missing_prompt.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/__snapshots__/index_patterns_missing_prompt.test.tsx.snap @@ -15,43 +15,41 @@ exports[`IndexPatternsMissingPrompt renders correctly against snapshot 1`] = ` body={

- An ECS compliant Kibana index pattern must be configured to view event data on the map. When using beats, you can run the following setup commands to create the required Kibana index patterns, otherwise you can configure them manually within Kibana settings. + + beats + , + "example": + ./packetbeat setup + , + "setup": + setup + , + } + } + />

- - auditbeat-* - - , - - filebeat-* - - , - - packetbeat-* - - , - - winlogbeat-* - +

} iconType="gisApp" title={

- Required Index Patterns Not Configured + Required index patterns not configured

} titleSize="xs" diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable.test.tsx new file mode 100644 index 0000000000000..49f5306dc1b60 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable.test.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import React from 'react'; + +import '../../mock/ui_settings'; +import { TestProviders } from '../../mock'; +import { Embeddable } from './embeddable'; + +jest.mock('../../lib/settings/use_kibana_ui_setting'); + +describe('Embeddable', () => { + test('it renders', () => { + const wrapper = shallow( + + +

{'Test content'}

+
+
+ ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable.tsx new file mode 100644 index 0000000000000..b9a2d01ee0a70 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable.tsx @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiPanel } from '@elastic/eui'; +import React from 'react'; +import styled from 'styled-components'; + +const Panel = styled(EuiPanel)` + overflow: hidden; +`; +Panel.displayName = 'Panel'; + +export interface EmbeddableProps { + children: React.ReactNode; +} + +export const Embeddable = React.memo(({ children }) => ( +
+ {children} +
+)); +Embeddable.displayName = 'Embeddable'; diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable_header.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable_header.test.tsx new file mode 100644 index 0000000000000..4536da3ba7b97 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable_header.test.tsx @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { mount, shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import React from 'react'; + +import '../../mock/ui_settings'; +import { TestProviders } from '../../mock'; +import { EmbeddableHeader } from './embeddable_header'; + +jest.mock('../../lib/settings/use_kibana_ui_setting'); + +describe('EmbeddableHeader', () => { + test('it renders', () => { + const wrapper = shallow( + + + + ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); + + test('it renders the title', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('[data-test-subj="header-embeddable-title"]') + .first() + .exists() + ).toBe(true); + }); + + test('it renders supplements when children provided', () => { + const wrapper = mount( + + +

{'Test children'}

+
+
+ ); + + expect( + wrapper + .find('[data-test-subj="header-embeddable-supplements"]') + .first() + .exists() + ).toBe(true); + }); + + test('it DOES NOT render supplements when children not provided', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('[data-test-subj="header-embeddable-supplements"]') + .first() + .exists() + ).toBe(false); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable_header.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable_header.tsx new file mode 100644 index 0000000000000..dbd9e3f763f92 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable_header.tsx @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; +import React from 'react'; +import styled, { css } from 'styled-components'; + +const Header = styled.header.attrs({ + className: 'siemEmbeddable__header', +})` + ${({ theme }) => css` + border-bottom: ${theme.eui.euiBorderThin}; + padding: ${theme.eui.paddingSizes.m}; + `} +`; +Header.displayName = 'Header'; + +export interface EmbeddableHeaderProps { + children?: React.ReactNode; + title: string | React.ReactNode; +} + +export const EmbeddableHeader = React.memo(({ children, title }) => ( +
+ + + +
{title}
+
+
+ + {children && ( + + {children} + + )} +
+
+)); +EmbeddableHeader.displayName = 'EmbeddableHeader'; diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx index 87e38e0fac2e1..1c712f874969c 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx @@ -4,41 +4,74 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiFlexGroup, EuiSpacer } from '@elastic/eui'; +import { EuiLink, EuiText } from '@elastic/eui'; import { Filter } from '@kbn/es-query'; import React, { useEffect, useState } from 'react'; -import { SavedObjectFinder } from 'ui/saved_objects/components/saved_object_finder'; import { createPortalNode, InPortal } from 'react-reverse-portal'; import { Query } from 'src/plugins/data/common'; +import styled, { css } from 'styled-components'; +import { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } from 'ui/documentation_links'; +import { SavedObjectFinder } from 'ui/saved_objects/components/saved_object_finder'; -import styled from 'styled-components'; -import { start } from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public/legacy'; import { EmbeddablePanel } from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public'; - +import { start } from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public/legacy'; +import { DEFAULT_INDEX_KEY } from '../../../common/constants'; import { getIndexPatternTitleIdMapping } from '../../hooks/api/helpers'; import { useIndexPatterns } from '../../hooks/use_index_patterns'; -import { useKibanaUiSetting } from '../../lib/settings/use_kibana_ui_setting'; -import { DEFAULT_INDEX_KEY } from '../../../common/constants'; -import { useKibanaPlugins } from '../../lib/compose/kibana_plugins'; import { useKibanaCore } from '../../lib/compose/kibana_core'; -import { useStateToaster } from '../toasters'; +import { useKibanaPlugins } from '../../lib/compose/kibana_plugins'; +import { useKibanaUiSetting } from '../../lib/settings/use_kibana_ui_setting'; import { Loader } from '../loader'; +import { useStateToaster } from '../toasters'; +import { Embeddable } from './embeddable'; +import { EmbeddableHeader } from './embeddable_header'; +import { createEmbeddable, displayErrorToast, setupEmbeddablesAPI } from './embedded_map_helpers'; import { IndexPatternsMissingPrompt } from './index_patterns_missing_prompt'; -import { MapEmbeddable, SetQuery } from './types'; +import { MapToolTip } from './map_tool_tip/map_tool_tip'; import * as i18n from './translations'; +import { MapEmbeddable, SetQuery } from './types'; -import { createEmbeddable, displayErrorToast, setupEmbeddablesAPI } from './embedded_map_helpers'; -import { MapToolTip } from './map_tool_tip/map_tool_tip'; +interface EmbeddableMapProps { + maintainRatio?: boolean; +} -const EmbeddableWrapper = styled(EuiFlexGroup)` - position: relative; - height: 400px; - margin: 0; +const EmbeddableMap = styled.div.attrs({ + className: 'siemEmbeddable__map', +})` + ${({ maintainRatio, theme }) => css` + .embPanel { + border: none; + box-shadow: none; + } + + .mapToolbarOverlay__button { + display: none; + } + + ${maintainRatio && + css` + padding-top: calc(3 / 4 * 100%); //4:3 (standard) ratio + position: relative; + + @media only screen and (min-width: ${theme.eui.euiBreakpoints.m}) { + padding-top: calc(9 / 32 * 100%); //32:9 (ultra widescreen) ratio + } - .mapToolbarOverlay__button { - display: none; - } + @media only screen and (min-width: 1441px) and (min-height: 901px) { + padding-top: calc(9 / 21 * 100%); //21:9 (ultrawide) ratio + } + + .embPanel { + bottom: 0; + left: 0; + position: absolute; + right: 0; + top: 0; + } + `} + `} `; +EmbeddableMap.displayName = 'EmbeddableMap'; export interface EmbeddedMapProps { query: Query; @@ -152,11 +185,23 @@ export const EmbeddedMap = React.memo( }, [startDate, endDate]); return isError ? null : ( - <> + + + + + {i18n.EMBEDDABLE_HEADER_HELP} + + + + - + + {embeddable != null ? ( ( ) : ( )} - - - + + ); } ); diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.tsx index 709725b853dd2..e71398455ee88 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.tsx +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.tsx @@ -4,69 +4,58 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } from 'ui/documentation_links'; -import { EuiButton, EuiEmptyPrompt, EuiLink } from '@elastic/eui'; - +import { EuiButton, EuiCode, EuiEmptyPrompt } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; import * as React from 'react'; import chrome from 'ui/chrome'; +import { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } from 'ui/documentation_links'; import * as i18n from './translations'; -interface DocMapping { - beat: string; - docLink: string; -} - -export const IndexPatternsMissingPrompt = React.memo(() => { - const beatsSetupDocMapping: DocMapping[] = [ - { - beat: 'auditbeat', - docLink: `${ELASTIC_WEBSITE_URL}/guide/en/beats/auditbeat/${DOC_LINK_VERSION}/load-kibana-dashboards.html`, - }, - { - beat: 'filebeat', - docLink: `${ELASTIC_WEBSITE_URL}/guide/en/beats/filebeat/${DOC_LINK_VERSION}/load-kibana-dashboards.html`, - }, - { - beat: 'packetbeat', - docLink: `${ELASTIC_WEBSITE_URL}/guide/en/beats/packetbeat/${DOC_LINK_VERSION}/load-kibana-dashboards.html`, - }, - { - beat: 'winlogbeat', - docLink: `${ELASTIC_WEBSITE_URL}/guide/en/beats/winlogbeat/${DOC_LINK_VERSION}/load-kibana-dashboards.html`, - }, - ]; - - return ( - {i18n.ERROR_TITLE}

} - titleSize="xs" - body={ - <> -

{i18n.ERROR_DESCRIPTION}

+export const IndexPatternsMissingPrompt = React.memo(() => ( + {i18n.ERROR_TITLE}} + titleSize="xs" + body={ + <> +

+ + {'beats'} + + ), + setup: {'setup'}, + example: {'./packetbeat setup'}, + }} + /> +

-

- {beatsSetupDocMapping - .map(v => ( - - {`${v.beat}-*`} - - )) - .reduce((acc, v) => [acc, ', ', v])} -

- - } - actions={ - - {i18n.ERROR_BUTTON} - - } - /> - ); -}); +

+ +

+ + } + actions={ + + {i18n.ERROR_BUTTON} + + } + /> +)); diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/translations.ts b/x-pack/legacy/plugins/siem/public/components/embeddables/translations.ts index 373bd1d054a43..958619bee19d3 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/translations.ts +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/translations.ts @@ -6,6 +6,20 @@ import { i18n } from '@kbn/i18n'; +export const EMBEDDABLE_HEADER_TITLE = i18n.translate( + 'xpack.siem.components.embeddables.embeddedMap.embeddableHeaderTitle', + { + defaultMessage: 'Network map', + } +); + +export const EMBEDDABLE_HEADER_HELP = i18n.translate( + 'xpack.siem.components.embeddables.embeddedMap.embeddableHeaderHelp', + { + defaultMessage: 'Map configuration help', + } +); + export const MAP_TITLE = i18n.translate( 'xpack.siem.components.embeddables.embeddedMap.embeddablePanelTitle', { @@ -51,15 +65,7 @@ export const ERROR_CREATING_EMBEDDABLE = i18n.translate( export const ERROR_TITLE = i18n.translate( 'xpack.siem.components.embeddables.indexPatternsMissingPrompt.errorTitle', { - defaultMessage: 'Required Index Patterns Not Configured', - } -); - -export const ERROR_DESCRIPTION = i18n.translate( - 'xpack.siem.components.embeddables.indexPatternsMissingPrompt.errorDescription', - { - defaultMessage: - 'An ECS compliant Kibana index pattern must be configured to view event data on the map. When using beats, you can run the following setup commands to create the required Kibana index patterns, otherwise you can configure them manually within Kibana settings.', + defaultMessage: 'Required index patterns not configured', } ); diff --git a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx index b10c09d65426b..f7b3cfb4962fc 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx @@ -14,9 +14,9 @@ import { EmbeddedMap } from '../../components/embeddables/embedded_map'; import { FiltersGlobal } from '../../components/filters_global'; import { HeaderPage } from '../../components/header_page'; import { LastEventTime } from '../../components/last_event_time'; +import { SiemNavigation } from '../../components/navigation'; import { manageQuery } from '../../components/page/manage_query'; import { KpiNetworkComponent } from '../../components/page/network'; -import { SiemNavigation } from '../../components/navigation'; import { SiemSearchBar } from '../../components/search_bar'; import { KpiNetworkQuery } from '../../containers/kpi_network'; import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source'; @@ -26,7 +26,6 @@ import { convertToBuildEsQuery } from '../../lib/keury'; import { networkModel, State, inputsSelectors } from '../../store'; import { setAbsoluteRangeDatePicker as dispatchSetAbsoluteRangeDatePicker } from '../../store/inputs/actions'; import { SpyRoute } from '../../utils/route/spy_routes'; - import { navTabsNetwork, NetworkRoutes, NetworkRoutesLoading } from './navigation'; import { NetworkEmptyPage } from './network_empty_page'; import * as i18n from './translations'; @@ -78,6 +77,8 @@ const NetworkComponent = React.memo( setQuery={setQuery} /> + + Date: Fri, 25 Oct 2019 17:22:34 -0500 Subject: [PATCH 46/61] Update dependency @elastic/charts to ^13.5.9 (#49390) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 7aaf2573cc8de..289c2e8b0a8d0 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "dependencies": { "@babel/core": "^7.5.5", "@babel/register": "^7.5.5", - "@elastic/charts": "^13.5.8", + "@elastic/charts": "^13.5.9", "@elastic/datemath": "5.0.2", "@elastic/ems-client": "1.0.5", "@elastic/eui": "14.7.0", diff --git a/yarn.lock b/yarn.lock index a3752df9b024c..0c37018bdd596 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1064,10 +1064,10 @@ debug "^3.1.0" lodash.once "^4.1.1" -"@elastic/charts@^13.5.8": - version "13.5.8" - resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-13.5.8.tgz#ae26371e373d79cb7fe5e7394711013e1416cb81" - integrity sha512-wXz5vVKwdbOhNZwRyd1py9YdVOGHmMJ4K+PERMIJ4VwAfjHimN1qieIVAKun9vfomt/j25tDhF3Kxq3XA9W0+g== +"@elastic/charts@^13.5.9": + version "13.5.9" + resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-13.5.9.tgz#8e27ec7de934e20a9b853921cd453a372be99ef4" + integrity sha512-H5xsW/tEpjZhm0FpZThMyjuVBWlcXF2ImpfTWYv13p8GKmorCyQWbePau9Ya8N3lMmkHUMH2e95ifd3K3g9RgA== dependencies: "@types/d3-shape" "^1.3.1" classnames "^2.2.6" From e7d82f29d9ee651ff199c4f7feff21864f25fc6a Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 25 Oct 2019 18:42:31 -0400 Subject: [PATCH 47/61] [Uptime] Do not drop edge buckets (#48157) * Checkpoint first uptime bucket * Add code to specify interval for histogram chart, delete obsolete formatting code. * Revert file to master version. * Update usages of modified helper function. * Delete obslete snapshot. * Modify outdated tests and refresh snapshots. * Update API test fixtures and several tests to avoid flakiness. * Remove unneeded size field. * Rename a type. * Split concerns to two separate functions. * Update chart formatting label stops and casing to fit latest charts. * Remove addition of interval to x domain. * Update tests to accommodate new changes. --- .../common/constants/chart_format_limits.ts | 10 +- .../uptime/common/domain_types/monitors.ts | 7 + .../functional/charts/snapshot_histogram.tsx | 19 +- .../charts/__tests__/get_label_format.test.ts | 18 +- .../lib/helper/charts/get_chart_date_label.ts | 2 +- .../lib/helper/charts/get_label_format.ts | 15 +- .../queries/snapshot_histogram_query.ts | 5 +- .../server/graphql/monitors/resolvers.ts | 6 +- .../server/graphql/monitors/schema.gql.ts | 7 +- .../search/enrich_monitor_groups.ts | 4 +- ...lasticsearch_monitors_adapter.test.ts.snap | 14 + .../elasticsearch_monitors_adapter.ts | 14 +- .../elasticsearch_pings_adapter.test.ts.snap | 177 +++++---- .../elasticsearch_pings_adapter.test.ts | 4 +- .../lib/adapters/pings/adapter_types.ts | 5 +- .../pings/elasticsearch_pings_adapter.ts | 29 +- .../drop_latest_buckets.test.ts.snap | 9 - ...rmat_es_buckets_for_histogram.test.ts.snap | 42 -- .../__test__/drop_latest_buckets.test.ts | 25 -- .../format_es_buckets_for_histogram.test.ts | 29 -- .../__test__/get_histogram_interval.test.ts | 23 +- .../get_histogram_interval_formatted.test.ts | 35 ++ .../server/lib/helper/drop_latest_bucket.ts | 14 - .../helper/format_es_buckets_for_histogram.ts | 42 -- .../lib/helper/get_histogram_interval.ts | 6 +- .../get_histogram_interval_formatted.ts | 13 + .../plugins/uptime/server/lib/helper/index.ts | 3 +- .../graphql/fixtures/monitor_charts.json | 10 + .../graphql/fixtures/snapshot_histogram.json | 363 +++++++++--------- .../snapshot_histogram_by_filter.json | 363 +++++++++--------- .../fixtures/snapshot_histogram_by_id.json | 363 +++++++++--------- .../apis/uptime/graphql/snapshot_histogram.ts | 11 + 32 files changed, 849 insertions(+), 838 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/helper/__test__/__snapshots__/drop_latest_buckets.test.ts.snap delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/helper/__test__/__snapshots__/format_es_buckets_for_histogram.test.ts.snap delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/helper/__test__/drop_latest_buckets.test.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/helper/__test__/format_es_buckets_for_histogram.test.ts create mode 100644 x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_histogram_interval_formatted.test.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/helper/drop_latest_bucket.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/helper/format_es_buckets_for_histogram.ts create mode 100644 x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval_formatted.ts diff --git a/x-pack/legacy/plugins/uptime/common/constants/chart_format_limits.ts b/x-pack/legacy/plugins/uptime/common/constants/chart_format_limits.ts index 1e691b45e1792..f291450ab2a7a 100644 --- a/x-pack/legacy/plugins/uptime/common/constants/chart_format_limits.ts +++ b/x-pack/legacy/plugins/uptime/common/constants/chart_format_limits.ts @@ -4,8 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ +const MINUTE = 1000 * 60; +const HOUR = MINUTE * 60; const DAY = 24 * 60 * 60 * 1000; const WEEK = DAY * 7; +const MONTH = WEEK * 4; /** * These contsants are used by the charting code to determine @@ -14,9 +17,10 @@ const WEEK = DAY * 7; */ export const CHART_FORMAT_LIMITS = { DAY, - FIFTEEN_DAYS: 1000 * 60 * 60 * 24 * 15, - EIGHT_MINUTES: 1000 * 60 * 8, + EIGHT_MINUTES: MINUTE * 8, FOUR_YEARS: 4 * 12 * 4 * WEEK, - THIRTY_SIX_HOURS: 1000 * 60 * 60 * 36, + THIRTY_SIX_HOURS: HOUR * 36, THREE_WEEKS: WEEK * 3, + SIX_MONTHS: MONTH * 7, + NINE_DAYS: DAY * 9, }; diff --git a/x-pack/legacy/plugins/uptime/common/domain_types/monitors.ts b/x-pack/legacy/plugins/uptime/common/domain_types/monitors.ts index 7f5699eb7e8a4..296df279b8eec 100644 --- a/x-pack/legacy/plugins/uptime/common/domain_types/monitors.ts +++ b/x-pack/legacy/plugins/uptime/common/domain_types/monitors.ts @@ -4,7 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ +import { HistogramDataPoint } from '../graphql/types'; + export interface UMGqlRange { dateRangeStart: string; dateRangeEnd: string; } + +export interface HistogramResult { + histogram: HistogramDataPoint[]; + interval: number; +} diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/snapshot_histogram.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/charts/snapshot_histogram.tsx index e39adc2868c84..a5d2d9cfc27f2 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/charts/snapshot_histogram.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/charts/snapshot_histogram.tsx @@ -20,13 +20,13 @@ import React, { useContext } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import moment from 'moment'; import styled from 'styled-components'; -import { HistogramDataPoint } from '../../../../common/graphql/types'; import { getColorsMap } from './get_colors_map'; import { getChartDateLabel } from '../../../lib/helper'; import { withUptimeGraphQL, UptimeGraphQLQueryProps } from '../../higher_order'; import { snapshotHistogramQuery } from '../../../queries/snapshot_histogram_query'; import { ChartWrapper } from './chart_wrapper'; import { UptimeSettingsContext } from '../../../contexts'; +import { HistogramResult } from '../../../../common/domain_types'; const SnapshotHistogramWrapper = styled.div` margin-left: 120px; @@ -56,7 +56,7 @@ export interface SnapshotHistogramProps { } interface SnapshotHistogramQueryResult { - histogram?: HistogramDataPoint[]; + queryResult?: HistogramResult; } type Props = UptimeGraphQLQueryProps & SnapshotHistogramProps; @@ -68,7 +68,7 @@ export const SnapshotHistogramComponent = ({ loading = false, height, }: Props) => { - if (!data || !data.histogram) + if (!data || !data.queryResult) /** * TODO: the Fragment, EuiTitle, and EuiPanel should be extracted to a dumb component * that we can reuse in the subsequent return statement at the bottom of this function. @@ -107,7 +107,9 @@ export const SnapshotHistogramComponent = ({ ); - const { histogram } = data; + const { + queryResult: { histogram, interval }, + } = data; const { colors: { danger, gray }, @@ -145,7 +147,14 @@ export const SnapshotHistogramComponent = ({ })} > - + { it('creates a label with month/day and hour/minute for time between 36 hours and 4 days', () => { // Sun, 15 Jul 2001 17:53:10 GMT -> Thu, 19 Jul 2001 17:52:59 GMT - expect(getChartDateLabel(995219590000, 995565179000)).toBe('MM-dd HH:mm'); + expect(getChartDateLabel(995219590000, 995565179000)).toBe('MM-DD HH:mm'); }); it('creates a format without day/month string for delta within same day local time', () => { @@ -34,17 +34,25 @@ describe('getChartLabelFormatter', () => { it('creates a format with date/month string for delta crossing dates', () => { // Wed, 18 Jul 2001 11:06:19 GMT -> Thu, 19 Jul 2001 17:52:59 GMT - expect(getChartDateLabel(995454379000, 995565179000)).toBe('MM-dd HH:mm'); + expect(getChartDateLabel(995454379000, 995565179000)).toBe('MM-DD HH:mm'); }); it('creates a format with only month/day for delta between to eight days and two weeks', () => { // Sun, 01 Jul 2001 23:28:15 GMT -> Thu, 19 Jul 2001 17:52:59 GMT - expect(getChartDateLabel(994030095000, 995565179000)).toBe('MM-dd'); + expect(getChartDateLabel(994030095000, 995565179000)).toBe('MM-DD'); }); - it('creates a format with the year/month for range exceeding a week', () => { + it('creates a format with the date and hour/min for 36h < range < 9d', () => { + expect(getChartDateLabel(1003752000000, 1004270400000)).toBe('MM-DD HH:mm'); + }); + + it('creates a format with month/day for range between nine days and three weeks', () => { + expect(getChartDateLabel(1003752000000, 1004875200000)).toBe('MM-DD'); + }); + + it('creates a format with the year/month/day for range exceeding three weeks', () => { // Sun, 15 Jul 2001 12:27:59 GMT -> Fri, 28 Dec 2001 18:46:19 GMT - expect(getChartDateLabel(995200079000, 1009565179000)).toBe('yyyy-MM'); + expect(getChartDateLabel(995200079000, 1009565179000)).toBe('YYYY-MM-DD'); }); it('creates a format of only year for timespan > 4 years', () => { diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts b/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts index 3533f2667b66c..126b1d85f749f 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts +++ b/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts @@ -34,7 +34,7 @@ export const getChartDateLabel = (dateRangeStart: number, dateRangeEnd: number) delta < CHART_FORMAT_LIMITS.THIRTY_SIX_HOURS && !isWithinCurrentDate(dateRangeStart, dateRangeEnd) ) { - formatString = 'MM-dd '; + formatString = 'MM-DD '; } return formatString + getLabelFormat(delta); }; diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_label_format.ts b/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_label_format.ts index ad3e04f403640..668147fee8055 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_label_format.ts +++ b/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_label_format.ts @@ -7,11 +7,12 @@ import { CHART_FORMAT_LIMITS } from '../../../../common/constants'; const { - FIFTEEN_DAYS, EIGHT_MINUTES, FOUR_YEARS, THIRTY_SIX_HOURS, THREE_WEEKS, + SIX_MONTHS, + NINE_DAYS, } = CHART_FORMAT_LIMITS; /** @@ -30,16 +31,20 @@ const dateStops: Array<{ key: number; value: string }> = [ value: 'HH:mm', }, { - key: FIFTEEN_DAYS, - value: 'MM-dd HH:mm', + key: NINE_DAYS, + value: 'MM-DD HH:mm', }, { key: THREE_WEEKS, - value: 'MM-dd', + value: 'MM-DD', + }, + { + key: SIX_MONTHS, + value: 'YYYY-MM-DD', }, { key: FOUR_YEARS, - value: 'yyyy-MM', + value: 'YYYY-MM', }, ]; diff --git a/x-pack/legacy/plugins/uptime/public/queries/snapshot_histogram_query.ts b/x-pack/legacy/plugins/uptime/public/queries/snapshot_histogram_query.ts index 37f7178d23630..7eb56ea4e9dd1 100644 --- a/x-pack/legacy/plugins/uptime/public/queries/snapshot_histogram_query.ts +++ b/x-pack/legacy/plugins/uptime/public/queries/snapshot_histogram_query.ts @@ -14,18 +14,21 @@ export const snapshotHistogramQueryString = ` $monitorId: String $statusFilter: String ) { - histogram: getSnapshotHistogram( + queryResult: getSnapshotHistogram( dateRangeStart: $dateRangeStart dateRangeEnd: $dateRangeEnd filters: $filters statusFilter: $statusFilter monitorId: $monitorId ) { + histogram { upCount downCount x x0 y + } + interval } } `; diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts b/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts index 287e80a6291ca..96a386b6a6848 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts @@ -17,11 +17,11 @@ import { MonitorPageTitle, Ping, Snapshot, - HistogramDataPoint, GetSnapshotHistogramQueryArgs, } from '../../../common/graphql/types'; import { UMServerLibs } from '../../lib/lib'; import { CreateUMGraphQLResolvers, UMContext } from '../types'; +import { HistogramResult } from '../../../common/domain_types'; export type UMSnapshotResolver = UMResolver< Snapshot | Promise, @@ -61,7 +61,7 @@ export type UMGetMontiorPageTitleResolver = UMResolver< >; export type UMGetSnapshotHistogram = UMResolver< - HistogramDataPoint[] | Promise, + HistogramResult | Promise, any, GetSnapshotHistogramQueryArgs, UMContext @@ -101,7 +101,7 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = ( resolver, { dateRangeStart, dateRangeEnd, filters, monitorId, statusFilter }, { req } - ): Promise { + ): Promise { return await libs.pings.getPingHistogram( req, dateRangeStart, diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitors/schema.gql.ts b/x-pack/legacy/plugins/uptime/server/graphql/monitors/schema.gql.ts index d406be2e8b15b..97dcbd12fff2e 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/monitors/schema.gql.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/monitors/schema.gql.ts @@ -120,6 +120,11 @@ export const monitorsSchema = gql` monitors: [LatestMonitor!] } + type HistogramResult { + histogram: [HistogramDataPoint]! + interval: UnsignedInteger! + } + type MonitorPageTitle { id: String! url: String @@ -147,7 +152,7 @@ export const monitorsSchema = gql` filters: String statusFilter: String monitorId: String - ): [HistogramDataPoint!]! + ): HistogramResult getMonitorChartsData( monitorId: String! diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/enrich_monitor_groups.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/enrich_monitor_groups.ts index 2518264292cbd..6b594d8b49118 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/enrich_monitor_groups.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/enrich_monitor_groups.ts @@ -6,7 +6,7 @@ import { get, sortBy } from 'lodash'; import { QueryContext } from '../elasticsearch_monitor_states_adapter'; -import { getHistogramInterval } from '../../../helper'; +import { getHistogramIntervalFormatted } from '../../../helper'; import { INDEX_NAMES, STATES } from '../../../../../common/constants'; import { MonitorSummary, @@ -324,7 +324,7 @@ const getHistogramForMonitors = async ( histogram: { date_histogram: { field: '@timestamp', - fixed_interval: getHistogramInterval( + fixed_interval: getHistogramIntervalFormatted( queryContext.dateRangeStart, queryContext.dateRangeEnd ), diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/__snapshots__/elasticsearch_monitors_adapter.test.ts.snap b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/__snapshots__/elasticsearch_monitors_adapter.test.ts.snap index 75b19d7381a62..99349f42d5750 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/__snapshots__/elasticsearch_monitors_adapter.test.ts.snap +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/__snapshots__/elasticsearch_monitors_adapter.test.ts.snap @@ -221,6 +221,10 @@ Object { "x": 1568412432000, "y": 1972483.25, }, + Object { + "x": 1568412468000, + "y": 1020490, + }, ], "name": "us-east-2", }, @@ -302,6 +306,10 @@ Object { "x": 1568412432000, "y": 1543307.5, }, + Object { + "x": 1568412468000, + "y": null, + }, ], "name": "us-west-4", }, @@ -421,6 +429,12 @@ Object { "up": null, "x": 1568412432000, }, + Object { + "down": null, + "total": 1, + "up": null, + "x": 1568412468000, + }, ], "statusMaxCount": 0, } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts index c14e3dab987d7..f2d84d149344b 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts @@ -13,12 +13,7 @@ import { Ping, LocationDurationLine, } from '../../../../common/graphql/types'; -import { - dropLatestBucket, - getFilterClause, - getHistogramInterval, - parseFilterQuery, -} from '../../helper'; +import { getFilterClause, parseFilterQuery, getHistogramIntervalFormatted } from '../../helper'; import { DatabaseAdapter } from '../database'; import { UMMonitorsAdapter } from './adapter_types'; @@ -80,7 +75,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { timeseries: { date_histogram: { field: '@timestamp', - fixed_interval: getHistogramInterval(dateRangeStart, dateRangeEnd), + fixed_interval: getHistogramIntervalFormatted(dateRangeStart, dateRangeEnd), min_doc_count: 0, }, aggs: { @@ -102,10 +97,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { const result = await this.database.search(request, params); - const dateHistogramBuckets = dropLatestBucket( - get(result, 'aggregations.timeseries.buckets', []) - ); - + const dateHistogramBuckets = get(result, 'aggregations.timeseries.buckets', []); /** * The code below is responsible for formatting the aggregation data we fetched above in a way * that the chart components used by the client understands. diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/__snapshots__/elasticsearch_pings_adapter.test.ts.snap b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/__snapshots__/elasticsearch_pings_adapter.test.ts.snap index a7526739c95ac..b73595d539e93 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/__snapshots__/elasticsearch_pings_adapter.test.ts.snap +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/__snapshots__/elasticsearch_pings_adapter.test.ts.snap @@ -1,82 +1,127 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`ElasticsearchPingsAdapter class getPingHistogram handles simple_text_query without issues 1`] = ` -Array [ - Object { - "downCount": 1, - "key": 1, - "upCount": 2, - "x": 2, - "x0": 1, - "y": 1, - }, - Object { - "downCount": 2, - "key": 2, - "upCount": 1, - "x": 3, - "x0": 2, - "y": 1, - }, -] +Object { + "histogram": Array [ + Object { + "downCount": 1, + "upCount": 2, + "x": 1, + "y": 1, + }, + Object { + "downCount": 2, + "upCount": 1, + "x": 2, + "y": 1, + }, + Object { + "downCount": 1, + "upCount": 3, + "x": 3, + "y": 1, + }, + ], + "interval": 36000, +} `; exports[`ElasticsearchPingsAdapter class getPingHistogram handles status + additional user queries 1`] = ` -Array [ - Object { - "downCount": 1, - "key": 1, - "upCount": 0, - "x": 2, - "x0": 1, - "y": 1, - }, - Object { - "downCount": 2, - "key": 2, - "upCount": 0, - "x": 3, - "x0": 2, - "y": 1, - }, -] +Object { + "histogram": Array [ + Object { + "downCount": 1, + "upCount": 0, + "x": 1, + "y": 1, + }, + Object { + "downCount": 2, + "upCount": 0, + "x": 2, + "y": 1, + }, + Object { + "downCount": 1, + "upCount": 0, + "x": 3, + "y": 1, + }, + ], + "interval": 5609564928000, +} `; exports[`ElasticsearchPingsAdapter class getPingHistogram returns a down-filtered array for when filtered by down status 1`] = ` -Array [ - Object { - "downCount": 1, - "key": 1, - "upCount": 0, - "x": 2, - "x0": 1, - "y": 1, - }, -] +Object { + "histogram": Array [ + Object { + "downCount": 1, + "upCount": 0, + "x": 1, + "y": 1, + }, + Object { + "downCount": undefined, + "upCount": 0, + "x": 2, + "y": 1, + }, + ], + "interval": 5609564928000, +} `; exports[`ElasticsearchPingsAdapter class getPingHistogram returns a down-filtered array for when filtered by up status 1`] = ` -Array [ - Object { - "downCount": 0, - "key": 1, - "upCount": 2, - "x": 2, - "x0": 1, - "y": 1, - }, -] +Object { + "histogram": Array [ + Object { + "downCount": 0, + "upCount": 2, + "x": 1, + "y": 1, + }, + Object { + "downCount": 0, + "upCount": 2, + "x": 2, + "y": 1, + }, + ], + "interval": 5609564928000, +} +`; + +exports[`ElasticsearchPingsAdapter class getPingHistogram returns a single bucket if array has 1 1`] = ` +Object { + "histogram": Array [ + Object { + "downCount": 1, + "upCount": 2, + "x": 1, + "y": 1, + }, + ], + "interval": 36000, +} `; exports[`ElasticsearchPingsAdapter class getPingHistogram returns expected result for no status filter 1`] = ` -Array [ - Object { - "downCount": 1, - "key": 1, - "upCount": 2, - "x": 2, - "x0": 1, - "y": 1, - }, -] +Object { + "histogram": Array [ + Object { + "downCount": 1, + "upCount": 2, + "x": 1, + "y": 1, + }, + Object { + "downCount": undefined, + "upCount": 2, + "x": 2, + "y": 1, + }, + ], + "interval": 36000, +} `; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts index ec414cda7d811..5c481cd147c61 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts @@ -88,7 +88,7 @@ describe('ElasticsearchPingsAdapter class', () => { }); describe('getPingHistogram', () => { - it('returns an empty array for <= 1 bucket', async () => { + it('returns a single bucket if array has 1', async () => { expect.assertions(2); const search = jest.fn(); search.mockReturnValue({ @@ -116,7 +116,7 @@ describe('ElasticsearchPingsAdapter class', () => { const pingAdapter = new ElasticsearchPingsAdapter(pingDatabase); const result = await pingAdapter.getPingHistogram(serverRequest, 'now-15m', 'now', null); expect(pingDatabase.search).toHaveBeenCalledTimes(1); - expect(result).toEqual([]); + expect(result).toMatchSnapshot(); }); it('returns expected result for no status filter', async () => { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/adapter_types.ts index bb26e04f2fc9e..1e0cf7ec40646 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/adapter_types.ts @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { DocCount, HistogramDataPoint, Ping, PingResults } from '../../../../common/graphql/types'; +import { DocCount, Ping, PingResults } from '../../../../common/graphql/types'; +import { HistogramResult } from '../../../../common/domain_types'; export interface UMPingsAdapter { getAll( @@ -33,7 +34,7 @@ export interface UMPingsAdapter { filters?: string | null, monitorId?: string | null, statusFilter?: string | null - ): Promise; + ): Promise; getDocCount(request: any): Promise; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts index 822441449a774..cad8b412f3e58 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts @@ -6,17 +6,12 @@ import { get } from 'lodash'; import { INDEX_NAMES } from '../../../../common/constants'; -import { - DocCount, - HistogramDataPoint, - HttpBody, - Ping, - PingResults, -} from '../../../../common/graphql/types'; -import { formatEsBucketsForHistogram, parseFilterQuery, getFilterClause } from '../../helper'; +import { DocCount, HttpBody, Ping, PingResults } from '../../../../common/graphql/types'; +import { parseFilterQuery, getFilterClause, getHistogramIntervalFormatted } from '../../helper'; import { DatabaseAdapter, HistogramQueryResult } from '../database'; import { UMPingsAdapter } from './adapter_types'; import { getHistogramInterval } from '../../helper/get_histogram_interval'; +import { HistogramResult } from '../../../../common/domain_types'; export class ElasticsearchPingsAdapter implements UMPingsAdapter { private database: DatabaseAdapter; @@ -195,7 +190,7 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter { filters?: string | null, monitorId?: string | null, statusFilter?: string | null - ): Promise { + ): Promise { const boolFilters = parseFilterQuery(filters); const additionaFilters = []; if (monitorId) { @@ -205,6 +200,8 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter { additionaFilters.push(boolFilters); } const filter = getFilterClause(dateRangeStart, dateRangeEnd, additionaFilters); + const interval = getHistogramInterval(dateRangeStart, dateRangeEnd); + const intervalFormatted = getHistogramIntervalFormatted(dateRangeStart, dateRangeEnd); const params = { index: INDEX_NAMES.HEARTBEAT, @@ -219,7 +216,7 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter { timeseries: { date_histogram: { field: '@timestamp', - fixed_interval: getHistogramInterval(dateRangeStart, dateRangeEnd), + fixed_interval: intervalFormatted, }, aggs: { down: { @@ -244,19 +241,21 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter { const result = await this.database.search(request, params); const buckets: HistogramQueryResult[] = get(result, 'aggregations.timeseries.buckets', []); - const mappedBuckets = buckets.map(bucket => { - const key: number = get(bucket, 'key'); + const histogram = buckets.map(bucket => { + const x: number = get(bucket, 'key'); const downCount: number = get(bucket, 'down.doc_count'); const upCount: number = get(bucket, 'up.doc_count'); return { - key, + x, downCount: statusFilter && statusFilter !== 'down' ? 0 : downCount, upCount: statusFilter && statusFilter !== 'up' ? 0 : upCount, y: 1, }; }); - - return formatEsBucketsForHistogram(mappedBuckets); + return { + histogram, + interval, + }; } /** diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/__snapshots__/drop_latest_buckets.test.ts.snap b/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/__snapshots__/drop_latest_buckets.test.ts.snap deleted file mode 100644 index db05bb02be8a9..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/__snapshots__/drop_latest_buckets.test.ts.snap +++ /dev/null @@ -1,9 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`dropLatestBucket drops the last of a list with greater length than 1 1`] = ` -Array [ - Object { - "prop": "val", - }, -] -`; diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/__snapshots__/format_es_buckets_for_histogram.test.ts.snap b/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/__snapshots__/format_es_buckets_for_histogram.test.ts.snap deleted file mode 100644 index 1b30ee1549273..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/__snapshots__/format_es_buckets_for_histogram.test.ts.snap +++ /dev/null @@ -1,42 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`formatEsBucketsForHistogram returns properly formatted buckets 1`] = ` -Array [ - Object { - "key": 1000, - "x": 2000, - "x0": 1000, - }, - Object { - "key": 2000, - "x": 3000, - "x0": 2000, - }, - Object { - "key": 3000, - "x": 4000, - "x0": 3000, - }, -] -`; - -exports[`formatEsBucketsForHistogram returns properly formatted object for generic call 1`] = ` -Array [ - Object { - "key": 1000, - "name": "something", - "value": 150, - "x": 2000, - "x0": 1000, - }, - Object { - "key": 2000, - "name": "something", - "value": 120, - "x": 3000, - "x0": 2000, - }, -] -`; - -exports[`formatEsBucketsForHistogram returns the provided buckets if length is below min threshold 1`] = `Array []`; diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/drop_latest_buckets.test.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/drop_latest_buckets.test.ts deleted file mode 100644 index 57ae48f0c7b63..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/drop_latest_buckets.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { dropLatestBucket } from '../drop_latest_bucket'; - -describe('dropLatestBucket', () => { - it('drops the last of a list with greater length than 1', () => { - const testData = [{ prop: 'val' }, { prop: 'val' }]; - const result = dropLatestBucket(testData); - expect(result).toMatchSnapshot(); - }); - it('returns an empty list when length === 1', () => { - const testData = [{ prop: 'val' }]; - const result = dropLatestBucket(testData); - expect(result).toEqual([]); - }); - it('returns an empty list when length === 0', () => { - const testData: any[] = []; - const result = dropLatestBucket(testData); - expect(result).toEqual([]); - }); -}); diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/format_es_buckets_for_histogram.test.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/format_es_buckets_for_histogram.test.ts deleted file mode 100644 index 87c6aad5da032..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/format_es_buckets_for_histogram.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { formatEsBucketsForHistogram } from '../format_es_buckets_for_histogram'; - -describe('formatEsBucketsForHistogram', () => { - it('returns the provided buckets if length is below min threshold', () => { - const buckets = [{ key: 1000 }]; - const result = formatEsBucketsForHistogram(buckets); - expect(result).toMatchSnapshot(); - }); - it('returns properly formatted buckets', () => { - const buckets = [{ key: 1000 }, { key: 2000 }, { key: 3000 }, { key: 4000 }]; - const result = formatEsBucketsForHistogram(buckets); - expect(result).toMatchSnapshot(); - }); - it('returns properly formatted object for generic call', () => { - const buckets = [ - { key: 1000, name: 'something', value: 150 }, - { key: 2000, name: 'something', value: 120 }, - { key: 3000, name: 'something', value: 180 }, - ]; - const result = formatEsBucketsForHistogram(buckets); - expect(result).toMatchSnapshot(); - }); -}); diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts index 83f861d3fb467..bddca1b863ce4 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts @@ -5,29 +5,16 @@ */ import { getHistogramInterval } from '../get_histogram_interval'; +import { assertCloseTo } from '../assert_close_to'; describe('getHistogramInterval', () => { it('specifies the interval necessary to divide a given timespan into equal buckets, rounded to the nearest integer, expressed in ms', () => { - const result = getHistogramInterval('now-15m', 'now', 10); - /** - * These assertions were verbatim comparisons but that introduced - * some flakiness at the ms resolution, sometimes values like "9001ms" - * are returned. - */ - expect(result.startsWith('9000')).toBeTruthy(); - expect(result.endsWith('ms')).toBeTruthy(); - expect(result).toHaveLength(7); + const interval = getHistogramInterval('now-15m', 'now', 10); + assertCloseTo(interval, 90000, 10); }); it('will supply a default constant value for bucketCount when none is provided', () => { - const result = getHistogramInterval('now-15m', 'now'); - /** - * These assertions were verbatim comparisons but that introduced - * some flakiness at the ms resolution, sometimes values like "9001ms" - * are returned. - */ - expect(result.startsWith('3600')).toBeTruthy(); - expect(result.endsWith('ms')).toBeTruthy(); - expect(result).toHaveLength(7); + const interval = getHistogramInterval('now-15m', 'now'); + assertCloseTo(interval, 36000, 10); }); }); diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_histogram_interval_formatted.test.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_histogram_interval_formatted.test.ts new file mode 100644 index 0000000000000..e67a93f24b3ca --- /dev/null +++ b/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_histogram_interval_formatted.test.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getHistogramIntervalFormatted } from '../get_histogram_interval_formatted'; + +describe('getHistogramIntervalFormatted', () => { + it('specifies the interval necessary to divide a given timespan into equal buckets, rounded to the nearest integer, expressed in ms', () => { + const intervalFormatted = getHistogramIntervalFormatted('now-15m', 'now', 10); + /** + * Expected result is 90000. + * These assertions were verbatim comparisons but that introduced + * some flakiness at the ms resolution, sometimes values like "9001ms" + * are returned. + */ + expect(intervalFormatted.startsWith('9000')).toBeTruthy(); + expect(intervalFormatted.endsWith('ms')).toBeTruthy(); + expect(intervalFormatted).toHaveLength(7); + }); + + it('will supply a default constant value for bucketCount when none is provided', () => { + const intervalFormatted = getHistogramIntervalFormatted('now-15m', 'now'); + /** + * Expected result is 36000. + * These assertions were verbatim comparisons but that introduced + * some flakiness at the ms resolution, sometimes values like "9001ms" + * are returned. + */ + expect(intervalFormatted.startsWith('3600')).toBeTruthy(); + expect(intervalFormatted.endsWith('ms')).toBeTruthy(); + expect(intervalFormatted).toHaveLength(7); + }); +}); diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/drop_latest_bucket.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/drop_latest_bucket.ts deleted file mode 100644 index 4d072266fa4ea..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/drop_latest_bucket.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -/** - * We've had numerous requests to not display semi-full buckets (i.e. it is 13:01 and the - * bounds of our bucket are 13:00-13:05). If the first bucket isn't done filling, we'll - * start out with nothing returned, otherwise we drop the most recent bucket. - * @param buckets The bucket list - */ -export const dropLatestBucket = (buckets: any[]) => - buckets.length > 1 ? buckets.slice(0, buckets.length - 1) : []; diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/format_es_buckets_for_histogram.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/format_es_buckets_for_histogram.ts deleted file mode 100644 index 1b0a2bfdfc5c0..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/format_es_buckets_for_histogram.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { UMESBucket, UMESHistogramBucket } from '../adapters/database'; -import { dropLatestBucket } from './drop_latest_bucket'; - -/** - * The charting library we're currently using requires histogram data points have an - * x and an x0 property, where x0 is the beginning of a data point and x provides - * the size of the point from the start. This function attempts to generalize the - * concept so any bucket that has a numeric value as its key can be put into this format. - * - * Additionally, histograms that stack horizontally instead of vertically need to have - * a y and a y0 value. We're not doing this currently but with some minor modification - * this function could provide formatting for those buckets as well. - * @param buckets The ES data to format. - */ -export function formatEsBucketsForHistogram( - buckets: T[] -): Array { - // wait for first bucket to fill up - if (buckets.length < 2) { - return []; - } - const TERMINAL_INDEX = buckets.length - 1; - const { key: terminalBucketTime } = buckets[TERMINAL_INDEX]; - // drop the most recent bucket to avoid returning incomplete bucket - return dropLatestBucket(buckets).map((item, index, array) => { - const { key } = item; - const nextItem = array[index + 1]; - const bucketSize = nextItem ? Math.abs(nextItem.key - key) : Math.abs(terminalBucketTime - key); - - return { - x: key + bucketSize, - x0: key, - ...item, - }; - }); -} diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval.ts index 107a635366a0b..0dedc3e456f51 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval.ts @@ -11,7 +11,7 @@ export const getHistogramInterval = ( dateRangeStart: string, dateRangeEnd: string, bucketCount?: number -): string => { +): number => { const from = DateMath.parse(dateRangeStart); const to = DateMath.parse(dateRangeEnd); if (from === undefined) { @@ -20,7 +20,5 @@ export const getHistogramInterval = ( if (to === undefined) { throw Error('Invalid dateRangeEnd value'); } - return `${Math.round( - (to.valueOf() - from.valueOf()) / (bucketCount || QUERY.DEFAULT_BUCKET_COUNT) - )}ms`; + return Math.round((to.valueOf() - from.valueOf()) / (bucketCount || QUERY.DEFAULT_BUCKET_COUNT)); }; diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval_formatted.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval_formatted.ts new file mode 100644 index 0000000000000..29af862611ca4 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval_formatted.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getHistogramInterval } from './get_histogram_interval'; + +export const getHistogramIntervalFormatted = ( + dateRangeStart: string, + dateRangeEnd: string, + bucketCount?: number +): string => `${getHistogramInterval(dateRangeStart, dateRangeEnd, bucketCount)}ms`; diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/index.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/index.ts index a2a72825c6b98..4c88da7eca85a 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/index.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/helper/index.ts @@ -4,9 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -export { dropLatestBucket } from './drop_latest_bucket'; -export { formatEsBucketsForHistogram } from './format_es_buckets_for_histogram'; export { getFilterClause } from './get_filter_clause'; export { getHistogramInterval } from './get_histogram_interval'; +export { getHistogramIntervalFormatted } from './get_histogram_interval_formatted'; export { parseFilterQuery } from './parse_filter_query'; export { assertCloseTo } from './assert_close_to'; diff --git a/x-pack/test/api_integration/apis/uptime/graphql/fixtures/monitor_charts.json b/x-pack/test/api_integration/apis/uptime/graphql/fixtures/monitor_charts.json index f5368ad7ecf0c..dbfc17a468796 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/fixtures/monitor_charts.json +++ b/x-pack/test/api_integration/apis/uptime/graphql/fixtures/monitor_charts.json @@ -103,6 +103,10 @@ { "x": 1568173204510, "y": null + }, + { + "x": 1568173227311, + "y": 24627 } ] } @@ -257,6 +261,12 @@ "up": null, "down": null, "total": 0 + }, + { + "x": 1568173227311, + "up": null, + "down": null, + "total": 1 } ], "statusMaxCount": 0, diff --git a/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_histogram.json b/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_histogram.json index c12ec7f3847c3..cf88ccae9cb99 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_histogram.json +++ b/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_histogram.json @@ -1,179 +1,188 @@ { - "histogram": [ - { - "upCount": 93, - "downCount": 7, - "x": 1568172680087, - "x0": 1568172657286, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172702888, - "x0": 1568172680087, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172725689, - "x0": 1568172702888, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568172748490, - "x0": 1568172725689, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172771291, - "x0": 1568172748490, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172794092, - "x0": 1568172771291, - "y": 1 - }, - { - "upCount": 92, - "downCount": 8, - "x": 1568172816893, - "x0": 1568172794092, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568172839694, - "x0": 1568172816893, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172862495, - "x0": 1568172839694, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172885296, - "x0": 1568172862495, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172908097, - "x0": 1568172885296, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568172930898, - "x0": 1568172908097, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172953699, - "x0": 1568172930898, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172976500, - "x0": 1568172953699, - "y": 1 - }, - { - "upCount": 92, - "downCount": 8, - "x": 1568172999301, - "x0": 1568172976500, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568173022102, - "x0": 1568172999301, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568173044903, - "x0": 1568173022102, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568173067704, - "x0": 1568173044903, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568173090505, - "x0": 1568173067704, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568173113306, - "x0": 1568173090505, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568173136107, - "x0": 1568173113306, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568173158908, - "x0": 1568173136107, - "y": 1 - }, - { - "upCount": 92, - "downCount": 8, - "x": 1568173181709, - "x0": 1568173158908, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568173204510, - "x0": 1568173181709, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568173227311, - "x0": 1568173204510, - "y": 1 - } - ] + "queryResult": { + "histogram": [ + { + "upCount": 93, + "downCount": 7, + "x": 1568172657286, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172680087, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172702888, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568172725689, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172748490, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172771291, + "x0": null, + "y": 1 + }, + { + "upCount": 92, + "downCount": 8, + "x": 1568172794092, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568172816893, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172839694, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172862495, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172885296, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568172908097, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172930898, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172953699, + "x0": null, + "y": 1 + }, + { + "upCount": 92, + "downCount": 8, + "x": 1568172976500, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568172999301, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173022102, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173044903, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173067704, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568173090505, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173113306, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173136107, + "x0": null, + "y": 1 + }, + { + "upCount": 92, + "downCount": 8, + "x": 1568173158908, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173181709, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568173204510, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173227311, + "x0": null, + "y": 1 + } + ] + } } \ No newline at end of file diff --git a/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_histogram_by_filter.json b/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_histogram_by_filter.json index f61a101ce4462..383d4acd96340 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_histogram_by_filter.json +++ b/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_histogram_by_filter.json @@ -1,179 +1,188 @@ { - "histogram": [ - { - "upCount": 93, - "downCount": 0, - "x": 1568172680087, - "x0": 1568172657286, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568172702888, - "x0": 1568172680087, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568172725689, - "x0": 1568172702888, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568172748490, - "x0": 1568172725689, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568172771291, - "x0": 1568172748490, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568172794092, - "x0": 1568172771291, - "y": 1 - }, - { - "upCount": 92, - "downCount": 0, - "x": 1568172816893, - "x0": 1568172794092, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568172839694, - "x0": 1568172816893, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568172862495, - "x0": 1568172839694, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568172885296, - "x0": 1568172862495, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568172908097, - "x0": 1568172885296, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568172930898, - "x0": 1568172908097, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568172953699, - "x0": 1568172930898, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568172976500, - "x0": 1568172953699, - "y": 1 - }, - { - "upCount": 92, - "downCount": 0, - "x": 1568172999301, - "x0": 1568172976500, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568173022102, - "x0": 1568172999301, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568173044903, - "x0": 1568173022102, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568173067704, - "x0": 1568173044903, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568173090505, - "x0": 1568173067704, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568173113306, - "x0": 1568173090505, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568173136107, - "x0": 1568173113306, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568173158908, - "x0": 1568173136107, - "y": 1 - }, - { - "upCount": 92, - "downCount": 0, - "x": 1568173181709, - "x0": 1568173158908, - "y": 1 - }, - { - "upCount": 93, - "downCount": 0, - "x": 1568173204510, - "x0": 1568173181709, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568173227311, - "x0": 1568173204510, - "y": 1 - } - ] + "queryResult": { + "histogram": [ + { + "upCount": 93, + "downCount": 0, + "x": 1568172657286, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568172680087, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568172702888, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568172725689, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568172748490, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568172771291, + "x0": null, + "y": 1 + }, + { + "upCount": 92, + "downCount": 0, + "x": 1568172794092, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568172816893, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568172839694, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568172862495, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568172885296, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568172908097, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568172930898, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568172953699, + "x0": null, + "y": 1 + }, + { + "upCount": 92, + "downCount": 0, + "x": 1568172976500, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568172999301, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568173022102, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568173044903, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568173067704, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568173090505, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568173113306, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568173136107, + "x0": null, + "y": 1 + }, + { + "upCount": 92, + "downCount": 0, + "x": 1568173158908, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568173181709, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568173204510, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 0, + "x": 1568173227311, + "x0": null, + "y": 1 + } + ] + } } \ No newline at end of file diff --git a/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_histogram_by_id.json b/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_histogram_by_id.json index c12ec7f3847c3..cf88ccae9cb99 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_histogram_by_id.json +++ b/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_histogram_by_id.json @@ -1,179 +1,188 @@ { - "histogram": [ - { - "upCount": 93, - "downCount": 7, - "x": 1568172680087, - "x0": 1568172657286, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172702888, - "x0": 1568172680087, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172725689, - "x0": 1568172702888, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568172748490, - "x0": 1568172725689, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172771291, - "x0": 1568172748490, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172794092, - "x0": 1568172771291, - "y": 1 - }, - { - "upCount": 92, - "downCount": 8, - "x": 1568172816893, - "x0": 1568172794092, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568172839694, - "x0": 1568172816893, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172862495, - "x0": 1568172839694, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172885296, - "x0": 1568172862495, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172908097, - "x0": 1568172885296, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568172930898, - "x0": 1568172908097, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172953699, - "x0": 1568172930898, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568172976500, - "x0": 1568172953699, - "y": 1 - }, - { - "upCount": 92, - "downCount": 8, - "x": 1568172999301, - "x0": 1568172976500, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568173022102, - "x0": 1568172999301, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568173044903, - "x0": 1568173022102, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568173067704, - "x0": 1568173044903, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568173090505, - "x0": 1568173067704, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568173113306, - "x0": 1568173090505, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568173136107, - "x0": 1568173113306, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568173158908, - "x0": 1568173136107, - "y": 1 - }, - { - "upCount": 92, - "downCount": 8, - "x": 1568173181709, - "x0": 1568173158908, - "y": 1 - }, - { - "upCount": 93, - "downCount": 7, - "x": 1568173204510, - "x0": 1568173181709, - "y": 1 - }, - { - "upCount": 0, - "downCount": 0, - "x": 1568173227311, - "x0": 1568173204510, - "y": 1 - } - ] + "queryResult": { + "histogram": [ + { + "upCount": 93, + "downCount": 7, + "x": 1568172657286, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172680087, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172702888, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568172725689, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172748490, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172771291, + "x0": null, + "y": 1 + }, + { + "upCount": 92, + "downCount": 8, + "x": 1568172794092, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568172816893, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172839694, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172862495, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172885296, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568172908097, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172930898, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568172953699, + "x0": null, + "y": 1 + }, + { + "upCount": 92, + "downCount": 8, + "x": 1568172976500, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568172999301, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173022102, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173044903, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173067704, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568173090505, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173113306, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173136107, + "x0": null, + "y": 1 + }, + { + "upCount": 92, + "downCount": 8, + "x": 1568173158908, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173181709, + "x0": null, + "y": 1 + }, + { + "upCount": 0, + "downCount": 0, + "x": 1568173204510, + "x0": null, + "y": 1 + }, + { + "upCount": 93, + "downCount": 7, + "x": 1568173227311, + "x0": null, + "y": 1 + } + ] + } } \ No newline at end of file diff --git a/x-pack/test/api_integration/apis/uptime/graphql/snapshot_histogram.ts b/x-pack/test/api_integration/apis/uptime/graphql/snapshot_histogram.ts index 7af9de99d8327..02fd3fd630d4b 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/snapshot_histogram.ts +++ b/x-pack/test/api_integration/apis/uptime/graphql/snapshot_histogram.ts @@ -7,6 +7,7 @@ import { snapshotHistogramQueryString } from '../../../../../legacy/plugins/uptime/public/queries/snapshot_histogram_query'; import { expectFixtureEql } from './helpers/expect_fixture_eql'; import { FtrProviderContext } from '../../../ftr_provider_context'; +import { assertCloseTo } from '../../../../../legacy/plugins/uptime/server/lib/helper'; export default function({ getService }: FtrProviderContext) { describe('snapshotHistogram', () => { @@ -31,6 +32,10 @@ export default function({ getService }: FtrProviderContext) { .post('/api/uptime/graphql') .set('kbn-xsrf', 'foo') .send({ ...getSnapshotHistogramQuery }); + // manually testing this value and then removing it to avoid flakiness + const { interval } = data.queryResult; + assertCloseTo(interval, 22801, 100); + delete data.queryResult.interval; expectFixtureEql(data, 'snapshot_histogram'); }); @@ -50,6 +55,9 @@ export default function({ getService }: FtrProviderContext) { .post('/api/uptime/graphql') .set('kbn-xsrf', 'foo') .send({ ...getSnapshotHistogramQuery }); + const { interval } = data.queryResult; + assertCloseTo(interval, 22801, 100); + delete data.queryResult.interval; expectFixtureEql(data, 'snapshot_histogram_by_id'); }); @@ -71,6 +79,9 @@ export default function({ getService }: FtrProviderContext) { .post('/api/uptime/graphql') .set('kbn-xsrf', 'foo') .send({ ...getSnapshotHistogramQuery }); + const { interval } = data.queryResult; + assertCloseTo(interval, 22801, 100); + delete data.queryResult.interval; expectFixtureEql(data, 'snapshot_histogram_by_filter'); }); }); From 11d3445b5da225e18a92dbb1836875c4ece36bf3 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Sat, 26 Oct 2019 02:06:50 +0200 Subject: [PATCH 48/61] watch ignores resolved to plugins internals (#48629) --- src/cli/cluster/cluster_manager.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/cli/cluster/cluster_manager.js b/src/cli/cluster/cluster_manager.js index 8d56f6406ef59..a67593c02a593 100644 --- a/src/cli/cluster/cluster_manager.js +++ b/src/cli/cluster/cluster_manager.js @@ -113,7 +113,7 @@ export default class ClusterManager { ...scanDirs, ]; - const extraIgnores = scanDirs + const pluginInternalDirsIgnore = scanDirs .map(scanDir => resolve(scanDir, '*')) .concat(pluginPaths) .reduce( @@ -124,16 +124,11 @@ export default class ClusterManager { resolve(path, 'target'), resolve(path, 'scripts'), resolve(path, 'docs'), - resolve(path, 'src/legacy/server/sass/__tmp__'), - resolve(path, 'legacy/plugins/reporting/.chromium'), - resolve(path, 'legacy/plugins/siem/cypress'), - resolve(path, 'legacy/plugins/apm/cypress'), - resolve(path, 'x-pack/legacy/plugins/canvas/canvas_plugin_src') // prevents server from restarting twice for Canvas plugin changes ), [] ); - this.setupWatching(extraPaths, extraIgnores); + this.setupWatching(extraPaths, pluginInternalDirsIgnore); } else this.startCluster(); } @@ -170,7 +165,7 @@ export default class ClusterManager { .then(() => opn(openUrl)); } - setupWatching(extraPaths, extraIgnores) { + setupWatching(extraPaths, pluginInternalDirsIgnore) { const chokidar = require('chokidar'); const { fromRoot } = require('../../legacy/utils'); @@ -187,12 +182,21 @@ export default class ClusterManager { ...extraPaths, ].map(path => resolve(path)); + const ignorePaths = [ + fromRoot('src/legacy/server/sass/__tmp__'), + fromRoot('x-pack/legacy/plugins/reporting/.chromium'), + fromRoot('x-pack/legacy/plugins/siem/cypress'), + fromRoot('x-pack/legacy/plugins/apm/cypress'), + fromRoot('x-pack/legacy/plugins/canvas/canvas_plugin_src') // prevents server from restarting twice for Canvas plugin changes + ]; + this.watcher = chokidar.watch(uniq(watchPaths), { cwd: fromRoot('.'), ignored: [ /[\\\/](\..*|node_modules|bower_components|public|__[a-z0-9_]+__|coverage)[\\\/]/, /\.test\.(js|ts)$/, - ...extraIgnores, + ...pluginInternalDirsIgnore, + ...ignorePaths, 'plugins/java_languageserver' ], }); From 3e89cb54ded6a8c302bae9e40a8a70a4d4ced6a9 Mon Sep 17 00:00:00 2001 From: Nick Peihl Date: Fri, 25 Oct 2019 17:35:16 -0700 Subject: [PATCH 49/61] Remove mapping type from example url (#49425) --- docs/getting-started/tutorial-full-experience.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/tutorial-full-experience.asciidoc b/docs/getting-started/tutorial-full-experience.asciidoc index 08f65b0a24091..eafbb7d8f7c91 100644 --- a/docs/getting-started/tutorial-full-experience.asciidoc +++ b/docs/getting-started/tutorial-full-experience.asciidoc @@ -183,7 +183,7 @@ At this point, you're ready to use the Elasticsearch {ref}/docs-bulk.html[bulk] API to load the data sets: [source,shell] -curl -u elastic -H 'Content-Type: application/x-ndjson' -XPOST ':/bank/account/_bulk?pretty' --data-binary @accounts.json +curl -u elastic -H 'Content-Type: application/x-ndjson' -XPOST ':/bank/_bulk?pretty' --data-binary @accounts.json curl -u elastic -H 'Content-Type: application/x-ndjson' -XPOST ':/shakespeare/_bulk?pretty' --data-binary @shakespeare.json curl -u elastic -H 'Content-Type: application/x-ndjson' -XPOST ':/_bulk?pretty' --data-binary @logs.jsonl From 9482ba576508ab74a1da42760e7213c2c88a7147 Mon Sep 17 00:00:00 2001 From: Catherine Liu Date: Sat, 26 Oct 2019 06:25:09 -0700 Subject: [PATCH 50/61] Fixed typo in formatnumber example (#49379) --- docs/canvas/canvas-function-reference.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/canvas/canvas-function-reference.asciidoc b/docs/canvas/canvas-function-reference.asciidoc index 2b437728b2d01..07f3cf028dc0e 100644 --- a/docs/canvas/canvas-function-reference.asciidoc +++ b/docs/canvas/canvas-function-reference.asciidoc @@ -1355,7 +1355,7 @@ Formats a `number` into a formatted `string` using NumeralJS. See http://numeral [source,js] ---- formatnumber format=”$0,0.00” -fortmatnumber “0.0a” +formatnumber “0.0a” ---- *Code example* From f9b0a46dfdfbbacada1f9e6c0ae024d405437641 Mon Sep 17 00:00:00 2001 From: Dmitry Lemeshko Date: Sat, 26 Oct 2019 15:51:45 +0200 Subject: [PATCH 51/61] [kbn-expect] add optional error message (#48895) * [kbn-expect] add optional error message * review feedback: replace error message with provided one * add optional message for contain/string --- packages/kbn-expect/expect.js | 43 ++++++++++++++++++++++++------ packages/kbn-expect/expect.js.d.ts | 26 +++++++++--------- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/packages/kbn-expect/expect.js b/packages/kbn-expect/expect.js index 8dc8af4cab894..bc75d19d2ab1f 100644 --- a/packages/kbn-expect/expect.js +++ b/packages/kbn-expect/expect.js @@ -98,6 +98,9 @@ Assertion.prototype.assert = function (truth, msg, error, expected) { if (!ok) { err = new Error(msg.call(this)); + if (this.customMsg) { + err.message = this.customMsg; + } if (arguments.length > 3) { err.actual = this.obj; err.expected = expected; @@ -217,7 +220,10 @@ Assertion.prototype.empty = function () { */ Assertion.prototype.be = -Assertion.prototype.equal = function (obj) { +Assertion.prototype.equal = function (obj, msg) { + if (typeof(msg) === 'string') { + this.customMsg = msg; + } this.assert( obj === this.obj , function(){ return 'expected ' + i(this.obj) + ' to equal ' + i(obj) } @@ -231,7 +237,10 @@ Assertion.prototype.equal = function (obj) { * @api public */ -Assertion.prototype.eql = function (obj) { +Assertion.prototype.eql = function (obj, msg) { + if (typeof(msg) === 'string') { + this.customMsg = msg; + } this.assert( expect.eql(this.obj, obj) , function(){ return 'expected ' + i(this.obj) + ' to sort of equal ' + i(obj) } @@ -248,7 +257,10 @@ Assertion.prototype.eql = function (obj) { * @api public */ -Assertion.prototype.within = function (start, finish) { +Assertion.prototype.within = function (start, finish, msg) { + if (typeof(msg) === 'string') { + this.customMsg = msg; + } var range = start + '..' + finish; this.assert( this.obj >= start && this.obj <= finish @@ -298,7 +310,10 @@ Assertion.prototype.an = function (type) { */ Assertion.prototype.greaterThan = -Assertion.prototype.above = function (n) { +Assertion.prototype.above = function (n, msg) { + if (typeof(msg) === 'string') { + this.customMsg = msg; + } this.assert( this.obj > n , function(){ return 'expected ' + i(this.obj) + ' to be above ' + n } @@ -314,7 +329,10 @@ Assertion.prototype.above = function (n) { */ Assertion.prototype.lessThan = -Assertion.prototype.below = function (n) { +Assertion.prototype.below = function (n, msg) { + if (typeof(msg) === 'string') { + this.customMsg = msg; + } this.assert( this.obj < n , function(){ return 'expected ' + i(this.obj) + ' to be below ' + n } @@ -329,7 +347,10 @@ Assertion.prototype.below = function (n) { * @api public */ -Assertion.prototype.match = function (regexp) { +Assertion.prototype.match = function (regexp, msg) { + if (typeof(msg) === 'string') { + this.customMsg = msg; + } this.assert( regexp.exec(this.obj) , function(){ return 'expected ' + i(this.obj) + ' to match ' + regexp } @@ -344,7 +365,10 @@ Assertion.prototype.match = function (regexp) { * @api public */ -Assertion.prototype.length = function (n) { +Assertion.prototype.length = function (n, msg) { + if (typeof(msg) === 'string') { + this.customMsg = msg; + } expect(this.obj).to.have.property('length'); var len = this.obj.length; this.assert( @@ -410,7 +434,10 @@ Assertion.prototype.property = function (name, val) { */ Assertion.prototype.string = -Assertion.prototype.contain = function (obj) { +Assertion.prototype.contain = function (obj, msg) { + if (typeof(msg) === 'string') { + this.customMsg = msg; + } if ('string' == typeof this.obj) { this.assert( ~this.obj.indexOf(obj) diff --git a/packages/kbn-expect/expect.js.d.ts b/packages/kbn-expect/expect.js.d.ts index 2062dea686500..b957a1f9ab109 100644 --- a/packages/kbn-expect/expect.js.d.ts +++ b/packages/kbn-expect/expect.js.d.ts @@ -59,12 +59,12 @@ interface Assertion { /** * Checks if the obj exactly equals another. */ - equal(obj: any): Assertion; + equal(obj: any, msg?: string): Assertion; /** * Checks if the obj sortof equals another. */ - eql(obj: any): Assertion; + eql(obj: any, msg?: string): Assertion; /** * Assert within start to finish (inclusive). @@ -72,7 +72,7 @@ interface Assertion { * @param start * @param finish */ - within(start: number, finish: number): Assertion; + within(start: number, finish: number, msg?: string): Assertion; /** * Assert typeof. @@ -87,36 +87,36 @@ interface Assertion { /** * Assert numeric value above n. */ - greaterThan(n: number): Assertion; + greaterThan(n: number, msg?: string): Assertion; /** * Assert numeric value above n. */ - above(n: number): Assertion; + above(n: number, msg?: string): Assertion; /** * Assert numeric value below n. */ - lessThan(n: number): Assertion; + lessThan(n: number, msg?: string): Assertion; /** * Assert numeric value below n. */ - below(n: number): Assertion; + below(n: number, msg?: string): Assertion; /** * Assert string value matches regexp. * * @param regexp */ - match(regexp: RegExp): Assertion; + match(regexp: RegExp, msg?: string): Assertion; /** * Assert property "length" exists and has value of n. * * @param n */ - length(n: number): Assertion; + length(n: number, msg?: string): Assertion; /** * Assert property name exists, with optional val. @@ -129,14 +129,14 @@ interface Assertion { /** * Assert that string contains str. */ - contain(str: string): Assertion; - string(str: string): Assertion; + contain(str: string, msg?: string): Assertion; + string(str: string, msg?: string): Assertion; /** * Assert that the array contains obj. */ - contain(obj: any): Assertion; - string(obj: any): Assertion; + contain(obj: any, msg?: string): Assertion; + string(obj: any, msg?: string): Assertion; /** * Assert exact keys or inclusion of keys by using the `.own` modifier. From 795d1caa5a9644bdca68290e5c048d4bd0557c68 Mon Sep 17 00:00:00 2001 From: patrykkopycinski Date: Sun, 27 Oct 2019 06:23:51 -0700 Subject: [PATCH 52/61] [SIEM] Fix host details page redirect (#48720) --- .../legacy/plugins/siem/public/pages/hosts/index.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/index.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/index.tsx index 6596d4c65c00e..72b19dbbb13b2 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/index.tsx @@ -229,12 +229,12 @@ export const HostsContainer = React.memo(({ url }) => ( /> ( - - )} + render={({ + match: { + params: { detailName }, + }, + location: { search = '' }, + }) => } /> Date: Mon, 28 Oct 2019 10:40:21 +0200 Subject: [PATCH 53/61] Allow plugins to register top nav menu items (regression fix) (#48542) * Move top nav menu to its own plugin Allow registering additional options from other plugins Added demo plugin * Added functional test to validate top nav registration * Improved names * Rename array * Fixed lens tests * Deleted old NavBarExtensionsRegistryProvider * Fixed top nav menu test * Attempt fixing test by clearing ui_actions on stop * temporary disable test --- .github/CODEOWNERS | 1 + .github/labeler.yml | 1 + .i18nrc.json | 1 + src/core/MIGRATION.md | 2 +- .../kibana_react/public/index.scss | 2 - .../core_plugins/kibana_react/public/index.ts | 2 - src/legacy/core_plugins/navigation/index.ts | 42 +++++++++++ .../core_plugins/navigation/package.json | 4 + .../core_plugins/navigation/public/index.scss | 3 + .../core_plugins/navigation/public/index.ts | 32 ++++++++ .../core_plugins/navigation/public/legacy.ts | 30 ++++++++ .../core_plugins/navigation/public/plugin.ts | 74 +++++++++++++++++++ .../public/top_nav_menu/_index.scss | 0 .../top_nav_menu/create_top_nav_menu.tsx | 31 ++++++++ .../public/top_nav_menu/index.ts | 1 + .../public/top_nav_menu/top_nav_menu.test.tsx | 25 +++---- .../public/top_nav_menu/top_nav_menu.tsx | 12 +-- .../public/top_nav_menu/top_nav_menu_data.tsx | 0 .../top_nav_menu_extensions_registry.ts | 46 ++++++++++++ .../top_nav_menu/top_nav_menu_item.test.tsx | 0 .../public/top_nav_menu/top_nav_menu_item.tsx | 0 .../ui/public/kbn_top_nav/kbn_top_nav.js | 3 +- src/plugins/ui_actions/public/plugin.ts | 5 +- .../plugins/kbn_tp_top_nav/index.js | 20 ++--- .../plugins/kbn_tp_top_nav/package.json | 9 +++ .../plugins/kbn_tp_top_nav/public/app.js | 54 ++++++++++++++ .../plugins/kbn_tp_top_nav/public/top_nav.tsx | 54 ++++++++++++++ .../plugins/kbn_tp_top_nav/tsconfig.json | 15 ++++ .../test_suites/core_plugins/index.js | 1 + .../test_suites/core_plugins/top_nav.js | 40 ++++++++++ .../lens/public/app_plugin/app.test.tsx | 17 +++-- .../plugins/lens/public/app_plugin/app.tsx | 4 +- 32 files changed, 487 insertions(+), 44 deletions(-) create mode 100644 src/legacy/core_plugins/navigation/index.ts create mode 100644 src/legacy/core_plugins/navigation/package.json create mode 100644 src/legacy/core_plugins/navigation/public/index.scss create mode 100644 src/legacy/core_plugins/navigation/public/index.ts create mode 100644 src/legacy/core_plugins/navigation/public/legacy.ts create mode 100644 src/legacy/core_plugins/navigation/public/plugin.ts rename src/legacy/core_plugins/{kibana_react => navigation}/public/top_nav_menu/_index.scss (100%) create mode 100644 src/legacy/core_plugins/navigation/public/top_nav_menu/create_top_nav_menu.tsx rename src/legacy/core_plugins/{kibana_react => navigation}/public/top_nav_menu/index.ts (94%) rename src/legacy/core_plugins/{kibana_react => navigation}/public/top_nav_menu/top_nav_menu.test.tsx (88%) rename src/legacy/core_plugins/{kibana_react => navigation}/public/top_nav_menu/top_nav_menu.tsx (89%) rename src/legacy/core_plugins/{kibana_react => navigation}/public/top_nav_menu/top_nav_menu_data.tsx (100%) create mode 100644 src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_extensions_registry.ts rename src/legacy/core_plugins/{kibana_react => navigation}/public/top_nav_menu/top_nav_menu_item.test.tsx (100%) rename src/legacy/core_plugins/{kibana_react => navigation}/public/top_nav_menu/top_nav_menu_item.tsx (100%) rename src/legacy/ui/public/registry/navbar_extensions.js => test/plugin_functional/plugins/kbn_tp_top_nav/index.js (74%) create mode 100644 test/plugin_functional/plugins/kbn_tp_top_nav/package.json create mode 100644 test/plugin_functional/plugins/kbn_tp_top_nav/public/app.js create mode 100644 test/plugin_functional/plugins/kbn_tp_top_nav/public/top_nav.tsx create mode 100644 test/plugin_functional/plugins/kbn_tp_top_nav/tsconfig.json create mode 100644 test/plugin_functional/test_suites/core_plugins/top_nav.js diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4ae7b27a58ee4..7001e32754abb 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -10,6 +10,7 @@ /src/plugins/data/ @elastic/kibana-app-arch /src/plugins/kibana_utils/ @elastic/kibana-app-arch /src/plugins/kibana_react/ @elastic/kibana-app-arch +/src/plugins/navigation/ @elastic/kibana-app-arch # APM /x-pack/legacy/plugins/apm/ @elastic/apm-ui diff --git a/.github/labeler.yml b/.github/labeler.yml index 8a776a909cd9e..57b299912ae9e 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -2,6 +2,7 @@ - src/plugins/data/**/* - src/plugins/embeddable/**/* - src/plugins/kibana_react/**/* +- src/plugins/navigation/**/* - src/plugins/kibana_utils/**/* - src/legacy/core_plugins/dashboard_embeddable_container/**/* - src/legacy/core_plugins/data/**/* diff --git a/.i18nrc.json b/.i18nrc.json index 0ea51fe8212c4..d77293e3dc8f7 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -4,6 +4,7 @@ "data": ["src/legacy/core_plugins/data", "src/plugins/data"], "expressions": "src/legacy/core_plugins/expressions", "kibana_react": "src/legacy/core_plugins/kibana_react", + "navigation": "src/legacy/core_plugins/navigation", "server": "src/legacy/server", "console": "src/legacy/core_plugins/console", "core": "src/core", diff --git a/src/core/MIGRATION.md b/src/core/MIGRATION.md index b5942cc82941f..018a91be4c3d1 100644 --- a/src/core/MIGRATION.md +++ b/src/core/MIGRATION.md @@ -1132,7 +1132,7 @@ import { setup, start } from '../core_plugins/visualizations/public/legacy'; | `import 'ui/filter_bar'` | `import { FilterBar } from '../data/public'` | `import '../data/public/legacy` should be called to load legacy directives | | `import 'ui/query_bar'` | `import { QueryBar, QueryBarInput } from '../data/public'` | Directives are deprecated. | | `import 'ui/search_bar'` | `import { SearchBar } from '../data/public'` | Directive is deprecated. | -| `import 'ui/kbn_top_nav'` | `import { TopNavMenu } from '../kibana_react/public'` | Directive is still available in `ui/kbn_top_nav`. | +| `import 'ui/kbn_top_nav'` | `import { TopNavMenu } from '../navigation/public'` | Directive is still available in `ui/kbn_top_nav`. | | `ui/saved_objects/components/saved_object_finder` | `import { SavedObjectFinder } from '../kibana_react/public'` | | | `core_plugins/interpreter` | `data.expressions` | still in progress | | `ui/courier` | `data.search` | still in progress | diff --git a/src/legacy/core_plugins/kibana_react/public/index.scss b/src/legacy/core_plugins/kibana_react/public/index.scss index 14922ca8ee8eb..14b4687c459e1 100644 --- a/src/legacy/core_plugins/kibana_react/public/index.scss +++ b/src/legacy/core_plugins/kibana_react/public/index.scss @@ -1,5 +1,3 @@ @import 'src/legacy/ui/public/styles/styling_constants'; -@import './top_nav_menu/index'; - @import './markdown/index'; diff --git a/src/legacy/core_plugins/kibana_react/public/index.ts b/src/legacy/core_plugins/kibana_react/public/index.ts index 2497671ca98d2..7e68b6c3886ff 100644 --- a/src/legacy/core_plugins/kibana_react/public/index.ts +++ b/src/legacy/core_plugins/kibana_react/public/index.ts @@ -23,6 +23,4 @@ // of the ExpressionExectorService /** @public types */ -export { TopNavMenu, TopNavMenuData } from './top_nav_menu'; - export { Markdown, MarkdownSimple } from './markdown'; diff --git a/src/legacy/core_plugins/navigation/index.ts b/src/legacy/core_plugins/navigation/index.ts new file mode 100644 index 0000000000000..32d5f040760c6 --- /dev/null +++ b/src/legacy/core_plugins/navigation/index.ts @@ -0,0 +1,42 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { resolve } from 'path'; +import { Legacy } from '../../../../kibana'; + +// eslint-disable-next-line import/no-default-export +export default function NavigationPlugin(kibana: any) { + const config: Legacy.PluginSpecOptions = { + id: 'navigation', + require: [], + publicDir: resolve(__dirname, 'public'), + config: (Joi: any) => { + return Joi.object({ + enabled: Joi.boolean().default(true), + }).default(); + }, + init: (server: Legacy.Server) => ({}), + uiExports: { + injectDefaultVars: () => ({}), + styleSheetPaths: resolve(__dirname, 'public/index.scss'), + }, + }; + + return new kibana.Plugin(config); +} diff --git a/src/legacy/core_plugins/navigation/package.json b/src/legacy/core_plugins/navigation/package.json new file mode 100644 index 0000000000000..8fddb8e6aeced --- /dev/null +++ b/src/legacy/core_plugins/navigation/package.json @@ -0,0 +1,4 @@ +{ + "name": "navigation", + "version": "kibana" +} diff --git a/src/legacy/core_plugins/navigation/public/index.scss b/src/legacy/core_plugins/navigation/public/index.scss new file mode 100644 index 0000000000000..4c969b1a37e8c --- /dev/null +++ b/src/legacy/core_plugins/navigation/public/index.scss @@ -0,0 +1,3 @@ +@import 'src/legacy/ui/public/styles/styling_constants'; + +@import './top_nav_menu/index'; diff --git a/src/legacy/core_plugins/navigation/public/index.ts b/src/legacy/core_plugins/navigation/public/index.ts new file mode 100644 index 0000000000000..439405cc90b57 --- /dev/null +++ b/src/legacy/core_plugins/navigation/public/index.ts @@ -0,0 +1,32 @@ +/* + * 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. + */ + +// TODO these are imports from the old plugin world. +// Once the new platform is ready, they can get removed +// and handled by the platform itself in the setup method +// of the ExpressionExectorService + +/** @public types */ +export { TopNavMenu, TopNavMenuData } from './top_nav_menu'; +export { NavigationSetup, NavigationStart } from './plugin'; + +import { NavigationPlugin as Plugin } from './plugin'; +export function plugin() { + return new Plugin(); +} diff --git a/src/legacy/core_plugins/navigation/public/legacy.ts b/src/legacy/core_plugins/navigation/public/legacy.ts new file mode 100644 index 0000000000000..1783514e6fbdc --- /dev/null +++ b/src/legacy/core_plugins/navigation/public/legacy.ts @@ -0,0 +1,30 @@ +/* + * 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 { npSetup, npStart } from 'ui/new_platform'; +import { start as dataShim } from '../../data/public/legacy'; +import { plugin } from '.'; + +const navPlugin = plugin(); + +export const setup = navPlugin.setup(npSetup.core); + +export const start = navPlugin.start(npStart.core, { + data: dataShim, +}); diff --git a/src/legacy/core_plugins/navigation/public/plugin.ts b/src/legacy/core_plugins/navigation/public/plugin.ts new file mode 100644 index 0000000000000..65a0902dec986 --- /dev/null +++ b/src/legacy/core_plugins/navigation/public/plugin.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 { CoreSetup, CoreStart, Plugin } from 'kibana/public'; +import { TopNavMenuExtensionsRegistry, TopNavMenuExtensionsRegistrySetup } from './top_nav_menu'; +import { createTopNav } from './top_nav_menu/create_top_nav_menu'; +import { TopNavMenuProps } from './top_nav_menu/top_nav_menu'; +import { DataStart } from '../../data/public'; + +/** + * Interface for this plugin's returned `setup` contract. + * + * @public + */ +export interface NavigationSetup { + registerMenuItem: TopNavMenuExtensionsRegistrySetup['register']; +} + +/** + * Interface for this plugin's returned `start` contract. + * + * @public + */ +export interface NavigationStart { + ui: { + TopNavMenu: React.ComponentType; + }; +} + +export interface NavigationPluginStartDependencies { + data: DataStart; +} + +export class NavigationPlugin implements Plugin { + private readonly topNavMenuExtensionsRegistry: TopNavMenuExtensionsRegistry = new TopNavMenuExtensionsRegistry(); + + public setup(core: CoreSetup): NavigationSetup { + return { + registerMenuItem: this.topNavMenuExtensionsRegistry.register.bind( + this.topNavMenuExtensionsRegistry + ), + }; + } + + public start(core: CoreStart, { data }: NavigationPluginStartDependencies): NavigationStart { + const extensions = this.topNavMenuExtensionsRegistry.getAll(); + + return { + ui: { + TopNavMenu: createTopNav(data, extensions), + }, + }; + } + + public stop() { + this.topNavMenuExtensionsRegistry.clear(); + } +} diff --git a/src/legacy/core_plugins/kibana_react/public/top_nav_menu/_index.scss b/src/legacy/core_plugins/navigation/public/top_nav_menu/_index.scss similarity index 100% rename from src/legacy/core_plugins/kibana_react/public/top_nav_menu/_index.scss rename to src/legacy/core_plugins/navigation/public/top_nav_menu/_index.scss diff --git a/src/legacy/core_plugins/navigation/public/top_nav_menu/create_top_nav_menu.tsx b/src/legacy/core_plugins/navigation/public/top_nav_menu/create_top_nav_menu.tsx new file mode 100644 index 0000000000000..fa0e5fcac7407 --- /dev/null +++ b/src/legacy/core_plugins/navigation/public/top_nav_menu/create_top_nav_menu.tsx @@ -0,0 +1,31 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { TopNavMenuProps, TopNavMenu } from './top_nav_menu'; +import { TopNavMenuData } from './top_nav_menu_data'; +import { DataStart } from '../../../../core_plugins/data/public'; + +export function createTopNav(data: DataStart, extraConfig: TopNavMenuData[]) { + return (props: TopNavMenuProps) => { + const config = (props.config || []).concat(extraConfig); + + return ; + }; +} diff --git a/src/legacy/core_plugins/kibana_react/public/top_nav_menu/index.ts b/src/legacy/core_plugins/navigation/public/top_nav_menu/index.ts similarity index 94% rename from src/legacy/core_plugins/kibana_react/public/top_nav_menu/index.ts rename to src/legacy/core_plugins/navigation/public/top_nav_menu/index.ts index b45baaf0e4711..dd139bbd6410f 100644 --- a/src/legacy/core_plugins/kibana_react/public/top_nav_menu/index.ts +++ b/src/legacy/core_plugins/navigation/public/top_nav_menu/index.ts @@ -19,3 +19,4 @@ export { TopNavMenu } from './top_nav_menu'; export { TopNavMenuData } from './top_nav_menu_data'; +export * from './top_nav_menu_extensions_registry'; diff --git a/src/legacy/core_plugins/kibana_react/public/top_nav_menu/top_nav_menu.test.tsx b/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx similarity index 88% rename from src/legacy/core_plugins/kibana_react/public/top_nav_menu/top_nav_menu.test.tsx rename to src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx index 21c5cef4ae925..803119bdac119 100644 --- a/src/legacy/core_plugins/kibana_react/public/top_nav_menu/top_nav_menu.test.tsx +++ b/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx @@ -27,21 +27,11 @@ const timefilterSetupMock = timefilterServiceMock.createSetupContract(); jest.mock('ui/new_platform'); -jest.mock('../../../../../../src/legacy/core_plugins/data/public/legacy', () => ({ - start: { - ui: { - SearchBar: () => {}, - }, - }, - setup: {}, -})); - -jest.mock('../../../../core_plugins/data/public', () => { - return { +const dataShim = { + ui: { SearchBar: () =>
, - SearchBarProps: {}, - }; -}); + }, +}; describe('TopNavMenu', () => { const TOP_NAV_ITEM_SELECTOR = 'TopNavMenuItem'; @@ -84,7 +74,12 @@ describe('TopNavMenu', () => { it('Should render search bar', () => { const component = shallowWithIntl( - + ); expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(0); diff --git a/src/legacy/core_plugins/kibana_react/public/top_nav_menu/top_nav_menu.tsx b/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu.tsx similarity index 89% rename from src/legacy/core_plugins/kibana_react/public/top_nav_menu/top_nav_menu.tsx rename to src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu.tsx index aec91c2aa6bc6..14599e76470c0 100644 --- a/src/legacy/core_plugins/kibana_react/public/top_nav_menu/top_nav_menu.tsx +++ b/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu.tsx @@ -24,13 +24,13 @@ import { I18nProvider } from '@kbn/i18n/react'; import { TopNavMenuData } from './top_nav_menu_data'; import { TopNavMenuItem } from './top_nav_menu_item'; -import { SearchBarProps } from '../../../../core_plugins/data/public'; -import { start as data } from '../../../data/public/legacy'; +import { SearchBarProps, DataStart } from '../../../../core_plugins/data/public'; -type Props = Partial & { +export type TopNavMenuProps = Partial & { appName: string; config?: TopNavMenuData[]; showSearchBar?: boolean; + data?: DataStart; }; /* @@ -42,8 +42,7 @@ type Props = Partial & { * **/ -export function TopNavMenu(props: Props) { - const { SearchBar } = data.ui; +export function TopNavMenu(props: TopNavMenuProps) { const { config, showSearchBar, ...searchBarProps } = props; function renderItems() { if (!config) return; @@ -58,7 +57,8 @@ export function TopNavMenu(props: Props) { function renderSearchBar() { // Validate presense of all required fields - if (!showSearchBar) return; + if (!showSearchBar || !props.data) return; + const { SearchBar } = props.data.ui; return ; } diff --git a/src/legacy/core_plugins/kibana_react/public/top_nav_menu/top_nav_menu_data.tsx b/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_data.tsx similarity index 100% rename from src/legacy/core_plugins/kibana_react/public/top_nav_menu/top_nav_menu_data.tsx rename to src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_data.tsx diff --git a/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_extensions_registry.ts b/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_extensions_registry.ts new file mode 100644 index 0000000000000..c3eab3cce18e6 --- /dev/null +++ b/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_extensions_registry.ts @@ -0,0 +1,46 @@ +/* + * 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 { TopNavMenuData } from './top_nav_menu_data'; + +export class TopNavMenuExtensionsRegistry { + private menuItems: TopNavMenuData[]; + + constructor() { + this.menuItems = []; + } + + /** @public **/ + // Items registered into this registry will be appended to any TopNavMenu rendered in any application. + public register(menuItem: TopNavMenuData) { + this.menuItems.push(menuItem); + } + + /** @internal **/ + public getAll() { + return this.menuItems; + } + + /** @internal **/ + public clear() { + this.menuItems.length = 0; + } +} + +export type TopNavMenuExtensionsRegistrySetup = Pick; diff --git a/src/legacy/core_plugins/kibana_react/public/top_nav_menu/top_nav_menu_item.test.tsx b/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_item.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana_react/public/top_nav_menu/top_nav_menu_item.test.tsx rename to src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_item.test.tsx diff --git a/src/legacy/core_plugins/kibana_react/public/top_nav_menu/top_nav_menu_item.tsx b/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx similarity index 100% rename from src/legacy/core_plugins/kibana_react/public/top_nav_menu/top_nav_menu_item.tsx rename to src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx diff --git a/src/legacy/ui/public/kbn_top_nav/kbn_top_nav.js b/src/legacy/ui/public/kbn_top_nav/kbn_top_nav.js index 72fa6bc4c1182..9c4cee6b05db0 100644 --- a/src/legacy/ui/public/kbn_top_nav/kbn_top_nav.js +++ b/src/legacy/ui/public/kbn_top_nav/kbn_top_nav.js @@ -20,7 +20,7 @@ import 'ngreact'; import { wrapInI18nContext } from 'ui/i18n'; import { uiModules } from 'ui/modules'; -import { TopNavMenu } from '../../../core_plugins/kibana_react/public'; +import { start as navigation } from '../../../core_plugins/navigation/public/legacy'; const module = uiModules.get('kibana'); @@ -76,6 +76,7 @@ export function createTopNavDirective() { module.directive('kbnTopNav', createTopNavDirective); export function createTopNavHelper(reactDirective) { + const { TopNavMenu } = navigation.ui; return reactDirective( wrapInI18nContext(TopNavMenu), [ diff --git a/src/plugins/ui_actions/public/plugin.ts b/src/plugins/ui_actions/public/plugin.ts index fda25659d1226..374acaaab3999 100644 --- a/src/plugins/ui_actions/public/plugin.ts +++ b/src/plugins/ui_actions/public/plugin.ts @@ -52,5 +52,8 @@ export class UiActionsPlugin implements Plugin return this.api; } - public stop() {} + public stop() { + this.actions.clear(); + this.triggers.clear(); + } } diff --git a/src/legacy/ui/public/registry/navbar_extensions.js b/test/plugin_functional/plugins/kbn_tp_top_nav/index.js similarity index 74% rename from src/legacy/ui/public/registry/navbar_extensions.js rename to test/plugin_functional/plugins/kbn_tp_top_nav/index.js index 6c7911c6f0f52..144050beb7868 100644 --- a/src/legacy/ui/public/registry/navbar_extensions.js +++ b/test/plugin_functional/plugins/kbn_tp_top_nav/index.js @@ -17,12 +17,14 @@ * under the License. */ -import { uiRegistry } from './_registry'; - -export const NavBarExtensionsRegistryProvider = uiRegistry({ - name: 'navbarExtensions', - index: ['name'], - group: ['appName'], - order: ['order'] -}); - +export default function (kibana) { + return new kibana.Plugin({ + uiExports: { + app: { + title: 'Top Nav Menu test', + description: 'This is a sample plugin for the functional tests.', + main: 'plugins/kbn_tp_top_nav/app', + } + } + }); +} diff --git a/test/plugin_functional/plugins/kbn_tp_top_nav/package.json b/test/plugin_functional/plugins/kbn_tp_top_nav/package.json new file mode 100644 index 0000000000000..7102d24d3292d --- /dev/null +++ b/test/plugin_functional/plugins/kbn_tp_top_nav/package.json @@ -0,0 +1,9 @@ +{ + "name": "kbn_tp_top_nav", + "version": "1.0.0", + "kibana": { + "version": "kibana", + "templateVersion": "1.0.0" + }, + "license": "Apache-2.0" +} diff --git a/test/plugin_functional/plugins/kbn_tp_top_nav/public/app.js b/test/plugin_functional/plugins/kbn_tp_top_nav/public/app.js new file mode 100644 index 0000000000000..e7f97e68c086d --- /dev/null +++ b/test/plugin_functional/plugins/kbn_tp_top_nav/public/app.js @@ -0,0 +1,54 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; + +import { uiModules } from 'ui/modules'; +import chrome from 'ui/chrome'; + +// This is required so some default styles and required scripts/Angular modules are loaded, +// or the timezone setting is correctly applied. +import 'ui/autoload/all'; + +import { AppWithTopNav } from './top_nav'; + +const app = uiModules.get('apps/topnavDemoPlugin', ['kibana']); + +app.config($locationProvider => { + $locationProvider.html5Mode({ + enabled: false, + requireBase: false, + rewriteLinks: false, + }); +}); + +function RootController($scope, $element) { + const domNode = $element[0]; + + // render react to DOM + render(, domNode); + + // unmount react on controller destroy + $scope.$on('$destroy', () => { + unmountComponentAtNode(domNode); + }); +} + +chrome.setRootController('topnavDemoPlugin', RootController); diff --git a/test/plugin_functional/plugins/kbn_tp_top_nav/public/top_nav.tsx b/test/plugin_functional/plugins/kbn_tp_top_nav/public/top_nav.tsx new file mode 100644 index 0000000000000..d56ac5f92db88 --- /dev/null +++ b/test/plugin_functional/plugins/kbn_tp_top_nav/public/top_nav.tsx @@ -0,0 +1,54 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { Component } from 'react'; +import { + setup as navSetup, + start as navStart, +} from '../../../../../src/legacy/core_plugins/navigation/public/legacy'; + +const customExtension = { + id: 'registered-prop', + label: 'Registered Button', + description: 'Registered Demo', + run() {}, + testId: 'demoRegisteredNewButton', +}; + +navSetup.registerMenuItem(customExtension); + +export class AppWithTopNav extends Component { + public render() { + const { TopNavMenu } = navStart.ui; + const config = [ + { + id: 'new', + label: 'New Button', + description: 'New Demo', + run() {}, + testId: 'demoNewButton', + }, + ]; + return ( + + Hey + + ); + } +} diff --git a/test/plugin_functional/plugins/kbn_tp_top_nav/tsconfig.json b/test/plugin_functional/plugins/kbn_tp_top_nav/tsconfig.json new file mode 100644 index 0000000000000..1ba21f11b7de2 --- /dev/null +++ b/test/plugin_functional/plugins/kbn_tp_top_nav/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../../../tsconfig.json", + "compilerOptions": { + "outDir": "./target", + "skipLibCheck": true + }, + "include": [ + "index.ts", + "public/**/*.ts", + "public/**/*.tsx", + "server/**/*.ts", + "../../../../typings/**/*", + ], + "exclude": [] +} diff --git a/test/plugin_functional/test_suites/core_plugins/index.js b/test/plugin_functional/test_suites/core_plugins/index.js index eeb81f67751ed..376c6f1ebadb1 100644 --- a/test/plugin_functional/test_suites/core_plugins/index.js +++ b/test/plugin_functional/test_suites/core_plugins/index.js @@ -23,5 +23,6 @@ export default function ({ loadTestFile }) { loadTestFile(require.resolve('./legacy_plugins')); loadTestFile(require.resolve('./server_plugins')); loadTestFile(require.resolve('./ui_plugins')); + loadTestFile(require.resolve('./top_nav')); }); } diff --git a/test/plugin_functional/test_suites/core_plugins/top_nav.js b/test/plugin_functional/test_suites/core_plugins/top_nav.js new file mode 100644 index 0000000000000..5c46e3d7f76db --- /dev/null +++ b/test/plugin_functional/test_suites/core_plugins/top_nav.js @@ -0,0 +1,40 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import expect from '@kbn/expect'; + +export default function ({ getService, getPageObjects }) { + const PageObjects = getPageObjects(['common']); + + const browser = getService('browser'); + const testSubjects = getService('testSubjects'); + + describe.skip('top nav', function describeIndexTests() { + before(async () => { + const url = `${PageObjects.common.getHostPort()}/app/kbn_tp_top_nav/`; + await browser.get(url); + }); + + it('Shows registered menu items', async () => { + const ownMenuItem = await testSubjects.find('demoNewButton'); + expect(await ownMenuItem.getVisibleText()).to.be('New Button'); + const demoRegisteredNewButton = await testSubjects.find('demoRegisteredNewButton'); + expect(await demoRegisteredNewButton.getVisibleText()).to.be('Registered Button'); + }); + }); +} diff --git a/x-pack/legacy/plugins/lens/public/app_plugin/app.test.tsx b/x-pack/legacy/plugins/lens/public/app_plugin/app.test.tsx index 0e3e6b0381309..ea4f8edf508e1 100644 --- a/x-pack/legacy/plugins/lens/public/app_plugin/app.test.tsx +++ b/x-pack/legacy/plugins/lens/public/app_plugin/app.test.tsx @@ -17,17 +17,22 @@ import { mount } from 'enzyme'; import { dataPluginMock } from '../../../../../../src/plugins/data/public/mocks'; const dataStartMock = dataPluginMock.createStartContract(); -import { - TopNavMenu, - TopNavMenuData, -} from '../../../../../../src/legacy/core_plugins/kibana_react/public'; +import { TopNavMenuData } from '../../../../../../src/legacy/core_plugins/navigation/public'; import { DataStart } from '../../../../../../src/legacy/core_plugins/data/public'; import { coreMock } from 'src/core/public/mocks'; -jest.mock('../../../../../../src/legacy/core_plugins/kibana_react/public', () => ({ - TopNavMenu: jest.fn(() => null), +jest.mock('../../../../../../src/legacy/core_plugins/navigation/public/legacy', () => ({ + start: { + ui: { + TopNavMenu: jest.fn(() => null), + }, + }, })); +import { start as navigation } from '../../../../../../src/legacy/core_plugins/navigation/public/legacy'; + +const { TopNavMenu } = navigation.ui; + jest.mock('ui/new_platform'); jest.mock('../persistence'); jest.mock('src/core/public'); diff --git a/x-pack/legacy/plugins/lens/public/app_plugin/app.tsx b/x-pack/legacy/plugins/lens/public/app_plugin/app.tsx index 1152a3de77181..375ab3aad1eaf 100644 --- a/x-pack/legacy/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/legacy/plugins/lens/public/app_plugin/app.tsx @@ -20,7 +20,7 @@ import { Query, } from 'src/legacy/core_plugins/data/public'; import { Filter } from '@kbn/es-query'; -import { TopNavMenu } from '../../../../../../src/legacy/core_plugins/kibana_react/public'; +import { start as navigation } from '../../../../../../src/legacy/core_plugins/navigation/public/legacy'; import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public'; import { Document, SavedObjectStore } from '../persistence'; import { EditorFrameInstance } from '../types'; @@ -163,6 +163,8 @@ export function App({ [] ); + const { TopNavMenu } = navigation.ui; + return ( Date: Mon, 28 Oct 2019 09:39:53 +0000 Subject: [PATCH 54/61] [DOCS] Changes to support the split of the Metrics Guide and the Logs Guide (#48633) * Linking to new Metrics and Logs documents * Linking to new Metrics and Logs documents --- docs/infrastructure/getting-started.asciidoc | 2 +- docs/logs/getting-started.asciidoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/infrastructure/getting-started.asciidoc b/docs/infrastructure/getting-started.asciidoc index 151a8e2928cf8..1c5645f5a6e4e 100644 --- a/docs/infrastructure/getting-started.asciidoc +++ b/docs/infrastructure/getting-started.asciidoc @@ -5,7 +5,7 @@ To get started with the Metrics app in Kibana, you need to start collecting metrics data for your infrastructure. Kibana provides step-by-step instructions to help you add metrics data. -The {infra-guide}[Infrastructure Monitoring Guide] is a good source for more detailed information and instructions. +The {metrics-guide}[Metrics Monitoring Guide] is a good source for more detailed information and instructions. [role="screenshot"] image::infrastructure/images/metrics-add-data.png[Screenshot showing Add metric data to Kibana UI] diff --git a/docs/logs/getting-started.asciidoc b/docs/logs/getting-started.asciidoc index 1ed8798a4b87f..ca09bb34c0e56 100644 --- a/docs/logs/getting-started.asciidoc +++ b/docs/logs/getting-started.asciidoc @@ -5,7 +5,7 @@ To get started with the Logs app in Kibana, you need to start collecting logs data for your infrastructure. Kibana provides step-by-step instructions to help you add logs data. -The {infra-guide}[Infrastructure Monitoring Guide] is a good source for more detailed information and instructions. +The {logs-guide}[Logs Monitoring Guide] is a good source for more detailed information and instructions. [role="screenshot"] image::logs/images/logs-add-data.png[Screenshot showing Add logging data in Kibana] From f868fa66fa40d146dc1831a8bb185d7e28f9b144 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 28 Oct 2019 11:47:59 +0100 Subject: [PATCH 55/61] [Console][Legacy Editor] Ace Range implementation not being used (#49352) * Use ace Range implementation, not interface, for instantiating * Add simple smoke test for use of Ace ranges * Update test title --- .../application/models/legacy_editor.test.ts | 69 +++++++++++++++++++ .../application/models/legacy_editor.ts | 9 ++- 2 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 src/legacy/core_plugins/console/np_ready/public/application/models/legacy_editor.test.ts diff --git a/src/legacy/core_plugins/console/np_ready/public/application/models/legacy_editor.test.ts b/src/legacy/core_plugins/console/np_ready/public/application/models/legacy_editor.test.ts new file mode 100644 index 0000000000000..0dc1bcc96ddee --- /dev/null +++ b/src/legacy/core_plugins/console/np_ready/public/application/models/legacy_editor.test.ts @@ -0,0 +1,69 @@ +/* + * 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 { Range as AceRange } from 'brace'; +import { LegacyEditor } from './legacy_editor'; + +describe('Legacy Editor', () => { + const aceMock: any = { + getValue() { + return 'ok'; + }, + + getCursorPosition() { + return { + row: 1, + column: 1, + }; + }, + + getSession() { + return { + replace(range: AceRange, value: string) {}, + getLine(n: number) { + return 'line'; + }, + doc: { + getTextRange(r: any) { + return ''; + }, + }, + getState(n: number) { + return n; + }, + }; + }, + }; + + // This is to ensure that we are correctly importing Ace's Range component + it('smoke tests for updates to ranges', () => { + const legacyEditor = new LegacyEditor(aceMock); + legacyEditor.getValueInRange({ + start: { lineNumber: 1, column: 1 }, + end: { lineNumber: 2, column: 2 }, + }); + legacyEditor.replace( + { + start: { lineNumber: 1, column: 1 }, + end: { lineNumber: 2, column: 2 }, + }, + 'test!' + ); + }); +}); diff --git a/src/legacy/core_plugins/console/np_ready/public/application/models/legacy_editor.ts b/src/legacy/core_plugins/console/np_ready/public/application/models/legacy_editor.ts index 1b083adcfea76..f8c3f425a1032 100644 --- a/src/legacy/core_plugins/console/np_ready/public/application/models/legacy_editor.ts +++ b/src/legacy/core_plugins/console/np_ready/public/application/models/legacy_editor.ts @@ -17,10 +17,13 @@ * under the License. */ -import { Editor as IAceEditor, Range as AceRange } from 'brace'; +import ace from 'brace'; +import { Editor as IAceEditor } from 'brace'; import { CoreEditor, Position, Range, Token, TokensProvider } from '../../types'; import { AceTokensProvider } from '../../lib/ace_token_provider'; +const _AceRange = ace.acequire('ace/range').Range; + export class LegacyEditor implements CoreEditor { constructor(private readonly editor: IAceEditor) {} @@ -31,7 +34,7 @@ export class LegacyEditor implements CoreEditor { getValueInRange({ start, end }: Range): string { const session = this.editor.getSession(); - const aceRange = new AceRange( + const aceRange = new _AceRange( start.lineNumber - 1, start.column - 1, end.lineNumber - 1, @@ -90,7 +93,7 @@ export class LegacyEditor implements CoreEditor { } replace({ start, end }: Range, value: string): void { - const aceRange = new AceRange( + const aceRange = new _AceRange( start.lineNumber - 1, start.column - 1, end.lineNumber - 1, From d9d8398fb125ade50ac29541aed6af432e843d4b Mon Sep 17 00:00:00 2001 From: Shahzad Date: Mon, 28 Oct 2019 16:52:33 +0500 Subject: [PATCH 56/61] [Uptime] Issue/48845 Disable filter and Add link to location docs when no location exists (#49175) * disable search text if no item exists * update snaps --- .../__tests__/__snapshots__/filter_popover.test.tsx.snap | 2 ++ .../components/functional/filter_group/filter_popover.tsx | 3 +++ 2 files changed, 5 insertions(+) diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap index e54129015b3e9..6efce389b72f7 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap +++ b/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap @@ -25,6 +25,7 @@ exports[`FilterPopover component does not show item list when loading 1`] = ` setSearchQuery(query)} placeholder={ isLoading @@ -98,6 +100,7 @@ export const FilterPopover = ({ {item} ))} + {id === 'location' && items.length === 0 && } ); }; From 17464f8612fdff0801cfb5e1637ad8ddfa5e5383 Mon Sep 17 00:00:00 2001 From: Maryia Lapata Date: Mon, 28 Oct 2019 15:23:18 +0300 Subject: [PATCH 57/61] [Vis: Default editor] Fix validation for bounds margin (#48216) * Fix validation for bounds margin * Update custom_extents_options.tsx * Rename isValid property * Revert boundsMargin type --- .../components/common/validation_wrapper.tsx | 23 ++++++++---------- .../custom_extents_options.test.tsx | 19 ++++++++------- .../metrics_axes/custom_extents_options.tsx | 24 ++++++++++--------- .../options/metrics_axes/y_extents.tsx | 2 +- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/validation_wrapper.tsx b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/validation_wrapper.tsx index a3a41d2249b32..1dd1ab49d9a47 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/validation_wrapper.tsx +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/validation_wrapper.tsx @@ -29,7 +29,7 @@ interface ValidationWrapperProps extends VisOptionsProps { } interface Item { - valid: boolean; + isValid: boolean; } function ValidationWrapper({ @@ -37,20 +37,17 @@ function ValidationWrapper({ ...rest }: ValidationWrapperProps) { const [panelState, setPanelState] = useState({} as { [key: string]: Item }); - const isPanelValid = Object.values(panelState).every(item => item.valid); + const isPanelValid = Object.values(panelState).every(item => item.isValid); const { setValidity } = rest; - const setValidityHandler = useCallback( - (paramName: string, isValid: boolean) => { - setPanelState({ - ...panelState, - [paramName]: { - valid: isValid, - }, - }); - }, - [panelState] - ); + const setValidityHandler = useCallback((paramName: string, isValid: boolean) => { + setPanelState(state => ({ + ...state, + [paramName]: { + isValid, + }, + })); + }, []); useEffect(() => { setValidity(isPanelValid); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.test.tsx b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.test.tsx index b55d363fa56c8..5f1779ad35304 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.test.tsx +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.test.tsx @@ -18,7 +18,7 @@ */ import React from 'react'; -import { shallow } from 'enzyme'; +import { shallow, mount } from 'enzyme'; import { CustomExtentsOptions, CustomExtentsOptionsProps } from './custom_extents_options'; import { YExtents } from './y_extents'; import { valueAxis } from './mocks'; @@ -55,23 +55,27 @@ describe('CustomExtentsOptions component', () => { describe('boundsMargin', () => { it('should set validity as true when value is positive', () => { - const comp = shallow(); - comp.find({ paramName: BOUNDS_MARGIN }).prop('setValue')(BOUNDS_MARGIN, 5); + defaultProps.axis.scale.boundsMargin = 5; + mount(); expect(setMultipleValidity).toBeCalledWith(BOUNDS_MARGIN, true); }); it('should set validity as true when value is empty', () => { - const comp = shallow(); - comp.find({ paramName: BOUNDS_MARGIN }).prop('setValue')(BOUNDS_MARGIN, ''); + const comp = mount(); + comp.setProps({ + axis: { ...valueAxis, scale: { ...valueAxis.scale, boundsMargin: undefined } }, + }); expect(setMultipleValidity).toBeCalledWith(BOUNDS_MARGIN, true); }); it('should set validity as false when value is negative', () => { defaultProps.axis.scale.defaultYExtents = true; - const comp = shallow(); - comp.find({ paramName: BOUNDS_MARGIN }).prop('setValue')(BOUNDS_MARGIN, -1); + const comp = mount(); + comp.setProps({ + axis: { ...valueAxis, scale: { ...valueAxis.scale, boundsMargin: -1 } }, + }); expect(setMultipleValidity).toBeCalledWith(BOUNDS_MARGIN, false); }); @@ -103,7 +107,6 @@ describe('CustomExtentsOptions component', () => { const comp = shallow(); comp.find({ paramName: DEFAULT_Y_EXTENTS }).prop('setValue')(DEFAULT_Y_EXTENTS, false); - expect(setMultipleValidity).toBeCalledWith(BOUNDS_MARGIN, true); const newScale = { ...defaultProps.axis.scale, boundsMargin: undefined, diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.tsx b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.tsx index e04d8e646160e..df7eedd2c0ea1 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.tsx +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { useState, useCallback } from 'react'; +import React, { useCallback, useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import { ValueAxis } from '../../../types'; @@ -38,21 +38,18 @@ function CustomExtentsOptions({ setValueAxis, setValueAxisScale, }: CustomExtentsOptionsProps) { - const [isBoundsMarginValid, setIsBoundsMarginValid] = useState(true); const invalidBoundsMarginMessage = i18n.translate( 'kbnVislibVisTypes.controls.pointSeries.valueAxes.scaleToDataBounds.minNeededBoundsMargin', { defaultMessage: 'Bounds margin must be greater than or equal to 0.' } ); - const setBoundsMargin = useCallback( - (paramName: 'boundsMargin', value: number | '') => { - const isValid = value === '' ? true : value >= 0; - setIsBoundsMarginValid(isValid); - setMultipleValidity('boundsMargin', isValid); + const isBoundsMarginValid = + !axis.scale.defaultYExtents || !axis.scale.boundsMargin || axis.scale.boundsMargin >= 0; - setValueAxisScale(paramName, value); - }, - [setMultipleValidity, setValueAxisScale] + const setBoundsMargin = useCallback( + (paramName: 'boundsMargin', value: number | '') => + setValueAxisScale(paramName, value === '' ? undefined : value), + [setValueAxisScale] ); const onDefaultYExtentsChange = useCallback( @@ -60,7 +57,6 @@ function CustomExtentsOptions({ const scale = { ...axis.scale, [paramName]: value }; if (!scale.defaultYExtents) { delete scale.boundsMargin; - setMultipleValidity('boundsMargin', true); } setValueAxis('scale', scale); }, @@ -79,6 +75,12 @@ function CustomExtentsOptions({ [setValueAxis, axis.scale] ); + useEffect(() => { + setMultipleValidity('boundsMargin', isBoundsMarginValid); + + return () => setMultipleValidity('boundsMargin', true); + }, [isBoundsMarginValid, setMultipleValidity]); + return ( <> setMultipleValidity('yExtents', true); - }, [isValid]); + }, [isValid, setMultipleValidity]); return ( From fb903f4f9f4686caa2824537045269385095ba76 Mon Sep 17 00:00:00 2001 From: Maryia Lapata Date: Mon, 28 Oct 2019 15:50:39 +0300 Subject: [PATCH 58/61] [Vis: Default editor] Unit tests for number list (#48412) * Add unit tests for number list * Remove unused dependency * Fix code review comments * Refactor NumberList to set model validity in one place --- .../__snapshots__/number_list.test.tsx.snap | 77 +++++++ .../__snapshots__/number_row.test.tsx.snap | 38 +++ .../number_list/number_list.test.tsx | 147 ++++++++++++ .../components/number_list/number_list.tsx | 119 +++++----- .../number_list/number_row.test.tsx | 69 ++++++ .../components/number_list/number_row.tsx | 26 ++- .../components/number_list/utils.test.ts | 218 ++++++++++++++++++ .../controls/components/number_list/utils.ts | 57 +++-- .../default/controls/percentile_ranks.tsx | 4 +- .../editors/default/controls/percentiles.tsx | 4 +- 10 files changed, 653 insertions(+), 106 deletions(-) create mode 100644 src/legacy/ui/public/vis/editors/default/controls/components/number_list/__snapshots__/number_list.test.tsx.snap create mode 100644 src/legacy/ui/public/vis/editors/default/controls/components/number_list/__snapshots__/number_row.test.tsx.snap create mode 100644 src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_list.test.tsx create mode 100644 src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_row.test.tsx create mode 100644 src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/__snapshots__/number_list.test.tsx.snap b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/__snapshots__/number_list.test.tsx.snap new file mode 100644 index 0000000000000..ab192e6fd3cbb --- /dev/null +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/__snapshots__/number_list.test.tsx.snap @@ -0,0 +1,77 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`NumberList should be rendered with default set of props 1`] = ` + + + + + + + + + + + +`; diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/__snapshots__/number_row.test.tsx.snap b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/__snapshots__/number_row.test.tsx.snap new file mode 100644 index 0000000000000..3882425594cf3 --- /dev/null +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/__snapshots__/number_row.test.tsx.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`NumberRow should be rendered with default set of props 1`] = ` + + + + + + + + +`; diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_list.test.tsx b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_list.test.tsx new file mode 100644 index 0000000000000..3faf164c365d9 --- /dev/null +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_list.test.tsx @@ -0,0 +1,147 @@ +/* + * 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 React from 'react'; +import { shallow } from 'enzyme'; +import { mountWithIntl } from 'test_utils/enzyme_helpers'; + +import { NumberList, NumberListProps } from './number_list'; +import { NumberRow } from './number_row'; + +jest.mock('./number_row', () => ({ + NumberRow: () => 'NumberRow', +})); + +jest.mock('@elastic/eui', () => ({ + htmlIdGenerator: jest.fn(() => { + let counter = 1; + return () => `12${counter++}`; + }), + EuiSpacer: require.requireActual('@elastic/eui').EuiSpacer, + EuiFlexItem: require.requireActual('@elastic/eui').EuiFlexItem, + EuiButtonEmpty: require.requireActual('@elastic/eui').EuiButtonEmpty, + EuiFormErrorText: require.requireActual('@elastic/eui').EuiFormErrorText, +})); + +describe('NumberList', () => { + let defaultProps: NumberListProps; + + beforeEach(() => { + defaultProps = { + labelledbyId: 'numberList', + numberArray: [1, 2], + range: '[1, 10]', + showValidation: false, + unitName: 'value', + onChange: jest.fn(), + setTouched: jest.fn(), + setValidity: jest.fn(), + }; + }); + + test('should be rendered with default set of props', () => { + const comp = shallow(); + + expect(comp).toMatchSnapshot(); + }); + + test('should show an order error', () => { + defaultProps.numberArray = [3, 1]; + defaultProps.showValidation = true; + const comp = mountWithIntl(); + + expect(comp.find('EuiFormErrorText').length).toBe(1); + }); + + test('should set validity as true', () => { + mountWithIntl(); + + expect(defaultProps.setValidity).lastCalledWith(true); + }); + + test('should set validity as false when the order is invalid', () => { + defaultProps.numberArray = [3, 2]; + const comp = mountWithIntl(); + + expect(defaultProps.setValidity).lastCalledWith(false); + + comp.setProps({ numberArray: [1, 2] }); + expect(defaultProps.setValidity).lastCalledWith(true); + }); + + test('should set validity as false when there is an empty field', () => { + defaultProps.numberArray = [1, 2]; + const comp = mountWithIntl(); + + comp.setProps({ numberArray: [1, undefined] }); + expect(defaultProps.setValidity).lastCalledWith(false); + }); + + test('should set 0 when number array is empty', () => { + defaultProps.numberArray = []; + mountWithIntl(); + + expect(defaultProps.onChange).lastCalledWith([0]); + }); + + test('should add a number', () => { + const comp = shallow(); + comp.find('EuiButtonEmpty').simulate('click'); + + expect(defaultProps.onChange).lastCalledWith([1, 2, 3]); + }); + + test('should remove a number', () => { + const comp = shallow(); + const row = comp.find(NumberRow).first(); + row.prop('onDelete')(row.prop('model').id); + + expect(defaultProps.onChange).lastCalledWith([2]); + }); + + test('should disable remove button if there is one number', () => { + defaultProps.numberArray = [1]; + const comp = shallow(); + + expect( + comp + .find(NumberRow) + .first() + .prop('disableDelete') + ).toEqual(true); + }); + + test('should change value', () => { + const comp = shallow(); + const row = comp.find(NumberRow).first(); + row.prop('onChange')({ id: row.prop('model').id, value: '3' }); + + expect(defaultProps.onChange).lastCalledWith([3, 2]); + }); + + test('should call setTouched', () => { + const comp = shallow(); + comp + .find(NumberRow) + .first() + .prop('onBlur')(); + + expect(defaultProps.setTouched).toBeCalled(); + }); +}); diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_list.tsx b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_list.tsx index 54040814028f7..4aae217c1bc8d 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_list.tsx +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_list.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { Fragment, useState, useEffect } from 'react'; +import React, { Fragment, useState, useEffect, useMemo, useCallback } from 'react'; import { EuiSpacer, EuiButtonEmpty, EuiFlexItem, EuiFormErrorText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -34,16 +34,15 @@ import { getUpdatedModels, hasInvalidValues, } from './utils'; +import { useValidation } from '../../agg_utils'; -interface NumberListProps { +export interface NumberListProps { labelledbyId: string; numberArray: Array; range?: string; showValidation: boolean; unitName: string; validateAscendingOrder?: boolean; - onBlur?(): void; - onFocus?(): void; onChange(list: Array): void; setTouched(): void; setValidity(isValid: boolean): void; @@ -56,81 +55,84 @@ function NumberList({ showValidation, unitName, validateAscendingOrder = true, - onBlur, - onFocus, onChange, setTouched, setValidity, }: NumberListProps) { - const numberRange = getRange(range); + const numberRange = useMemo(() => getRange(range), [range]); const [models, setModels] = useState(getInitModelList(numberArray)); const [ascendingError, setAscendingError] = useState(EMPTY_STRING); - // responsible for discarding changes + // set up validity for each model useEffect(() => { - const updatedModels = getUpdatedModels(numberArray, models, numberRange); + let id: number | undefined; if (validateAscendingOrder) { - const isOrderValid = validateOrder(updatedModels); + const { isValidOrder, modelIndex } = validateOrder(numberArray); + id = isValidOrder ? undefined : modelIndex; setAscendingError( - isOrderValid - ? i18n.translate('common.ui.aggTypes.numberList.invalidAscOrderErrorMessage', { + isValidOrder + ? EMPTY_STRING + : i18n.translate('common.ui.aggTypes.numberList.invalidAscOrderErrorMessage', { defaultMessage: 'The values should be in ascending order.', }) - : EMPTY_STRING ); } - setModels(updatedModels); - }, [numberArray]); + setModels(state => getUpdatedModels(numberArray, state, numberRange, id)); + }, [numberArray, numberRange, validateAscendingOrder]); + // responsible for setting up an initial value ([0]) when there is no default value useEffect(() => { - setValidity(!hasInvalidValues(models)); - }, [models]); - - // resposible for setting up an initial value ([0]) when there is no default value - useEffect(() => { - onChange(models.map(({ value }) => (value === EMPTY_STRING ? undefined : value))); + if (!numberArray.length) { + onChange([models[0].value as number]); + } }, []); - const onChangeValue = ({ id, value }: { id: string; value: string }) => { - const parsedValue = parse(value); - const { isValid, errors } = validateValue(parsedValue, numberRange); - setValidity(isValid); + const isValid = !hasInvalidValues(models); + useValidation(setValidity, isValid); - const currentModel = models.find(model => model.id === id); - if (currentModel) { - currentModel.value = parsedValue; - currentModel.isInvalid = !isValid; - currentModel.errors = errors; - } + const onUpdate = useCallback( + (modelList: NumberRowModel[]) => { + setModels(modelList); + onChange(modelList.map(({ value }) => (value === EMPTY_STRING ? undefined : value))); + }, + [onChange] + ); - onUpdate(models); - }; + const onChangeValue = useCallback( + ({ id, value }: { id: string; value: string }) => { + const parsedValue = parse(value); + + onUpdate( + models.map(model => { + if (model.id === id) { + const { isInvalid, error } = validateValue(parsedValue, numberRange); + return { + id, + value: parsedValue, + isInvalid, + error, + }; + } + return model; + }) + ); + }, + [numberRange, models, onUpdate] + ); // Add an item to the end of the list - const onAdd = () => { + const onAdd = useCallback(() => { const newArray = [...models, getNextModel(models, numberRange)]; onUpdate(newArray); - }; - - const onDelete = (id: string) => { - const newArray = models.filter(model => model.id !== id); - onUpdate(newArray); - }; - - const onBlurFn = (model: NumberRowModel) => { - if (model.value === EMPTY_STRING) { - model.isInvalid = true; - } - setTouched(); - if (onBlur) { - onBlur(); - } - }; - - const onUpdate = (modelList: NumberRowModel[]) => { - setModels(modelList); - onChange(modelList.map(({ value }) => (value === EMPTY_STRING ? undefined : value))); - }; + }, [models, numberRange, onUpdate]); + + const onDelete = useCallback( + (id: string) => { + const newArray = models.filter(model => model.id !== id); + onUpdate(newArray); + }, + [models, onUpdate] + ); return ( <> @@ -143,13 +145,12 @@ function NumberList({ labelledbyId={labelledbyId} range={numberRange} onDelete={onDelete} - onFocus={onFocus} onChange={onChangeValue} - onBlur={() => onBlurFn(model)} + onBlur={setTouched} autoFocus={models.length !== 1 && arrayIndex === models.length - 1} /> - {showValidation && model.isInvalid && model.errors && model.errors.length > 0 && ( - {model.errors.join('\n')} + {showValidation && model.isInvalid && model.error && ( + {model.error} )} {models.length - 1 !== arrayIndex && } diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_row.test.tsx b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_row.test.tsx new file mode 100644 index 0000000000000..2173d92819e3d --- /dev/null +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_row.test.tsx @@ -0,0 +1,69 @@ +/* + * 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 React from 'react'; +import { shallow } from 'enzyme'; + +import { NumberRow, NumberRowProps } from './number_row'; + +describe('NumberRow', () => { + let defaultProps: NumberRowProps; + + beforeEach(() => { + defaultProps = { + autoFocus: false, + disableDelete: false, + isInvalid: false, + labelledbyId: 'numberList', + model: { value: 1, id: '1', isInvalid: false }, + range: { + min: 1, + max: 10, + minInclusive: true, + maxInclusive: true, + within: jest.fn(() => true), + }, + onChange: jest.fn(), + onBlur: jest.fn(), + onDelete: jest.fn(), + }; + }); + + test('should be rendered with default set of props', () => { + const comp = shallow(); + + expect(comp).toMatchSnapshot(); + }); + + test('should call onDelete', () => { + const comp = shallow(); + comp.find('EuiButtonIcon').simulate('click'); + + expect(defaultProps.onDelete).lastCalledWith(defaultProps.model.id); + }); + + test('should call onChange', () => { + const comp = shallow(); + comp.find('EuiFieldNumber').prop('onChange')!({ target: { value: '5' } } as React.ChangeEvent< + HTMLInputElement + >); + + expect(defaultProps.onChange).lastCalledWith({ id: defaultProps.model.id, value: '5' }); + }); +}); diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_row.tsx b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_row.tsx index cef574e806e01..23e671180e980 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_row.tsx +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/number_row.tsx @@ -17,13 +17,13 @@ * under the License. */ -import React from 'react'; +import React, { useCallback } from 'react'; import { EuiFieldNumber, EuiFlexGroup, EuiFlexItem, EuiButtonIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { Range } from '../../../../../../utils/range'; -interface NumberRowProps { +export interface NumberRowProps { autoFocus: boolean; disableDelete: boolean; isInvalid: boolean; @@ -31,7 +31,6 @@ interface NumberRowProps { model: NumberRowModel; range: Range; onBlur(): void; - onFocus?(): void; onChange({ id, value }: { id: string; value: string }): void; onDelete(index: string): void; } @@ -40,7 +39,7 @@ export interface NumberRowModel { id: string; isInvalid: boolean; value: number | ''; - errors?: string[]; + error?: string; } function NumberRow({ @@ -52,7 +51,6 @@ function NumberRow({ range, onBlur, onDelete, - onFocus, onChange, }: NumberRowProps) { const deleteBtnAriaLabel = i18n.translate( @@ -63,11 +61,16 @@ function NumberRow({ } ); - const onValueChanged = (event: React.ChangeEvent) => - onChange({ - value: event.target.value, - id: model.id, - }); + const onValueChanged = useCallback( + (event: React.ChangeEvent) => + onChange({ + value: event.target.value, + id: model.id, + }), + [onChange, model.id] + ); + + const onDeleteFn = useCallback(() => onDelete(model.id), [onDelete, model.id]); return ( @@ -81,7 +84,6 @@ function NumberRow({ defaultMessage: 'Enter a value', })} onChange={onValueChanged} - onFocus={onFocus} value={model.value} fullWidth={true} min={range.min} @@ -95,7 +97,7 @@ function NumberRow({ title={deleteBtnAriaLabel} color="danger" iconType="trash" - onClick={() => onDelete(model.id)} + onClick={onDeleteFn} disabled={disableDelete} /> diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts new file mode 100644 index 0000000000000..3928c0a62eeaa --- /dev/null +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts @@ -0,0 +1,218 @@ +/* + * 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 { + getInitModelList, + getUpdatedModels, + validateOrder, + hasInvalidValues, + parse, + validateValue, + getNextModel, + getRange, +} from './utils'; +import { Range } from '../../../../../../utils/range'; +import { NumberRowModel } from './number_row'; + +describe('NumberList utils', () => { + let modelList: NumberRowModel[]; + let range: Range; + + beforeEach(() => { + modelList = [{ value: 1, id: '1', isInvalid: false }, { value: 2, id: '2', isInvalid: false }]; + range = { + min: 1, + max: 10, + minInclusive: true, + maxInclusive: true, + within: jest.fn(() => true), + }; + }); + + describe('getInitModelList', () => { + test('should return list with default model when number list is empty', () => { + const models = getInitModelList([]); + + expect(models).toEqual([{ value: 0, id: expect.any(String), isInvalid: false }]); + }); + + test('should return model list', () => { + const models = getInitModelList([1, undefined]); + + expect(models).toEqual([ + { value: 1, id: expect.any(String), isInvalid: false }, + { value: '', id: expect.any(String), isInvalid: false }, + ]); + }); + }); + + describe('getUpdatedModels', () => { + test('should return model list when number list is empty', () => { + const updatedModelList = getUpdatedModels([], modelList, range); + + expect(updatedModelList).toEqual([{ value: 0, id: expect.any(String), isInvalid: false }]); + }); + + test('should not update model list when number list is the same', () => { + const updatedModelList = getUpdatedModels([1, 2], modelList, range); + + expect(updatedModelList).toEqual(modelList); + }); + + test('should update model list when number list was changed', () => { + const updatedModelList = getUpdatedModels([1, 3], modelList, range); + modelList[1].value = 3; + expect(updatedModelList).toEqual(modelList); + }); + + test('should update model list when number list increased', () => { + const updatedModelList = getUpdatedModels([1, 2, 3], modelList, range); + expect(updatedModelList).toEqual([ + ...modelList, + { value: 3, id: expect.any(String), isInvalid: false }, + ]); + }); + + test('should update model list when number list decreased', () => { + const updatedModelList = getUpdatedModels([2], modelList, range); + expect(updatedModelList).toEqual([{ value: 2, id: '1', isInvalid: false }]); + }); + + test('should update model list when number list has undefined value', () => { + const updatedModelList = getUpdatedModels([1, undefined], modelList, range); + modelList[1].value = ''; + modelList[1].isInvalid = true; + expect(updatedModelList).toEqual(modelList); + }); + + test('should update model list when number order is invalid', () => { + const updatedModelList = getUpdatedModels([1, 3, 2], modelList, range, 2); + expect(updatedModelList).toEqual([ + modelList[0], + { ...modelList[1], value: 3 }, + { value: 2, id: expect.any(String), isInvalid: true }, + ]); + }); + }); + + describe('validateOrder', () => { + test('should return true when order is valid', () => { + expect(validateOrder([1, 2])).toEqual({ + isValidOrder: true, + }); + }); + + test('should return true when a number is undefined', () => { + expect(validateOrder([1, undefined])).toEqual({ + isValidOrder: true, + }); + }); + + test('should return false when order is invalid', () => { + expect(validateOrder([2, 1])).toEqual({ + isValidOrder: false, + modelIndex: 1, + }); + }); + }); + + describe('hasInvalidValues', () => { + test('should return false when there are no invalid models', () => { + expect(hasInvalidValues(modelList)).toBeFalsy(); + }); + + test('should return true when there is an invalid model', () => { + modelList[1].isInvalid = true; + expect(hasInvalidValues(modelList)).toBeTruthy(); + }); + }); + + describe('parse', () => { + test('should return a number', () => { + expect(parse('3')).toBe(3); + }); + + test('should return an empty string when value is invalid', () => { + expect(parse('')).toBe(''); + expect(parse('test')).toBe(''); + expect(parse('NaN')).toBe(''); + }); + }); + + describe('validateValue', () => { + test('should return valid', () => { + expect(validateValue(3, range)).toEqual({ isInvalid: false }); + }); + + test('should return invalid', () => { + range.within = jest.fn(() => false); + expect(validateValue(11, range)).toEqual({ isInvalid: true, error: expect.any(String) }); + }); + }); + + describe('getNextModel', () => { + test('should return 3 as next value', () => { + expect(getNextModel(modelList, range)).toEqual({ + value: 3, + id: expect.any(String), + isInvalid: false, + }); + }); + + test('should return 1 as next value', () => { + expect(getNextModel([{ value: '', id: '2', isInvalid: false }], range)).toEqual({ + value: 1, + id: expect.any(String), + isInvalid: false, + }); + }); + + test('should return 9 as next value', () => { + expect(getNextModel([{ value: 11, id: '2', isInvalid: false }], range)).toEqual({ + value: 9, + id: expect.any(String), + isInvalid: false, + }); + }); + }); + + describe('getRange', () => { + test('should return default range', () => { + expect(getRange()).toEqual({ + min: 0, + max: Infinity, + maxInclusive: false, + minInclusive: true, + }); + }); + + test('should return parsed range', () => { + expect(getRange('(-Infinity, 100]')).toEqual({ + min: -Infinity, + max: 100, + maxInclusive: true, + minInclusive: false, + }); + }); + + test('should throw an error', () => { + expect(() => getRange('test')).toThrowError(); + }); + }); +}); diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.ts b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.ts index f90f545aeffba..563e8f0a6a9b7 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.ts +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.ts @@ -27,6 +27,7 @@ import { NumberRowModel } from './number_row'; const EMPTY_STRING = ''; const defaultRange = parseRange('[0,Infinity)'); const generateId = htmlIdGenerator(); +const defaultModel = { value: 0, id: generateId(), isInvalid: false }; function parse(value: string) { const parsedValue = parseFloat(value); @@ -42,44 +43,37 @@ function getRange(range?: string): Range { } function validateValue(value: number | '', numberRange: Range) { - const result = { - isValid: true, - errors: [] as string[], + const result: { isInvalid: boolean; error?: string } = { + isInvalid: false, }; if (value === EMPTY_STRING) { - result.isValid = false; + result.isInvalid = true; } else if (!numberRange.within(value)) { - result.isValid = false; - result.errors.push( - i18n.translate('common.ui.aggTypes.numberList.invalidRangeErrorMessage', { - defaultMessage: 'The value should be in the range of {min} to {max}.', - values: { min: numberRange.min, max: numberRange.max }, - }) - ); + result.isInvalid = true; + result.error = i18n.translate('common.ui.aggTypes.numberList.invalidRangeErrorMessage', { + defaultMessage: 'The value should be in the range of {min} to {max}.', + values: { min: numberRange.min, max: numberRange.max }, + }); } return result; } -function validateOrder(list: NumberRowModel[]) { - let isInvalidOrder = false; - list.forEach((model, index, array) => { - const previousModel = array[index - 1]; - if (previousModel && model.value !== EMPTY_STRING) { - const isInvalidOrderOfItem = model.value <= previousModel.value; - - if (!model.isInvalid && isInvalidOrderOfItem) { - model.isInvalid = true; - } +function validateOrder(list: Array) { + const result: { isValidOrder: boolean; modelIndex?: number } = { + isValidOrder: true, + }; - if (isInvalidOrderOfItem) { - isInvalidOrder = true; - } + list.forEach((inputValue, index, array) => { + const previousModel = array[index - 1]; + if (previousModel !== undefined && inputValue !== undefined && inputValue <= previousModel) { + result.isValidOrder = false; + result.modelIndex = index; } }); - return isInvalidOrder; + return result; } function getNextModel(list: NumberRowModel[], range: Range): NumberRowModel { @@ -104,26 +98,27 @@ function getInitModelList(list: Array): NumberRowModel[] { id: generateId(), isInvalid: false, })) - : [{ value: 0, id: generateId(), isInvalid: false }]; + : [defaultModel]; } function getUpdatedModels( numberList: Array, modelList: NumberRowModel[], - numberRange: Range + numberRange: Range, + invalidOrderModelIndex?: number ): NumberRowModel[] { if (!numberList.length) { - return modelList; + return [defaultModel]; } return numberList.map((number, index) => { const model = modelList[index] || { id: generateId() }; const newValue: NumberRowModel['value'] = number === undefined ? EMPTY_STRING : number; - const { isValid, errors } = validateValue(newValue, numberRange); + const { isInvalid, error } = validateValue(newValue, numberRange); return { ...model, value: newValue, - isInvalid: !isValid, - errors, + isInvalid: invalidOrderModelIndex === index ? true : isInvalid, + error, }; }); } diff --git a/src/legacy/ui/public/vis/editors/default/controls/percentile_ranks.tsx b/src/legacy/ui/public/vis/editors/default/controls/percentile_ranks.tsx index 8b63bb23475b2..420bf8a87c3d5 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/percentile_ranks.tsx +++ b/src/legacy/ui/public/vis/editors/default/controls/percentile_ranks.tsx @@ -37,7 +37,7 @@ function PercentileRanksEditor({ }); const [isValid, setIsValid] = useState(true); - const setModelValidy = (isListValid: boolean) => { + const setModelValidity = (isListValid: boolean) => { setIsValid(isListValid); setValidity(isListValid); }; @@ -62,7 +62,7 @@ function PercentileRanksEditor({ showValidation={showValidation} onChange={setValue} setTouched={setTouched} - setValidity={setModelValidy} + setValidity={setModelValidity} /> ); diff --git a/src/legacy/ui/public/vis/editors/default/controls/percentiles.tsx b/src/legacy/ui/public/vis/editors/default/controls/percentiles.tsx index 158ae3442ff0c..b8ad212edead9 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/percentiles.tsx +++ b/src/legacy/ui/public/vis/editors/default/controls/percentiles.tsx @@ -37,7 +37,7 @@ function PercentilesEditor({ }); const [isValid, setIsValid] = useState(true); - const setModelValidy = (isListValid: boolean) => { + const setModelValidity = (isListValid: boolean) => { setIsValid(isListValid); setValidity(isListValid); }; @@ -62,7 +62,7 @@ function PercentilesEditor({ showValidation={showValidation} onChange={setValue} setTouched={setTouched} - setValidity={setModelValidy} + setValidity={setModelValidity} /> ); From 49804a264579f3034510661f2200f30e3a14ca31 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 28 Oct 2019 13:54:47 +0100 Subject: [PATCH 59/61] [Console] Restore completer behaviour (#49422) * Restore completer behaviour * Move ace logic into shim and update getCursor -> getCursorPosition --- .../public/quarantined/src/autocomplete.ts | 15 +++++++-------- .../console/public/quarantined/src/input.ts | 15 +++++++++++++-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/legacy/core_plugins/console/public/quarantined/src/autocomplete.ts b/src/legacy/core_plugins/console/public/quarantined/src/autocomplete.ts index 41869f41c222f..47edf42f0eec5 100644 --- a/src/legacy/core_plugins/console/public/quarantined/src/autocomplete.ts +++ b/src/legacy/core_plugins/console/public/quarantined/src/autocomplete.ts @@ -317,16 +317,16 @@ export default function({ coreEditor: editor, parser, execCommand, - getCursor, - isCompleteActive, + getCursorPosition, + isCompleterActive, addChangeListener, removeChangeListener, }: { coreEditor: LegacyEditor; parser: any; execCommand: (cmd: string) => void; - getCursor: () => any; - isCompleteActive: () => boolean; + getCursorPosition: () => Position | null; + isCompleterActive: () => boolean; addChangeListener: (fn: any) => void; removeChangeListener: (fn: any) => void; }) { @@ -969,11 +969,10 @@ export default function({ 100); function editorChangeListener() { - const cursor = getCursor(); - if (isCompleteActive()) { - return; + const position = getCursorPosition(); + if (position && !isCompleterActive()) { + evaluateCurrentTokenAfterAChange(position); } - evaluateCurrentTokenAfterAChange(cursor); } function getCompletions( diff --git a/src/legacy/core_plugins/console/public/quarantined/src/input.ts b/src/legacy/core_plugins/console/public/quarantined/src/input.ts index a5e38e7a06e0e..eb93f8e165cb5 100644 --- a/src/legacy/core_plugins/console/public/quarantined/src/input.ts +++ b/src/legacy/core_plugins/console/public/quarantined/src/input.ts @@ -24,6 +24,7 @@ import { LegacyEditor } from '../../../np_ready/public/application/models'; // @ts-ignore import SenseEditor from './sense_editor/editor'; +import { Position } from '../../../np_ready/public/types'; let input: any; export function initializeEditor($el: JQuery, $actionsEl: JQuery) { @@ -35,8 +36,18 @@ export function initializeEditor($el: JQuery, $actionsEl: JQuery input.execCommand(cmd), - getCursor: () => input.selection.lead, - isCompleteActive: () => input.__ace.completer && input.__ace.completer.activated, + getCursorPosition: (): Position | null => { + if (input.selection && input.selection.lead) { + return { + lineNumber: input.selection.lead.row + 1, + column: input.selection.lead.column + 1, + }; + } + return null; + }, + isCompleterActive: () => { + return Boolean(input.__ace.completer && input.__ace.completer.activated); + }, addChangeListener: (fn: any) => input.on('changeSelection', fn), removeChangeListener: (fn: any) => input.off('changeSelection', fn), }; From d01099778bc454e9d6a6b6c2b010bee9715406a7 Mon Sep 17 00:00:00 2001 From: patrykkopycinski Date: Mon, 28 Oct 2019 14:16:49 +0100 Subject: [PATCH 60/61] [SIEM] Refactor hosts routing (#47459) --- .../details/__snapshots__/body.test.tsx.snap | 15 -- .../public/pages/hosts/details/body.test.tsx | 99 -------- .../siem/public/pages/hosts/details/body.tsx | 106 --------- .../pages/hosts/details/details_tabs.test.tsx | 108 +++++++++ .../pages/hosts/details/details_tabs.tsx | 100 +++++++++ .../siem/public/pages/hosts/details/index.tsx | 204 +++++++++-------- .../siem/public/pages/hosts/details/types.ts | 33 ++- .../siem/public/pages/hosts/details/utils.ts | 11 +- .../siem/public/pages/hosts/hosts.test.tsx | 4 +- .../plugins/siem/public/pages/hosts/hosts.tsx | 143 ++++++------ .../siem/public/pages/hosts/hosts_body.tsx | 96 -------- .../siem/public/pages/hosts/hosts_tabs.tsx | 87 +++++++ .../plugins/siem/public/pages/hosts/index.tsx | 212 ++---------------- .../plugins/siem/public/pages/hosts/types.ts | 45 ++++ 14 files changed, 581 insertions(+), 682 deletions(-) delete mode 100644 x-pack/legacy/plugins/siem/public/pages/hosts/details/__snapshots__/body.test.tsx.snap delete mode 100644 x-pack/legacy/plugins/siem/public/pages/hosts/details/body.test.tsx delete mode 100644 x-pack/legacy/plugins/siem/public/pages/hosts/details/body.tsx create mode 100644 x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.tsx delete mode 100644 x-pack/legacy/plugins/siem/public/pages/hosts/hosts_body.tsx create mode 100644 x-pack/legacy/plugins/siem/public/pages/hosts/hosts_tabs.tsx create mode 100644 x-pack/legacy/plugins/siem/public/pages/hosts/types.ts diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/__snapshots__/body.test.tsx.snap b/x-pack/legacy/plugins/siem/public/pages/hosts/details/__snapshots__/body.test.tsx.snap deleted file mode 100644 index 3815b319820ef..0000000000000 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/__snapshots__/body.test.tsx.snap +++ /dev/null @@ -1,15 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`body render snapshot 1`] = ` - - - - - -`; diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/body.test.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/body.test.tsx deleted file mode 100644 index 83af0a616a660..0000000000000 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/body.test.tsx +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { shallow, mount } from 'enzyme'; -import toJson from 'enzyme-to-json'; -import React from 'react'; -import { StaticIndexPattern } from 'ui/index_patterns'; - -import { mockIndexPattern } from '../../../mock/index_pattern'; -import { TestProviders } from '../../../mock/test_providers'; -import { mockUiSettings } from '../../../mock/ui_settings'; -import { CommonChildren } from '../navigation/types'; -import { HostDetailsBody } from './body'; -import { useKibanaCore } from '../../../lib/compose/kibana_core'; - -const mockUseKibanaCore = useKibanaCore as jest.Mock; -jest.mock('../../../lib/compose/kibana_core'); -mockUseKibanaCore.mockImplementation(() => ({ - uiSettings: mockUiSettings, -})); - -jest.mock('../../../containers/source', () => ({ - indicesExistOrDataTemporarilyUnavailable: () => true, - WithSource: ({ - children, - }: { - children: (args: { - indicesExist: boolean; - indexPattern: StaticIndexPattern; - }) => React.ReactNode; - }) => children({ indicesExist: true, indexPattern: mockIndexPattern }), -})); - -describe('body', () => { - test('render snapshot', () => { - const child: CommonChildren = () => {'I am a child'}; - const wrapper = shallow( - - {}} - to={0} - /> - - ); - expect(toJson(wrapper)).toMatchSnapshot(); - }); - - test('it should pass expected object properties to children', () => { - const child = jest.fn(); - mount( - - {}} - to={0} - /> - - ); - // match against everything but the functions to ensure they are there as expected - expect(child.mock.calls[0][0]).toMatchObject({ - endDate: 0, - filterQuery: - '{"bool":{"must":[],"filter":[{"match_all":{}},{"match_phrase":{"host.name":{"query":"host-1"}}}],"should":[],"must_not":[]}}', - skip: false, - startDate: 0, - type: 'details', - indexPattern: { - fields: [ - { name: '@timestamp', searchable: true, type: 'date', aggregatable: true }, - { name: '@version', searchable: true, type: 'string', aggregatable: true }, - { name: 'agent.ephemeral_id', searchable: true, type: 'string', aggregatable: true }, - { name: 'agent.hostname', searchable: true, type: 'string', aggregatable: true }, - { name: 'agent.id', searchable: true, type: 'string', aggregatable: true }, - { name: 'agent.test1', searchable: true, type: 'string', aggregatable: true }, - { name: 'agent.test2', searchable: true, type: 'string', aggregatable: true }, - { name: 'agent.test3', searchable: true, type: 'string', aggregatable: true }, - { name: 'agent.test4', searchable: true, type: 'string', aggregatable: true }, - { name: 'agent.test5', searchable: true, type: 'string', aggregatable: true }, - { name: 'agent.test6', searchable: true, type: 'string', aggregatable: true }, - { name: 'agent.test7', searchable: true, type: 'string', aggregatable: true }, - { name: 'agent.test8', searchable: true, type: 'string', aggregatable: true }, - { name: 'host.name', searchable: true, type: 'string', aggregatable: true }, - ], - title: 'filebeat-*,auditbeat-*,packetbeat-*', - }, - hostName: 'host-1', - }); - }); -}); diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/body.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/body.tsx deleted file mode 100644 index ae8ebcf41cd56..0000000000000 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/body.tsx +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getEsQueryConfig } from '@kbn/es-query'; -import React from 'react'; -import { connect } from 'react-redux'; - -import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../../containers/source'; -import { setAbsoluteRangeDatePicker as dispatchAbsoluteRangeDatePicker } from '../../../store/inputs/actions'; -import { scoreIntervalToDateTime } from '../../../components/ml/score/score_interval_to_datetime'; -import { Anomaly } from '../../../components/ml/types'; -import { convertToBuildEsQuery } from '../../../lib/keury'; -import { useKibanaCore } from '../../../lib/compose/kibana_core'; - -import { HostDetailsBodyComponentProps } from './types'; -import { type, makeMapStateToProps } from './utils'; - -const HostDetailsBodyComponent = React.memo( - ({ - children, - deleteQuery, - detailName, - filters, - from, - isInitializing, - query, - setAbsoluteRangeDatePicker, - setQuery, - to, - }) => { - const core = useKibanaCore(); - return ( - - {({ indicesExist, indexPattern }) => { - const filterQuery = convertToBuildEsQuery({ - config: getEsQueryConfig(core.uiSettings), - indexPattern, - queries: [query], - filters: [ - { - meta: { - alias: null, - negate: false, - disabled: false, - type: 'phrase', - key: 'host.name', - value: detailName, - params: { - query: detailName, - }, - }, - query: { - match: { - 'host.name': { - query: detailName, - type: 'phrase', - }, - }, - }, - }, - ...filters, - ], - }); - return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( - <> - {children({ - deleteQuery, - endDate: to, - filterQuery, - skip: isInitializing, - setQuery, - startDate: from, - type, - indexPattern, - hostName: detailName, - narrowDateRange: (score: Anomaly, interval: string) => { - const fromTo = scoreIntervalToDateTime(score, interval); - setAbsoluteRangeDatePicker({ - id: 'global', - from: fromTo.from, - to: fromTo.to, - }); - }, - updateDateRange: (min: number, max: number) => { - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); - }, - })} - - ) : null; - }} - - ); - } -); - -HostDetailsBodyComponent.displayName = 'HostDetailsBodyComponent'; - -export const HostDetailsBody = connect( - makeMapStateToProps, - { - setAbsoluteRangeDatePicker: dispatchAbsoluteRangeDatePicker, - } -)(HostDetailsBodyComponent); diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.test.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.test.tsx new file mode 100644 index 0000000000000..6ceebc1708b18 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.test.tsx @@ -0,0 +1,108 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { mount } from 'enzyme'; +import React from 'react'; +import { StaticIndexPattern } from 'ui/index_patterns'; +import { MemoryRouter } from 'react-router-dom'; + +import { mockIndexPattern } from '../../../mock/index_pattern'; +import { TestProviders } from '../../../mock/test_providers'; +import { mockUiSettings } from '../../../mock/ui_settings'; +import { HostDetailsTabs } from './details_tabs'; +import { SetAbsoluteRangeDatePicker } from './types'; +import { hostDetailsPagePath } from '../types'; +import { type } from './utils'; +import { useKibanaCore } from '../../../lib/compose/kibana_core'; + +jest.mock('../../../lib/settings/use_kibana_ui_setting'); + +const mockUseKibanaCore = useKibanaCore as jest.Mock; +jest.mock('../../../lib/compose/kibana_core'); +mockUseKibanaCore.mockImplementation(() => ({ + uiSettings: mockUiSettings, +})); + +jest.mock('../../../containers/source', () => ({ + indicesExistOrDataTemporarilyUnavailable: () => true, + WithSource: ({ + children, + }: { + children: (args: { + indicesExist: boolean; + indexPattern: StaticIndexPattern; + }) => React.ReactNode; + }) => children({ indicesExist: true, indexPattern: mockIndexPattern }), +})); + +// Test will fail because we will to need to mock some core services to make the test work +// For now let's forget about SiemSearchBar +jest.mock('../../../components/search_bar', () => ({ + SiemSearchBar: () => null, +})); + +describe('body', () => { + const scenariosMap = { + authentications: 'AuthenticationsQueryTabBody', + allHosts: 'HostsQueryTabBody', + uncommonProcesses: 'UncommonProcessQueryTabBody', + anomalies: 'AnomaliesQueryTabBody', + events: 'EventsQueryTabBody', + }; + + Object.entries(scenariosMap).forEach(([path, componentName]) => + test(`it should pass expected object properties to ${componentName}`, () => { + const wrapper = mount( + + + {}} + to={0} + setAbsoluteRangeDatePicker={(jest.fn() as unknown) as SetAbsoluteRangeDatePicker} + hostDetailsPagePath={hostDetailsPagePath} + indexPattern={mockIndexPattern} + type={type} + filterQuery='{"bool":{"must":[],"filter":[{"match_all":{}},{"match_phrase":{"host.name":{"query":"host-1"}}}],"should":[],"must_not":[]}}' + /> + + + ); + + // match against everything but the functions to ensure they are there as expected + expect(wrapper.find(componentName).props()).toMatchObject({ + endDate: 0, + filterQuery: + '{"bool":{"must":[],"filter":[{"match_all":{}},{"match_phrase":{"host.name":{"query":"host-1"}}}],"should":[],"must_not":[]}}', + skip: false, + startDate: 0, + type: 'details', + indexPattern: { + fields: [ + { name: '@timestamp', searchable: true, type: 'date', aggregatable: true }, + { name: '@version', searchable: true, type: 'string', aggregatable: true }, + { name: 'agent.ephemeral_id', searchable: true, type: 'string', aggregatable: true }, + { name: 'agent.hostname', searchable: true, type: 'string', aggregatable: true }, + { name: 'agent.id', searchable: true, type: 'string', aggregatable: true }, + { name: 'agent.test1', searchable: true, type: 'string', aggregatable: true }, + { name: 'agent.test2', searchable: true, type: 'string', aggregatable: true }, + { name: 'agent.test3', searchable: true, type: 'string', aggregatable: true }, + { name: 'agent.test4', searchable: true, type: 'string', aggregatable: true }, + { name: 'agent.test5', searchable: true, type: 'string', aggregatable: true }, + { name: 'agent.test6', searchable: true, type: 'string', aggregatable: true }, + { name: 'agent.test7', searchable: true, type: 'string', aggregatable: true }, + { name: 'agent.test8', searchable: true, type: 'string', aggregatable: true }, + { name: 'host.name', searchable: true, type: 'string', aggregatable: true }, + ], + title: 'filebeat-*,auditbeat-*,packetbeat-*', + }, + hostName: 'host-1', + }); + }) + ); +}); diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.tsx new file mode 100644 index 0000000000000..48b6d34d0b28b --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.tsx @@ -0,0 +1,100 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback } from 'react'; +import { Route, Switch } from 'react-router-dom'; + +import { scoreIntervalToDateTime } from '../../../components/ml/score/score_interval_to_datetime'; +import { Anomaly } from '../../../components/ml/types'; +import { HostsTableType } from '../../../store/hosts/model'; + +import { HostDetailsTabsProps } from './types'; +import { type } from './utils'; + +import { + HostsQueryTabBody, + AuthenticationsQueryTabBody, + UncommonProcessQueryTabBody, + AnomaliesQueryTabBody, + EventsQueryTabBody, +} from '../navigation'; + +const HostDetailsTabs = React.memo( + ({ + deleteQuery, + filterQuery, + from, + isInitializing, + detailName, + setAbsoluteRangeDatePicker, + setQuery, + to, + indexPattern, + hostDetailsPagePath, + }) => { + const narrowDateRange = useCallback( + (score: Anomaly, interval: string) => { + const fromTo = scoreIntervalToDateTime(score, interval); + setAbsoluteRangeDatePicker({ + id: 'global', + from: fromTo.from, + to: fromTo.to, + }); + }, + [setAbsoluteRangeDatePicker, scoreIntervalToDateTime] + ); + + const updateDateRange = useCallback( + (min: number, max: number) => { + setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + }, + [setAbsoluteRangeDatePicker, scoreIntervalToDateTime] + ); + + const tabProps = { + deleteQuery, + endDate: to, + filterQuery, + skip: isInitializing, + setQuery, + startDate: from, + type, + indexPattern, + hostName: detailName, + narrowDateRange, + updateDateRange, + }; + + return ( + + } + /> + } + /> + } + /> + } + /> + } + /> + + ); + } +); + +HostDetailsTabs.displayName = 'HostDetailsTabs'; + +export { HostDetailsTabs }; diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx index d1d29c3d2ea82..aa81481bedbe7 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx @@ -11,6 +11,8 @@ import { compose } from 'redux'; import { connect } from 'react-redux'; import { StickyContainer } from 'react-sticky'; +import { inputsSelectors, State } from '../../../store'; + import { FiltersGlobal } from '../../../components/filters_global'; import { HeaderPage } from '../../../components/header_page'; import { KpiHostDetailsQuery } from '../../../containers/kpi_host_details'; @@ -32,22 +34,19 @@ import { LastEventIndexKey } from '../../../graphql/types'; import { convertToBuildEsQuery } from '../../../lib/keury'; import { setAbsoluteRangeDatePicker as dispatchAbsoluteRangeDatePicker } from '../../../store/inputs/actions'; import { SpyRoute } from '../../../utils/route/spy_routes'; +import { useKibanaCore } from '../../../lib/compose/kibana_core'; -import { HostsQueryProps } from '../hosts'; import { HostsEmptyPage } from '../hosts_empty_page'; - -export { HostDetailsBody } from './body'; import { navTabsHostDetails } from './nav_tabs'; -import { HostDetailsComponentProps } from './types'; -import { makeMapStateToProps } from './utils'; -import { useKibanaCore } from '../../../lib/compose/kibana_core'; +import { HostDetailsComponentProps, HostDetailsProps } from './types'; +import { HostDetailsTabs } from './details_tabs'; +import { type } from './utils'; const HostOverviewManage = manageQuery(HostOverview); const KpiHostDetailsManage = manageQuery(KpiHostsComponent); const HostDetailsComponent = React.memo( ({ - detailName, filters, from, isInitializing, @@ -56,6 +55,9 @@ const HostDetailsComponent = React.memo( setHostDetailsTablesActivePageToZero, setQuery, to, + detailName, + deleteQuery, + hostDetailsPagePath, }) => { useEffect(() => { setHostDetailsTablesActivePageToZero(null); @@ -96,94 +98,111 @@ const HostDetailsComponent = React.memo( ], }); return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( - - - - + <> + + + + - - } - title={detailName} - /> - - {({ hostOverview, loading, id, inspect, refetch }) => ( - - {({ isLoadingAnomaliesData, anomaliesData }) => ( - { - const fromTo = scoreIntervalToDateTime(score, interval); - setAbsoluteRangeDatePicker({ - id: 'global', - from: fromTo.from, - to: fromTo.to, - }); - }} - /> - )} - - )} - + + } + title={detailName} + /> + + {({ hostOverview, loading, id, inspect, refetch }) => ( + + {({ isLoadingAnomaliesData, anomaliesData }) => ( + { + const fromTo = scoreIntervalToDateTime(score, interval); + setAbsoluteRangeDatePicker({ + id: 'global', + from: fromTo.from, + to: fromTo.to, + }); + }} + /> + )} + + )} + - + - - {({ kpiHostDetails, id, inspect, loading, refetch }) => ( - { - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); - }} - /> - )} - + + {({ kpiHostDetails, id, inspect, loading, refetch }) => ( + { + setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + }} + /> + )} + - + + + - - + ) : ( <> - ); @@ -197,7 +216,16 @@ const HostDetailsComponent = React.memo( HostDetailsComponent.displayName = 'HostDetailsComponent'; -export const HostDetails = compose>( +export const makeMapStateToProps = () => { + const getGlobalQuerySelector = inputsSelectors.globalQuerySelector(); + const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector(); + return (state: State) => ({ + query: getGlobalQuerySelector(state), + filters: getGlobalFiltersQuerySelector(state), + }); +}; + +export const HostDetails = compose>( connect( makeMapStateToProps, { diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/types.ts b/x-pack/legacy/plugins/siem/public/pages/hosts/details/types.ts index b4dda2cee8760..9df57970176eb 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/types.ts +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/types.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { StaticIndexPattern } from 'ui/index_patterns'; import { Filter } from '@kbn/es-query'; import { ActionCreator } from 'typescript-fsa'; import { Query } from 'src/plugins/data/common'; @@ -11,13 +12,10 @@ import { Query } from 'src/plugins/data/common'; import { InputsModelId } from '../../../store/inputs/constants'; import { HostComponentProps } from '../../../components/link_to/redirect_to_hosts'; import { HostsTableType } from '../../../store/hosts/model'; -import { HostsQueryProps } from '../hosts'; +import { HostsQueryProps } from '../types'; import { NavTab } from '../../../components/navigation/types'; -import { - AnomaliesChildren, - CommonChildren, - KeyHostsNavTabWithoutMlPermission, -} from '../navigation/types'; +import { KeyHostsNavTabWithoutMlPermission } from '../navigation/types'; +import { hostsModel } from '../../../store'; interface HostDetailsComponentReduxProps { query: Query; @@ -31,14 +29,16 @@ interface HostBodyComponentDispatchProps { to: number; }>; detailName: string; + hostDetailsPagePath: string; } interface HostDetailsComponentDispatchProps extends HostBodyComponentDispatchProps { setHostDetailsTablesActivePageToZero: ActionCreator; } -export interface HostDetailsBodyProps extends HostsQueryProps { - children: CommonChildren | AnomaliesChildren; +export interface HostDetailsProps extends HostsQueryProps { + detailName: string; + hostDetailsPagePath: string; } export type HostDetailsComponentProps = HostDetailsComponentReduxProps & @@ -46,10 +46,6 @@ export type HostDetailsComponentProps = HostDetailsComponentReduxProps & HostComponentProps & HostsQueryProps; -export type HostDetailsBodyComponentProps = HostDetailsComponentReduxProps & - HostBodyComponentDispatchProps & - HostDetailsBodyProps; - type KeyHostDetailsNavTabWithoutMlPermission = HostsTableType.authentications & HostsTableType.uncommonProcesses & HostsTableType.events; @@ -62,3 +58,16 @@ type KeyHostDetailsNavTab = | KeyHostDetailsNavTabWithMlPermission; export type HostDetailsNavTab = Record; + +export type HostDetailsTabsProps = HostBodyComponentDispatchProps & + HostsQueryProps & { + indexPattern: StaticIndexPattern; + type: hostsModel.HostsType; + filterQuery: string; + }; + +export type SetAbsoluteRangeDatePicker = ActionCreator<{ + id: InputsModelId; + from: number; + to: number; +}>; diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/utils.ts b/x-pack/legacy/plugins/siem/public/pages/hosts/details/utils.ts index 52efe93c0c8dc..7483636cfe03d 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/utils.ts +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/utils.ts @@ -6,7 +6,7 @@ import { Breadcrumb } from 'ui/chrome'; -import { hostsModel, inputsSelectors, State } from '../../../store'; +import { hostsModel } from '../../../store'; import { HostsTableType } from '../../../store/hosts/model'; import { getHostsUrl, getHostDetailsUrl } from '../../../components/link_to/redirect_to_hosts'; @@ -15,15 +15,6 @@ import { RouteSpyState } from '../../../utils/route/types'; export const type = hostsModel.HostsType.details; -export const makeMapStateToProps = () => { - const getGlobalQuerySelector = inputsSelectors.globalQuerySelector(); - const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector(); - return (state: State) => ({ - query: getGlobalQuerySelector(state), - filters: getGlobalFiltersQuerySelector(state), - }); -}; - const TabNameMappedToI18nKey = { [HostsTableType.hosts]: i18n.NAVIGATION_ALL_HOSTS_TITLE, [HostsTableType.authentications]: i18n.NAVIGATION_AUTHENTICATIONS_TITLE, diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.test.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.test.tsx index 5b6444148045d..d2c9822889c26 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.test.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.test.tsx @@ -19,7 +19,8 @@ import { wait } from '../../lib/helpers'; import { TestProviders } from '../../mock'; import { mockUiSettings } from '../../mock/ui_settings'; import { InputsModelId } from '../../store/inputs/constants'; -import { Hosts, HostsComponentProps } from './hosts'; +import { HostsComponentProps } from './types'; +import { Hosts } from './hosts'; import { useKibanaCore } from '../../lib/compose/kibana_core'; jest.mock('../../lib/settings/use_kibana_ui_setting'); @@ -97,6 +98,7 @@ describe('Hosts - rendering', () => { }>, query: { query: '', language: 'kuery' }, filters: [], + hostsPagePath: '', }; beforeAll(() => { diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx index 7c54745f872a9..334d730378b23 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx @@ -5,13 +5,11 @@ */ import { EuiSpacer } from '@elastic/eui'; -import { Filter, getEsQueryConfig } from '@kbn/es-query'; +import { getEsQueryConfig } from '@kbn/es-query'; import * as React from 'react'; import { compose } from 'redux'; import { connect } from 'react-redux'; import { StickyContainer } from 'react-sticky'; -import { ActionCreator } from 'typescript-fsa'; -import { Query } from 'src/plugins/data/common'; import { FiltersGlobal } from '../../components/filters_global'; import { GlobalTimeArgs } from '../../containers/global_time'; @@ -27,41 +25,34 @@ import { SiemSearchBar } from '../../components/search_bar'; import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source'; import { LastEventIndexKey } from '../../graphql/types'; import { convertToBuildEsQuery } from '../../lib/keury'; -import { inputsSelectors, State } from '../../store'; +import { inputsSelectors, State, hostsModel } from '../../store'; import { setAbsoluteRangeDatePicker as dispatchSetAbsoluteRangeDatePicker } from '../../store/inputs/actions'; -import { InputsModelId } from '../../store/inputs/constants'; import { SpyRoute } from '../../utils/route/spy_routes'; +import { useKibanaCore } from '../../lib/compose/kibana_core'; import { HostsEmptyPage } from './hosts_empty_page'; import { navTabsHosts } from './nav_tabs'; import * as i18n from './translations'; -import { useKibanaCore } from '../../lib/compose/kibana_core'; +import { HostsComponentProps, HostsComponentReduxProps } from './types'; +import { HostsTabs } from './hosts_tabs'; const KpiHostsComponentManage = manageQuery(KpiHostsComponent); -interface HostsComponentReduxProps { - query: Query; - filters: Filter[]; -} - -interface HostsComponentDispatchProps { - setAbsoluteRangeDatePicker: ActionCreator<{ - id: InputsModelId; - from: number; - to: number; - }>; -} - -export type HostsQueryProps = GlobalTimeArgs; - -export type HostsComponentProps = HostsComponentReduxProps & - HostsComponentDispatchProps & - HostsQueryProps; - const HostsComponent = React.memo( - ({ isInitializing, filters, from, query, setAbsoluteRangeDatePicker, setQuery, to }) => { + ({ + deleteQuery, + isInitializing, + filters, + from, + query, + setAbsoluteRangeDatePicker, + setQuery, + to, + hostsPagePath, + }) => { const capabilities = React.useContext(MlCapabilitiesContext); const core = useKibanaCore(); + return ( <> @@ -73,48 +64,62 @@ const HostsComponent = React.memo( filters, }); return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( - - - - + <> + + + + - } - title={i18n.PAGE_TITLE} - /> - <> - - {({ kpiHosts, loading, id, inspect, refetch }) => ( - { - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); - }} - /> - )} - - - } + title={i18n.PAGE_TITLE} /> - - - + <> + + {({ kpiHosts, loading, id, inspect, refetch }) => ( + { + setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + }} + /> + )} + + + + + + + + ) : ( <> @@ -142,8 +147,12 @@ const makeMapStateToProps = () => { return mapStateToProps; }; +interface HostsProps extends GlobalTimeArgs { + hostsPagePath: string; +} + // eslint-disable-next-line @typescript-eslint/no-explicit-any -export const Hosts = compose>( +export const Hosts = compose>( connect( makeMapStateToProps, { diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_body.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_body.tsx deleted file mode 100644 index 3d7e54b4a19ac..0000000000000 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_body.tsx +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getEsQueryConfig } from '@kbn/es-query'; -import React, { memo } from 'react'; -import { connect } from 'react-redux'; - -import { scoreIntervalToDateTime } from '../../components/ml/score/score_interval_to_datetime'; -import { Anomaly } from '../../components/ml/types'; -import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source'; -import { convertToBuildEsQuery } from '../../lib/keury'; -import { useKibanaCore } from '../../lib/compose/kibana_core'; -import { hostsModel, inputsSelectors, State } from '../../store'; -import { setAbsoluteRangeDatePicker as dispatchSetAbsoluteRangeDatePicker } from '../../store/inputs/actions'; - -import { HostsComponentProps } from './hosts'; -import { CommonChildren, AnomaliesChildren } from './navigation/types'; - -interface HostsBodyComponentProps extends HostsComponentProps { - children: CommonChildren | AnomaliesChildren; -} - -const HostsBodyComponent = memo( - ({ - children, - deleteQuery, - filters, - from, - isInitializing, - query, - setAbsoluteRangeDatePicker, - setQuery, - to, - }) => { - const core = useKibanaCore(); - return ( - - {({ indicesExist, indexPattern }) => { - const filterQuery = convertToBuildEsQuery({ - config: getEsQueryConfig(core.uiSettings), - indexPattern, - queries: [query], - filters, - }); - return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( - <> - {children({ - deleteQuery, - endDate: to, - filterQuery, - skip: isInitializing, - setQuery, - startDate: from, - type: hostsModel.HostsType.page, - indexPattern, - narrowDateRange: (score: Anomaly, interval: string) => { - const fromTo = scoreIntervalToDateTime(score, interval); - setAbsoluteRangeDatePicker({ - id: 'global', - from: fromTo.from, - to: fromTo.to, - }); - }, - updateDateRange: (min: number, max: number) => { - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); - }, - })} - - ) : null; - }} - - ); - } -); - -HostsBodyComponent.displayName = 'HostsBodyComponent'; - -const makeMapStateToProps = () => { - const getGlobalQuerySelector = inputsSelectors.globalQuerySelector(); - const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector(); - const mapStateToProps = (state: State) => ({ - query: getGlobalQuerySelector(state), - filters: getGlobalFiltersQuerySelector(state), - }); - return mapStateToProps; -}; - -export const HostsBody = connect( - makeMapStateToProps, - { - setAbsoluteRangeDatePicker: dispatchSetAbsoluteRangeDatePicker, - } -)(HostsBodyComponent); diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_tabs.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_tabs.tsx new file mode 100644 index 0000000000000..6dbfb422ed7a6 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_tabs.tsx @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { memo } from 'react'; +import { Route, Switch } from 'react-router-dom'; + +import { HostsTabsProps } from './types'; +import { scoreIntervalToDateTime } from '../../components/ml/score/score_interval_to_datetime'; +import { Anomaly } from '../../components/ml/types'; +import { HostsTableType } from '../../store/hosts/model'; + +import { + HostsQueryTabBody, + AuthenticationsQueryTabBody, + UncommonProcessQueryTabBody, + AnomaliesQueryTabBody, + EventsQueryTabBody, +} from './navigation'; + +const HostsTabs = memo( + ({ + deleteQuery, + filterQuery, + setAbsoluteRangeDatePicker, + to, + from, + setQuery, + isInitializing, + type, + indexPattern, + hostsPagePath, + }) => { + const tabProps = { + deleteQuery, + endDate: to, + filterQuery, + skip: isInitializing, + setQuery, + startDate: from, + type, + indexPattern, + narrowDateRange: (score: Anomaly, interval: string) => { + const fromTo = scoreIntervalToDateTime(score, interval); + setAbsoluteRangeDatePicker({ + id: 'global', + from: fromTo.from, + to: fromTo.to, + }); + }, + updateDateRange: (min: number, max: number) => { + setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + }, + }; + + return ( + + } + /> + } + /> + } + /> + } + /> + } + /> + + ); + } +); + +HostsTabs.displayName = 'HostsTabs'; + +export { HostsTabs }; diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/index.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/index.tsx index 72b19dbbb13b2..c8d450a62cc57 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/index.tsx @@ -7,21 +7,13 @@ import React from 'react'; import { Redirect, Route, Switch, RouteComponentProps } from 'react-router-dom'; -import { HostDetailsBody, HostDetails } from './details'; -import { - HostsQueryTabBody, - AuthenticationsQueryTabBody, - UncommonProcessQueryTabBody, - AnomaliesQueryTabBody, - EventsQueryTabBody, -} from './navigation'; -import { HostsBody } from './hosts_body'; +import { HostDetails } from './details'; import { HostsTableType } from '../../store/hosts/model'; + import { GlobalTime } from '../../containers/global_time'; import { SiemPageName } from '../home/types'; import { Hosts } from './hosts'; - -const hostsPagePath = `/:pageName(${SiemPageName.hosts})`; +import { hostsPagePath, hostDetailsPagePath } from './types'; const getHostsTabPath = (pagePath: string) => `${pagePath}/:tabName(` + @@ -32,7 +24,7 @@ const getHostsTabPath = (pagePath: string) => `${HostsTableType.events})`; const getHostDetailsTabPath = (pagePath: string) => - `${pagePath}/:detailName/:tabName(` + + `${hostDetailsPagePath}/:tabName(` + `${HostsTableType.authentications}|` + `${HostsTableType.uncommonProcesses}|` + `${HostsTableType.anomalies}|` + @@ -44,191 +36,38 @@ export const HostsContainer = React.memo(({ url }) => ( {({ to, from, setQuery, deleteQuery, isInitializing }) => ( - ( - ( - <> - - - - )} - /> - )} - /> ( - <> - - ( - - )} - /> - ( - - )} - /> - ( - - )} - /> - ( - - )} - /> - ( - - )} - /> - + )} /> ( - <> - - ( - - )} - /> - ( - - )} - /> - ( - - )} - /> - ( - - )} - /> - ( - - )} - /> - + )} /> (({ url }) => ( }) => } /> ( - + )} /> diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/types.ts b/x-pack/legacy/plugins/siem/public/pages/hosts/types.ts new file mode 100644 index 0000000000000..980c5535129aa --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/types.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { StaticIndexPattern } from 'ui/index_patterns'; +import { ActionCreator } from 'typescript-fsa'; +import { Filter } from '@kbn/es-query'; +import { Query } from 'src/plugins/data/common'; + +import { SiemPageName } from '../home/types'; +import { hostsModel } from '../../store'; +import { InputsModelId } from '../../store/inputs/constants'; +import { GlobalTimeArgs } from '../../containers/global_time'; + +export const hostsPagePath = `/:pageName(${SiemPageName.hosts})`; +export const hostDetailsPagePath = `${hostsPagePath}/:detailName`; + +export interface HostsComponentReduxProps { + query: Query; + filters: Filter[]; +} + +export interface HostsComponentDispatchProps { + setAbsoluteRangeDatePicker: ActionCreator<{ + id: InputsModelId; + from: number; + to: number; + }>; + hostsPagePath: string; +} + +export type HostsTabsProps = HostsComponentDispatchProps & + HostsQueryProps & { + filterQuery: string; + type: hostsModel.HostsType; + indexPattern: StaticIndexPattern; + }; + +export type HostsQueryProps = GlobalTimeArgs; + +export type HostsComponentProps = HostsComponentReduxProps & + HostsComponentDispatchProps & + HostsQueryProps; From d9a5acf971bbf32516dd77870dbad82de017b415 Mon Sep 17 00:00:00 2001 From: Dmitry Lemeshko Date: Mon, 28 Oct 2019 09:37:34 -0400 Subject: [PATCH 61/61] FTR: clear browser storage between test suites (#48683) * clear browser storage on test suite completion * [logstash/pipeline_list] fix tests dependency * always load new index data --- test/functional/services/remote/remote.ts | 2 ++ .../functional/apps/logstash/pipeline_list.js | 16 ++++------------ .../anomaly_detection/multi_metric_job.ts | 2 +- .../anomaly_detection/population_job.ts | 2 +- .../anomaly_detection/saved_search_job.ts | 2 +- .../anomaly_detection/single_metric_job.ts | 2 +- 6 files changed, 10 insertions(+), 16 deletions(-) diff --git a/test/functional/services/remote/remote.ts b/test/functional/services/remote/remote.ts index 4dc608542c3c3..b30a0e50886d1 100644 --- a/test/functional/services/remote/remote.ts +++ b/test/functional/services/remote/remote.ts @@ -128,6 +128,8 @@ export async function RemoteProvider({ getService }: FtrProviderContext) { .manage() .window() .setRect({ width, height }); + await driver.executeScript('window.sessionStorage.clear();'); + await driver.executeScript('window.localStorage.clear();'); }); lifecycle.on('cleanup', async () => { diff --git a/x-pack/test/functional/apps/logstash/pipeline_list.js b/x-pack/test/functional/apps/logstash/pipeline_list.js index d04f50690368d..ce0c9d881f51b 100644 --- a/x-pack/test/functional/apps/logstash/pipeline_list.js +++ b/x-pack/test/functional/apps/logstash/pipeline_list.js @@ -22,6 +22,9 @@ export default function ({ getService, getPageObjects }) { originalWindowSize = await browser.getWindowSize(); await browser.setWindowSize(1600, 1000); await esArchiver.load('logstash/example_pipelines'); + }); + + beforeEach(async () => { await PageObjects.logstash.gotoPipelineList(); }); @@ -86,10 +89,6 @@ export default function ({ getService, getPageObjects }) { await pipelineEditor.assertExists(); await pipelineEditor.assertDefaultInputs(); }); - - after(async () => { - await PageObjects.logstash.gotoPipelineList(); - }); }); describe('delete button', () => { @@ -122,15 +121,12 @@ export default function ({ getService, getPageObjects }) { describe('row links', () => { it('opens the selected row in the editor', async () => { + await PageObjects.logstash.gotoPipelineList(); await pipelineList.setFilter('tweets_and_beats'); await pipelineList.clickFirstRowId(); await pipelineEditor.assertExists(); await pipelineEditor.assertEditorId('tweets_and_beats'); }); - - after(async () => { - await PageObjects.logstash.gotoPipelineList(); - }); }); describe('next page button', () => { @@ -225,10 +221,6 @@ export default function ({ getService, getPageObjects }) { queueCheckpointWrites, }); }); - - after(async () => { - await PageObjects.logstash.gotoPipelineList(); - }); }); }); } diff --git a/x-pack/test/functional/apps/machine_learning/anomaly_detection/multi_metric_job.ts b/x-pack/test/functional/apps/machine_learning/anomaly_detection/multi_metric_job.ts index 06dd0df9e470c..6163e99b5eaa4 100644 --- a/x-pack/test/functional/apps/machine_learning/anomaly_detection/multi_metric_job.ts +++ b/x-pack/test/functional/apps/machine_learning/anomaly_detection/multi_metric_job.ts @@ -74,7 +74,7 @@ export default function({ getService }: FtrProviderContext) { describe('multi metric', function() { this.tags(['smoke', 'mlqa']); before(async () => { - await esArchiver.loadIfNeeded('ml/farequote'); + await esArchiver.load('ml/farequote'); }); after(async () => { diff --git a/x-pack/test/functional/apps/machine_learning/anomaly_detection/population_job.ts b/x-pack/test/functional/apps/machine_learning/anomaly_detection/population_job.ts index cd88a9bba1769..7ccd9214591f2 100644 --- a/x-pack/test/functional/apps/machine_learning/anomaly_detection/population_job.ts +++ b/x-pack/test/functional/apps/machine_learning/anomaly_detection/population_job.ts @@ -88,7 +88,7 @@ export default function({ getService }: FtrProviderContext) { describe('population', function() { this.tags(['smoke', 'mlqa']); before(async () => { - await esArchiver.loadIfNeeded('ml/ecommerce'); + await esArchiver.load('ml/ecommerce'); }); after(async () => { diff --git a/x-pack/test/functional/apps/machine_learning/anomaly_detection/saved_search_job.ts b/x-pack/test/functional/apps/machine_learning/anomaly_detection/saved_search_job.ts index 2cca37a944563..5645bc7277d19 100644 --- a/x-pack/test/functional/apps/machine_learning/anomaly_detection/saved_search_job.ts +++ b/x-pack/test/functional/apps/machine_learning/anomaly_detection/saved_search_job.ts @@ -274,7 +274,7 @@ export default function({ getService }: FtrProviderContext) { describe('saved search', function() { this.tags(['smoke', 'mlqa']); before(async () => { - await esArchiver.loadIfNeeded('ml/farequote'); + await esArchiver.load('ml/farequote'); }); after(async () => { diff --git a/x-pack/test/functional/apps/machine_learning/anomaly_detection/single_metric_job.ts b/x-pack/test/functional/apps/machine_learning/anomaly_detection/single_metric_job.ts index 6e640f7d173d5..06ec840b36aae 100644 --- a/x-pack/test/functional/apps/machine_learning/anomaly_detection/single_metric_job.ts +++ b/x-pack/test/functional/apps/machine_learning/anomaly_detection/single_metric_job.ts @@ -73,7 +73,7 @@ export default function({ getService }: FtrProviderContext) { describe('single metric', function() { this.tags(['smoke', 'mlqa']); before(async () => { - await esArchiver.loadIfNeeded('ml/farequote'); + await esArchiver.load('ml/farequote'); }); after(async () => {