From 828108729a3879506055a6d70ad0dcd3006d53d5 Mon Sep 17 00:00:00 2001 From: Daniil Suleiman <31325372+sulemanof@users.noreply.github.com> Date: Mon, 18 May 2020 12:53:00 +0300 Subject: [PATCH 001/129] Prevent further failures if timezone was not set (#66529) Co-authored-by: Elastic Machine --- .../apps/visualize/_point_series_options.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/functional/apps/visualize/_point_series_options.js b/test/functional/apps/visualize/_point_series_options.js index 17e0d1ca87fdd..cc25d10cf3257 100644 --- a/test/functional/apps/visualize/_point_series_options.js +++ b/test/functional/apps/visualize/_point_series_options.js @@ -341,6 +341,17 @@ export default function({ getService, getPageObjects }) { log.debug('close inspector'); await inspector.close(); }); + + after(async () => { + const timezone = await kibanaServer.uiSettings.get('dateFormat:tz'); + + // make sure the timezone was set to default correctly to avoid further failures + // for details see https://github.com/elastic/kibana/issues/63037 + if (timezone !== 'UTC') { + log.debug("set 'dateFormat:tz': 'UTC'"); + await kibanaServer.uiSettings.replace({ 'dateFormat:tz': 'UTC' }); + } + }); }); }); } From 404743a9ae723d42228ddbf2c5d1e576038d20fb Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Mon, 18 May 2020 13:29:26 +0200 Subject: [PATCH 002/129] stabilize listing page object (#66564) --- .../apps/dashboard/dashboard_clone.js | 19 ++------- .../apps/dashboard/dashboard_listing.js | 42 +++++-------------- .../apps/dashboard/dashboard_save.js | 20 ++------- .../apps/visualize/_visualize_listing.js | 29 ++++--------- test/functional/services/listing_table.ts | 29 ++++++++----- 5 files changed, 44 insertions(+), 95 deletions(-) diff --git a/test/functional/apps/dashboard/dashboard_clone.js b/test/functional/apps/dashboard/dashboard_clone.js index 8b7f6ba6a34dd..5d49e0cb97088 100644 --- a/test/functional/apps/dashboard/dashboard_clone.js +++ b/test/functional/apps/dashboard/dashboard_clone.js @@ -42,12 +42,7 @@ export default function({ getService, getPageObjects }) { await PageObjects.dashboard.clickClone(); await PageObjects.dashboard.confirmClone(); await PageObjects.dashboard.gotoDashboardLandingPage(); - const countOfDashboards = await listingTable.searchAndGetItemsCount( - 'dashboard', - clonedDashboardName - ); - - expect(countOfDashboards).to.equal(1); + await listingTable.searchAndExpectItemsCount('dashboard', clonedDashboardName, 1); }); it('the copy should have all the same visualizations', async function() { @@ -75,11 +70,7 @@ export default function({ getService, getPageObjects }) { await PageObjects.dashboard.cancelClone(); await PageObjects.dashboard.gotoDashboardLandingPage(); - const countOfDashboards = await listingTable.searchAndGetItemsCount( - 'dashboard', - dashboardName - ); - expect(countOfDashboards).to.equal(1); + await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 1); }); it('Clones on confirm duplicate title warning', async function() { @@ -92,11 +83,7 @@ export default function({ getService, getPageObjects }) { await PageObjects.dashboard.waitForRenderComplete(); await PageObjects.dashboard.gotoDashboardLandingPage(); - const countOfDashboards = await listingTable.searchAndGetItemsCount( - 'dashboard', - dashboardName + ' Copy' - ); - expect(countOfDashboards).to.equal(2); + await listingTable.searchAndExpectItemsCount('dashboard', dashboardName + ' Copy', 2); }); }); } diff --git a/test/functional/apps/dashboard/dashboard_listing.js b/test/functional/apps/dashboard/dashboard_listing.js index e3e835109da2c..2ab2e107dae2d 100644 --- a/test/functional/apps/dashboard/dashboard_listing.js +++ b/test/functional/apps/dashboard/dashboard_listing.js @@ -42,11 +42,7 @@ export default function({ getService, getPageObjects }) { await PageObjects.dashboard.saveDashboard(dashboardName); await PageObjects.dashboard.gotoDashboardLandingPage(); - const countOfDashboards = await listingTable.searchAndGetItemsCount( - 'dashboard', - dashboardName - ); - expect(countOfDashboards).to.equal(1); + await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 1); }); it('is not shown when there is a dashboard', async function() { @@ -55,11 +51,7 @@ export default function({ getService, getPageObjects }) { }); it('is not shown when there are no dashboards shown during a search', async function() { - const countOfDashboards = await listingTable.searchAndGetItemsCount( - 'dashboard', - 'gobeldeguck' - ); - expect(countOfDashboards).to.equal(0); + await listingTable.searchAndExpectItemsCount('dashboard', 'gobeldeguck', 0); const promptExists = await PageObjects.dashboard.getCreateDashboardPromptExists(); expect(promptExists).to.be(false); @@ -78,11 +70,7 @@ export default function({ getService, getPageObjects }) { await PageObjects.common.expectConfirmModalOpenState(false); - const countOfDashboards = await listingTable.searchAndGetItemsCount( - 'dashboard', - dashboardName - ); - expect(countOfDashboards).to.equal(1); + await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 1); }); it('succeeds on confirmation press', async function() { @@ -91,11 +79,7 @@ export default function({ getService, getPageObjects }) { await PageObjects.common.clickConfirmOnModal(); - const countOfDashboards = await listingTable.searchAndGetItemsCount( - 'dashboard', - dashboardName - ); - expect(countOfDashboards).to.equal(0); + await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 0); }); }); @@ -109,38 +93,32 @@ export default function({ getService, getPageObjects }) { it('matches on the first word', async function() { await listingTable.searchForItemWithName('Two'); - const countOfDashboards = await listingTable.getItemsCount('dashboard'); - expect(countOfDashboards).to.equal(1); + await listingTable.expectItemsCount('dashboard', 1); }); it('matches the second word', async function() { await listingTable.searchForItemWithName('Words'); - const countOfDashboards = await listingTable.getItemsCount('dashboard'); - expect(countOfDashboards).to.equal(1); + await listingTable.expectItemsCount('dashboard', 1); }); it('matches the second word prefix', async function() { await listingTable.searchForItemWithName('Wor'); - const countOfDashboards = await listingTable.getItemsCount('dashboard'); - expect(countOfDashboards).to.equal(1); + await listingTable.expectItemsCount('dashboard', 1); }); it('does not match mid word', async function() { await listingTable.searchForItemWithName('ords'); - const countOfDashboards = await listingTable.getItemsCount('dashboard'); - expect(countOfDashboards).to.equal(0); + await listingTable.expectItemsCount('dashboard', 0); }); it('is case insensitive', async function() { await listingTable.searchForItemWithName('two words'); - const countOfDashboards = await listingTable.getItemsCount('dashboard'); - expect(countOfDashboards).to.equal(1); + await listingTable.expectItemsCount('dashboard', 1); }); it('is using AND operator', async function() { await listingTable.searchForItemWithName('three words'); - const countOfDashboards = await listingTable.getItemsCount('dashboard'); - expect(countOfDashboards).to.equal(0); + await listingTable.expectItemsCount('dashboard', 0); }); }); diff --git a/test/functional/apps/dashboard/dashboard_save.js b/test/functional/apps/dashboard/dashboard_save.js index 7ffe951faa398..d0da033788689 100644 --- a/test/functional/apps/dashboard/dashboard_save.js +++ b/test/functional/apps/dashboard/dashboard_save.js @@ -17,8 +17,6 @@ * under the License. */ -import expect from '@kbn/expect'; - export default function({ getPageObjects, getService }) { const PageObjects = getPageObjects(['dashboard', 'header']); const listingTable = getService('listingTable'); @@ -50,11 +48,7 @@ export default function({ getPageObjects, getService }) { await PageObjects.dashboard.cancelSave(); await PageObjects.dashboard.gotoDashboardLandingPage(); - const countOfDashboards = await listingTable.searchAndGetItemsCount( - 'dashboard', - dashboardName - ); - expect(countOfDashboards).to.equal(1); + await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 1); }); it('Saves on confirm duplicate title warning', async function() { @@ -73,11 +67,7 @@ export default function({ getPageObjects, getService }) { await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.dashboard.gotoDashboardLandingPage(); - const countOfDashboards = await listingTable.searchAndGetItemsCount( - 'dashboard', - dashboardName - ); - expect(countOfDashboards).to.equal(2); + await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 2); }); it('Does not warn when you save an existing dashboard with the title it already has, and that title is a duplicate', async function() { @@ -128,11 +118,7 @@ export default function({ getPageObjects, getService }) { await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.dashboard.gotoDashboardLandingPage(); - const countOfDashboards = await listingTable.searchAndGetItemsCount( - 'dashboard', - dashboardNameEnterKey - ); - expect(countOfDashboards).to.equal(1); + await listingTable.searchAndExpectItemsCount('dashboard', dashboardNameEnterKey, 1); }); }); } diff --git a/test/functional/apps/visualize/_visualize_listing.js b/test/functional/apps/visualize/_visualize_listing.js index e277c3c7d104d..dc07301a8ad50 100644 --- a/test/functional/apps/visualize/_visualize_listing.js +++ b/test/functional/apps/visualize/_visualize_listing.js @@ -17,8 +17,6 @@ * under the License. */ -import expect from '@kbn/expect'; - export default function({ getService, getPageObjects }) { const PageObjects = getPageObjects(['visualize', 'visEditor']); const listingTable = getService('listingTable'); @@ -37,8 +35,7 @@ export default function({ getService, getPageObjects }) { // type markdown is used for simplicity await PageObjects.visualize.createSimpleMarkdownViz(vizName); await PageObjects.visualize.gotoVisualizationLandingPage(); - const visCount = await listingTable.getItemsCount('visualize'); - expect(visCount).to.equal(1); + await listingTable.expectItemsCount('visualize', 1); }); it('delete all viz', async function() { @@ -46,12 +43,10 @@ export default function({ getService, getPageObjects }) { await PageObjects.visualize.createSimpleMarkdownViz(vizName + '2'); await PageObjects.visualize.gotoVisualizationLandingPage(); - let visCount = await listingTable.getItemsCount('visualize'); - expect(visCount).to.equal(3); + await listingTable.expectItemsCount('visualize', 3); await PageObjects.visualize.deleteAllVisualizations(); - visCount = await listingTable.getItemsCount('visualize'); - expect(visCount).to.equal(0); + await listingTable.expectItemsCount('visualize', 0); }); }); @@ -69,38 +64,32 @@ export default function({ getService, getPageObjects }) { it('matches on the first word', async function() { await listingTable.searchForItemWithName('Hello'); - const itemCount = await listingTable.getItemsCount('visualize'); - expect(itemCount).to.equal(1); + await listingTable.expectItemsCount('visualize', 1); }); it('matches the second word', async function() { await listingTable.searchForItemWithName('World'); - const itemCount = await listingTable.getItemsCount('visualize'); - expect(itemCount).to.equal(1); + await listingTable.expectItemsCount('visualize', 1); }); it('matches the second word prefix', async function() { await listingTable.searchForItemWithName('Wor'); - const itemCount = await listingTable.getItemsCount('visualize'); - expect(itemCount).to.equal(1); + await listingTable.expectItemsCount('visualize', 1); }); it('does not match mid word', async function() { await listingTable.searchForItemWithName('orld'); - const itemCount = await listingTable.getItemsCount('visualize'); - expect(itemCount).to.equal(0); + await listingTable.expectItemsCount('visualize', 0); }); it('is case insensitive', async function() { await listingTable.searchForItemWithName('hello world'); - const itemCount = await listingTable.getItemsCount('visualize'); - expect(itemCount).to.equal(1); + await listingTable.expectItemsCount('visualize', 1); }); it('is using AND operator', async function() { await listingTable.searchForItemWithName('hello banana'); - const itemCount = await listingTable.getItemsCount('visualize'); - expect(itemCount).to.equal(0); + await listingTable.expectItemsCount('visualize', 0); }); }); }); diff --git a/test/functional/services/listing_table.ts b/test/functional/services/listing_table.ts index c7667ae7b4049..9a117458c7f76 100644 --- a/test/functional/services/listing_table.ts +++ b/test/functional/services/listing_table.ts @@ -17,6 +17,7 @@ * under the License. */ +import expect from '@kbn/expect'; import { FtrProviderContext } from '../ftr_provider_context'; export function ListingTableProvider({ getService, getPageObjects }: FtrProviderContext) { @@ -85,11 +86,13 @@ export function ListingTableProvider({ getService, getPageObjects }: FtrProvider * Returns items count on landing page * @param appName 'visualize' | 'dashboard' */ - public async getItemsCount(appName: 'visualize' | 'dashboard'): Promise { - const elements = await find.allByCssSelector( - `[data-test-subj^="${prefixMap[appName]}ListingTitleLink"]` - ); - return elements.length; + public async expectItemsCount(appName: 'visualize' | 'dashboard', count: number) { + await retry.try(async () => { + const elements = await find.allByCssSelector( + `[data-test-subj^="${prefixMap[appName]}ListingTitleLink"]` + ); + expect(elements.length).to.equal(count); + }); } /** @@ -116,12 +119,18 @@ export function ListingTableProvider({ getService, getPageObjects }: FtrProvider * @param appName 'visualize' | 'dashboard' * @param name item name */ - public async searchAndGetItemsCount(appName: 'visualize' | 'dashboard', name: string) { + public async searchAndExpectItemsCount( + appName: 'visualize' | 'dashboard', + name: string, + count: number + ) { await this.searchForItemWithName(name); - const links = await testSubjects.findAll( - `${prefixMap[appName]}ListingTitleLink-${name.replace(/ /g, '-')}` - ); - return links.length; + await retry.try(async () => { + const links = await testSubjects.findAll( + `${prefixMap[appName]}ListingTitleLink-${name.replace(/ /g, '-')}` + ); + expect(links.length).to.equal(count); + }); } public async clickDeleteSelected() { From 1c7227933d010a6267130ef6b23ad2f9489410af Mon Sep 17 00:00:00 2001 From: Shahzad Date: Mon, 18 May 2020 16:23:17 +0200 Subject: [PATCH 003/129] [Uptime] Remove error while index pattern is loading (#66729) --- .../uptime/public/components/overview/kuery_bar/kuery_bar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx b/x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx index 1ff823750a346..bd6fb4cf54b2b 100644 --- a/x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx +++ b/x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx @@ -134,7 +134,7 @@ export function KueryBarComponent({ queryExample="" /> - {indexPatternMissing && ( + {indexPatternMissing && !loading && ( Date: Mon, 18 May 2020 17:29:24 +0200 Subject: [PATCH 004/129] [ML] Functional tests - stablize AD job creation checks (#66733) With this PR, anomaly detection jobs are checked to have a processed_record_count > 0 before waiting for a stopped datafeed. --- .../apis/ml/modules/setup_module.ts | 3 ++ .../services/machine_learning/api.ts | 42 ++++++++++++++++--- .../machine_learning/job_management.ts | 1 + 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/x-pack/test/api_integration/apis/ml/modules/setup_module.ts b/x-pack/test/api_integration/apis/ml/modules/setup_module.ts index 39c87a91f0ccf..54ccbb5e0cbbd 100644 --- a/x-pack/test/api_integration/apis/ml/modules/setup_module.ts +++ b/x-pack/test/api_integration/apis/ml/modules/setup_module.ts @@ -236,6 +236,9 @@ export default ({ getService }: FtrProviderContext) => { const datafeedId = `datafeed-${job.jobId}`; await ml.api.waitForAnomalyDetectionJobToExist(job.jobId); await ml.api.waitForDatafeedToExist(datafeedId); + if (testData.requestBody.startDatafeed === true) { + await ml.api.waitForADJobRecordCountToBePositive(job.jobId); + } await ml.api.waitForJobState(job.jobId, job.jobState); await ml.api.waitForDatafeedState(datafeedId, job.datafeedState); } diff --git a/x-pack/test/functional/services/machine_learning/api.ts b/x-pack/test/functional/services/machine_learning/api.ts index afc2567f3cce9..6fdc268810036 100644 --- a/x-pack/test/functional/services/machine_learning/api.ts +++ b/x-pack/test/functional/services/machine_learning/api.ts @@ -138,11 +138,7 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) { }, async getJobState(jobId: string): Promise { - log.debug(`Fetching job state for job ${jobId}`); - const jobStats = await esSupertest - .get(`/_ml/anomaly_detectors/${jobId}/_stats`) - .expect(200) - .then((res: any) => res.body); + const jobStats = await this.getADJobStats(jobId); expect(jobStats.jobs).to.have.length(1); const state: JOB_STATE = jobStats.jobs[0].state; @@ -150,6 +146,16 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) { return state; }, + async getADJobStats(jobId: string): Promise { + log.debug(`Fetching anomaly detection job stats for job ${jobId}...`); + const jobStats = await esSupertest + .get(`/_ml/anomaly_detectors/${jobId}/_stats`) + .expect(200) + .then((res: any) => res.body); + + return jobStats; + }, + async waitForJobState(jobId: string, expectedJobState: JOB_STATE) { await retry.waitForWithTimeout( `job state to be ${expectedJobState}`, @@ -390,5 +396,31 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) { await this.waitForDataFrameAnalyticsJobToExist(analyticsId); }, + + async getADJobRecordCount(jobId: string): Promise { + const jobStats = await this.getADJobStats(jobId); + + expect(jobStats.jobs).to.have.length(1); + const processedRecordCount: number = jobStats.jobs[0].data_counts.processed_record_count; + + return processedRecordCount; + }, + + async waitForADJobRecordCountToBePositive(jobId: string) { + await retry.waitForWithTimeout( + `'${jobId}' to have processed_record_count > 0`, + 10 * 1000, + async () => { + const processedRecordCount = await this.getADJobRecordCount(jobId); + if (processedRecordCount > 0) { + return true; + } else { + throw new Error( + `expected anomaly detection job '${jobId}' to have processed_record_count > 0 (got ${processedRecordCount})` + ); + } + } + ); + }, }; } diff --git a/x-pack/test/functional/services/machine_learning/job_management.ts b/x-pack/test/functional/services/machine_learning/job_management.ts index 8b85f85d46cf4..085bb31258012 100644 --- a/x-pack/test/functional/services/machine_learning/job_management.ts +++ b/x-pack/test/functional/services/machine_learning/job_management.ts @@ -43,6 +43,7 @@ export function MachineLearningJobManagementProvider( }, async waitForJobCompletion(jobId: string) { + await mlApi.waitForADJobRecordCountToBePositive(jobId); await mlApi.waitForDatafeedState(`datafeed-${jobId}`, DATAFEED_STATE.STOPPED); await mlApi.waitForJobState(jobId, JOB_STATE.CLOSED); }, From e5f56ad7a79b5df6fddf80f8c26cbaf59074cdac Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Mon, 18 May 2020 18:05:24 +0200 Subject: [PATCH 005/129] [RFC] Global search API (#64284) * initial file import * update types * update RFC PR number * first draft complete * draft v1.1.0 * initial self review * nits and comments * add 'preference' option * change meta type to Record * specify cancellation * remove generic for GlobalSearchResponse, use distinct type on client and server * use plain string instead of enum for GlobalSearchResult.type * remove terminology from unresolved questions * update pros/cons of core vs plugin * GS is exposed from a plugin instead of core * remove the server.publicAddress proposal, return mixed abs url / rel paths instead * distinguish result type between GS api and result providers * return batched results, no longer sort * remove request from GlobalSearchProviderContext * add maxResults to GlobalSearchProviderFindOptions * nit/typo --- rfcs/text/0011_global_search.md | 591 ++++++++++++++++++++++++++++++++ 1 file changed, 591 insertions(+) create mode 100644 rfcs/text/0011_global_search.md diff --git a/rfcs/text/0011_global_search.md b/rfcs/text/0011_global_search.md new file mode 100644 index 0000000000000..5ec368a1c2f02 --- /dev/null +++ b/rfcs/text/0011_global_search.md @@ -0,0 +1,591 @@ +- Start Date: 2020-04-19 +- RFC PR: [#64284](https://github.com/elastic/kibana/pull/64284) +- Kibana Issue: [#61657](https://github.com/elastic/kibana/issues/61657) + +# Summary + +A new Kibana plugin exposing an API on both public and server side, to allow consumers to search for various objects and +register result providers. + +Note: whether this will be an oss or xpack plugin still depends on https://github.com/elastic/dev/issues/1404. + +# Basic example + +- registering a result provider: + +```ts +setupDeps.globalSearch.registerResultProvider({ + id: 'my_provider', + find: (term, options, context) => { + const resultPromise = myService.search(term, context.core.savedObjects.client); + return from(resultPromise); + }, +}); +``` + +- using the `find` API from the client-side: + +```ts +startDeps.globalSearch.find('some term').subscribe( + ({ results }) => { + updateResults(results); + }, + () => {}, + () => { + showAsyncSearchIndicator(false); + } +); +``` + +# Motivation + +Kibana should do its best to assist users searching for and navigating to the various objects present on the Kibana platform. + +We should expose an API to make it possible for plugins to search for the various objects present on a Kibana instance. + +The first consumer of this API will be the global search bar [#57576](https://github.com/elastic/kibana/issues/57576). This API +should still be generic to answer similar needs from any other consumer, either client or server side. + +# Detailed design + +## API Design + +### Result provider API + +#### common types + +```ts +/** + * Static, non exhaustive list of the common search types. + * Only present to allow consumers and result providers to have aliases to the most common types. + */ +enum GlobalSearchCommonResultTypes { + application = 'application', + dashboard = 'dashboard', + visualization = 'visualization', + search = 'search', +} + +/** + * Options provided to {@link GlobalSearchResultProvider | result providers} `find` method. + */ +interface GlobalSearchProviderFindOptions { + /** + * A custom preference token associated with a search 'session' that should be used to get consistent scoring + * when performing calls to ES. Can also be used as a 'session' token for providers returning data from elsewhere + * than an elasticsearch cluster. + */ + preference: string; + /** + * Observable that emit once if and when the `find` call has been aborted by the consumer, or when the timeout period as been reached. + * When a `find` request is aborted, the service will stop emitting any new result to the consumer anyway, but + * this can (and should) be used to cancel any pending asynchronous task and complete the result observable. + */ + aborted$: Observable; + /** + * The total maximum number of results (including all batches / emissions) that should be returned by the provider for a given `find` request. + * Any result emitted exceeding this quota will be ignored by the service and not emitted to the consumer. + */ + maxResults: number; +} + +/** + * Representation of a result returned by a {@link GlobalSearchResultProvider | result provider} + */ +interface GlobalSearchProviderResult { + /** an id that should be unique for an individual provider's results */ + id: string; + /** the title/label of the result */ + title: string; + /** the type of result */ + type: string; + /** an optional EUI icon name to associate with the search result */ + icon?: string; + /** + * The url associated with this result. + * This can be either an absolute url, a path relative to the basePath, or a structure specifying if the basePath should be prepended. + * + * @example + * `result.url = 'https://kibana-instance:8080/base-path/app/my-app/my-result-type/id';` + * `result.url = '/app/my-app/my-result-type/id';` + * `result.url = { path: '/base-path/app/my-app/my-result-type/id', prependBasePath: false };` + */ + url: string | { path: string; prependBasePath: boolean }; + /** the score of the result, from 1 (lowest) to 100 (highest) */ + score: number; + /** an optional record of metadata for this result */ + meta?: Record; +} +``` + +Notes: + +- The `Serializable` type should be implemented and exposed from `core`. A basic implementation could be: + +```ts +type Serializable = string | number | boolean | PrimitiveArray | PrimitiveRecord; +interface PrimitiveArray extends Array {} +interface PrimitiveRecord extends Record {} +``` + +#### server + +```ts +/** + * Context passed to server-side {@GlobalSearchResultProvider | result provider}'s `find` method. + */ +export interface GlobalSearchProviderContext { + core: { + savedObjects: { + client: SavedObjectsClientContract; + typeRegistry: ISavedObjectTypeRegistry; + }; + elasticsearch: { + legacy: { + client: IScopedClusterClient; + }; + }; + uiSettings: { + client: IUiSettingsClient; + }; + }; +} + +/** + * GlobalSearch result provider, to be registered using the {@link GlobalSearchSetup | global search API} + */ +type GlobalSearchResultProvider = { + id: string; + find( + term: string, + options: GlobalSearchProviderFindOptions, + context: GlobalSearchProviderContext + ): Observable; +}; +``` + +Notes: + +- Initial implementation will only provide a static / non extensible `GlobalSearchProviderContext` context. + It would be possible to allow plugins to register their own context providers as it's done for `RequestHandlerContext`, + but this will not be done until the need arises. +- The performing `request` object could also be exposed on the context to allow result providers + to scope their custom services if needed. However as the previous option, this should only be done once needed. + +#### public + +```ts +/** + * GlobalSearch result provider, to be registered using the {@link GlobalSearchSetup | global search API} + */ +type GlobalSearchResultProvider = { + id: string; + find( + term: string, + options: GlobalSearchProviderFindOptions + ): Observable; +}; +``` + +Notes: + +- The client-side version of `GlobalSearchResultProvider` is slightly different than the + server one, as there is no `context` parameter on the `find` signature. + +### Plugin API + +#### server API + +```ts +/** + * Representation of a result returned by the {@link GlobalSearchPluginStart.find | `find` API} + */ +type GlobalSearchResult = Omit & { + /** + * The url associated with this result. + * This can be either an absolute url, or a relative path including the basePath + */ + url: string; +}; + +/** + * Options for the server-side {@link GlobalSearchServiceStart.find | find API} + */ +interface GlobalSearchFindOptions { + /** + * a custom preference token associated with a search 'session' that should be used to get consistent scoring + * when performing calls to ES. Can also be used as a 'session' token for providers returning data from elsewhere + * than an elasticsearch cluster. + * If not specified, a random token will be generated and used when callingn the underlying result providers. + */ + preference?: string; + /** + * Optional observable to notify that the associated `find` call should be canceled. + * If/when provided and emitting, the result observable will be completed and no further result emission will be performed. + */ + aborted$?: Observable; +} + +/** + * Response returned from the server-side {@link GlobalSearchServiceStart | global search service}'s `find` API + */ +type GlobalSearchBatchedResults = { + /** + * Results for this batch + */ + results: GlobalSearchResult[]; +}; + +/** @public */ +interface GlobalSearchPluginSetup { + registerResultProvider(provider: GlobalSearchResultProvider); +} + +/** @public */ +interface GlobalSearchPluginStart { + find( + term: string, + options: GlobalSearchFindOptions, + request: KibanaRequest + ): Observable; +} +``` + +#### public API + +```ts +/** + * Options for the client-side {@link GlobalSearchServiceStart.find | find API} + */ +interface GlobalSearchFindOptions { + /** + * Optional observable to notify that the associated `find` call should be canceled. + * If/when provided and emitting, the result observable will be completed and no further result emission will be performed. + */ + aborted$?: Observable; +} + +/** + * Enhanced {@link GlobalSearchResult | result type} for the client-side, + * to allow navigating to a given result. + */ +interface NavigableGlobalSearchResult extends GlobalSearchResult { + /** + * Navigate to this result's associated url. If the result is on this kibana instance, user will be redirected to it + * in a SPA friendly way using `application.navigateToApp`, else, a full page refresh will be performed. + */ + navigate: () => Promise; +} + +/** + * Response returned from the client-side {@link GlobalSearchServiceStart | global search service}'s `find` API + */ +type GlobalSearchBatchedResults = { + /** + * Results for this batch + */ + results: NavigableGlobalSearchResult[]; +}; + +/** @public */ +interface GlobalSearchPluginSetup { + registerResultProvider(provider: GlobalSearchResultProvider); +} + +/** @public */ +interface GlobalSearchPluginStart { + find(term: string, options: GlobalSearchFindOptions): Observable; +} +``` + +Notes: + +- The public API is very similar to its server counterpart. The differences are: + - The `registerResultProvider` setup APIs share the same signature, however the input `GlobalSearchResultProvider` + types are different on the client and server. + - The `find` start API signature got a `KibanaRequest` for `server`, when this parameter is not present for `public`. +- The `find` API returns a observable of `NavigableGlobalSearchResult` instead of plain `GlobalSearchResult`. This type + is here to enhance results with a `navigate` method to let the `GlobalSearch` plugin handle the navigation logic, which is + non-trivial. See the [Redirecting to a result](#redirecting-to-a-result) section for more info. + +#### http API + +An internal HTTP API will be exposed on `/internal/global_search/find` to allow the client-side `GlobalSearch` plugin +to fetch results from the server-side result providers. + +It should be very close to: + +```ts +router.post( + { + path: '/internal/global_search/find', + validate: { + body: schema.object({ + term: schema.string(), + options: schema.maybe( + schema.object({ + preference: schema.maybe(schema.string()), + }) + ), + }), + }, + }, + async (ctx, req, res) => { + const { term, options } = req.body; + const results = await ctx.globalSearch + .find(term, { ...options, $aborted: req.events.aborted$ }) + .pipe(reduce((acc, results) => [...acc, ...results])) + .toPromise(); + return res.ok({ + body: { + results, + }, + }); + } +); +``` + +Notes: + +- This API is only for internal use and communication between the client and the server parts of the `GS` API. When + the need to expose an API for external consumers will appear, a new public API will be exposed for that. +- A new `globalSearch` context will be exposed on core's `RequestHandlerContext` to wrap a `find` call with current request. +- Example implementation is awaiting for all results and then returns them as a single response. Ideally, we would + leverage the `bfetch` plugin to stream the results to the client instead. + +## Functional behavior + +### summary + +- the `GlobalSearch` plugin setup contract exposes an API to be able to register result providers (`GlobalSearchResultProvider`). + These providers can be registered from either public or server side, even if the interface for each side is not + exactly the same. +- the `GlobalSearch` plugin start contract exposes an API to be able to search for objects. This API is available from both public + and server sides. + - When using the server `find` API, only results from providers registered from the server will be returned. + - When using the public `find` API, results from provider registered from both server and public sides will be returned. +- During a `find` call, the service will call all the registered result providers and collect their result observables. + Every time a result provider emits some new results, the `globalSearch` service will: + - process them to convert their url to the expected output format + - emit the processed results + +### result provider registration + +Due to the fact that some kind of results (i.e `application`, and maybe later `management_section`) only exists on +the public side of Kibana and therefor are not known on the server side, the `registerResultProvider` API will be +available both from the public and the server counterpart of the `GlobalSearchPluginSetup` contract. + +However, as results from providers registered from the client-side will not be available from the server's `find` API, +registering result providers from the client should only be done to answer this specific use case and will be +discouraged, by providing appropriated jsdoc and documentation explaining that it should only +be used when it is not technically possible to register it from the server side instead. + +### results url processing + +When retrieving results from providers, the GS service will convert them from the provider's `GlobalSearchProviderResult` +result type to `GlobalSeachResult`, which is the structure returned from the `GlobalSearchPluginStart.find` observable. + +In current specification, the only conversion step is to transform the `result.url` property following this logic: + +- if `url` is an absolute url, it will not be modified +- if `url` is a relative path, the basePath will be prepended using `basePath.prepend` +- if `url` is a `{ path: string; prependBasePath: boolean }` structure: + - if `prependBasePath` is true, the basePath will be prepended to the given `path` using `basePath.prepend` + - if `prependBasePath` is false, the given `path` will be returned unmodified + +#### redirecting to a result + +Parsing a relative or absolute result url to perform SPA navigation can be non trivial, and should remains the responsibility +of the GlobalSearch plugin API. + +This is why `NavigableGlobalSearchResult.navigate` has been introduced on the client-side version of the `find` API + +When using `navigate` from a result instance, the following logic will be executed: + +If all these criteria are true for `result.url`: + +- (only for absolute URLs) The origin of the URL matches the origin of the browser's current location +- The pathname of the URL starts with the current basePath (eg. /mybasepath/s/my-space) +- The pathname segment after the basePath matches any known application route (eg. /app// or any application's `appRoute` configuration) + +Then: match the pathname segment to the corresponding application and do the SPA navigation to that application using +`application.navigateToApp` using the remaining pathname segment for the `path` option. + +Otherwise: do a full page navigation using `window.location.assign` + +### searching from the server side + +When calling `GlobalSearchPluginStart.find` from the server-side service: + +- the service will call `find` on each server-side registered result provider and collect the resulting result observables + +- then, the service will merge every result observable and trigger the next step on every emission until either + - A predefined timeout duration is reached + - All result observables are completed + +- on every emission of the merged observable, the results will be processed then emitted. + +A very naive implementation of this behavior would be: + +```ts +search( + term: string, + options: GlobalSearchFindOptions, + request: KibanaRequest +): Observable { + const aborted$ = merge(timeout$, options.$aborted).pipe(first()) + const fromProviders$ = this.providers.map(p => + p.find(term, { ...options, aborted$ }, contextFromRequest(request)) + ); + return merge([...fromProviders$]).pipe( + takeUntil(aborted$), + map(newResults => { + return process(newResults); + }), + ); +} +``` + +### searching from the client side + +When calling `GlobalSearchPluginStart.find` from the public-side service: + +- The service will call: + + - the server-side API via an http call to fetch results from the server-side result providers + - `find` on each client-side registered result provider and collect the resulting observables + +- Then, the service will merge every result observable and trigger the next step on every emission until either + + - A predefined timeout duration is reached + - All result observables are completed + +- on every emission of the merged observable, the results will be processed then emitted. + +A very naive implementation of this behavior would be: + +``` +search( + term: string, + options: GlobalSearchFindOptions, +): Observable { + const aborted$ = merge(timeout$, options.$aborted).pipe(first()) + const fromProviders$ = this.providers.map(p => + p.find(term, { ...options, aborted$ }) + ); + const fromServer$ = of(this.fetchServerResults(term, options, aborted$)) + return merge([...fromProviders$, fromServer$]).pipe( + takeUntil(aborted$), + map(newResults => { + return process(newResults); + }), + ); +} +``` + +Notes: + +- The example implementation is not streaming results from the server, meaning that all results from server-side + registered providers will all be fetched and emitted in a single batch. Ideally, we would leverage the `bfetch` plugin + to stream the results to the client instead. + +### results sorting + +As the GS `find` API is 'streaming' the results from the result providers by emitting the results in batches, sorting results in +each individual batch, even if technically possible, wouldn't provide much value as the consumer will need to sort the +aggregated results on each emission anyway. This is why the results emitted by the `find` API should be considered as +unsorted. Consumers should implement sorting themselves, using either the `score` attribute, or any other arbitrary logic. + +#### Note on score value + +Due to the fact that the results will be coming from various providers, from multiple ES queries or even not from ES, +using a centralized scoring mechanism is not possible. + +the `GlobalSearchResult` contains a `score` field, with an expected value going from 1 (lowest) to 100 (highest). +How this field is populated from each individual provider is considered an implementation detail. + +### Search cancellation + +Consumers can cancel a `find` call at any time by providing a cancellation observable with +the `GlobalSearchFindOptions.aborted$` option and then emitting from it. + +When this observable is provided and emitting, the GS service will complete the result observable. + +This observable will also be passed down to the underlying result providers, that can leverage it to cancel any pending +asynchronous task and perform cleanup if necessary. + +# Drawbacks + +See alternatives. + +# Alternatives + +## Result providers could be only registrable from the server-side API + +The fact that some kinds of results, and therefore some result providers, must be on the client-side makes the API more complex, +while making these results not available from the server-side and HTTP APIs. + +We could decide to only allow providers registration from the server-side. It would reduce API exposure, while simplifying +the service implementation. However to do that, we would need to find a solution to be able to implement a server-side +result provider for `application` (and later `management_section`) type provider. + +I will directly exclude the option to move the `application` registration (`core.application.register`) from client +to server-side, as it's a very heavy impacting (and breaking) change to `core` APIs that would requires more reasons +than just this RFC/API to consider. + +### AST parsing + +One option to make the `application` results 'visible' from the server-side would be to parse the client code at build time +using AST to find all usages to `application.register` inspect the parameters, and generates a server file +containing the applications. The server-side `application` result provider would then just read this file and uses it +to return application results. + +However + +- At the parsing would be done at build time, we would not be able to generate entries for any 3rd party plugins +- As entries for every existing applications would be generated, the search provider would to be able to know which + applications are actually enabled/accessible at runtime to filter them, which is all but easy +- It will also not contains test plugin apps, making it really hard to FTR +- AST parsing is a complex mechanism for an already unsatisfactory alternative + +### Duplicated server-side `application.register` API + +One other option would be to duplicate the `application.register` API on the server side, with a subset of the +client-side metadata. + +```ts +core.application.register({ + id: 'app_status', + title: 'App Status', + euiIconType: 'snowflake', +}); +``` + +This way, the applications could be searchable from the server using this server-side `applications` registry. + +However + +- It forces plugin developers to add this API call. In addition to be a very poor developer experience, it can also + very easily be forgotten, making a given app non searchable +- client-side only plugins would need to add a server-side part to their plugin just to register their application on + the server side + +# Adoption strategy + +The `globalSearch` service is a new feature provided by the `core` API. Also, the base providers +used to search for saved objects and applications will be implemented by the platform team, meaning +that by default, plugin developers won't have to do anything. + +Plugins that wish to expose additional result providers will easily be able to do so by using the exposed APIs and +documentation. + +# How we teach this + +This follows the same patterns we have used for other Core APIs: Observables subscriptions, etc. + +This should be taught using the same channels we've leveraged for other Kibana Platform APIs, API documentation and +example plugins. + +# Unresolved questions + +N/A From 3b4814ba48f0088ed62ded231d255a9bfe4fa40e Mon Sep 17 00:00:00 2001 From: Stacey Gammon Date: Mon, 18 May 2020 12:48:50 -0400 Subject: [PATCH 006/129] dont hide errors (#66764) Co-authored-by: Elastic Machine --- src/core/public/application/ui/app_container.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/public/application/ui/app_container.tsx b/src/core/public/application/ui/app_container.tsx index aad7e6dcf270a..4317ede547202 100644 --- a/src/core/public/application/ui/app_container.tsx +++ b/src/core/public/application/ui/app_container.tsx @@ -87,6 +87,8 @@ export const AppContainer: FunctionComponent = ({ })) || null; } catch (e) { // TODO: add error UI + // eslint-disable-next-line no-console + console.error(e); } finally { setShowSpinner(false); setIsMounting(false); From 1c61ca2c6d7321542ddf5513effb42f2beb7ead6 Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Mon, 18 May 2020 18:13:43 +0100 Subject: [PATCH 007/129] [ML] Enhances api docs for modules endpoints (#66738) * [ML] Enhances api docs for modules endpoints * [ML] Edits to modules schema following review Co-authored-by: Elastic Machine --- .../routes/apidoc_scripts/schema_worker.ts | 7 +- x-pack/plugins/ml/server/routes/modules.ts | 336 ++++++++++++++++-- .../ml/server/routes/schemas/modules.ts | 69 +++- 3 files changed, 385 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/ml/server/routes/apidoc_scripts/schema_worker.ts b/x-pack/plugins/ml/server/routes/apidoc_scripts/schema_worker.ts index 7514e482783b3..0eaf3143eaac0 100644 --- a/x-pack/plugins/ml/server/routes/apidoc_scripts/schema_worker.ts +++ b/x-pack/plugins/ml/server/routes/apidoc_scripts/schema_worker.ts @@ -44,9 +44,10 @@ export function postProcess(parsedFiles: any[]): void { */ function updateBlockParameters(docEntries: DocEntry[], block: Block, paramsGroup: string): void { if (!block.local.parameter) { - block.local.parameter = { - fields: {}, - }; + block.local.parameter = {}; + } + if (!block.local.parameter.fields) { + block.local.parameter.fields = {}; } if (!block.local.parameter.fields![paramsGroup]) { diff --git a/x-pack/plugins/ml/server/routes/modules.ts b/x-pack/plugins/ml/server/routes/modules.ts index 622ae66ede426..ade3d3eca90ea 100644 --- a/x-pack/plugins/ml/server/routes/modules.ts +++ b/x-pack/plugins/ml/server/routes/modules.ts @@ -4,13 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { schema, TypeOf } from '@kbn/config-schema'; +import { TypeOf } from '@kbn/config-schema'; import { RequestHandlerContext } from 'kibana/server'; import { DatafeedOverride, JobOverride } from '../../common/types/modules'; import { wrapError } from '../client/error_wrapper'; import { DataRecognizer } from '../models/data_recognizer'; -import { getModuleIdParamSchema, setupModuleBodySchema } from './schemas/modules'; +import { + moduleIdParamSchema, + optionalModuleIdParamSchema, + modulesIndexPatternTitleSchema, + setupModuleBodySchema, +} from './schemas/modules'; import { RouteInitialization } from '../types'; function recognize(context: RequestHandlerContext, indexPatternTitle: string) { @@ -85,17 +90,33 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { * * @api {get} /api/ml/modules/recognize/:indexPatternTitle Recognize index pattern * @apiName RecognizeIndex - * @apiDescription Returns the list of modules that matching the index pattern. - * - * @apiParam {String} indexPatternTitle Index pattern title. + * @apiDescription By supplying an index pattern, discover if any of the modules are a match for data in that index. + * @apiSchema (params) modulesIndexPatternTitleSchema + * @apiSuccess {object[]} modules Array of objects describing the modules which match the index pattern. + * @apiSuccessExample {json} Success-Response: + * [{ + * "id": "nginx_ecs", + * "query": { + * "bool": { + * "filter": [ + * { "term": { "event.dataset": "nginx.access" } }, + * { "exists": { "field": "source.address" } }, + * { "exists": { "field": "url.original" } }, + * { "exists": { "field": "http.response.status_code" } } + * ] + * } + * }, + * "description": "Find unusual activity in HTTP access logs from filebeat (ECS)", + * "logo": { + * "icon": "logoNginx" + * } + * }] */ router.get( { path: '/api/ml/modules/recognize/{indexPatternTitle}', validate: { - params: schema.object({ - indexPatternTitle: schema.string(), - }), + params: modulesIndexPatternTitleSchema, }, options: { tags: ['access:ml:canCreateJob'], @@ -118,17 +139,114 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { * * @api {get} /api/ml/modules/get_module/:moduleId Get module * @apiName GetModule - * @apiDescription Returns module by id. - * - * @apiParam {String} [moduleId] Module id + * @apiDescription Retrieve a whole ML module, containing jobs, datafeeds and saved objects. If + * no module ID is supplied, returns all modules. + * @apiSchema (params) moduleIdParamSchema + * @apiSuccess {object} module When a module ID is specified, returns a module object containing + * all of the jobs, datafeeds and saved objects which will be created when the module is setup. + * @apiSuccess {object[]} modules If no module ID is supplied, an array of all modules will be returned. + * @apiSuccessExample {json} Success-Response: + * { + * "id":"sample_data_ecommerce", + * "title":"Kibana sample data eCommerce", + * "description":"Find anomalies in eCommerce total sales data", + * "type":"Sample Dataset", + * "logoFile":"logo.json", + * "defaultIndexPattern":"kibana_sample_data_ecommerce", + * "query":{ + * "bool":{ + * "filter":[ + * { + * "term":{ + * "_index":"kibana_sample_data_ecommerce" + * } + * } + * ] + * } + * }, + * "jobs":[ + * { + * "id":"high_sum_total_sales", + * "config":{ + * "groups":[ + * "kibana_sample_data", + * "kibana_sample_ecommerce" + * ], + * "description":"Find customers spending an unusually high amount in an hour", + * "analysis_config":{ + * "bucket_span":"1h", + * "detectors":[ + * { + * "detector_description":"High total sales", + * "function":"high_sum", + * "field_name":"taxful_total_price", + * "over_field_name":"customer_full_name.keyword" + * } + * ], + * "influencers":[ + * "customer_full_name.keyword", + * "category.keyword" + * ] + * }, + * "analysis_limits":{ + * "model_memory_limit":"10mb" + * }, + * "data_description":{ + * "time_field":"order_date" + * }, + * "model_plot_config":{ + * "enabled":true + * }, + * "custom_settings":{ + * "created_by":"ml-module-sample", + * "custom_urls":[ + * { + * "url_name":"Raw data", + * "url_value":"kibana#/discover?_g=(time:(from:'$earliest$',mode:absolute,to:'$latest$'))&_a + * (index:ff959d40-b880-11e8-a6d9-e546fe2bba5f,query:(language:kuery,query:'customer_full_name + * keyword:\"$customer_full_name.keyword$\"'),sort:!('@timestamp',desc))" + * }, + * { + * "url_name":"Data dashboard", + * "url_value":"kibana#/dashboard/722b74f0-b882-11e8-a6d9-e546fe2bba5f?_g=(filters:!(),time:(from:'$earliest$', + * mode:absolute,to:'$latest$'))&_a=(filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f + * index:'INDEX_PATTERN_ID', key:customer_full_name.keyword,negate:!f,params:(query:'$customer_full_name.keyword$') + * type:phrase,value:'$customer_full_name.keyword$'),query:(match:(customer_full_name.keyword: + * (query:'$customer_full_name.keyword$',type:phrase))))),query:(language:kuery, query:''))" + * } + * ] + * } + * } + * } + * ], + * "datafeeds":[ + * { + * "id":"datafeed-high_sum_total_sales", + * "config":{ + * "job_id":"high_sum_total_sales", + * "indexes":[ + * "INDEX_PATTERN_NAME" + * ], + * "query":{ + * "bool":{ + * "filter":[ + * { + * "term":{ "_index":"kibana_sample_data_ecommerce" } + * } + * ] + * } + * } + * } + * } + * ], + * "kibana":{} + * } */ router.get( { path: '/api/ml/modules/get_module/{moduleId?}', validate: { - params: schema.object({ - ...getModuleIdParamSchema(true), - }), + params: optionalModuleIdParamSchema, }, options: { tags: ['access:ml:canGetJobs'], @@ -154,17 +272,148 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { /** * @apiGroup Modules * - * @api {post} /api/ml/modules/setup/:moduleId Setup module + * @api {post} /api/ml/modules/setup/:moduleId Set up module * @apiName SetupModule - * @apiDescription Created module items. - * + * @apiDescription Runs the module setup process. + * This creates jobs, datafeeds and kibana saved objects. It allows for customization of the module, + * overriding the default configuration. It also allows the user to start the datafeed. + * @apiSchema (params) moduleIdParamSchema * @apiSchema (body) setupModuleBodySchema + * @apiParamExample {json} jobOverrides-no-job-ID: + * "jobOverrides": { + * "analysis_limits": { + * "model_memory_limit": "13mb" + * } + * } + * @apiParamExample {json} jobOverrides-with-job-ID: + * "jobOverrides": [ + * { + * "analysis_limits": { + * "job_id": "foo" + * "model_memory_limit": "13mb" + * } + * } + * ] + * @apiParamExample {json} datafeedOverrides: + * "datafeedOverrides": [ + * { + * "scroll_size": 1001 + * }, + * { + * "job_id": "visitor_rate_ecs", + * "frequency": "30m" + * } + * ] + * @apiParamExample {json} query-overrrides-datafeedOverrides-query: + * { + * "query": {"bool":{"must":[{"match_all":{}}]}} + * "datafeedOverrides": { + * "query": {} + * } + * } + * @apiSuccess {object} results An object containing the results of creating the items in a module, + * i.e. the jobs, datafeeds and saved objects. Each item is listed by id with a success flag + * signifying whether the creation was successful. If the item creation failed, an error object + * with also be supplied containing the error. + * @apiSuccessExample {json} Success-Response: + * { + * "jobs": [{ + * "id": "test-visitor_rate_ecs", + * "success": true + * }, { + * "id": "test-status_code_rate_ecs", + * "success": true + * }, { + * "id": "test-source_ip_url_count_ecs", + * "success": true + * }, { + * "id": "test-source_ip_request_rate_ecs", + * "success": true + * }, { + * "id": "test-low_request_rate_ecs", + * "success": true + * }], + * "datafeeds": [{ + * "id": "datafeed-test-visitor_rate_ecs", + * "success": true, + * "started": false + * }, { + * "id": "datafeed-test-status_code_rate_ecs", + * "success": true, + * "started": false + * }, { + * "id": "datafeed-test-source_ip_url_count_ecs", + * "success": true, + * "started": false + * }, { + * "id": "datafeed-test-low_request_rate_ecs", + * "success": true, + * "started": false + * }, { + * "id": "datafeed-test-source_ip_request_rate_ecs", + * "success": true, + * "started": false + * }], + * "kibana": { + * "dashboard": [{ + * "id": "ml_http_access_explorer_ecs", + * "success": true + * }], + * "search": [{ + * "id": "ml_http_access_filebeat_ecs", + * "success": true + * }], + * "visualization": [{ + * "id": "ml_http_access_map_ecs", + * "success": true + * }, { + * "id": "ml_http_access_source_ip_timechart_ecs", + * "success": true + * }, { + * "id": "ml_http_access_status_code_timechart_ecs", + * "success": true + * }, { + * "id": "ml_http_access_top_source_ips_table_ecs", + * "success": true + * }, { + * "id": "ml_http_access_top_urls_table_ecs", + * "success": true + * }, { + * "id": "ml_http_access_events_timechart_ecs", + * "success": true + * }, { + * "id": "ml_http_access_unique_count_url_timechart_ecs", + * "success": true + * }] + * } + * } + * @apiSuccessExample {json} Error-Response: + * { + * "jobs": [{ + * "id": "test-status_code_rate_ecs", + * "success": false, + * "error": { + * "msg": "[resource_already_exists_exception] The job cannot be created with the Id 'test-status_code_rate_ecs'. The Id is + * already used.", + * "path": "/_ml/anomaly_detectors/test-status_code_rate_ecs", + * "query": {}, + * "body": "{...}", + * "statusCode": 400, + * "response": "{\"error\":{\"root_cause\":[{\"type\":\"resource_already_exists_exception\",\"reason\":\"The job cannot be created + * with the Id 'test-status_code_rate_ecs'. The Id is already used.\"}],\"type\":\"resource_already_exists_exception\", + * \"reason\":\"The job cannot be created with the Id 'test-status_code_rate_ecs'. The Id is already used.\"},\"status\":400}" + * } + * }, + * }, + * ... + * }] + * } */ router.post( { path: '/api/ml/modules/setup/{moduleId}', validate: { - params: schema.object(getModuleIdParamSchema()), + params: moduleIdParamSchema, body: setupModuleBodySchema, }, options: { @@ -217,15 +466,58 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { * * @api {post} /api/ml/modules/jobs_exist/:moduleId Check if module jobs exist * @apiName CheckExistingModuleJobs - * @apiDescription Checks if the jobs in the module have been created. - * - * @apiParam {String} moduleId Module id + * @apiDescription Check whether the jobs in the module with the specified ID exist in the + * current list of jobs. The check runs a test to see if any of the jobs in existence + * have an ID which ends with the ID of each job in the module. This is done as a prefix + * may be supplied in the setup endpoint which is added to the start of the ID of every job in the module. + * @apiSchema (params) moduleIdParamSchema + * @apiSuccess {boolean} jobsExist true if all the jobs in the module have a matching job with an + * ID which ends with the job ID specified in the module, false otherwise. + * @apiSuccess {Object[]} jobs present if the jobs do all exist, with each object having keys of id, + * and optionally earliestTimestampMs, latestTimestampMs, latestResultsTimestampMs + * properties if the job has processed any data. + * @apiSuccessExample {json} Success-Response: + * { + * "jobsExist":true, + * "jobs":[ + * { + * "id":"nginx_low_request_rate_ecs", + * "earliestTimestampMs":1547016291000, + * "latestTimestampMs":1548256497000 + * "latestResultsTimestampMs":1548255600000 + * }, + * { + * "id":"nginx_source_ip_request_rate_ecs", + * "earliestTimestampMs":1547015109000, + * "latestTimestampMs":1548257222000 + * "latestResultsTimestampMs":1548255600000 + * }, + * { + * "id":"nginx_source_ip_url_count_ecs", + * "earliestTimestampMs":1547015109000, + * "latestTimestampMs":1548257222000 + * "latestResultsTimestampMs":1548255600000 + * }, + * { + * "id":"nginx_status_code_rate_ecs", + * "earliestTimestampMs":1547015109000, + * "latestTimestampMs":1548257222000 + * "latestResultsTimestampMs":1548255600000 + * }, + * { + * "id":"nginx_visitor_rate_ecs", + * "earliestTimestampMs":1547016291000, + * "latestTimestampMs":1548256497000 + * "latestResultsTimestampMs":1548255600000 + * } + * ] + * } */ router.get( { path: '/api/ml/modules/jobs_exist/{moduleId}', validate: { - params: schema.object(getModuleIdParamSchema()), + params: moduleIdParamSchema, }, options: { tags: ['access:ml:canGetJobs'], diff --git a/x-pack/plugins/ml/server/routes/schemas/modules.ts b/x-pack/plugins/ml/server/routes/schemas/modules.ts index 98e3d80f0ff84..23148c14c734e 100644 --- a/x-pack/plugins/ml/server/routes/schemas/modules.ts +++ b/x-pack/plugins/ml/server/routes/schemas/modules.ts @@ -7,24 +7,89 @@ import { schema } from '@kbn/config-schema'; export const setupModuleBodySchema = schema.object({ + /** + * Job ID prefix. This will be added to the start of the ID every job created by the module (optional). + */ prefix: schema.maybe(schema.string()), + /** + * List of group IDs. This will override the groups assigned to each job created by the module (optional). + */ groups: schema.maybe(schema.arrayOf(schema.string())), + /** + * Name of kibana index pattern. Overrides the index used in each datafeed and each index pattern + * used in the custom urls and saved objects created by the module. A matching index pattern must + * exist in kibana if the module contains custom urls or saved objects which rely on an index pattern ID. + * If the module does not contain custom urls or saved objects which require an index pattern ID, the + * indexPatternName can be any index name or pattern that will match an ES index. It can also be a comma + * separated list of names. If no indexPatternName is supplied, the default index pattern specified in + * the manifest.json will be used (optional). + */ indexPatternName: schema.maybe(schema.string()), + /** + * ES Query DSL object. Overrides the query object for each datafeed created by the module (optional). + */ query: schema.maybe(schema.any()), + /** + * Flag to specify that each job created by the module uses a dedicated index (optional). + */ useDedicatedIndex: schema.maybe(schema.boolean()), + /** + * Flag to specify that each datafeed created by the module is started once saved. Defaults to false (optional). + */ startDatafeed: schema.maybe(schema.boolean()), + /** + * Start date for datafeed. Specified in epoch seconds. Only used if startDatafeed is true. + * If not specified, a value of 0 is used i.e. start at the beginning of the data (optional). + */ start: schema.maybe(schema.number()), + /** + * End date for datafeed. Specified in epoch seconds. Only used if startDatafeed is true. + * If not specified, the datafeed will continue to run in real time (optional). + */ end: schema.maybe(schema.number()), + /** + * Partial job configuration which will override jobs contained in the module. Can be an array of objects. + * If a job_id is specified, only that job in the module will be overridden. + * Applied before any of the existing + * overridable options (e.g. useDedicatedIndex, groups, indexPatternName etc) + * and so can be overridden themselves (optional). + */ jobOverrides: schema.maybe(schema.any()), + /** + * Partial datafeed configuration which will override datafeeds contained in the module. + * Can be an array of objects. + * If a datafeed_id or a job_id is specified, + * only that datafeed in the module will be overridden. Applied before any of the existing + * overridable options (e.g. useDedicatedIndex, groups, indexPatternName etc) + * and so can be overridden themselves (optional). + */ datafeedOverrides: schema.maybe(schema.any()), /** * Indicates whether an estimate of the model memory limit - * should be made by checking the cardinality of fields in the job configurations. + * should be made by checking the cardinality of fields in the job configurations (optional). */ estimateModelMemory: schema.maybe(schema.boolean()), }); export const getModuleIdParamSchema = (optional = false) => { const stringType = schema.string(); - return { moduleId: optional ? schema.maybe(stringType) : stringType }; + return schema.object({ + /** + * ID of the module. + */ + moduleId: optional ? schema.maybe(stringType) : stringType, + }); }; + +export const optionalModuleIdParamSchema = getModuleIdParamSchema(true); + +export const moduleIdParamSchema = getModuleIdParamSchema(false); + +export const modulesIndexPatternTitleSchema = schema.object({ + /** + * Index pattern to recognize. Note that this does not need to be a Kibana + * index pattern, and can be the name of a single Elasticsearch index, + * or include a wildcard (*) to match multiple indices. + */ + indexPatternTitle: schema.string(), +}); From 84e06afddc264c20349f357e62f0794d22de5db4 Mon Sep 17 00:00:00 2001 From: Sonja Krause-Harder Date: Mon, 18 May 2020 19:18:25 +0200 Subject: [PATCH 008/129] [Ingest Manager] Better handling of package installation problems (#66541) * Better handle non-available package registry * Log errors in route handler only * Await installation of prebuilt component templates * Remove leftover import * Remove useless use of await. --- .../server/routes/setup/handlers.ts | 10 ++++++ .../epm/elasticsearch/template/install.ts | 36 +++++++++++-------- .../server/services/epm/packages/install.ts | 18 ++++------ .../server/services/epm/registry/requests.ts | 2 +- 4 files changed, 39 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/ingest_manager/server/routes/setup/handlers.ts b/x-pack/plugins/ingest_manager/server/routes/setup/handlers.ts index 12781f2f77d17..8bc80c69ce9b2 100644 --- a/x-pack/plugins/ingest_manager/server/routes/setup/handlers.ts +++ b/x-pack/plugins/ingest_manager/server/routes/setup/handlers.ts @@ -74,12 +74,22 @@ export const createFleetSetupHandler: RequestHandler< export const ingestManagerSetupHandler: RequestHandler = async (context, request, response) => { const soClient = context.core.savedObjects.client; const callCluster = context.core.elasticsearch.adminClient.callAsCurrentUser; + const logger = appContextService.getLogger(); try { await setupIngestManager(soClient, callCluster); return response.ok({ body: { isInitialized: true }, }); } catch (e) { + if (e.isBoom) { + logger.error(e.output.payload.message); + return response.customError({ + statusCode: e.output.statusCode, + body: { message: e.output.payload.message }, + }); + } + logger.error(e.message); + logger.error(e.stack); return response.customError({ statusCode: 500, body: { message: e.message }, diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/install.ts index 6ef6f863753b5..2c452f16cc104 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/install.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import Boom from 'boom'; import { Dataset, RegistryPackage, ElasticsearchAssetType, TemplateRef } from '../../../../types'; import { CallESAsCurrentUser } from '../../../../types'; import { Field, loadFieldsFromYaml, processFields } from '../../fields/field'; @@ -20,8 +21,8 @@ export const installTemplates = async ( // install any pre-built index template assets, // atm, this is only the base package's global index templates // Install component templates first, as they are used by the index templates - installPreBuiltComponentTemplates(pkgName, pkgVersion, callCluster); - installPreBuiltTemplates(pkgName, pkgVersion, callCluster); + await installPreBuiltComponentTemplates(pkgName, pkgVersion, callCluster); + await installPreBuiltTemplates(pkgName, pkgVersion, callCluster); // build templates per dataset from yml files const datasets = registryPackage.datasets; @@ -53,16 +54,7 @@ const installPreBuiltTemplates = async ( pkgVersion, (entry: Registry.ArchiveEntry) => isTemplate(entry) ); - // templatePaths.forEach(async path => { - // const { file } = Registry.pathParts(path); - // const templateName = file.substr(0, file.lastIndexOf('.')); - // const content = JSON.parse(Registry.getAsset(path).toString('utf8')); - // await callCluster('indices.putTemplate', { - // name: templateName, - // body: content, - // }); - // }); - templatePaths.forEach(async path => { + const templateInstallPromises = templatePaths.map(async path => { const { file } = Registry.pathParts(path); const templateName = file.substr(0, file.lastIndexOf('.')); const content = JSON.parse(Registry.getAsset(path).toString('utf8')); @@ -91,8 +83,15 @@ const installPreBuiltTemplates = async ( // The existing convenience endpoint `indices.putTemplate` only sends to _template, // which does not support v2 templates. // See src/core/server/elasticsearch/api_types.ts for available endpoints. - await callCluster('transport.request', callClusterParams); + return callCluster('transport.request', callClusterParams); }); + try { + return await Promise.all(templateInstallPromises); + } catch (e) { + throw new Boom(`Error installing prebuilt index templates ${e.message}`, { + statusCode: 400, + }); + } }; const installPreBuiltComponentTemplates = async ( @@ -105,7 +104,7 @@ const installPreBuiltComponentTemplates = async ( pkgVersion, (entry: Registry.ArchiveEntry) => isComponentTemplate(entry) ); - templatePaths.forEach(async path => { + const templateInstallPromises = templatePaths.map(async path => { const { file } = Registry.pathParts(path); const templateName = file.substr(0, file.lastIndexOf('.')); const content = JSON.parse(Registry.getAsset(path).toString('utf8')); @@ -124,8 +123,15 @@ const installPreBuiltComponentTemplates = async ( // This uses the catch-all endpoint 'transport.request' because there is no // convenience endpoint for component templates yet. // See src/core/server/elasticsearch/api_types.ts for available endpoints. - await callCluster('transport.request', callClusterParams); + return callCluster('transport.request', callClusterParams); }); + try { + return await Promise.all(templateInstallPromises); + } catch (e) { + throw new Boom(`Error installing prebuilt component templates ${e.message}`, { + statusCode: 400, + }); + } }; const isTemplate = ({ path }: Registry.ArchiveEntry) => { diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts index 632bc3ac9b69f..79a5e98b9507d 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts @@ -73,17 +73,13 @@ export async function ensureInstalledPackage(options: { if (installedPackage) { return installedPackage; } - // if the requested packaged was not found to be installed, try installing - try { - await installLatestPackage({ - savedObjectsClient, - pkgName, - callCluster, - }); - return await getInstallation({ savedObjectsClient, pkgName }); - } catch (err) { - throw new Error(err.message); - } + // if the requested packaged was not found to be installed, install + await installLatestPackage({ + savedObjectsClient, + pkgName, + callCluster, + }); + return await getInstallation({ savedObjectsClient, pkgName }); } export async function installPackage(options: { diff --git a/x-pack/plugins/ingest_manager/server/services/epm/registry/requests.ts b/x-pack/plugins/ingest_manager/server/services/epm/registry/requests.ts index 654aa8aae1355..93e475cbc5956 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/registry/requests.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/registry/requests.ts @@ -17,7 +17,7 @@ export async function getResponse(url: string): Promise { throw new Boom(response.statusText, { statusCode: response.status }); } } catch (e) { - throw Boom.boomify(e); + throw new Boom(`Error connecting to package registry: ${e.message}`, { statusCode: 502 }); } } From 4f1b9a234f556052d265ae8db6f06689e54d943e Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 18 May 2020 10:20:53 -0700 Subject: [PATCH 009/129] [dev/cli] add support for --no-cache (#66837) --- src/cli/cluster/run_kbn_optimizer.ts | 1 + src/cli/serve/serve.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/cli/cluster/run_kbn_optimizer.ts b/src/cli/cluster/run_kbn_optimizer.ts index b811fc1f6b294..e4bd6b98dd2b9 100644 --- a/src/cli/cluster/run_kbn_optimizer.ts +++ b/src/cli/cluster/run_kbn_optimizer.ts @@ -35,6 +35,7 @@ export function runKbnOptimizer(opts: Record, config: LegacyConfig) repoRoot: REPO_ROOT, watch: true, includeCoreBundle: true, + cache: !!opts.cache, oss: !!opts.oss, examples: !!opts.runExamples, pluginPaths: config.get('plugins.paths'), diff --git a/src/cli/serve/serve.js b/src/cli/serve/serve.js index 471939121143a..6b0daebd5a042 100644 --- a/src/cli/serve/serve.js +++ b/src/cli/serve/serve.js @@ -218,6 +218,7 @@ export default function(program) { "Don't put a proxy in front of the dev server, which adds a random basePath" ) .option('--no-watch', 'Prevents automatic restarts of the server in --dev mode') + .option('--no-cache', 'Disable the kbn/optimizer cache') .option('--no-dev-config', 'Prevents loading the kibana.dev.yml file in --dev mode'); } From 1006c315cb067d34ac973928f40c0f10d1e53273 Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Mon, 18 May 2020 14:25:44 -0500 Subject: [PATCH 010/129] [APM] Lowercase agent names so icons work (#66824) * [APM] Lowercase agent names so icons work .NET agent name can be reported as "dotNet" instead of "dotnet". Lowercase the key so either one will work. * Extract getNormalizedAgentName --- x-pack/plugins/apm/common/agent_name.ts | 13 +++++++++++++ .../components/app/ServiceMap/Cytoscape.stories.tsx | 7 +++++++ .../apm/public/components/app/ServiceMap/icons.ts | 5 ++--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/apm/common/agent_name.ts b/x-pack/plugins/apm/common/agent_name.ts index 085828b729ea5..dac29a4f50682 100644 --- a/x-pack/plugins/apm/common/agent_name.ts +++ b/x-pack/plugins/apm/common/agent_name.ts @@ -41,3 +41,16 @@ export function isJavaAgentName( ): agentName is 'java' { return agentName === 'java'; } + +/** + * "Normalizes" and agent name by: + * + * * Converting to lowercase + * * Converting "rum-js" to "js-base" + * + * This helps dealing with some older agent versions + */ +export function getNormalizedAgentName(agentName?: string) { + const lowercased = agentName && agentName.toLowerCase(); + return isRumAgentName(lowercased) ? 'js-base' : lowercased; +} diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/Cytoscape.stories.tsx b/x-pack/plugins/apm/public/components/app/ServiceMap/Cytoscape.stories.tsx index 340c299f52c0b..2d1e99096a44f 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/Cytoscape.stories.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/Cytoscape.stories.tsx @@ -186,6 +186,13 @@ storiesOf('app/ServiceMap/Cytoscape', module) 'agent.name': 'dotnet' } }, + { + data: { + id: 'dotNet', + 'service.name': 'dotNet service', + 'agent.name': 'dotNet' + } + }, { data: { id: 'go', diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/icons.ts b/x-pack/plugins/apm/public/components/app/ServiceMap/icons.ts index 9fe5cbd23b07c..1b4bf1b77791c 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/icons.ts +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/icons.ts @@ -5,7 +5,7 @@ */ import cytoscape from 'cytoscape'; -import { isRumAgentName } from '../../../../common/agent_name'; +import { getNormalizedAgentName } from '../../../../common/agent_name'; import { AGENT_NAME, SPAN_SUBTYPE, @@ -87,8 +87,7 @@ const agentIcons: { [key: string]: string } = { }; function getAgentIcon(agentName?: string) { - // RUM can have multiple names. Normalize it - const normalizedAgentName = isRumAgentName(agentName) ? 'js-base' : agentName; + const normalizedAgentName = getNormalizedAgentName(agentName); return normalizedAgentName && agentIcons[normalizedAgentName]; } From 1178811ec76fd37d5db53c4fb81c44b59941a97a Mon Sep 17 00:00:00 2001 From: Steph Milovic Date: Mon, 18 May 2020 15:11:16 -0600 Subject: [PATCH 011/129] [SIEM] Cases] Capture timeline click and open timeline in case view (#66327) --- .../siem/cypress/integration/cases.spec.ts | 13 ++- .../siem/cypress/screens/case_details.ts | 2 +- .../siem/cypress/tasks/case_details.ts | 7 +- .../user_action_markdown.test.tsx | 79 +++++++++++++++++++ .../user_action_tree/user_action_markdown.tsx | 35 +++++++- .../common/components/markdown/index.test.tsx | 32 ++++++++ .../common/components/markdown/index.tsx | 43 +++++++--- .../components/markdown/translations.ts | 8 ++ .../components/markdown_editor/form.tsx | 3 + .../components/markdown_editor/index.tsx | 5 +- .../components/open_timeline/helpers.ts | 2 +- 11 files changed, 200 insertions(+), 29 deletions(-) create mode 100644 x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.test.tsx diff --git a/x-pack/plugins/siem/cypress/integration/cases.spec.ts b/x-pack/plugins/siem/cypress/integration/cases.spec.ts index e11d76d8f608a..8f35a3209c69d 100644 --- a/x-pack/plugins/siem/cypress/integration/cases.spec.ts +++ b/x-pack/plugins/siem/cypress/integration/cases.spec.ts @@ -30,7 +30,6 @@ import { CASE_DETAILS_PUSH_TO_EXTERNAL_SERVICE_BTN, CASE_DETAILS_STATUS, CASE_DETAILS_TAGS, - CASE_DETAILS_TIMELINE_MARKDOWN, CASE_DETAILS_USER_ACTION, CASE_DETAILS_USERNAMES, PARTICIPANTS, @@ -103,13 +102,11 @@ describe('Cases', () => { .should('have.text', case1.reporter); cy.get(CASE_DETAILS_TAGS).should('have.text', expectedTags); cy.get(CASE_DETAILS_PUSH_TO_EXTERNAL_SERVICE_BTN).should('have.attr', 'disabled'); - cy.get(CASE_DETAILS_TIMELINE_MARKDOWN).then($element => { - const timelineLink = $element.prop('href').match(/http(s?):\/\/\w*:\w*(\S*)/)[0]; - openCaseTimeline(timelineLink); - cy.get(TIMELINE_TITLE).should('have.attr', 'value', case1.timeline.title); - cy.get(TIMELINE_DESCRIPTION).should('have.attr', 'value', case1.timeline.description); - cy.get(TIMELINE_QUERY).should('have.attr', 'value', case1.timeline.query); - }); + openCaseTimeline(); + + cy.get(TIMELINE_TITLE).should('have.attr', 'value', case1.timeline.title); + cy.get(TIMELINE_DESCRIPTION).should('have.attr', 'value', case1.timeline.description); + cy.get(TIMELINE_QUERY).should('have.attr', 'value', case1.timeline.query); }); }); diff --git a/x-pack/plugins/siem/cypress/screens/case_details.ts b/x-pack/plugins/siem/cypress/screens/case_details.ts index 32bb64e93b05f..f2cdaa6994356 100644 --- a/x-pack/plugins/siem/cypress/screens/case_details.ts +++ b/x-pack/plugins/siem/cypress/screens/case_details.ts @@ -17,7 +17,7 @@ export const CASE_DETAILS_STATUS = '[data-test-subj="case-view-status"]'; export const CASE_DETAILS_TAGS = '[data-test-subj="case-tags"]'; -export const CASE_DETAILS_TIMELINE_MARKDOWN = '[data-test-subj="markdown-link"]'; +export const CASE_DETAILS_TIMELINE_LINK_MARKDOWN = '[data-test-subj="markdown-timeline-link"]'; export const CASE_DETAILS_USER_ACTION = '[data-test-subj="user-action-title"] .euiFlexItem'; diff --git a/x-pack/plugins/siem/cypress/tasks/case_details.ts b/x-pack/plugins/siem/cypress/tasks/case_details.ts index a28f8b8010adb..976d568ab3a91 100644 --- a/x-pack/plugins/siem/cypress/tasks/case_details.ts +++ b/x-pack/plugins/siem/cypress/tasks/case_details.ts @@ -5,10 +5,9 @@ */ import { TIMELINE_TITLE } from '../screens/timeline'; +import { CASE_DETAILS_TIMELINE_LINK_MARKDOWN } from '../screens/case_details'; -export const openCaseTimeline = (link: string) => { - cy.visit('/app/kibana'); - cy.visit(link); - cy.contains('a', 'SIEM'); +export const openCaseTimeline = () => { + cy.get(CASE_DETAILS_TIMELINE_LINK_MARKDOWN).click(); cy.get(TIMELINE_TITLE).should('exist'); }; diff --git a/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.test.tsx b/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.test.tsx new file mode 100644 index 0000000000000..27438207bed97 --- /dev/null +++ b/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.test.tsx @@ -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. + */ + +import React from 'react'; +import { mount } from 'enzyme'; +import { Router, mockHistory } from '../__mock__/router'; +import { UserActionMarkdown } from './user_action_markdown'; +import { TestProviders } from '../../../common/mock'; +import * as timelineHelpers from '../../../timelines/components/open_timeline/helpers'; +import { useApolloClient } from '../../../common/utils/apollo_context'; +const mockUseApolloClient = useApolloClient as jest.Mock; +jest.mock('../../../common/utils/apollo_context'); +const onChangeEditable = jest.fn(); +const onSaveContent = jest.fn(); + +const timelineId = '1e10f150-949b-11ea-b63c-2bc51864784c'; +const defaultProps = { + content: `A link to a timeline [timeline](http://localhost:5601/app/siem#/timelines?timeline=(id:'${timelineId}',isOpen:!t))`, + id: 'markdown-id', + isEditable: false, + onChangeEditable, + onSaveContent, +}; + +describe('UserActionMarkdown ', () => { + const queryTimelineByIdSpy = jest.spyOn(timelineHelpers, 'queryTimelineById'); + beforeEach(() => { + mockUseApolloClient.mockClear(); + jest.resetAllMocks(); + }); + + it('Opens timeline when timeline link clicked - isEditable: false', async () => { + const wrapper = mount( + + + + + + ); + wrapper + .find(`[data-test-subj="markdown-timeline-link"]`) + .first() + .simulate('click'); + + expect(queryTimelineByIdSpy).toBeCalledWith({ + apolloClient: mockUseApolloClient(), + timelineId, + updateIsLoading: expect.any(Function), + updateTimeline: expect.any(Function), + }); + }); + + it('Opens timeline when timeline link clicked - isEditable: true ', async () => { + const wrapper = mount( + + + + + + ); + wrapper + .find(`[data-test-subj="preview-tab"]`) + .first() + .simulate('click'); + wrapper + .find(`[data-test-subj="markdown-timeline-link"]`) + .first() + .simulate('click'); + expect(queryTimelineByIdSpy).toBeCalledWith({ + apolloClient: mockUseApolloClient(), + timelineId, + updateIsLoading: expect.any(Function), + updateTimeline: expect.any(Function), + }); + }); +}); diff --git a/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.tsx b/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.tsx index 23d8d8f1a7e68..03dd599da88e5 100644 --- a/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.tsx +++ b/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.tsx @@ -8,6 +8,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiButtonEmpty, EuiButton } from '@elastic/e import React, { useCallback } from 'react'; import styled, { css } from 'styled-components'; +import { useDispatch } from 'react-redux'; import * as i18n from '../case_view/translations'; import { Markdown } from '../../../common/components/markdown'; import { Form, useForm, UseField } from '../../../shared_imports'; @@ -15,6 +16,13 @@ import { schema, Content } from './schema'; import { InsertTimelinePopover } from '../../../timelines/components/timeline/insert_timeline_popover'; import { useInsertTimeline } from '../../../timelines/components/timeline/insert_timeline_popover/use_insert_timeline'; import { MarkdownEditorForm } from '../../../common/components//markdown_editor/form'; +import { + dispatchUpdateTimeline, + queryTimelineById, +} from '../../../timelines/components/open_timeline/helpers'; + +import { updateIsLoading as dispatchUpdateIsLoading } from '../../../timelines/store/timeline/actions'; +import { useApolloClient } from '../../../common/utils/apollo_context'; const ContentWrapper = styled.div` ${({ theme }) => css` @@ -36,6 +44,8 @@ export const UserActionMarkdown = ({ onChangeEditable, onSaveContent, }: UserActionMarkdownProps) => { + const dispatch = useDispatch(); + const apolloClient = useApolloClient(); const { form } = useForm({ defaultValue: { content }, options: { stripEmptyFields: false }, @@ -49,6 +59,24 @@ export const UserActionMarkdown = ({ onChangeEditable(id); }, [id, onChangeEditable]); + const handleTimelineClick = useCallback( + (timelineId: string) => { + queryTimelineById({ + apolloClient, + timelineId, + updateIsLoading: ({ + id: currentTimelineId, + isLoading, + }: { + id: string; + isLoading: boolean; + }) => dispatch(dispatchUpdateIsLoading({ id: currentTimelineId, isLoading })), + updateTimeline: dispatchUpdateTimeline(dispatch), + }); + }, + [apolloClient] + ); + const handleSaveAction = useCallback(async () => { const { isValid, data } = await form.submit(); if (isValid) { @@ -98,6 +126,7 @@ export const UserActionMarkdown = ({ cancelAction: handleCancelAction, saveAction: handleSaveAction, }), + onClickTimeline: handleTimelineClick, onCursorPositionUpdate: handleCursorChange, topRightContent: ( ) : ( - + ); }; diff --git a/x-pack/plugins/siem/public/common/components/markdown/index.test.tsx b/x-pack/plugins/siem/public/common/components/markdown/index.test.tsx index 89af9202a597e..bbf59177bcf04 100644 --- a/x-pack/plugins/siem/public/common/components/markdown/index.test.tsx +++ b/x-pack/plugins/siem/public/common/components/markdown/index.test.tsx @@ -164,5 +164,37 @@ describe('Markdown', () => { expect(wrapper).toMatchSnapshot(); }); + + describe('markdown timeline links', () => { + const timelineId = '1e10f150-949b-11ea-b63c-2bc51864784c'; + const markdownWithTimelineLink = `A link to a timeline [timeline](http://localhost:5601/app/siem#/timelines?timeline=(id:'${timelineId}',isOpen:!t))`; + const onClickTimeline = jest.fn(); + beforeEach(() => { + jest.resetAllMocks(); + }); + test('it renders a timeline link without href when provided the onClickTimeline argument', () => { + const wrapper = mount( + + ); + + expect( + wrapper + .find('[data-test-subj="markdown-timeline-link"]') + .first() + .getDOMNode() + ).not.toHaveProperty('href'); + }); + test('timeline link onClick calls onClickTimeline with timelineId', () => { + const wrapper = mount( + + ); + wrapper + .find('[data-test-subj="markdown-timeline-link"]') + .first() + .simulate('click'); + + expect(onClickTimeline).toHaveBeenCalledWith(timelineId); + }); + }); }); }); diff --git a/x-pack/plugins/siem/public/common/components/markdown/index.tsx b/x-pack/plugins/siem/public/common/components/markdown/index.tsx index 8e051685af56d..1a4c9cb71a77e 100644 --- a/x-pack/plugins/siem/public/common/components/markdown/index.tsx +++ b/x-pack/plugins/siem/public/common/components/markdown/index.tsx @@ -10,6 +10,7 @@ import { EuiLink, EuiTableRow, EuiTableRowCell, EuiText, EuiToolTip } from '@ela import React from 'react'; import ReactMarkdown from 'react-markdown'; import styled, { css } from 'styled-components'; +import * as i18n from './translations'; const TableHeader = styled.thead` font-weight: bold; @@ -37,8 +38,9 @@ const REL_NOREFERRER = 'noreferrer'; export const Markdown = React.memo<{ disableLinks?: boolean; raw?: string; + onClickTimeline?: (timelineId: string) => void; size?: 'xs' | 's' | 'm'; -}>(({ disableLinks = false, raw, size = 's' }) => { +}>(({ disableLinks = false, onClickTimeline, raw, size = 's' }) => { const markdownRenderers = { root: ({ children }: { children: React.ReactNode[] }) => ( @@ -59,18 +61,33 @@ export const Markdown = React.memo<{ tableCell: ({ children }: { children: React.ReactNode[] }) => ( {children} ), - link: ({ children, href }: { children: React.ReactNode[]; href?: string }) => ( - - - {children} - - - ), + link: ({ children, href }: { children: React.ReactNode[]; href?: string }) => { + if (onClickTimeline != null && href != null && href.indexOf(`timelines?timeline=(id:`) > -1) { + const timelineId = href.split('timelines?timeline=(id:')[1].split("'")[1] ?? ''; + return ( + + onClickTimeline(timelineId)} + data-test-subj="markdown-timeline-link" + > + {children} + + + ); + } + return ( + + + {children} + + + ); + }, blockquote: ({ children }: { children: React.ReactNode[] }) => ( {children} ), diff --git a/x-pack/plugins/siem/public/common/components/markdown/translations.ts b/x-pack/plugins/siem/public/common/components/markdown/translations.ts index cfd9e9ef1b106..4524d27739ea8 100644 --- a/x-pack/plugins/siem/public/common/components/markdown/translations.ts +++ b/x-pack/plugins/siem/public/common/components/markdown/translations.ts @@ -51,3 +51,11 @@ export const MARKDOWN_HINT_STRIKETHROUGH = i18n.translate( export const MARKDOWN_HINT_IMAGE_URL = i18n.translate('xpack.siem.markdown.hint.imageUrlLabel', { defaultMessage: '![image](url)', }); + +export const TIMELINE_ID = (timelineId: string) => + i18n.translate('xpack.siem.markdown.toolTip.timelineId', { + defaultMessage: 'Timeline id: { timelineId }', + values: { + timelineId, + }, + }); diff --git a/x-pack/plugins/siem/public/common/components/markdown_editor/form.tsx b/x-pack/plugins/siem/public/common/components/markdown_editor/form.tsx index 2ed85b04fe3f6..f9efbc5705b92 100644 --- a/x-pack/plugins/siem/public/common/components/markdown_editor/form.tsx +++ b/x-pack/plugins/siem/public/common/components/markdown_editor/form.tsx @@ -16,6 +16,7 @@ interface IMarkdownEditorForm { field: FieldHook; idAria: string; isDisabled: boolean; + onClickTimeline?: (timelineId: string) => void; onCursorPositionUpdate?: (cursorPosition: CursorPosition) => void; placeholder?: string; topRightContent?: React.ReactNode; @@ -26,6 +27,7 @@ export const MarkdownEditorForm = ({ field, idAria, isDisabled = false, + onClickTimeline, onCursorPositionUpdate, placeholder, topRightContent, @@ -55,6 +57,7 @@ export const MarkdownEditorForm = ({ content={field.value as string} isDisabled={isDisabled} onChange={handleContentChange} + onClickTimeline={onClickTimeline} onCursorPositionUpdate={onCursorPositionUpdate} placeholder={placeholder} topRightContent={topRightContent} diff --git a/x-pack/plugins/siem/public/common/components/markdown_editor/index.tsx b/x-pack/plugins/siem/public/common/components/markdown_editor/index.tsx index 4fb7086e82b28..b0df2b6b5b60f 100644 --- a/x-pack/plugins/siem/public/common/components/markdown_editor/index.tsx +++ b/x-pack/plugins/siem/public/common/components/markdown_editor/index.tsx @@ -74,6 +74,7 @@ export const MarkdownEditor = React.memo<{ content: string; isDisabled?: boolean; onChange: (description: string) => void; + onClickTimeline?: (timelineId: string) => void; onCursorPositionUpdate?: (cursorPosition: CursorPosition) => void; placeholder?: string; }>( @@ -83,6 +84,7 @@ export const MarkdownEditor = React.memo<{ content, isDisabled = false, onChange, + onClickTimeline, placeholder, onCursorPositionUpdate, }) => { @@ -125,9 +127,10 @@ export const MarkdownEditor = React.memo<{ { id: 'preview', name: i18n.PREVIEW, + 'data-test-subj': 'preview-tab', content: ( - + ), }, diff --git a/x-pack/plugins/siem/public/timelines/components/open_timeline/helpers.ts b/x-pack/plugins/siem/public/timelines/components/open_timeline/helpers.ts index df433f147490e..30a88c58afff8 100644 --- a/x-pack/plugins/siem/public/timelines/components/open_timeline/helpers.ts +++ b/x-pack/plugins/siem/public/timelines/components/open_timeline/helpers.ts @@ -189,7 +189,7 @@ export const formatTimelineResultToModel = ( export interface QueryTimelineById { apolloClient: ApolloClient | ApolloClient<{}> | undefined; - duplicate: boolean; + duplicate?: boolean; timelineId: string; onOpenTimeline?: (timeline: TimelineModel) => void; openTimeline?: boolean; From 1b1a0f430c96d240b0a7f7e1303206aec37f0fbd Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Mon, 18 May 2020 17:33:38 -0400 Subject: [PATCH 012/129] Resolver: Display node 75% view submenus (#64121) --- .../plugins/endpoint/common/models/event.ts | 21 +- .../embeddables/resolver/store/actions.ts | 36 ++- .../embeddables/resolver/store/data/action.ts | 23 +- .../resolver/store/data/reducer.ts | 21 ++ .../resolver/store/data/selectors.test.ts | 59 ++++ .../resolver/store/data/selectors.ts | 82 ++++++ .../embeddables/resolver/store/middleware.ts | 69 ++++- .../embeddables/resolver/store/selectors.ts | 5 + .../public/embeddables/resolver/types.ts | 48 ++++ .../embeddables/resolver/view/index.tsx | 3 +- .../resolver/view/process_event_dot.tsx | 272 +++++++++++++++--- .../embeddables/resolver/view/submenu.tsx | 178 ++++++++++++ 12 files changed, 768 insertions(+), 49 deletions(-) create mode 100644 x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.test.ts create mode 100644 x-pack/plugins/endpoint/public/embeddables/resolver/view/submenu.tsx diff --git a/x-pack/plugins/endpoint/common/models/event.ts b/x-pack/plugins/endpoint/common/models/event.ts index 47f39d2d11797..192daba4a717d 100644 --- a/x-pack/plugins/endpoint/common/models/event.ts +++ b/x-pack/plugins/endpoint/common/models/event.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - import { LegacyEndpointEvent, ResolverEvent } from '../types'; export function isLegacyEvent(event: ResolverEvent): event is LegacyEndpointEvent { @@ -46,3 +45,23 @@ export function parentEntityId(event: ResolverEvent): string | undefined { } return event.process.parent?.entity_id; } + +export function eventType(event: ResolverEvent): string { + // Returning "Process" as a catch-all here because it seems pretty general + let eventCategoryToReturn: string = 'Process'; + if (isLegacyEvent(event)) { + const legacyFullType = event.endgame.event_type_full; + if (legacyFullType) { + return legacyFullType; + } + } else { + const eventCategories = event.event.category; + const eventCategory = + typeof eventCategories === 'string' ? eventCategories : eventCategories[0] || ''; + + if (eventCategory) { + eventCategoryToReturn = eventCategory; + } + } + return eventCategoryToReturn; +} diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/actions.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/actions.ts index a26f43e1f8cc0..462f6e251d5d0 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/actions.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/actions.ts @@ -44,6 +44,15 @@ interface AppRequestedResolverData { readonly type: 'appRequestedResolverData'; } +/** + * The action dispatched when the app requests related event data for one or more + * subjects (whose ids should be included as an array @ `payload`) + */ +interface UserRequestedRelatedEventData { + readonly type: 'userRequestedRelatedEventData'; + readonly payload: ResolverEvent; +} + /** * When the user switches the "active descendant" of the Resolver. * The "active descendant" (from the point of view of the parent element) @@ -77,6 +86,28 @@ interface UserSelectedResolverNode { }; } +/** + * This action should dispatch to indicate that the user chose to + * focus on examining the related events of a particular ResolverEvent. + * Optionally, this can be bound by a category of related events (e.g. 'file' or 'dns') + */ +interface UserSelectedRelatedEventCategory { + readonly type: 'userSelectedRelatedEventCategory'; + readonly payload: { + subject: ResolverEvent; + category?: string; + }; +} + +/** + * This action should dispatch to indicate that the user chose to focus + * on examining alerts related to a particular ResolverEvent + */ +interface UserSelectedRelatedAlerts { + readonly type: 'userSelectedRelatedAlerts'; + readonly payload: ResolverEvent; +} + export type ResolverAction = | CameraAction | DataAction @@ -84,4 +115,7 @@ export type ResolverAction = | UserChangedSelectedEvent | AppRequestedResolverData | UserFocusedOnResolverNode - | UserSelectedResolverNode; + | UserSelectedResolverNode + | UserRequestedRelatedEventData + | UserSelectedRelatedEventCategory + | UserSelectedRelatedAlerts; diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/action.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/action.ts index 3ec15f2f1985d..8c84d8f82b874 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/action.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/action.ts @@ -5,6 +5,7 @@ */ import { ResolverEvent } from '../../../../../common/types'; +import { RelatedEventDataEntry } from '../../types'; interface ServerReturnedResolverData { readonly type: 'serverReturnedResolverData'; @@ -15,4 +16,24 @@ interface ServerFailedToReturnResolverData { readonly type: 'serverFailedToReturnResolverData'; } -export type DataAction = ServerReturnedResolverData | ServerFailedToReturnResolverData; +/** + * Will occur when a request for related event data is fulfilled by the API. + */ +interface ServerReturnedRelatedEventData { + readonly type: 'serverReturnedRelatedEventData'; + readonly payload: Map; +} + +/** + * Will occur when a request for related event data is unsuccessful. + */ +interface ServerFailedToReturnRelatedEventData { + readonly type: 'serverFailedToReturnRelatedEventData'; + readonly payload: ResolverEvent; +} + +export type DataAction = + | ServerReturnedResolverData + | ServerFailedToReturnResolverData + | ServerReturnedRelatedEventData + | ServerFailedToReturnRelatedEventData; diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/reducer.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/reducer.ts index fc307002819a9..9dd6bcdf385ae 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/reducer.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/reducer.ts @@ -12,6 +12,7 @@ function initialState(): DataState { results: [], isLoading: false, hasError: false, + resultsEnrichedWithRelatedEventInfo: new Map(), }; } @@ -23,6 +24,26 @@ export const dataReducer: Reducer = (state = initialS isLoading: false, hasError: false, }; + } else if (action.type === 'userRequestedRelatedEventData') { + const resolverEvent = action.payload; + const currentStatsMap = new Map(state.resultsEnrichedWithRelatedEventInfo); + /** + * Set the waiting indicator for this event to indicate that related event results are pending. + * It will be replaced by the actual results from the API when they are returned. + */ + currentStatsMap.set(resolverEvent, 'waitingForRelatedEventData'); + return { ...state, resultsEnrichedWithRelatedEventInfo: currentStatsMap }; + } else if (action.type === 'serverFailedToReturnRelatedEventData') { + const currentStatsMap = new Map(state.resultsEnrichedWithRelatedEventInfo); + const resolverEvent = action.payload; + currentStatsMap.set(resolverEvent, 'error'); + return { ...state, resultsEnrichedWithRelatedEventInfo: currentStatsMap }; + } else if (action.type === 'serverReturnedRelatedEventData') { + const relatedDataEntries = new Map([ + ...state.resultsEnrichedWithRelatedEventInfo, + ...action.payload, + ]); + return { ...state, resultsEnrichedWithRelatedEventInfo: relatedDataEntries }; } else if (action.type === 'appRequestedResolverData') { return { ...state, diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.test.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.test.ts new file mode 100644 index 0000000000000..561b0da12bcb1 --- /dev/null +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.test.ts @@ -0,0 +1,59 @@ +/* + * 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 { Store, createStore } from 'redux'; +import { DataAction } from './action'; +import { dataReducer } from './reducer'; +import { + DataState, + RelatedEventDataEntry, + RelatedEventDataEntryWithStats, + RelatedEventData, +} from '../../types'; +import { ResolverEvent } from '../../../../../common/types'; +import { relatedEventStats, relatedEvents } from './selectors'; + +describe('resolver data selectors', () => { + const store: Store = createStore(dataReducer, undefined); + describe('when related event data is reduced into state with no results', () => { + let relatedEventInfoBeforeAction: RelatedEventData; + beforeEach(() => { + relatedEventInfoBeforeAction = new Map(relatedEvents(store.getState()) || []); + const payload: Map = new Map(); + const action: DataAction = { type: 'serverReturnedRelatedEventData', payload }; + store.dispatch(action); + }); + it('should have the same related info as before the action', () => { + const relatedInfoAfterAction = relatedEvents(store.getState()); + expect(relatedInfoAfterAction).toEqual(relatedEventInfoBeforeAction); + }); + }); + describe('when related event data is reduced into state with 2 dns results', () => { + let mockBaseEvent: ResolverEvent; + beforeEach(() => { + mockBaseEvent = {} as ResolverEvent; + function dnsRelatedEventEntry() { + const fakeEvent = {} as ResolverEvent; + return { relatedEvent: fakeEvent, relatedEventType: 'dns' }; + } + const payload: Map = new Map([ + [ + mockBaseEvent, + { + relatedEvents: [dnsRelatedEventEntry(), dnsRelatedEventEntry()], + }, + ], + ]); + const action: DataAction = { type: 'serverReturnedRelatedEventData', payload }; + store.dispatch(action); + }); + it('should compile stats reflecting a count of 2 for dns', () => { + const actualStats = relatedEventStats(store.getState()); + const statsForFakeEvent = actualStats.get(mockBaseEvent)! as RelatedEventDataEntryWithStats; + expect(statsForFakeEvent.stats).toEqual({ dns: 2 }); + }); + }); +}); diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.ts index 59ee4b3b87505..413f4db1cc99e 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.ts @@ -14,6 +14,8 @@ import { ProcessWithWidthMetadata, Matrix3, AdjacentProcessMap, + RelatedEventData, + RelatedEventDataEntryWithStats, } from '../../types'; import { ResolverEvent } from '../../../../../common/types'; import { Vector2 } from '../../types'; @@ -405,6 +407,86 @@ export const indexedProcessTree = createSelector(graphableProcesses, function in return indexedProcessTreeFactory(graphableProcesses); }); +/** + * Process events that will be graphed. + */ +export const relatedEventResults = function(data: DataState) { + return data.resultsEnrichedWithRelatedEventInfo; +}; + +/** + * This selector compiles the related event data attached in `relatedEventResults` + * into a `RelatedEventData` map of ResolverEvents to statistics about their related events + */ +export const relatedEventStats = createSelector(relatedEventResults, function getRelatedEvents( + /* eslint-disable no-shadow */ + relatedEventResults + /* eslint-enable no-shadow */ +) { + /* eslint-disable no-shadow */ + const relatedEventStats: RelatedEventData = new Map(); + /* eslint-enable no-shadow */ + if (!relatedEventResults) { + return relatedEventStats; + } + + for (const updatedEvent of relatedEventResults.keys()) { + const newStatsEntry = relatedEventResults.get(updatedEvent); + if (newStatsEntry === 'error') { + // If the entry is an error, return it as is + relatedEventStats.set(updatedEvent, newStatsEntry); + continue; + } + if (typeof newStatsEntry === 'object') { + /** + * Otherwise, it should be a valid stats entry. + * Do the work to compile the stats. + * Folowing reduction, this will be a record like + * {DNS: 10, File: 2} etc. + */ + const statsForEntry = newStatsEntry?.relatedEvents.reduce( + (compiledStats: Record, relatedEvent: { relatedEventType: string }) => { + compiledStats[relatedEvent.relatedEventType] = + (compiledStats[relatedEvent.relatedEventType] || 0) + 1; + return compiledStats; + }, + {} + ); + + const newRelatedEventStats: RelatedEventDataEntryWithStats = Object.assign(newStatsEntry, { + stats: statsForEntry, + }); + relatedEventStats.set(updatedEvent, newRelatedEventStats); + } + } + return relatedEventStats; +}); + +/** + * This selects `RelatedEventData` maps specifically for graphable processes + */ +export const relatedEvents = createSelector( + graphableProcesses, + relatedEventStats, + function getRelatedEvents( + /* eslint-disable no-shadow */ + graphableProcesses, + relatedEventStats + /* eslint-enable no-shadow */ + ) { + const eventsRelatedByProcess: RelatedEventData = new Map(); + /* eslint-disable no-shadow */ + return graphableProcesses.reduce((relatedEvents, graphableProcess) => { + /* eslint-enable no-shadow */ + const relatedEventDataEntry = relatedEventStats?.get(graphableProcess); + if (relatedEventDataEntry) { + relatedEvents.set(graphableProcess, relatedEventDataEntry); + } + return relatedEvents; + }, eventsRelatedByProcess); + } +); + export const processAdjacencies = createSelector( indexedProcessTree, graphableProcesses, diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/middleware.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/middleware.ts index c7177c6387e7a..06758022b05c5 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/middleware.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/middleware.ts @@ -5,9 +5,10 @@ */ import { Dispatch, MiddlewareAPI } from 'redux'; +import { HttpHandler } from 'kibana/public'; import { KibanaReactContextValue } from '../../../../../../../src/plugins/kibana_react/public'; import { EndpointPluginServices } from '../../../plugin'; -import { ResolverState, ResolverAction } from '../types'; +import { ResolverState, ResolverAction, RelatedEventDataEntry } from '../types'; import { ResolverEvent, ResolverNode } from '../../../../common/types'; import * as event from '../../../../common/models/event'; @@ -30,6 +31,33 @@ function flattenEvents(children: ResolverNode[], events: ResolverEvent[] = []): }, events); } +type RelatedEventAPIResponse = 'error' | { events: ResolverEvent[] }; +/** + * As the design goal of this stopgap was to prevent saturating the server with /events + * requests, this generator intentionally processes events in serial rather than in parallel. + * @param eventsToFetch + * events to run against the /id/events API + * @param httpGetter + * the HttpHandler to use + */ +async function* getEachRelatedEventsResult( + eventsToFetch: ResolverEvent[], + httpGetter: HttpHandler +): AsyncGenerator<[ResolverEvent, RelatedEventAPIResponse]> { + for (const eventToQueryForRelateds of eventsToFetch) { + const id = event.entityId(eventToQueryForRelateds); + let result: RelatedEventAPIResponse; + try { + result = await httpGetter(`/api/endpoint/resolver/${id}/events`, { + query: { events: 100 }, + }); + } catch (e) { + result = 'error'; + } + yield [eventToQueryForRelateds, result]; + } +} + export const resolverMiddlewareFactory: MiddlewareFactory = context => { return api => next => async (action: ResolverAction) => { next(action); @@ -78,5 +106,44 @@ export const resolverMiddlewareFactory: MiddlewareFactory = context => { } } } + + if (action.type === 'userRequestedRelatedEventData') { + if (typeof context !== 'undefined') { + const response: Map = new Map(); + for await (const results of getEachRelatedEventsResult( + [action.payload], + context.services.http.get + )) { + /** + * results here will take the shape of + * [event requested , response of event against the /related api] + */ + const [baseEvent, apiResults] = results; + if (apiResults === 'error') { + api.dispatch({ + type: 'serverFailedToReturnRelatedEventData', + payload: results[0], + }); + continue; + } + + const fetchedResults = apiResults.events; + // pack up the results into response + const relatedEventEntry = fetchedResults.map(relatedEvent => { + return { + relatedEvent, + relatedEventType: event.eventType(relatedEvent), + }; + }); + + response.set(baseEvent, { relatedEvents: relatedEventEntry }); + } + + api.dispatch({ + type: 'serverReturnedRelatedEventData', + payload: response, + }); + } + } }; }; diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/selectors.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/selectors.ts index 7d09d90881da9..493c23621a6cf 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/selectors.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/selectors.ts @@ -60,6 +60,11 @@ export const processAdjacencies = composeSelectors( dataSelectors.processAdjacencies ); +/** + * Returns a map of `ResolverEvent`s to their related `ResolverEvent`s + */ +export const relatedEvents = composeSelectors(dataStateSelector, dataSelectors.relatedEvents); + /** * Returns the id of the "current" tree node (fake-focused) */ diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/types.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/types.ts index 17aa598720c59..32fefba8f0f20 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/types.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/types.ts @@ -9,6 +9,7 @@ import { Store } from 'redux'; import { ResolverAction } from './store/actions'; export { ResolverAction } from './store/actions'; import { ResolverEvent } from '../../../common/types'; +import { eventType } from '../../../common/models/event'; /** * Redux state for the Resolver feature. Properties on this interface are populated via multiple reducers using redux's `combineReducers`. @@ -130,6 +131,52 @@ export type CameraState = { } ); +/** + * This represents all the raw data (sans statistics, metadata, etc.) + * about a particular subject's related events + */ +export interface RelatedEventDataEntry { + relatedEvents: Array<{ + relatedEvent: ResolverEvent; + relatedEventType: ReturnType; + }>; +} + +/** + * Represents the status of the request for related event data, which will be either the data, + * a value indicating that it's still waiting for the data or an Error indicating the data can't be retrieved as expected + */ +export type RelatedEventDataResults = + | RelatedEventDataEntry + | 'waitingForRelatedEventData' + | 'error'; + +/** + * This represents the raw related events data enhanced with statistics + * (e.g. counts of items grouped by their related event types) + */ +export type RelatedEventDataEntryWithStats = RelatedEventDataEntry & { + stats: Record; +}; + +/** + * The status or value of any particular event's related events w.r.t. their valence to the current view. + * One of: + * `RelatedEventDataEntryWithStats` when results have been received and processed and are ready to display + * `waitingForRelatedEventData` when related events have been requested but have not yet matriculated + * `Error` when the request for any event encounters an error during service + */ +export type RelatedEventEntryWithStatsOrWaiting = + | RelatedEventDataEntryWithStats + | `waitingForRelatedEventData` + | 'error'; + +/** + * This represents a Map that will return either a `RelatedEventDataEntryWithStats` + * or a `waitingForRelatedEventData` symbol when referenced with a unique event. + */ +export type RelatedEventData = Map; + /** * State for `data` reducer which handles receiving Resolver data from the backend. */ @@ -137,6 +184,7 @@ export interface DataState { readonly results: readonly ResolverEvent[]; isLoading: boolean; hasError: boolean; + resultsEnrichedWithRelatedEventInfo: Map; } export type Vector2 = readonly [number, number]; diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/index.tsx b/x-pack/plugins/endpoint/public/embeddables/resolver/view/index.tsx index 2e7ca65c92dc1..5275ba3ec5b4c 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/view/index.tsx +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/view/index.tsx @@ -57,7 +57,7 @@ export const Resolver = styled( const dispatch: (action: ResolverAction) => unknown = useDispatch(); const { processToAdjacencyMap } = useSelector(selectors.processAdjacencies); - + const relatedEvents = useSelector(selectors.relatedEvents); const { projectionMatrix, ref, onMouseDown } = useCamera(); const isLoading = useSelector(selectors.isLoading); const hasError = useSelector(selectors.hasError); @@ -116,6 +116,7 @@ export const Resolver = styled( projectionMatrix={projectionMatrix} event={processEvent} adjacentNodeMap={adjacentNodeMap} + relatedEvents={relatedEvents.get(processEvent)} /> ); })} diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/process_event_dot.tsx b/x-pack/plugins/endpoint/public/embeddables/resolver/view/process_event_dot.tsx index 27844f09e2272..32928d511a1f9 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/view/process_event_dot.tsx +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/view/process_event_dot.tsx @@ -9,14 +9,21 @@ import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; import { htmlIdGenerator, + EuiI18nNumber, EuiKeyboardAccessible, - EuiButton, EuiFlexGroup, EuiFlexItem, } from '@elastic/eui'; import { useSelector } from 'react-redux'; +import { NodeSubMenu, subMenuAssets } from './submenu'; import { applyMatrix3 } from '../lib/vector2'; -import { Vector2, Matrix3, AdjacentProcessMap, ResolverProcessType } from '../types'; +import { + Vector2, + Matrix3, + AdjacentProcessMap, + ResolverProcessType, + RelatedEventEntryWithStatsOrWaiting, +} from '../types'; import { SymbolIds, NamedColors } from './defs'; import { ResolverEvent } from '../../../../common/types'; import { useResolverDispatch } from './use_resolver_dispatch'; @@ -59,46 +66,129 @@ const nodeAssets = { }, }; -const ChildEventsButton = React.memo(() => { - return ( - ) => { - clickEvent.preventDefault(); - clickEvent.stopPropagation(); - }, [])} - color="ghost" - size="s" - iconType="arrowDown" - iconSide="right" - tabIndex={-1} - > - {i18n.translate('xpack.endpoint.resolver.relatedEvents', { - defaultMessage: 'Events', - })} - - ); -}); - -const RelatedAlertsButton = React.memo(() => { +/** + * Take a gross `schemaName` and return a beautiful translated one. + */ +const getDisplayName: (schemaName: string) => string = function nameInSchemaToDisplayName( + schemaName: string +) { + const displayNameRecord: Record = { + application: i18n.translate('xpack.endpoint.resolver.applicationEventTypeDisplayName', { + defaultMessage: 'Application', + }), + apm: i18n.translate('xpack.endpoint.resolver.apmEventTypeDisplayName', { + defaultMessage: 'APM', + }), + audit: i18n.translate('xpack.endpoint.resolver.auditEventTypeDisplayName', { + defaultMessage: 'Audit', + }), + authentication: i18n.translate('xpack.endpoint.resolver.authenticationEventTypeDisplayName', { + defaultMessage: 'Authentication', + }), + certificate: i18n.translate('xpack.endpoint.resolver.certificateEventTypeDisplayName', { + defaultMessage: 'Certificate', + }), + cloud: i18n.translate('xpack.endpoint.resolver.cloudEventTypeDisplayName', { + defaultMessage: 'Cloud', + }), + database: i18n.translate('xpack.endpoint.resolver.databaseEventTypeDisplayName', { + defaultMessage: 'Database', + }), + driver: i18n.translate('xpack.endpoint.resolver.driverEventTypeDisplayName', { + defaultMessage: 'Driver', + }), + email: i18n.translate('xpack.endpoint.resolver.emailEventTypeDisplayName', { + defaultMessage: 'Email', + }), + file: i18n.translate('xpack.endpoint.resolver.fileEventTypeDisplayName', { + defaultMessage: 'File', + }), + host: i18n.translate('xpack.endpoint.resolver.hostEventTypeDisplayName', { + defaultMessage: 'Host', + }), + iam: i18n.translate('xpack.endpoint.resolver.iamEventTypeDisplayName', { + defaultMessage: 'IAM', + }), + iam_group: i18n.translate('xpack.endpoint.resolver.iam_groupEventTypeDisplayName', { + defaultMessage: 'IAM Group', + }), + intrusion_detection: i18n.translate( + 'xpack.endpoint.resolver.intrusion_detectionEventTypeDisplayName', + { + defaultMessage: 'Intrusion Detection', + } + ), + malware: i18n.translate('xpack.endpoint.resolver.malwareEventTypeDisplayName', { + defaultMessage: 'Malware', + }), + network_flow: i18n.translate('xpack.endpoint.resolver.network_flowEventTypeDisplayName', { + defaultMessage: 'Network Flow', + }), + network: i18n.translate('xpack.endpoint.resolver.networkEventTypeDisplayName', { + defaultMessage: 'Network', + }), + package: i18n.translate('xpack.endpoint.resolver.packageEventTypeDisplayName', { + defaultMessage: 'Package', + }), + process: i18n.translate('xpack.endpoint.resolver.processEventTypeDisplayName', { + defaultMessage: 'Process', + }), + registry: i18n.translate('xpack.endpoint.resolver.registryEventTypeDisplayName', { + defaultMessage: 'Registry', + }), + session: i18n.translate('xpack.endpoint.resolver.sessionEventTypeDisplayName', { + defaultMessage: 'Session', + }), + service: i18n.translate('xpack.endpoint.resolver.serviceEventTypeDisplayName', { + defaultMessage: 'Service', + }), + socket: i18n.translate('xpack.endpoint.resolver.socketEventTypeDisplayName', { + defaultMessage: 'Socket', + }), + vulnerability: i18n.translate('xpack.endpoint.resolver.vulnerabilityEventTypeDisplayName', { + defaultMessage: 'Vulnerability', + }), + web: i18n.translate('xpack.endpoint.resolver.webEventTypeDisplayName', { + defaultMessage: 'Web', + }), + alert: i18n.translate('xpack.endpoint.resolver.alertEventTypeDisplayName', { + defaultMessage: 'Alert', + }), + security: i18n.translate('xpack.endpoint.resolver.securityEventTypeDisplayName', { + defaultMessage: 'Security', + }), + dns: i18n.translate('xpack.endpoint.resolver.dnsEventTypeDisplayName', { + defaultMessage: 'DNS', + }), + clr: i18n.translate('xpack.endpoint.resolver.clrEventTypeDisplayName', { + defaultMessage: 'CLR', + }), + image_load: i18n.translate('xpack.endpoint.resolver.image_loadEventTypeDisplayName', { + defaultMessage: 'Image Load', + }), + powershell: i18n.translate('xpack.endpoint.resolver.powershellEventTypeDisplayName', { + defaultMessage: 'Powershell', + }), + wmi: i18n.translate('xpack.endpoint.resolver.wmiEventTypeDisplayName', { + defaultMessage: 'WMI', + }), + api: i18n.translate('xpack.endpoint.resolver.apiEventTypeDisplayName', { + defaultMessage: 'API', + }), + user: i18n.translate('xpack.endpoint.resolver.userEventTypeDisplayName', { + defaultMessage: 'User', + }), + }; return ( - ) => { - clickEvent.preventDefault(); - clickEvent.stopPropagation(); - }, [])} - color="ghost" - size="s" - tabIndex={-1} - > - {i18n.translate('xpack.endpoint.resolver.relatedAlerts', { - defaultMessage: 'Related Alerts', - })} - + displayNameRecord[schemaName] || + i18n.translate('xpack.endpoint.resolver.userEventTypeDisplayUnknown', { + defaultMessage: 'Unknown', + }) ); -}); +}; /** - * An artefact that represents a process node. + * An artifact that represents a process node and the things associated with it in the Resolver */ export const ProcessEventDot = styled( React.memo( @@ -108,6 +198,7 @@ export const ProcessEventDot = styled( event, projectionMatrix, adjacentNodeMap, + relatedEvents, }: { /** * A `className` string provided by `styled` @@ -129,6 +220,11 @@ export const ProcessEventDot = styled( * map of what nodes are "adjacent" to this one in "up, down, previous, next" directions */ adjacentNodeMap: AdjacentProcessMap; + /** + * A collection of events related to the current node and statistics (e.g. counts indexed by event type) + * to provide the user some visibility regarding the contents thereof. + */ + relatedEvents?: RelatedEventEntryWithStatsOrWaiting; }) => { /** * Convert the position, which is in 'world' coordinates, to screen coordinates. @@ -203,7 +299,6 @@ export const ProcessEventDot = styled( ]); const labelId = useMemo(() => resolverNodeIdGenerator(), [resolverNodeIdGenerator]); const descriptionId = useMemo(() => resolverNodeIdGenerator(), [resolverNodeIdGenerator]); - const isActiveDescendant = nodeId === activeDescendantId; const isSelectedDescendant = nodeId === selectedDescendantId; @@ -230,6 +325,70 @@ export const ProcessEventDot = styled( }); }, [animationTarget, dispatch, nodeId]); + const handleRelatedEventRequest = useCallback(() => { + dispatch({ + type: 'userRequestedRelatedEventData', + payload: event, + }); + }, [dispatch, event]); + + const handleRelatedAlertsRequest = useCallback(() => { + dispatch({ + type: 'userSelectedRelatedAlerts', + payload: event, + }); + }, [dispatch, event]); + /** + * Enumerates the stats for related events to display with the node as options, + * generally in the form `number of related events in category` `category title` + * e.g. "10 DNS", "230 File" + */ + const relatedEventOptions = useMemo(() => { + if (relatedEvents === 'error') { + // Return an empty set of options if there was an error requesting them + return []; + } + const relatedStats = typeof relatedEvents === 'object' && relatedEvents.stats; + if (!relatedStats) { + // Return an empty set of options if there are no stats to report + return []; + } + // If we have entries to show, map them into options to display in the selectable list + return Object.entries(relatedStats).map(statsEntry => { + const displayName = getDisplayName(statsEntry[0]); + return { + prefix: , + optionTitle: `${displayName}`, + action: () => { + dispatch({ + type: 'userSelectedRelatedEventCategory', + payload: { + subject: event, + category: statsEntry[0], + }, + }); + }, + }; + }); + }, [relatedEvents, dispatch, event]); + + const relatedEventStatusOrOptions = (() => { + if (!relatedEvents) { + // If related events have not yet been requested + return subMenuAssets.initialMenuStatus; + } + if (relatedEvents === 'error') { + // If there was an error when we tried to request the events + return subMenuAssets.menuError; + } + if (relatedEvents === 'waitingForRelatedEventData') { + // If we're waiting for events to be returned + // Pass on the waiting symbol + return relatedEvents; + } + return relatedEventOptions; + })(); + /* eslint-disable jsx-a11y/click-events-have-key-events */ /** * Key event handling (e.g. 'Enter'/'Space') is provisioned by the `EuiKeyboardAccessible` component @@ -359,11 +518,18 @@ export const ProcessEventDot = styled( {magFactorX >= 2 && ( - - + + - + )} @@ -383,9 +549,10 @@ export const ProcessEventDot = styled( border-radius: 10%; white-space: nowrap; will-change: left, top, width, height; - contain: strict; + contain: layout; min-width: 280px; min-height: 90px; + overflow-y: visible; //dasharray & dashoffset should be equal to "pull" the stroke back //when it is transitioned. @@ -400,10 +567,27 @@ export const ProcessEventDot = styled( transition-duration: 1s; stroke-dashoffset: 0; } + + & .related-dropdown { + width: 4.5em; + } + & .euiSelectableList-bordered { + border-top-right-radius: 0px; + border-top-left-radius: 0px; + } + & .euiSelectableListItem { + background-color: black; + } + & .euiSelectableListItem path { + fill: white; + } + & .euiSelectableListItem__text { + color: white; + } `; const processTypeToCube: Record = { - processCreated: 'terminatedProcessCube', + processCreated: 'runningProcessCube', processRan: 'runningProcessCube', processTerminated: 'terminatedProcessCube', unknownProcessEvent: 'runningProcessCube', diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/submenu.tsx b/x-pack/plugins/endpoint/public/embeddables/resolver/view/submenu.tsx new file mode 100644 index 0000000000000..9f6427d801ce4 --- /dev/null +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/view/submenu.tsx @@ -0,0 +1,178 @@ +/* + * 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'; +import React, { ReactNode, useState, useMemo, useCallback } from 'react'; +import { EuiSelectable, EuiButton } from '@elastic/eui'; +import styled from 'styled-components'; + +/** + * i18n-translated titles for submenus and identifiers for display of states: + * initialMenuStatus: submenu before it has been opened / requested data + * menuError: if the submenu requested data, but received an error + */ +export const subMenuAssets = { + initialMenuStatus: i18n.translate('xpack.endpoint.resolver.relatedNotRetrieved', { + defaultMessage: 'Related Events have not yet been retrieved.', + }), + menuError: i18n.translate('xpack.endpoint.resolver.relatedRetrievalError', { + defaultMessage: 'There was an error retrieving related events.', + }), + relatedAlerts: { + title: i18n.translate('xpack.endpoint.resolver.relatedAlerts', { + defaultMessage: 'Related Alerts', + }), + }, + relatedEvents: { + title: i18n.translate('xpack.endpoint.resolver.relatedEvents', { + defaultMessage: 'Events', + }), + }, +}; + +interface ResolverSubmenuOption { + optionTitle: string; + action: () => unknown; + prefix?: number | JSX.Element; +} + +export type ResolverSubmenuOptionList = ResolverSubmenuOption[] | string; + +const OptionList = React.memo( + ({ + subMenuOptions, + isLoading, + }: { + subMenuOptions: ResolverSubmenuOptionList; + isLoading: boolean; + }) => { + const [options, setOptions] = useState(() => + typeof subMenuOptions !== 'object' + ? [] + : subMenuOptions.map((opt: ResolverSubmenuOption): { + label: string; + prepend?: ReactNode; + } => { + return opt.prefix + ? { + label: opt.optionTitle, + prepend: {opt.prefix} , + } + : { + label: opt.optionTitle, + prepend: , + }; + }) + ); + return useMemo( + () => ( + { + setOptions(newOptions); + }} + listProps={{ showIcons: true, bordered: true }} + isLoading={isLoading} + > + {list => list} + + ), + [isLoading, options] + ); + } +); + +/** + * A Submenu to be displayed in one of two forms: + * 1) Provided a collection of `optionsWithActions`: it will call `menuAction` then - if and when menuData becomes available - display each item with an optional prefix and call the supplied action for the options when that option is clicked. + * 2) Provided `optionsWithActions` is undefined, it will call the supplied `menuAction` when its host button is clicked. + */ +export const NodeSubMenu = styled( + React.memo( + ({ + menuTitle, + menuAction, + optionsWithActions, + className, + }: { menuTitle: string; className?: string; menuAction: () => unknown } & { + optionsWithActions?: ResolverSubmenuOptionList | string | undefined; + }) => { + const [menuIsOpen, setMenuOpen] = useState(false); + const handleMenuOpenClick = useCallback( + (clickEvent: React.MouseEvent) => { + // stopping propagation/default to prevent other node animations from triggering + clickEvent.preventDefault(); + clickEvent.stopPropagation(); + setMenuOpen(!menuIsOpen); + }, + [menuIsOpen] + ); + const handleMenuActionClick = useCallback( + (clickEvent: React.MouseEvent) => { + // stopping propagation/default to prevent other node animations from triggering + clickEvent.preventDefault(); + clickEvent.stopPropagation(); + if (typeof menuAction === 'function') menuAction(); + setMenuOpen(true); + }, + [menuAction] + ); + + const isMenuLoading = optionsWithActions === 'waitingForRelatedEventData'; + + if (!optionsWithActions) { + /** + * When called with a `menuAction` + * Render without dropdown and call the supplied action when host button is clicked + */ + return ( +
+ + {menuTitle} + +
+ ); + } + /** + * When called with a set of `optionsWithActions`: + * Render with a panel of options that appear when the menu host button is clicked + */ + return ( +
+ + {menuTitle} + + {menuIsOpen && typeof optionsWithActions === 'object' && ( + + )} +
+ ); + } + ) +)` + margin: 0; + padding: 0; + border: none; + display: flex; + flex-flow: column; + &.is-open .euiButton { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + &.is-open .euiSelectableListItem__prepend { + color: white; + } +`; From 304a4ac5ebd39c99b700b3526f7a6717c048e565 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Tue, 19 May 2020 01:07:07 +0300 Subject: [PATCH 013/129] [SIEM][CASE] Fix configuration's page user experience (#66029) --- .../integration/cases_connectors.spec.ts | 2 - .../siem/cypress/screens/configure_cases.ts | 4 +- .../siem/cypress/tasks/configure_cases.ts | 10 +- .../cases/components/callout/index.test.tsx | 46 +- .../public/cases/components/callout/index.tsx | 63 +- .../configure_cases/connectors.test.tsx | 11 +- .../components/configure_cases/connectors.tsx | 22 +- .../configure_cases/connectors_dropdown.tsx | 70 ++- .../components/configure_cases/index.test.tsx | 562 +++--------------- .../components/configure_cases/index.tsx | 146 ++--- .../configure_cases/translations.ts | 11 - .../components/edit_connector/index.test.tsx | 61 +- .../cases/components/edit_connector/index.tsx | 32 +- .../components/use_push_to_service/index.tsx | 7 +- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 16 files changed, 313 insertions(+), 736 deletions(-) diff --git a/x-pack/plugins/siem/cypress/integration/cases_connectors.spec.ts b/x-pack/plugins/siem/cypress/integration/cases_connectors.spec.ts index 2d650b1bbd9d1..6beb936d15ee6 100644 --- a/x-pack/plugins/siem/cypress/integration/cases_connectors.spec.ts +++ b/x-pack/plugins/siem/cypress/integration/cases_connectors.spec.ts @@ -11,7 +11,6 @@ import { goToEditExternalConnection } from '../tasks/all_cases'; import { addServiceNowConnector, openAddNewConnectorOption, - saveChanges, selectLastConnectorCreated, } from '../tasks/configure_cases'; import { loginAndWaitForPageWithoutDateRange } from '../tasks/login'; @@ -37,7 +36,6 @@ describe('Cases connectors', () => { cy.get(TOASTER).should('have.text', "Created 'New connector'"); selectLastConnectorCreated(); - saveChanges(); cy.wait('@saveConnector', { timeout: 10000 }) .its('status') diff --git a/x-pack/plugins/siem/cypress/screens/configure_cases.ts b/x-pack/plugins/siem/cypress/screens/configure_cases.ts index 5a1e897c43e27..006c524a38acb 100644 --- a/x-pack/plugins/siem/cypress/screens/configure_cases.ts +++ b/x-pack/plugins/siem/cypress/screens/configure_cases.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -export const ADD_NEW_CONNECTOR_OPTION_LINK = - '[data-test-subj="case-configure-add-connector-button"]'; +export const ADD_NEW_CONNECTOR_DROPDOWN_BUTTON = + '[data-test-subj="dropdown-connector-add-connector"]'; export const CONNECTOR = (id: string) => { return `[data-test-subj='dropdown-connector-${id}']`; diff --git a/x-pack/plugins/siem/cypress/tasks/configure_cases.ts b/x-pack/plugins/siem/cypress/tasks/configure_cases.ts index 9172e02708ae7..6ba9e875c7cb0 100644 --- a/x-pack/plugins/siem/cypress/tasks/configure_cases.ts +++ b/x-pack/plugins/siem/cypress/tasks/configure_cases.ts @@ -5,13 +5,12 @@ */ import { - ADD_NEW_CONNECTOR_OPTION_LINK, + ADD_NEW_CONNECTOR_DROPDOWN_BUTTON, CONNECTOR, CONNECTOR_NAME, CONNECTORS_DROPDOWN, PASSWORD, SAVE_BTN, - SAVE_CHANGES_BTN, SERVICE_NOW_CONNECTOR_CARD, URL, USERNAME, @@ -33,15 +32,12 @@ export const openAddNewConnectorOption = () => { cy.get(MAIN_PAGE).then($page => { if ($page.find(SERVICE_NOW_CONNECTOR_CARD).length !== 1) { cy.wait(1000); - cy.get(ADD_NEW_CONNECTOR_OPTION_LINK).click({ force: true }); + cy.get(CONNECTORS_DROPDOWN).click({ force: true }); + cy.get(ADD_NEW_CONNECTOR_DROPDOWN_BUTTON).click(); } }); }; -export const saveChanges = () => { - cy.get(SAVE_CHANGES_BTN).click(); -}; - export const selectLastConnectorCreated = () => { cy.get(CONNECTORS_DROPDOWN).click({ force: true }); cy.get('@createConnector') diff --git a/x-pack/plugins/siem/public/cases/components/callout/index.test.tsx b/x-pack/plugins/siem/public/cases/components/callout/index.test.tsx index 0ab90d8a73126..f157f654d5617 100644 --- a/x-pack/plugins/siem/public/cases/components/callout/index.test.tsx +++ b/x-pack/plugins/siem/public/cases/components/callout/index.test.tsx @@ -19,53 +19,79 @@ describe('CaseCallOut ', () => { ...defaultProps, message: 'we have one message', }; + const wrapper = mount(); + expect( wrapper - .find(`[data-test-subj="callout-message"]`) + .find(`[data-test-subj="callout-message-primary"]`) .last() .exists() ).toBeTruthy(); + }); + + it('Renders multi message callout', () => { + const props = { + ...defaultProps, + messages: [ + { ...defaultProps, description:

{'we have two messages'}

}, + { ...defaultProps, description:

{'for real'}

}, + ], + }; + const wrapper = mount(); expect( wrapper - .find(`[data-test-subj="callout-messages"]`) + .find(`[data-test-subj="callout-message-primary"]`) .last() .exists() ).toBeFalsy(); + expect( + wrapper + .find(`[data-test-subj="callout-messages-primary"]`) + .last() + .exists() + ).toBeTruthy(); }); - it('Renders multi message callout', () => { + + it('it shows the correct type of callouts', () => { const props = { ...defaultProps, messages: [ - { ...defaultProps, description:

{'we have two messages'}

}, + { + ...defaultProps, + description:

{'we have two messages'}

, + errorType: 'danger' as 'primary' | 'success' | 'warning' | 'danger', + }, { ...defaultProps, description:

{'for real'}

}, ], }; const wrapper = mount(); expect( wrapper - .find(`[data-test-subj="callout-message"]`) + .find(`[data-test-subj="callout-messages-danger"]`) .last() .exists() - ).toBeFalsy(); + ).toBeTruthy(); + expect( wrapper - .find(`[data-test-subj="callout-messages"]`) + .find(`[data-test-subj="callout-messages-primary"]`) .last() .exists() ).toBeTruthy(); }); + it('Dismisses callout', () => { const props = { ...defaultProps, message: 'we have one message', }; const wrapper = mount(); - expect(wrapper.find(`[data-test-subj="case-call-out"]`).exists()).toBeTruthy(); + expect(wrapper.find(`[data-test-subj="case-call-out-primary"]`).exists()).toBeTruthy(); wrapper - .find(`[data-test-subj="callout-dismiss"]`) + .find(`[data-test-subj="callout-dismiss-primary"]`) .last() .simulate('click'); - expect(wrapper.find(`[data-test-subj="case-call-out"]`).exists()).toBeFalsy(); + expect(wrapper.find(`[data-test-subj="case-call-out-primary"]`).exists()).toBeFalsy(); }); }); diff --git a/x-pack/plugins/siem/public/cases/components/callout/index.tsx b/x-pack/plugins/siem/public/cases/components/callout/index.tsx index 0fc93af7f318d..5266c9aec9705 100644 --- a/x-pack/plugins/siem/public/cases/components/callout/index.tsx +++ b/x-pack/plugins/siem/public/cases/components/callout/index.tsx @@ -12,28 +12,69 @@ import * as i18n from './translations'; export * from './helpers'; +interface ErrorMessage { + title: string; + description: JSX.Element; + errorType?: 'primary' | 'success' | 'warning' | 'danger'; +} + interface CaseCallOutProps { title: string; message?: string; - messages?: Array<{ title: string; description: JSX.Element }>; + messages?: ErrorMessage[]; } const CaseCallOutComponent = ({ title, message, messages }: CaseCallOutProps) => { const [showCallOut, setShowCallOut] = useState(true); const handleCallOut = useCallback(() => setShowCallOut(false), [setShowCallOut]); + let callOutMessages = messages ?? []; + + if (message) { + callOutMessages = [ + ...callOutMessages, + { + title: '', + description:

{message}

, + errorType: 'primary', + }, + ]; + } + + const groupedErrorMessages = callOutMessages.reduce((acc, currentMessage: ErrorMessage) => { + const key = currentMessage.errorType == null ? 'primary' : currentMessage.errorType; + return { + ...acc, + [key]: [...(acc[key] || []), currentMessage], + }; + }, {} as { [key in NonNullable]: ErrorMessage[] }); return showCallOut ? ( <> - - {!isEmpty(messages) && ( - - )} - {!isEmpty(message) &&

{message}

} - - {i18n.DISMISS_CALLOUT} - -
- + {(Object.keys(groupedErrorMessages) as Array).map(key => ( + + + {!isEmpty(groupedErrorMessages[key]) && ( + + )} + + {i18n.DISMISS_CALLOUT} + + + + + ))} ) : null; }; diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/connectors.test.tsx b/x-pack/plugins/siem/public/cases/components/configure_cases/connectors.test.tsx index 41cd3e549415d..4f6fad8491206 100644 --- a/x-pack/plugins/siem/public/cases/components/configure_cases/connectors.test.tsx +++ b/x-pack/plugins/siem/public/cases/components/configure_cases/connectors.test.tsx @@ -15,7 +15,6 @@ import { connectors } from './__mock__'; describe('Connectors', () => { let wrapper: ReactWrapper; const onChangeConnector = jest.fn(); - const handleShowAddFlyout = jest.fn(); const handleShowEditFlyout = jest.fn(); const props: Props = { @@ -25,7 +24,6 @@ describe('Connectors', () => { selectedConnector: 'none', isLoading: false, onChangeConnector, - handleShowAddFlyout, handleShowEditFlyout, }; @@ -92,6 +90,15 @@ describe('Connectors', () => { expect(onChangeConnector).toHaveBeenCalledWith('none'); }); + test('it shows the add connector button', () => { + wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); + wrapper.update(); + + expect( + wrapper.find('button[data-test-subj="dropdown-connector-add-connector"]').exists() + ).toBeTruthy(); + }); + test('the text of the update button is shown correctly', () => { const newWrapper = mount(, { wrappingComponent: TestProviders, diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/connectors.tsx b/x-pack/plugins/siem/public/cases/components/configure_cases/connectors.tsx index 3916ce297a0a4..76e816a2909ab 100644 --- a/x-pack/plugins/siem/public/cases/components/configure_cases/connectors.tsx +++ b/x-pack/plugins/siem/public/cases/components/configure_cases/connectors.tsx @@ -11,7 +11,6 @@ import { EuiFlexGroup, EuiFlexItem, EuiLink, - EuiButton, } from '@elastic/eui'; import styled from 'styled-components'; @@ -29,12 +28,6 @@ const EuiFormRowExtended = styled(EuiFormRow)` } `; -const AddConnectorEuiFormRow = styled(EuiFormRow)` - width: 100%; - max-width: 100%; - text-align: right; -`; - export interface Props { connectors: Connector[]; disabled: boolean; @@ -42,7 +35,6 @@ export interface Props { updateConnectorDisabled: boolean; onChangeConnector: (id: string) => void; selectedConnector: string; - handleShowAddFlyout: () => void; handleShowEditFlyout: () => void; } const ConnectorsComponent: React.FC = ({ @@ -52,7 +44,6 @@ const ConnectorsComponent: React.FC = ({ updateConnectorDisabled, onChangeConnector, selectedConnector, - handleShowAddFlyout, handleShowEditFlyout, }) => { const connectorsName = useMemo( @@ -77,7 +68,7 @@ const ConnectorsComponent: React.FC = ({ ), - [connectorsName] + [connectorsName, updateConnectorDisabled] ); return ( @@ -100,18 +91,9 @@ const ConnectorsComponent: React.FC = ({ isLoading={isLoading} onChange={onChangeConnector} data-test-subj="case-connectors-dropdown" + appendAddConnectorButton={true} /> - - - {i18n.ADD_NEW_CONNECTOR} - - ); diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/connectors_dropdown.tsx b/x-pack/plugins/siem/public/cases/components/configure_cases/connectors_dropdown.tsx index b2b2edb04bd29..c5481f592e750 100644 --- a/x-pack/plugins/siem/public/cases/components/configure_cases/connectors_dropdown.tsx +++ b/x-pack/plugins/siem/public/cases/components/configure_cases/connectors_dropdown.tsx @@ -18,6 +18,7 @@ export interface Props { isLoading: boolean; onChange: (id: string) => void; selectedConnector: string; + appendAddConnectorButton?: boolean; } const ICON_SIZE = 'm'; @@ -42,40 +43,55 @@ const noConnectorOption = { 'data-test-subj': 'dropdown-connector-no-connector', }; +const addNewConnector = { + value: 'add-connector', + inputDisplay: ( + + {i18n.ADD_NEW_CONNECTOR} + + ), + 'data-test-subj': 'dropdown-connector-add-connector', +}; + const ConnectorsDropdownComponent: React.FC = ({ connectors, disabled, isLoading, onChange, selectedConnector, + appendAddConnectorButton = false, }) => { - const connectorsAsOptions = useMemo( - () => - connectors.reduce( - (acc, connector) => [ - ...acc, - { - value: connector.id, - inputDisplay: ( - - - - - - {connector.name} - - - ), - 'data-test-subj': `dropdown-connector-${connector.id}`, - }, - ], - [noConnectorOption] - ), - [connectors] - ); + const connectorsAsOptions = useMemo(() => { + const connectorsFormatted = connectors.reduce( + (acc, connector) => [ + ...acc, + { + value: connector.id, + inputDisplay: ( + + + + + + {connector.name} + + + ), + 'data-test-subj': `dropdown-connector-${connector.id}`, + }, + ], + [noConnectorOption] + ); + + if (appendAddConnectorButton) { + return [...connectorsFormatted, addNewConnector]; + } + + return connectorsFormatted; + }, [connectors]); return ( { wrapper.find('[data-test-subj="configure-cases-warning-callout"]').exists() ).toBeFalsy(); }); - - test('it does NOT render the EuiBottomBar', () => { - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeFalsy(); - }); - - test('it disables correctly ClosureOptions when the connector is set to none', () => { - expect(wrapper.find(ClosureOptions).prop('disabled')).toBe(true); - }); }); describe('Unhappy path', () => { @@ -182,12 +172,6 @@ describe('ConfigureCases', () => { expect(wrapper.find(ConnectorEditFlyout).prop('initialConnector')).toEqual(connectors[0]); }); - test('it does not shows the action bar when there is no change', () => { - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeFalsy(); - }); - test('it disables correctly when the user cannot crud', () => { const newWrapper = mount(, { wrappingComponent: TestProviders, @@ -197,12 +181,6 @@ describe('ConfigureCases', () => { true ); - expect( - newWrapper - .find('button[data-test-subj="case-configure-add-connector-button"]') - .prop('disabled') - ).toBe(true); - expect( newWrapper .find('button[data-test-subj="case-configure-update-selected-connector-button"]') @@ -275,26 +253,6 @@ describe('ConfigureCases', () => { .prop('disabled') ).toBe(true); }); - - test('it disables the buttons of action bar when loading connectors', () => { - const newWrapper = mount(, { - wrappingComponent: TestProviders, - }); - - expect( - newWrapper - .find('button[data-test-subj="case-configure-action-bottom-bar-cancel-button"]') - .first() - .prop('disabled') - ).toBe(true); - - expect( - newWrapper - .find('button[data-test-subj="case-configure-action-bottom-bar-save-button"]') - .first() - .prop('disabled') - ).toBe(true); - }); }); describe('saving configuration', () => { @@ -341,74 +299,6 @@ describe('ConfigureCases', () => { .prop('disabled') ).toBe(true); }); - - test('it disables the buttons of action bar when saving configuration', () => { - useCaseConfigureMock.mockImplementation(() => ({ - ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-user', - connectorId: 'servicenow-2', - connectorName: 'unchanged', - currentConfiguration: { - connectorName: 'unchanged', - connectorId: 'servicenow-1', - closureType: 'close-by-user', - }, - persistLoading: true, - })); - - const newWrapper = mount(, { - wrappingComponent: TestProviders, - }); - - expect( - newWrapper - .find('[data-test-subj="case-configure-action-bottom-bar-cancel-button"]') - .first() - .prop('isDisabled') - ).toBe(true); - - expect( - newWrapper - .find('[data-test-subj="case-configure-action-bottom-bar-save-button"]') - .first() - .prop('isDisabled') - ).toBe(true); - }); - - test('it shows the loading spinner when saving configuration', () => { - useCaseConfigureMock.mockImplementation(() => ({ - ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-user', - connectorId: 'servicenow-2', - connectorName: 'unchanged', - currentConfiguration: { - connectorName: 'unchanged', - connectorId: 'servicenow-1', - closureType: 'close-by-user', - }, - persistLoading: true, - })); - - const newWrapper = mount(, { - wrappingComponent: TestProviders, - }); - - expect( - newWrapper - .find('[data-test-subj="case-configure-action-bottom-bar-cancel-button"]') - .first() - .prop('isLoading') - ).toBe(true); - - expect( - newWrapper - .find('[data-test-subj="case-configure-action-bottom-bar-save-button"]') - .first() - .prop('isLoading') - ).toBe(true); - }); }); describe('loading configuration', () => { @@ -437,7 +327,7 @@ describe('ConfigureCases', () => { }); }); - describe('update connector', () => { + describe('connectors', () => { let wrapper: ReactWrapper; const persistCaseConfigure = jest.fn(); @@ -445,13 +335,13 @@ describe('ConfigureCases', () => { jest.resetAllMocks(); useCaseConfigureMock.mockImplementation(() => ({ ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, + mapping: connectors[0].config.casesConfiguration.mapping, closureType: 'close-by-user', - connectorId: 'servicenow-2', - connectorName: 'unchanged', + connectorId: 'servicenow-1', + connectorName: 'My connector', currentConfiguration: { - connectorName: 'unchanged', - connectorId: 'servicenow-1', + connectorName: 'My connector', + connectorId: 'My connector', closureType: 'close-by-user', }, persistCaseConfigure, @@ -463,12 +353,10 @@ describe('ConfigureCases', () => { wrapper = mount(, { wrappingComponent: TestProviders }); }); - test('it submits the configuration correctly', () => { - wrapper - .find('[data-test-subj="case-configure-action-bottom-bar-save-button"]') - .first() - .simulate('click'); - + test('it submits the configuration correctly when changing connector', () => { + wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); + wrapper.update(); + wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); wrapper.update(); expect(persistCaseConfigure).toHaveBeenCalled(); @@ -479,382 +367,112 @@ describe('ConfigureCases', () => { }); }); - test('it has the correct url on cancel button', () => { - expect( - wrapper - .find('[data-test-subj="case-configure-action-bottom-bar-cancel-button"]') - .first() - .prop('href') - ).toBe(`#/link-to/case${searchURL}`); - }); - - test('it disables the buttons of action bar when loading configuration', () => { - useCaseConfigureMock.mockImplementation(() => ({ - ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-user', - connectorId: 'servicenow-2', - connectorName: 'unchanged', - currentConfiguration: { - connectorName: 'unchanged', - connectorId: 'servicenow-1', - closureType: 'close-by-user', - }, - loading: true, - })); - const newWrapper = mount(, { - wrappingComponent: TestProviders, - }); - - expect( - newWrapper - .find('[data-test-subj="case-configure-action-bottom-bar-cancel-button"]') - .first() - .prop('isDisabled') - ).toBe(true); - - expect( - newWrapper - .find('[data-test-subj="case-configure-action-bottom-bar-save-button"]') - .first() - .prop('isDisabled') - ).toBe(true); - }); - }); - - describe('user interactions', () => { - beforeEach(() => { - jest.resetAllMocks(); - useCaseConfigureMock.mockImplementation(() => ({ - ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-user', - connectorId: 'servicenow-2', - connectorName: 'unchanged', - currentConfiguration: { - connectorName: 'unchanged', - connectorId: 'servicenow-2', - closureType: 'close-by-user', - }, - })); - useConnectorsMock.mockImplementation(() => useConnectorsResponse); - useKibanaMock.mockImplementation(() => kibanaMockImplementationArgs); - useGetUrlSearchMock.mockImplementation(() => searchURL); - }); - - test('it show the add flyout when pressing the add connector button', () => { - const wrapper = mount(, { wrappingComponent: TestProviders }); - wrapper - .find('button[data-test-subj="case-configure-add-connector-button"]') - .simulate('click'); - wrapper.update(); - - expect(wrapper.find(ConnectorAddFlyout).prop('addFlyoutVisible')).toBe(true); - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeFalsy(); - }); - - test('it show the edit flyout when pressing the update connector button', () => { - const wrapper = mount(, { wrappingComponent: TestProviders }); - wrapper - .find('button[data-test-subj="case-configure-update-selected-connector-button"]') - .simulate('click'); - wrapper.update(); - - expect(wrapper.find(ConnectorEditFlyout).prop('editFlyoutVisible')).toBe(true); - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeFalsy(); - }); - - test('it tracks the changes successfully', () => { - useCaseConfigureMock.mockImplementation(() => ({ - ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-user', - connectorId: 'servicenow-2', - connectorName: 'unchanged', - currentConfiguration: { - connectorName: 'unchanged', - connectorId: 'servicenow-1', - closureType: 'close-by-pushing', - }, - })); - const wrapper = mount(, { wrappingComponent: TestProviders }); - wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); - wrapper.update(); - wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); - wrapper.update(); - wrapper.find('input[id="close-by-pushing"]').simulate('change'); - wrapper.update(); - - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeTruthy(); - expect( - wrapper - .find('[data-test-subj="case-configure-action-bottom-bar-total-changes"]') - .first() - .text() - ).toBe('2 unsaved changes'); - }); - - test('it tracks the changes successfully when name changes', () => { - useCaseConfigureMock.mockImplementation(() => ({ - ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-user', - connectorId: 'servicenow-2', - connectorName: 'nameChange', - currentConfiguration: { - connectorId: 'servicenow-1', - closureType: 'close-by-pushing', - connectorName: 'before', - }, - })); - - const wrapper = mount(, { wrappingComponent: TestProviders }); - wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); - wrapper.update(); - wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); - wrapper.update(); - wrapper.find('input[id="close-by-pushing"]').simulate('change'); - wrapper.update(); - - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeTruthy(); - expect( - wrapper - .find('[data-test-subj="case-configure-action-bottom-bar-total-changes"]') - .first() - .text() - ).toBe('2 unsaved changes'); - }); - - test('it tracks and reverts the changes successfully ', () => { - const wrapper = mount(, { wrappingComponent: TestProviders }); - // change settings - wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); - wrapper.update(); - wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); - wrapper.update(); - wrapper.find('input[id="close-by-pushing"]').simulate('change'); - wrapper.update(); - - // revert back to initial settings - wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); - wrapper.update(); - wrapper.find('button[data-test-subj="dropdown-connector-servicenow-1"]').simulate('click'); - wrapper.update(); - wrapper.find('input[id="close-by-user"]').simulate('change'); - wrapper.update(); - - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeFalsy(); - }); - - test('it close and restores the action bar when the add connector button is pressed', () => { - useCaseConfigureMock - .mockImplementationOnce(() => ({ - ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-user', - connectorId: 'servicenow-2', - currentConfiguration: { connectorId: 'servicenow-2', closureType: 'close-by-user' }, - })) - .mockImplementation(() => ({ - ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-pushing', - connectorId: 'servicenow-2', - currentConfiguration: { connectorId: 'servicenow-2', closureType: 'close-by-user' }, - })); - const wrapper = mount(, { wrappingComponent: TestProviders }); - // Change closure type - wrapper.find('input[id="close-by-pushing"]').simulate('change'); - wrapper.update(); - - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeTruthy(); - - // Press add connector button - wrapper - .find('button[data-test-subj="case-configure-add-connector-button"]') - .simulate('click'); - wrapper.update(); - - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeFalsy(); - - expect(wrapper.find(ConnectorAddFlyout).prop('addFlyoutVisible')).toBe(true); - - // Close the add flyout - wrapper.find('button[data-test-subj="euiFlyoutCloseButton"]').simulate('click'); - wrapper.update(); - - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeTruthy(); - - expect(wrapper.find(ConnectorAddFlyout).prop('addFlyoutVisible')).toBe(false); - - expect( - wrapper - .find('[data-test-subj="case-configure-action-bottom-bar-total-changes"]') - .first() - .text() - ).toBe('1 unsaved changes'); - }); - - test('it close and restores the action bar when the update connector button is pressed', () => { + test('the text of the update button is changed successfully', () => { useCaseConfigureMock .mockImplementationOnce(() => ({ ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-user', - connectorId: 'servicenow-2', - currentConfiguration: { connectorId: 'servicenow-2', closureType: 'close-by-user' }, + connectorId: 'servicenow-1', })) .mockImplementation(() => ({ ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-pushing', connectorId: 'servicenow-2', - currentConfiguration: { connectorId: 'servicenow-2', closureType: 'close-by-user' }, })); - const wrapper = mount(, { wrappingComponent: TestProviders }); - - // Change closure type - wrapper.find('input[id="close-by-pushing"]').simulate('change'); - wrapper.update(); - - // Press update connector button - wrapper - .find('button[data-test-subj="case-configure-update-selected-connector-button"]') - .simulate('click'); - wrapper.update(); - - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeFalsy(); - - expect(wrapper.find(ConnectorEditFlyout).prop('editFlyoutVisible')).toBe(true); - - // Close the edit flyout - wrapper.find('button[data-test-subj="euiFlyoutCloseButton"]').simulate('click'); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeTruthy(); - - expect(wrapper.find(ConnectorEditFlyout).prop('editFlyoutVisible')).toBe(false); - - expect( - wrapper - .find('[data-test-subj="case-configure-action-bottom-bar-total-changes"]') - .first() - .text() - ).toBe('1 unsaved changes'); - }); + wrapper = mount(, { wrappingComponent: TestProviders }); - test('it shows the action bar when the connector is changed', () => { - useCaseConfigureMock - .mockImplementationOnce(() => ({ - ...useCaseConfigureResponse, - mapping: connectors[0].config.casesConfiguration.mapping, - closureType: 'close-by-user', - connectorId: 'servicenow-1', - currentConfiguration: { connectorId: 'servicenow-1', closureType: 'close-by-user' }, - })) - .mockImplementation(() => ({ - ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-user', - connectorId: 'servicenow-2', - currentConfiguration: { connectorId: 'servicenow-1', closureType: 'close-by-user' }, - })); - const wrapper = mount(, { wrappingComponent: TestProviders }); wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); wrapper.update(); wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); wrapper.update(); - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeTruthy(); expect( wrapper - .find('[data-test-subj="case-configure-action-bottom-bar-total-changes"]') - .first() + .find('button[data-test-subj="case-configure-update-selected-connector-button"]') .text() - ).toBe('1 unsaved changes'); + ).toBe('Update My Connector 2'); }); + }); +}); - test('it closes the action bar when pressing save', () => { - useCaseConfigureMock - .mockImplementationOnce(() => ({ - ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-user', - connectorId: 'servicenow-2', - currentConfiguration: { connectorId: 'servicenow-2', closureType: 'close-by-user' }, - })) - .mockImplementation(() => ({ - ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, - closureType: 'close-by-pushing', - connectorId: 'servicenow-2', - currentConfiguration: { connectorId: 'servicenow-2', closureType: 'close-by-user' }, - })); - const wrapper = mount(, { wrappingComponent: TestProviders }); - wrapper.find('input[id="close-by-pushing"]').simulate('change'); - wrapper.update(); - - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeTruthy(); - - wrapper - .find('[data-test-subj="case-configure-action-bottom-bar-save-button"]') - .first() - .simulate('click'); +describe('closure options', () => { + let wrapper: ReactWrapper; + const persistCaseConfigure = jest.fn(); + + beforeEach(() => { + jest.resetAllMocks(); + useCaseConfigureMock.mockImplementation(() => ({ + ...useCaseConfigureResponse, + mapping: connectors[0].config.casesConfiguration.mapping, + closureType: 'close-by-user', + connectorId: 'servicenow-1', + connectorName: 'My connector', + currentConfiguration: { + connectorName: 'My connector', + connectorId: 'My connector', + closureType: 'close-by-user', + }, + persistCaseConfigure, + })); + useConnectorsMock.mockImplementation(() => useConnectorsResponse); + useKibanaMock.mockImplementation(() => kibanaMockImplementationArgs); + useGetUrlSearchMock.mockImplementation(() => searchURL); + + wrapper = mount(, { wrappingComponent: TestProviders }); + }); - wrapper.update(); + test('it submits the configuration correctly when changing closure type', () => { + wrapper.find('input[id="close-by-pushing"]').simulate('change'); + wrapper.update(); - expect( - wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() - ).toBeFalsy(); + expect(persistCaseConfigure).toHaveBeenCalled(); + expect(persistCaseConfigure).toHaveBeenCalledWith({ + connectorId: 'servicenow-1', + connectorName: 'My Connector', + closureType: 'close-by-pushing', }); + }); +}); - test('the text of the update button is changed successfully', () => { - useCaseConfigureMock - .mockImplementationOnce(() => ({ - ...useCaseConfigureResponse, - connectorId: 'servicenow-1', - })) - .mockImplementation(() => ({ - ...useCaseConfigureResponse, - connectorId: 'servicenow-2', - })); +describe('user interactions', () => { + beforeEach(() => { + jest.resetAllMocks(); + useCaseConfigureMock.mockImplementation(() => ({ + ...useCaseConfigureResponse, + mapping: connectors[1].config.casesConfiguration.mapping, + closureType: 'close-by-user', + connectorId: 'servicenow-2', + connectorName: 'unchanged', + currentConfiguration: { + connectorName: 'unchanged', + connectorId: 'servicenow-2', + closureType: 'close-by-user', + }, + })); + useConnectorsMock.mockImplementation(() => useConnectorsResponse); + useKibanaMock.mockImplementation(() => kibanaMockImplementationArgs); + useGetUrlSearchMock.mockImplementation(() => searchURL); + }); - const wrapper = mount(, { wrappingComponent: TestProviders }); + test('it show the add flyout when pressing the add connector button', () => { + const wrapper = mount(, { wrappingComponent: TestProviders }); + wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); + wrapper.update(); + wrapper.find('button[data-test-subj="dropdown-connector-add-connector"]').simulate('click'); + wrapper.update(); - wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); - wrapper.update(); - wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); - wrapper.update(); + expect(wrapper.find(ConnectorAddFlyout).prop('addFlyoutVisible')).toBe(true); + }); - expect( - wrapper - .find('button[data-test-subj="case-configure-update-selected-connector-button"]') - .text() - ).toBe('Update My Connector 2'); - }); + test('it show the edit flyout when pressing the update connector button', () => { + const wrapper = mount(, { wrappingComponent: TestProviders }); + wrapper + .find('button[data-test-subj="case-configure-update-selected-connector-button"]') + .simulate('click'); + wrapper.update(); + + expect(wrapper.find(ConnectorEditFlyout).prop('editFlyoutVisible')).toBe(true); + expect( + wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists() + ).toBeFalsy(); }); }); diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/index.tsx b/x-pack/plugins/siem/public/cases/components/configure_cases/index.tsx index d5c6cc671433b..e6fbc7cd3e4db 100644 --- a/x-pack/plugins/siem/public/cases/components/configure_cases/index.tsx +++ b/x-pack/plugins/siem/public/cases/components/configure_cases/index.tsx @@ -7,16 +7,8 @@ import React, { useCallback, useEffect, useState, Dispatch, SetStateAction } from 'react'; import styled, { css } from 'styled-components'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiButton, - EuiCallOut, - EuiBottomBar, - EuiButtonEmpty, - EuiText, -} from '@elastic/eui'; -import { difference } from 'lodash/fp'; +import { EuiCallOut } from '@elastic/eui'; + import { useKibana } from '../../../common/lib/kibana'; import { useConnectors } from '../../containers/configure/use_connectors'; import { useCaseConfigure } from '../../containers/configure/use_configure'; @@ -27,16 +19,15 @@ import { ConnectorEditFlyout, } from '../../../../../triggers_actions_ui/public'; +import { ClosureType } from '../../containers/configure/types'; + // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ActionConnectorTableItem } from '../../../../../triggers_actions_ui/public/types'; -import { getCaseUrl } from '../../../common/components/link_to'; -import { useGetUrlSearch } from '../../../common/components/navigation/use_get_url_search'; import { connectorsConfiguration } from '../../../common/lib/connectors/config'; import { Connectors } from './connectors'; import { ClosureOptions } from './closure_options'; import { SectionWrapper } from '../wrappers'; -import { navTabs } from '../../../app/home/home_navigations'; import * as i18n from './translations'; const FormWrapper = styled.div` @@ -61,7 +52,6 @@ interface ConfigureCasesComponentProps { } const ConfigureCasesComponent: React.FC = ({ userCanCrud }) => { - const search = useGetUrlSearch(navTabs.case); const { http, triggers_actions_ui, notifications, application, docLinks } = useKibana().services; const [connectorIsValid, setConnectorIsValid] = useState(true); @@ -71,15 +61,13 @@ const ConfigureCasesComponent: React.FC = ({ userC null ); - const [actionBarVisible, setActionBarVisible] = useState(false); - const [totalConfigurationChanges, setTotalConfigurationChanges] = useState(0); - const { connectorId, closureType, currentConfiguration, loading: loadingCaseConfigure, persistLoading, + version, persistCaseConfigure, setConnector, setClosureType, @@ -93,45 +81,12 @@ const ConfigureCasesComponent: React.FC = ({ userC const isLoadingAny = isLoadingConnectors || persistLoading || loadingCaseConfigure; const updateConnectorDisabled = isLoadingAny || !connectorIsValid || connectorId === 'none'; - const handleSubmit = useCallback( - // TO DO give a warning/error to user when field are not mapped so they have chance to do it - () => { - setActionBarVisible(false); - persistCaseConfigure({ - connectorId, - connectorName: connectors.find(c => c.id === connectorId)?.name ?? '', - closureType, - }); - }, - [connectorId, connectors, closureType] - ); - - const onClickAddConnector = useCallback(() => { - setActionBarVisible(false); - setAddFlyoutVisibility(true); - }, []); - const onClickUpdateConnector = useCallback(() => { - setActionBarVisible(false); setEditFlyoutVisibility(true); }, []); - const handleActionBar = useCallback(() => { - const currentConfigurationMinusName = { - connectorId: currentConfiguration.connectorId, - closureType: currentConfiguration.closureType, - }; - const unsavedChanges = difference(Object.values(currentConfigurationMinusName), [ - connectorId, - closureType, - ]).length; - setActionBarVisible(!(unsavedChanges === 0)); - setTotalConfigurationChanges(unsavedChanges); - }, [currentConfiguration, connectorId, closureType]); - const handleSetAddFlyoutVisibility = useCallback( (isVisible: boolean) => { - handleActionBar(); setAddFlyoutVisibility(isVisible); }, [currentConfiguration, connectorId, closureType] @@ -139,12 +94,40 @@ const ConfigureCasesComponent: React.FC = ({ userC const handleSetEditFlyoutVisibility = useCallback( (isVisible: boolean) => { - handleActionBar(); setEditFlyoutVisibility(isVisible); }, [currentConfiguration, connectorId, closureType] ); + const onChangeConnector = useCallback( + (id: string) => { + if (id === 'add-connector') { + setAddFlyoutVisibility(true); + return; + } + + setConnector(id); + persistCaseConfigure({ + connectorId: id, + connectorName: connectors.find(c => c.id === id)?.name ?? '', + closureType, + }); + }, + [connectorId, closureType, version] + ); + + const onChangeClosureType = useCallback( + (type: ClosureType) => { + setClosureType(type); + persistCaseConfigure({ + connectorId, + connectorName: connectors.find(c => c.id === connectorId)?.name ?? '', + closureType: type, + }); + }, + [connectorId, closureType, version] + ); + useEffect(() => { if ( !isLoadingConnectors && @@ -168,16 +151,6 @@ const ConfigureCasesComponent: React.FC = ({ userC } }, [connectors, connectorId]); - useEffect(() => { - handleActionBar(); - }, [ - connectors, - connectorId, - closureType, - currentConfiguration.connectorId, - currentConfiguration.closureType, - ]); - return ( {!connectorIsValid && ( @@ -195,8 +168,8 @@ const ConfigureCasesComponent: React.FC = ({ userC @@ -204,57 +177,12 @@ const ConfigureCasesComponent: React.FC = ({ userC connectors={connectors ?? []} disabled={persistLoading || isLoadingConnectors || !userCanCrud} isLoading={isLoadingConnectors} - onChangeConnector={setConnector} + onChangeConnector={onChangeConnector} updateConnectorDisabled={updateConnectorDisabled || !userCanCrud} - handleShowAddFlyout={onClickAddConnector} handleShowEditFlyout={onClickUpdateConnector} selectedConnector={connectorId} /> - {actionBarVisible && ( - - - - - - {i18n.UNSAVED_CHANGES(totalConfigurationChanges)} - - - - - - - - {i18n.CANCEL} - - - - - {i18n.SAVE_CHANGES} - - - - - - - )} { defaultMessage: 'Update { connectorName }', }); }; - -export const UNSAVED_CHANGES = (unsavedChanges: number): string => { - return i18n.translate('xpack.siem.case.configureCases.unsavedChanges', { - values: { unsavedChanges }, - defaultMessage: '{unsavedChanges} unsaved changes', - }); -}; diff --git a/x-pack/plugins/siem/public/cases/components/edit_connector/index.test.tsx b/x-pack/plugins/siem/public/cases/components/edit_connector/index.test.tsx index 5dfed80baa8ed..8fada565b3463 100644 --- a/x-pack/plugins/siem/public/cases/components/edit_connector/index.test.tsx +++ b/x-pack/plugins/siem/public/cases/components/edit_connector/index.test.tsx @@ -40,23 +40,17 @@ describe('EditConnector ', () => { ); - expect( - wrapper - .find(`[data-test-subj="dropdown-connectors"]`) - .last() - .prop('disabled') - ).toBeTruthy(); - expect( wrapper .find(`span[data-test-subj="dropdown-connector-no-connector"]`) .last() .exists() ).toBeTruthy(); - wrapper - .find(`[data-test-subj="connector-edit-button"]`) - .last() - .simulate('click'); + + wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); + wrapper.update(); + wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); + wrapper.update(); expect( wrapper @@ -64,30 +58,27 @@ describe('EditConnector ', () => { .last() .exists() ).toBeTruthy(); - - expect( - wrapper - .find(`[data-test-subj="dropdown-connectors"]`) - .last() - .prop('disabled') - ).toBeFalsy(); }); + it('Edit external service on submit', async () => { const wrapper = mount( ); - wrapper - .find(`[data-test-subj="connector-edit-button"]`) - .last() - .simulate('click'); + + wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); + wrapper.update(); + wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); + wrapper.update(); + expect( wrapper .find(`[data-test-subj="edit-connectors-submit"]`) .last() .exists() ).toBeTruthy(); + await act(async () => { wrapper .find(`[data-test-subj="edit-connectors-submit"]`) @@ -97,6 +88,7 @@ describe('EditConnector ', () => { expect(onSubmit).toBeCalledWith(sampleConnector); }); }); + it('Resets selector on cancel', async () => { const props = { ...defaultProps, @@ -106,10 +98,12 @@ describe('EditConnector ', () => { ); - wrapper - .find(`[data-test-subj="connector-edit-button"]`) - .last() - .simulate('click'); + + wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); + wrapper.update(); + wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); + wrapper.update(); + await act(async () => { wrapper .find(`[data-test-subj="edit-connectors-cancel"]`) @@ -123,20 +117,7 @@ describe('EditConnector ', () => { ); }); }); - it('Renders disabled button', () => { - const props = { ...defaultProps, disabled: true }; - const wrapper = mount( - - - - ); - expect( - wrapper - .find(`[data-test-subj="connector-edit-button"]`) - .last() - .prop('disabled') - ).toBeTruthy(); - }); + it('Renders loading spinner', () => { const props = { ...defaultProps, isLoading: true }; const wrapper = mount( diff --git a/x-pack/plugins/siem/public/cases/components/edit_connector/index.tsx b/x-pack/plugins/siem/public/cases/components/edit_connector/index.tsx index 29f06532a4ab4..38062b8837054 100644 --- a/x-pack/plugins/siem/public/cases/components/edit_connector/index.tsx +++ b/x-pack/plugins/siem/public/cases/components/edit_connector/index.tsx @@ -12,7 +12,6 @@ import { EuiFlexItem, EuiButton, EuiButtonEmpty, - EuiButtonIcon, EuiLoadingSpinner, } from '@elastic/eui'; import styled, { css } from 'styled-components'; @@ -52,21 +51,24 @@ export const EditConnector = React.memo( options: { stripEmptyFields: false }, schema, }); - const [isEditConnector, setIsEditConnector] = useState(false); - const handleOnClick = useCallback(() => { - setIsEditConnector(true); - }, []); + const [connectorHasChanged, setConnectorHasChanged] = useState(false); + const onChangeConnector = useCallback( + connectorId => { + setConnectorHasChanged(selectedConnector !== connectorId); + }, + [selectedConnector] + ); const onCancelConnector = useCallback(() => { form.setFieldValue('connector', selectedConnector); - setIsEditConnector(false); + setConnectorHasChanged(false); }, [form, selectedConnector]); const onSubmitConnector = useCallback(async () => { const { isValid, data: newData } = await form.submit(); if (isValid && newData.connector) { onSubmit(newData.connector); - setIsEditConnector(false); + setConnectorHasChanged(false); } }, [form, onSubmit]); return ( @@ -76,17 +78,6 @@ export const EditConnector = React.memo(

{i18n.CONNECTORS}

{isLoading && } - {!isLoading && ( - - - - )} @@ -103,15 +94,16 @@ export const EditConnector = React.memo( dataTestSubj: 'caseConnectors', idAria: 'caseConnectors', isLoading, - disabled: !isEditConnector, + disabled, defaultValue: selectedConnector, }} + onChange={onChangeConnector} /> - {isEditConnector && ( + {connectorHasChanged && ( diff --git a/x-pack/plugins/siem/public/cases/components/use_push_to_service/index.tsx b/x-pack/plugins/siem/public/cases/components/use_push_to_service/index.tsx index ae8a67b75d36c..5d238b623eb4a 100644 --- a/x-pack/plugins/siem/public/cases/components/use_push_to_service/index.tsx +++ b/x-pack/plugins/siem/public/cases/components/use_push_to_service/index.tsx @@ -67,7 +67,11 @@ export const usePushToService = ({ }, [caseId, caseServices, caseConnectorId, caseConnectorName, postPushToService, updateCase]); const errorsMsg = useMemo(() => { - let errors: Array<{ title: string; description: JSX.Element }> = []; + let errors: Array<{ + title: string; + description: JSX.Element; + errorType?: 'primary' | 'success' | 'warning' | 'danger'; + }> = []; if (actionLicense != null && !actionLicense.enabledInLicense) { errors = [...errors, getLicenseError()]; } @@ -115,6 +119,7 @@ export const usePushToService = ({ id="xpack.siem.case.caseView.pushToServiceDisableByInvalidConnector" /> ), + errorType: 'danger', }, ]; } diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 219e922a0158c..da47e42ea02a6 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -13152,7 +13152,6 @@ "xpack.siem.case.configureCases.incidentManagementSystemLabel": "インシデント管理システム", "xpack.siem.case.configureCases.incidentManagementSystemTitle": "サードパーティのインシデント管理システムに接続", "xpack.siem.case.configureCases.noConnector": "コネクターを選択していません", - "xpack.siem.case.configureCases.saveChangesButton": "変更を保存", "xpack.siem.case.configureCases.updateConnector": "コネクターを更新", "xpack.siem.case.configureCases.warningMessage": "構成が無効のようです。選択したコネクターが見つかりませんコネクターを削除しましたか?", "xpack.siem.case.configureCases.warningTitle": "警告", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 954162647bf83..3d96a0ebe0a3f 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -13159,7 +13159,6 @@ "xpack.siem.case.configureCases.incidentManagementSystemLabel": "事件管理系统", "xpack.siem.case.configureCases.incidentManagementSystemTitle": "连接到第三方事件管理系统", "xpack.siem.case.configureCases.noConnector": "未选择连接器", - "xpack.siem.case.configureCases.saveChangesButton": "保存更改", "xpack.siem.case.configureCases.updateConnector": "更新连接器", "xpack.siem.case.configureCases.warningMessage": "配置似乎无效。选择的连接器缺失。您是否已删除该连接器?", "xpack.siem.case.configureCases.warningTitle": "警告", From d609f287899095bb99d3b2c1fd0cc9c2ce82d63f Mon Sep 17 00:00:00 2001 From: gchaps <33642766+gchaps@users.noreply.github.com> Date: Mon, 18 May 2020 15:22:49 -0700 Subject: [PATCH 014/129] [DOCS] Identifies cloud settings for APM (#66935) --- docs/settings/apm-settings.asciidoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/settings/apm-settings.asciidoc b/docs/settings/apm-settings.asciidoc index 8844fcd03ae9a..efc43e5d2f52d 100644 --- a/docs/settings/apm-settings.asciidoc +++ b/docs/settings/apm-settings.asciidoc @@ -43,29 +43,29 @@ Changing these settings may disable features of the APM App. | `xpack.apm.enabled` | Set to `false` to disable the APM app. Defaults to `true`. -| `xpack.apm.ui.enabled` +| `xpack.apm.ui.enabled` {ess-icon} | Set to `false` to hide the APM app from the menu. Defaults to `true`. | `xpack.apm.ui.transactionGroupBucketSize` | Number of top transaction groups displayed in the APM app. Defaults to `100`. -| `xpack.apm.ui.maxTraceItems` +| `xpack.apm.ui.maxTraceItems` {ess-icon} | Maximum number of child items displayed when viewing trace details. Defaults to `1000`. -| `apm_oss.indexPattern` +| `apm_oss.indexPattern` {ess-icon} | The index pattern used for integrations with Machine Learning and Query Bar. It must match all apm indices. Defaults to `apm-*`. -| `apm_oss.errorIndices` +| `apm_oss.errorIndices` {ess-icon} | Matcher for all {apm-server-ref}/error-indices.html[error indices]. Defaults to `apm-*`. | `apm_oss.onboardingIndices` | Matcher for all onboarding indices. Defaults to `apm-*`. -| `apm_oss.spanIndices` +| `apm_oss.spanIndices` {ess-icon} | Matcher for all {apm-server-ref}/span-indices.html[span indices]. Defaults to `apm-*`. -| `apm_oss.transactionIndices` +| `apm_oss.transactionIndices` {ess-icon} | Matcher for all {apm-server-ref}/transaction-indices.html[transaction indices]. Defaults to `apm-*`. | `apm_oss.metricsIndices` From 45cad352229475f042e63b4a218f2afaf7a4867b Mon Sep 17 00:00:00 2001 From: Dmitry Lemeshko Date: Tue, 19 May 2020 00:41:27 +0200 Subject: [PATCH 015/129] [services/testSubjects] reduce retry usage, add waitForEnabled (#66538) Co-authored-by: Elastic Machine --- test/functional/page_objects/home_page.ts | 3 +- .../services/common/test_subjects.ts | 59 +++++++++---------- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/test/functional/page_objects/home_page.ts b/test/functional/page_objects/home_page.ts index 215e3360bbd5b..6a503f4f73b66 100644 --- a/test/functional/page_objects/home_page.ts +++ b/test/functional/page_objects/home_page.ts @@ -53,8 +53,7 @@ export function HomePageProvider({ getService, getPageObjects }: FtrProviderCont async removeSampleDataSet(id: string) { // looks like overkill but we're hitting flaky cases where we click but it doesn't remove - await testSubjects.isDisplayed(`removeSampleDataSet${id}`); - await testSubjects.isEnabled(`removeSampleDataSet${id}`); + await testSubjects.waitForEnabled(`removeSampleDataSet${id}`); await testSubjects.click(`removeSampleDataSet${id}`); await this._waitForSampleDataLoadingAction(id); } diff --git a/test/functional/services/common/test_subjects.ts b/test/functional/services/common/test_subjects.ts index e4e0e7ce70bc4..c71154ba2ec6a 100644 --- a/test/functional/services/common/test_subjects.ts +++ b/test/functional/services/common/test_subjects.ts @@ -97,12 +97,10 @@ export function TestSubjectsProvider({ getService }: FtrProviderContext) { } public async append(selector: string, text: string): Promise { - return await retry.try(async () => { - log.debug(`TestSubjects.append(${selector}, ${text})`); - const input = await this.find(selector); - await input.click(); - await input.type(text); - }); + log.debug(`TestSubjects.append(${selector}, ${text})`); + const input = await this.find(selector); + await input.click(); + await input.type(text); } public async clickWhenNotDisabled( @@ -119,12 +117,10 @@ export function TestSubjectsProvider({ getService }: FtrProviderContext) { } public async doubleClick(selector: string, timeout: number = FIND_TIME): Promise { - return await retry.try(async () => { - log.debug(`TestSubjects.doubleClick(${selector})`); - const element = await this.find(selector, timeout); - await element.moveMouseTo(); - await element.doubleClick(); - }); + log.debug(`TestSubjects.doubleClick(${selector})`); + const element = await this.find(selector, timeout); + await element.moveMouseTo(); + await element.doubleClick(); } async descendantExists(selector: string, parentElement: WebElementWrapper): Promise { @@ -210,27 +206,21 @@ export function TestSubjectsProvider({ getService }: FtrProviderContext) { } public async isEnabled(selector: string): Promise { - return await retry.try(async () => { - log.debug(`TestSubjects.isEnabled(${selector})`); - const element = await this.find(selector); - return await element.isEnabled(); - }); + log.debug(`TestSubjects.isEnabled(${selector})`); + const element = await this.find(selector); + return await element.isEnabled(); } public async isDisplayed(selector: string): Promise { - return await retry.try(async () => { - log.debug(`TestSubjects.isDisplayed(${selector})`); - const element = await this.find(selector); - return await element.isDisplayed(); - }); + log.debug(`TestSubjects.isDisplayed(${selector})`); + const element = await this.find(selector); + return await element.isDisplayed(); } public async isSelected(selector: string): Promise { - return await retry.try(async () => { - log.debug(`TestSubjects.isSelected(${selector})`); - const element = await this.find(selector); - return await element.isSelected(); - }); + log.debug(`TestSubjects.isSelected(${selector})`); + const element = await this.find(selector); + return await element.isSelected(); } public async isSelectedAll(selectorAll: string): Promise { @@ -241,11 +231,9 @@ export function TestSubjectsProvider({ getService }: FtrProviderContext) { } public async getVisibleText(selector: string): Promise { - return await retry.try(async () => { - log.debug(`TestSubjects.getVisibleText(${selector})`); - const element = await this.find(selector); - return await element.getVisibleText(); - }); + log.debug(`TestSubjects.getVisibleText(${selector})`); + const element = await this.find(selector); + return await element.getVisibleText(); } async getVisibleTextAll(selectorAll: string): Promise { @@ -298,6 +286,13 @@ export function TestSubjectsProvider({ getService }: FtrProviderContext) { await find.waitForElementHidden(element, timeout); } + public async waitForEnabled(selector: string, timeout: number = TRY_TIME): Promise { + await retry.tryForTime(timeout, async () => { + const element = await this.find(selector); + return (await element.isDisplayed()) && (await element.isEnabled()); + }); + } + public getCssSelector(selector: string): string { return testSubjSelector(selector); } From 1964b7796d59203896d0de466dda0ad2476e3e5f Mon Sep 17 00:00:00 2001 From: Jonathan Buttner <56361221+jonathan-buttner@users.noreply.github.com> Date: Mon, 18 May 2020 19:39:32 -0400 Subject: [PATCH 016/129] [Endpoint] Encode the index of the alert in the id response (#66919) * Encode the index of the alert in the id response * Fixing tests * Adding missed test --- .../endpoint/common/alert_constants.ts | 4 -- .../server/routes/alerts/details/handlers.ts | 18 ++++--- .../routes/alerts/details/lib/pagination.ts | 5 +- .../server/routes/alerts/lib/alert_id.ts | 48 +++++++++++++++++++ .../server/routes/alerts/lib/error.ts | 11 +++++ .../server/routes/alerts/lib/index.ts | 2 + .../server/routes/alerts/list/lib/index.ts | 4 +- .../api_integration/apis/endpoint/alerts.ts | 35 +++++++++----- 8 files changed, 102 insertions(+), 25 deletions(-) create mode 100644 x-pack/plugins/endpoint/server/routes/alerts/lib/alert_id.ts create mode 100644 x-pack/plugins/endpoint/server/routes/alerts/lib/error.ts diff --git a/x-pack/plugins/endpoint/common/alert_constants.ts b/x-pack/plugins/endpoint/common/alert_constants.ts index 85e1643d684f2..66de2b85ef3a7 100644 --- a/x-pack/plugins/endpoint/common/alert_constants.ts +++ b/x-pack/plugins/endpoint/common/alert_constants.ts @@ -13,10 +13,6 @@ export class AlertConstants { * The path for the Alert's Index Pattern API. */ static INDEX_PATTERN_ROUTE = `${AlertConstants.BASE_API_URL}/index_pattern`; - /** - * Alert's Index pattern - */ - static ALERT_INDEX_NAME = 'events-endpoint-1'; /** * A paramter passed to Alert's Index Pattern. */ diff --git a/x-pack/plugins/endpoint/server/routes/alerts/details/handlers.ts b/x-pack/plugins/endpoint/server/routes/alerts/details/handlers.ts index 92f8aacbf26a2..ab6d1850e425d 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/details/handlers.ts +++ b/x-pack/plugins/endpoint/server/routes/alerts/details/handlers.ts @@ -6,11 +6,11 @@ import { GetResponse } from 'elasticsearch'; import { KibanaRequest, RequestHandler } from 'kibana/server'; import { AlertEvent } from '../../../../common/types'; -import { AlertConstants } from '../../../../common/alert_constants'; import { EndpointAppContext } from '../../../types'; import { AlertDetailsRequestParams } from '../types'; import { AlertDetailsPagination } from './lib'; import { getHostData } from '../../metadata'; +import { AlertId, AlertIdError } from '../lib'; export const alertDetailsHandlerWrapper = function( endpointAppContext: EndpointAppContext @@ -21,10 +21,10 @@ export const alertDetailsHandlerWrapper = function( res ) => { try { - const alertId = req.params.id; + const alertId = AlertId.fromEncoded(req.params.id); const response = (await ctx.core.elasticsearch.dataClient.callAsCurrentUser('get', { - index: AlertConstants.ALERT_INDEX_NAME, - id: alertId, + index: alertId.index, + id: alertId.id, })) as GetResponse; const indexPattern = await endpointAppContext.service @@ -50,7 +50,7 @@ export const alertDetailsHandlerWrapper = function( return res.ok({ body: { - id: response._id, + id: alertId.toString(), ...response._source, state: { host_metadata: currentHostInfo?.metadata, @@ -60,7 +60,13 @@ export const alertDetailsHandlerWrapper = function( }, }); } catch (err) { - if (err.status === 404) { + const logger = endpointAppContext.logFactory.get('alerts'); + logger.warn(err); + + // err will be an AlertIdError if the passed in alert id is not valid + if (err instanceof AlertIdError) { + return res.badRequest({ body: err }); + } else if (err.status === 404) { return res.notFound({ body: err }); } return res.internalError({ body: err }); diff --git a/x-pack/plugins/endpoint/server/routes/alerts/details/lib/pagination.ts b/x-pack/plugins/endpoint/server/routes/alerts/details/lib/pagination.ts index 0f69e1bb60c44..5c95b1217d829 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/details/lib/pagination.ts +++ b/x-pack/plugins/endpoint/server/routes/alerts/details/lib/pagination.ts @@ -8,7 +8,7 @@ import { GetResponse, SearchResponse } from 'elasticsearch'; import { AlertEvent, AlertHits, AlertAPIOrdering } from '../../../../../common/types'; import { AlertConstants } from '../../../../../common/alert_constants'; import { EndpointConfigType } from '../../../../config'; -import { searchESForAlerts, Pagination } from '../../lib'; +import { searchESForAlerts, Pagination, AlertId } from '../../lib'; import { AlertSearchQuery, SearchCursor, AlertDetailsRequestParams } from '../../types'; import { BASE_ALERTS_ROUTE } from '../..'; import { RequestHandlerContext } from '../../../../../../../../src/core/server'; @@ -59,7 +59,8 @@ export class AlertDetailsPagination extends Pagination< protected getUrlFromHits(hits: AlertHits): string | null { if (hits.length > 0) { - return `${BASE_ALERTS_ROUTE}/${hits[0]._id}`; + const id = new AlertId(hits[0]._index, hits[0]._id); + return `${BASE_ALERTS_ROUTE}/${id.toString()}`; } return null; } diff --git a/x-pack/plugins/endpoint/server/routes/alerts/lib/alert_id.ts b/x-pack/plugins/endpoint/server/routes/alerts/lib/alert_id.ts new file mode 100644 index 0000000000000..797bf69f5991a --- /dev/null +++ b/x-pack/plugins/endpoint/server/routes/alerts/lib/alert_id.ts @@ -0,0 +1,48 @@ +/* + * 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 { AlertIdError } from './error'; + +/** + * Abstraction over alert IDs. + */ +export class AlertId { + protected readonly _index: string; + protected readonly _id: string; + + constructor(index: string, id: string) { + this._index = index; + this._id = id; + } + + public get index() { + return this._index; + } + + public get id() { + return this._id; + } + + static fromEncoded(encoded: string): AlertId { + try { + const value = encoded.replace(/\-/g, '+').replace(/_/g, '/'); + const data = Buffer.from(value, 'base64').toString('utf8'); + const { index, id } = JSON.parse(data); + return new AlertId(index, id); + } catch (error) { + throw new AlertIdError(`Unable to decode alert id: ${encoded}`); + } + } + + toString(): string { + const value = JSON.stringify({ index: this.index, id: this.id }); + // replace invalid URL characters with valid ones + return Buffer.from(value, 'utf8') + .toString('base64') + .replace(/\+/g, '-') + .replace(/\//g, '_') + .replace(/=+$/g, ''); + } +} diff --git a/x-pack/plugins/endpoint/server/routes/alerts/lib/error.ts b/x-pack/plugins/endpoint/server/routes/alerts/lib/error.ts new file mode 100644 index 0000000000000..7b00634b25c9c --- /dev/null +++ b/x-pack/plugins/endpoint/server/routes/alerts/lib/error.ts @@ -0,0 +1,11 @@ +/* + * 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. + */ + +export class AlertIdError extends Error { + constructor(message: string) { + super(message); + } +} diff --git a/x-pack/plugins/endpoint/server/routes/alerts/lib/index.ts b/x-pack/plugins/endpoint/server/routes/alerts/lib/index.ts index 7bc1c0c306ae2..1c98e3c615669 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/lib/index.ts +++ b/x-pack/plugins/endpoint/server/routes/alerts/lib/index.ts @@ -17,7 +17,9 @@ import { UndefinedResultPosition, } from '../types'; +export { AlertIdError } from './error'; export { Pagination } from './pagination'; +export { AlertId } from './alert_id'; function reverseSortDirection(order: AlertAPIOrdering): AlertAPIOrdering { if (order === 'asc') { diff --git a/x-pack/plugins/endpoint/server/routes/alerts/list/lib/index.ts b/x-pack/plugins/endpoint/server/routes/alerts/list/lib/index.ts index 114251820ce4b..0af8f6cf792dd 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/list/lib/index.ts +++ b/x-pack/plugins/endpoint/server/routes/alerts/list/lib/index.ts @@ -20,6 +20,7 @@ import { AlertConstants } from '../../../../../common/alert_constants'; import { EndpointAppContext } from '../../../../types'; import { AlertSearchQuery } from '../../types'; import { AlertListPagination } from './pagination'; +import { AlertId } from '../../lib'; export const getRequestData = async ( request: KibanaRequest, @@ -105,8 +106,9 @@ export async function mapToAlertResultList( const pagination: AlertListPagination = new AlertListPagination(config, reqCtx, reqData, hits); function mapHit(entry: AlertHits[0]): AlertData { + const alertId = new AlertId(entry._index, entry._id); return { - id: entry._id, + id: alertId.toString(), ...entry._source, prev: null, next: null, diff --git a/x-pack/test/api_integration/apis/endpoint/alerts.ts b/x-pack/test/api_integration/apis/endpoint/alerts.ts index 7e72a2f9072f3..94aaab2530247 100644 --- a/x-pack/test/api_integration/apis/endpoint/alerts.ts +++ b/x-pack/test/api_integration/apis/endpoint/alerts.ts @@ -6,6 +6,7 @@ import expect from '@kbn/expect/expect.js'; import { FtrProviderContext } from '../../ftr_provider_context'; import { AlertData } from '../../../../plugins/endpoint/common/types'; +import { AlertId } from '../../../../plugins/endpoint/server/routes/alerts/lib/index'; /** * The number of alert documents in the es archive. @@ -65,6 +66,7 @@ export default function({ getService }: FtrProviderContext) { const nextPrevPrefixOrder = 'order=desc'; const nextPrevPrefixPageSize = 'page_size=10'; const nextPrevPrefix = `${nextPrevPrefixQuery}&${nextPrevPrefixDateRange}&${nextPrevPrefixSort}&${nextPrevPrefixOrder}&${nextPrevPrefixPageSize}`; + const alertIndex = 'events-endpoint-1'; let nullableEventId = ''; @@ -74,7 +76,7 @@ export default function({ getService }: FtrProviderContext) { await esArchiver.load('endpoint/alerts/api_feature'); await esArchiver.load('endpoint/alerts/host_api_feature'); const res = await es.search({ - index: 'events-endpoint-1', + index: alertIndex, body: ES_QUERY_MISSING, }); nullableEventId = res.hits.hits[0]._source.event.id; @@ -377,36 +379,45 @@ export default function({ getService }: FtrProviderContext) { }); it('should return alert details by id, getting last alert', async () => { - const documentID = 'zbNm0HABdD75WLjLYgcB'; - const prevDocumentID = '2rNm0HABdD75WLjLYgcU'; + const documentID = new AlertId(alertIndex, 'zbNm0HABdD75WLjLYgcB'); + const prevDocumentID = new AlertId(alertIndex, '2rNm0HABdD75WLjLYgcU'); const { body } = await supertest - .get(`/api/endpoint/alerts/${documentID}`) + .get(`/api/endpoint/alerts/${documentID.toString()}`) .set('kbn-xsrf', 'xxx') .expect(200); - expect(body.id).to.eql(documentID); - expect(body.prev).to.eql(`/api/endpoint/alerts/${prevDocumentID}`); + expect(body.id).to.eql(documentID.toString()); + expect(body.prev).to.eql(`/api/endpoint/alerts/${prevDocumentID.toString()}`); expect(body.next).to.eql(null); // last alert, no more beyond this expect(body.state.host_metadata.host.id).to.eql(body.host.id); }); it('should return alert details by id, getting first alert', async () => { - const documentID = 'p7Nm0HABdD75WLjLYghv'; - const nextDocumentID = 'mbNm0HABdD75WLjLYgho'; + const documentID = new AlertId(alertIndex, 'p7Nm0HABdD75WLjLYghv'); + const nextDocumentID = new AlertId(alertIndex, 'mbNm0HABdD75WLjLYgho'); const { body } = await supertest - .get(`/api/endpoint/alerts/${documentID}`) + .get(`/api/endpoint/alerts/${documentID.toString()}`) .set('kbn-xsrf', 'xxx') .expect(200); - expect(body.id).to.eql(documentID); - expect(body.next).to.eql(`/api/endpoint/alerts/${nextDocumentID}`); + expect(body.id).to.eql(documentID.toString()); + expect(body.next).to.eql(`/api/endpoint/alerts/${nextDocumentID.toString()}`); expect(body.prev).to.eql(null); // first alert, no more before this }); it('should return 404 when alert is not found', async () => { + const documentID = new AlertId(alertIndex, 'does-not-exit'); + await supertest - .get('/api/endpoint/alerts/does-not-exist') + .get(`/api/endpoint/alerts/${documentID.toString()}`) .set('kbn-xsrf', 'xxx') .expect(404); }); + + it('should return 400 when alert id is not valid', async () => { + await supertest + .get('/api/endpoint/alerts/does-not-exist') + .set('kbn-xsrf', 'xxx') + .expect(400); + }); }); }); } From 951c0f65287d022be423448d4002819be4d171a3 Mon Sep 17 00:00:00 2001 From: Garrett Spong Date: Mon, 18 May 2020 17:55:12 -0600 Subject: [PATCH 017/129] [SIEM] [Maps] Fixes Network Map empty tooltip (#66828) ## Summary Resolves https://github.com/elastic/kibana/issues/63474, and expands `ITooltipProperty`'s `rawValue` type to include `string[]` as mentioned [here](https://github.com/elastic/kibana/pull/61264#discussion_r398858559). ![image](https://user-images.githubusercontent.com/2946766/82100568-2c0e1480-96c7-11ea-958e-5b1c6b6a3db9.png) ### Checklist Delete any items that are not applicable to this PR. - [X] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios --- .../public/classes/fields/es_agg_field.ts | 2 +- .../public/classes/fields/es_doc_field.ts | 2 +- .../maps/public/classes/fields/field.ts | 4 +- .../fields/top_term_percentage_field.ts | 2 +- .../classes/tooltips/es_tooltip_property.ts | 9 +++- .../classes/tooltips/join_tooltip_property.ts | 2 +- .../classes/tooltips/tooltip_property.ts | 10 ++-- x-pack/plugins/maps/public/index.ts | 1 + .../point_tool_tip_content.test.tsx.snap | 3 +- .../line_tool_tip_content.test.tsx | 27 ++++------- .../map_tool_tip/line_tool_tip_content.tsx | 19 ++++---- .../embeddables/map_tool_tip/map_tool_tip.tsx | 7 +-- .../point_tool_tip_content.test.tsx | 46 ++----------------- .../map_tool_tip/point_tool_tip_content.tsx | 27 +++++------ .../network/components/embeddables/types.ts | 10 ---- 15 files changed, 59 insertions(+), 112 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/fields/es_agg_field.ts b/x-pack/plugins/maps/public/classes/fields/es_agg_field.ts index 4a3ac6390c5a7..60d437d2321b5 100644 --- a/x-pack/plugins/maps/public/classes/fields/es_agg_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/es_agg_field.ts @@ -87,7 +87,7 @@ export class ESAggField implements IESAggField { return this._esDocField ? this._esDocField.getName() : ''; } - async createTooltipProperty(value: string | undefined): Promise { + async createTooltipProperty(value: string | string[] | undefined): Promise { const indexPattern = await this._source.getIndexPattern(); const tooltipProperty = new TooltipProperty(this.getName(), await this.getLabel(), value); return new ESAggTooltipProperty(tooltipProperty, indexPattern, this, this.getAggType()); diff --git a/x-pack/plugins/maps/public/classes/fields/es_doc_field.ts b/x-pack/plugins/maps/public/classes/fields/es_doc_field.ts index 670b3ba32888b..9faa33fae5a43 100644 --- a/x-pack/plugins/maps/public/classes/fields/es_doc_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/es_doc_field.ts @@ -45,7 +45,7 @@ export class ESDocField extends AbstractField implements IField { : indexPatternField; } - async createTooltipProperty(value: string | undefined): Promise { + async createTooltipProperty(value: string | string[] | undefined): Promise { const indexPattern = await this._source.getIndexPattern(); const tooltipProperty = new TooltipProperty(this.getName(), await this.getLabel(), value); return new ESTooltipProperty(tooltipProperty, indexPattern, this as IField); diff --git a/x-pack/plugins/maps/public/classes/fields/field.ts b/x-pack/plugins/maps/public/classes/fields/field.ts index 04daedc59c032..dfd5dc05f7b83 100644 --- a/x-pack/plugins/maps/public/classes/fields/field.ts +++ b/x-pack/plugins/maps/public/classes/fields/field.ts @@ -14,7 +14,7 @@ export interface IField { canValueBeFormatted(): boolean; getLabel(): Promise; getDataType(): Promise; - createTooltipProperty(value: string | undefined): Promise; + createTooltipProperty(value: string | string[] | undefined): Promise; getSource(): IVectorSource; getOrigin(): FIELD_ORIGIN; isValid(): boolean; @@ -60,7 +60,7 @@ export class AbstractField implements IField { return this._fieldName; } - async createTooltipProperty(value: string | undefined): Promise { + async createTooltipProperty(value: string | string[] | undefined): Promise { const label = await this.getLabel(); return new TooltipProperty(this.getName(), label, value); } diff --git a/x-pack/plugins/maps/public/classes/fields/top_term_percentage_field.ts b/x-pack/plugins/maps/public/classes/fields/top_term_percentage_field.ts index 84bade4d94490..6c504daf3e192 100644 --- a/x-pack/plugins/maps/public/classes/fields/top_term_percentage_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/top_term_percentage_field.ts @@ -48,7 +48,7 @@ export class TopTermPercentageField implements IESAggField { return 'number'; } - async createTooltipProperty(value: string | undefined): Promise { + async createTooltipProperty(value: string | string[] | undefined): Promise { return new TooltipProperty(this.getName(), await this.getLabel(), value); } diff --git a/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.ts b/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.ts index d2fdcfaab476c..516ad25f933f6 100644 --- a/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.ts +++ b/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.ts @@ -33,7 +33,7 @@ export class ESTooltipProperty implements ITooltipProperty { return this._tooltipProperty.getPropertyName(); } - getRawValue(): string | undefined { + getRawValue(): string | string[] | undefined { return this._tooltipProperty.getRawValue(); } @@ -48,7 +48,12 @@ export class ESTooltipProperty implements ITooltipProperty { const indexPatternField = this._getIndexPatternField(); if (!indexPatternField || !this._field.canValueBeFormatted()) { - return _.escape(this.getRawValue()); + const rawValue = this.getRawValue(); + if (Array.isArray(rawValue)) { + return _.escape(rawValue.join()); + } else { + return _.escape(rawValue); + } } const htmlConverter = indexPatternField.format.getConverterFor('html'); diff --git a/x-pack/plugins/maps/public/classes/tooltips/join_tooltip_property.ts b/x-pack/plugins/maps/public/classes/tooltips/join_tooltip_property.ts index cc95c12ef630f..fad6d6b84f77f 100644 --- a/x-pack/plugins/maps/public/classes/tooltips/join_tooltip_property.ts +++ b/x-pack/plugins/maps/public/classes/tooltips/join_tooltip_property.ts @@ -29,7 +29,7 @@ export class JoinTooltipProperty implements ITooltipProperty { return this._tooltipProperty.getPropertyName(); } - getRawValue(): string | undefined { + getRawValue(): string | string[] | undefined { return this._tooltipProperty.getRawValue(); } diff --git a/x-pack/plugins/maps/public/classes/tooltips/tooltip_property.ts b/x-pack/plugins/maps/public/classes/tooltips/tooltip_property.ts index 8da2ed795943b..7149fe29f90ec 100644 --- a/x-pack/plugins/maps/public/classes/tooltips/tooltip_property.ts +++ b/x-pack/plugins/maps/public/classes/tooltips/tooltip_property.ts @@ -12,7 +12,7 @@ export interface ITooltipProperty { getPropertyKey(): string; getPropertyName(): string; getHtmlDisplayValue(): string; - getRawValue(): string | undefined; + getRawValue(): string | string[] | undefined; isFilterable(): boolean; getESFilters(): Promise; } @@ -41,10 +41,10 @@ export type RenderToolTipContent = (params: RenderTooltipContentParams) => JSX.E export class TooltipProperty implements ITooltipProperty { private readonly _propertyKey: string; - private readonly _rawValue: string | undefined; + private readonly _rawValue: string | string[] | undefined; private readonly _propertyName: string; - constructor(propertyKey: string, propertyName: string, rawValue: string | undefined) { + constructor(propertyKey: string, propertyName: string, rawValue: string | string[] | undefined) { this._propertyKey = propertyKey; this._propertyName = propertyName; this._rawValue = rawValue; @@ -59,10 +59,10 @@ export class TooltipProperty implements ITooltipProperty { } getHtmlDisplayValue(): string { - return _.escape(this._rawValue); + return _.escape(Array.isArray(this._rawValue) ? this._rawValue.join() : this._rawValue); } - getRawValue(): string | undefined { + getRawValue(): string | string[] | undefined { return this._rawValue; } diff --git a/x-pack/plugins/maps/public/index.ts b/x-pack/plugins/maps/public/index.ts index e3feb47691877..79953e35d51e5 100644 --- a/x-pack/plugins/maps/public/index.ts +++ b/x-pack/plugins/maps/public/index.ts @@ -12,3 +12,4 @@ export const plugin: PluginInitializer = () => }; export { MAP_SAVED_OBJECT_TYPE } from '../common/constants'; +export { ITooltipProperty } from './classes/tooltips/tooltip_property'; diff --git a/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/__snapshots__/point_tool_tip_content.test.tsx.snap b/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/__snapshots__/point_tool_tip_content.test.tsx.snap index 9d39b6e59365f..8927e492993d0 100644 --- a/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/__snapshots__/point_tool_tip_content.test.tsx.snap +++ b/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/__snapshots__/point_tool_tip_content.test.tsx.snap @@ -6,8 +6,9 @@ exports[`PointToolTipContent renders correctly against snapshot 1`] = ` contextId="contextId" featureProps={ Array [ - Object { + TooltipProperty { "_propertyKey": "host.name", + "_propertyName": "host.name", "_rawValue": "testPropValue", }, ] diff --git a/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/line_tool_tip_content.test.tsx b/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/line_tool_tip_content.test.tsx index a0e57a2e850c1..aef41ddaef5ae 100644 --- a/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/line_tool_tip_content.test.tsx +++ b/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/line_tool_tip_content.test.tsx @@ -7,35 +7,24 @@ import { shallow } from 'enzyme'; import React from 'react'; import { LineToolTipContentComponent } from './line_tool_tip_content'; -import { FeatureProperty } from '../types'; import { SUM_OF_CLIENT_BYTES, SUM_OF_DESTINATION_BYTES, SUM_OF_SERVER_BYTES, SUM_OF_SOURCE_BYTES, } from '../map_config'; +import { ITooltipProperty } from '../../../../../../maps/public'; +import { TooltipProperty } from '../../../../../../maps/public/classes/tooltips/tooltip_property'; describe('LineToolTipContent', () => { - const mockFeatureProps: FeatureProperty[] = [ - { - _propertyKey: SUM_OF_DESTINATION_BYTES, - _rawValue: 'testPropValue', - }, - { - _propertyKey: SUM_OF_SOURCE_BYTES, - _rawValue: 'testPropValue', - }, + const mockFeatureProps: ITooltipProperty[] = [ + new TooltipProperty(SUM_OF_DESTINATION_BYTES, SUM_OF_DESTINATION_BYTES, 'testPropValue'), + new TooltipProperty(SUM_OF_SOURCE_BYTES, SUM_OF_SOURCE_BYTES, 'testPropValue'), ]; - const mockClientServerFeatureProps: FeatureProperty[] = [ - { - _propertyKey: SUM_OF_SERVER_BYTES, - _rawValue: 'testPropValue', - }, - { - _propertyKey: SUM_OF_CLIENT_BYTES, - _rawValue: 'testPropValue', - }, + const mockClientServerFeatureProps: ITooltipProperty[] = [ + new TooltipProperty(SUM_OF_SERVER_BYTES, SUM_OF_SERVER_BYTES, 'testPropValue'), + new TooltipProperty(SUM_OF_CLIENT_BYTES, SUM_OF_CLIENT_BYTES, 'testPropValue'), ]; test('renders correctly against snapshot', () => { diff --git a/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/line_tool_tip_content.tsx b/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/line_tool_tip_content.tsx index 7c2d5e51d813f..9238f7ec65a20 100644 --- a/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/line_tool_tip_content.tsx +++ b/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/line_tool_tip_content.tsx @@ -14,8 +14,9 @@ import { SUM_OF_SERVER_BYTES, SUM_OF_SOURCE_BYTES, } from '../map_config'; -import { FeatureProperty } from '../types'; + import * as i18n from '../translations'; +import { ITooltipProperty } from '../../../../../../maps/public'; const FlowBadge = (styled(EuiBadge)` height: 45px; @@ -28,20 +29,22 @@ const EuiFlexGroupStyled = styled(EuiFlexGroup)` interface LineToolTipContentProps { contextId: string; - featureProps: FeatureProperty[]; + featureProps: ITooltipProperty[]; } export const LineToolTipContentComponent = ({ contextId, featureProps, }: LineToolTipContentProps) => { - const lineProps = featureProps.reduce>( - (acc, f) => ({ + const lineProps = featureProps.reduce>((acc, f) => { + const rawValue = f.getRawValue() ?? []; + return { ...acc, - ...{ [f._propertyKey]: Array.isArray(f._rawValue) ? f._rawValue : [f._rawValue] }, - }), - {} - ); + ...{ + [f.getPropertyKey()]: Array.isArray(rawValue) ? rawValue : [rawValue], + }, + }; + }, {}); const isSrcDest = Object.keys(lineProps).includes(SUM_OF_SOURCE_BYTES); diff --git a/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/map_tool_tip.tsx b/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/map_tool_tip.tsx index 0f38c350986b4..10267d398848e 100644 --- a/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/map_tool_tip.tsx +++ b/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/map_tool_tip.tsx @@ -11,12 +11,13 @@ import { EuiLoadingSpinner, EuiOutsideClickDetector, } from '@elastic/eui'; -import { FeatureGeometry, FeatureProperty, MapToolTipProps } from '../types'; +import { FeatureGeometry, MapToolTipProps } from '../types'; import { ToolTipFooter } from './tooltip_footer'; import { LineToolTipContent } from './line_tool_tip_content'; import { PointToolTipContent } from './point_tool_tip_content'; import { Loader } from '../../../../common/components/loader'; import * as i18n from '../translations'; +import { ITooltipProperty } from '../../../../../../maps/public'; export const MapToolTipComponent = ({ addFilters, @@ -31,7 +32,7 @@ export const MapToolTipComponent = ({ const [isLoadingNextFeature, setIsLoadingNextFeature] = useState(false); const [isError, setIsError] = useState(false); const [featureIndex, setFeatureIndex] = useState(0); - const [featureProps, setFeatureProps] = useState([]); + const [featureProps, setFeatureProps] = useState([]); const [featureGeometry, setFeatureGeometry] = useState(null); const [, setLayerName] = useState(''); @@ -64,7 +65,7 @@ export const MapToolTipComponent = ({ getLayerName(layerId), ]); - setFeatureProps((featureProperties as unknown) as FeatureProperty[]); + setFeatureProps(featureProperties); setFeatureGeometry(featureGeo); setLayerName(layerNameString); } catch (e) { diff --git a/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx b/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx index d5a7c51ccdeb8..36b9f44e19630 100644 --- a/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx +++ b/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx @@ -6,29 +6,17 @@ import { shallow } from 'enzyme'; import React from 'react'; -import { FeatureProperty } from '../types'; import { getRenderedFieldValue, PointToolTipContentComponent } from './point_tool_tip_content'; import { TestProviders } from '../../../../common/mock'; import { getEmptyStringTag } from '../../../../common/components/empty_value'; import { HostDetailsLink, IPDetailsLink } from '../../../../common/components/links'; -import { useMountAppended } from '../../../../common/utils/use_mount_appended'; import { FlowTarget } from '../../../../graphql/types'; +import { ITooltipProperty } from '../../../../../../maps/public'; +import { TooltipProperty } from '../../../../../../maps/public/classes/tooltips/tooltip_property'; describe('PointToolTipContent', () => { - const mount = useMountAppended(); - - const mockFeatureProps: FeatureProperty[] = [ - { - _propertyKey: 'host.name', - _rawValue: 'testPropValue', - }, - ]; - - const mockFeaturePropsArrayValue: FeatureProperty[] = [ - { - _propertyKey: 'host.name', - _rawValue: ['testPropValue1', 'testPropValue2'], - }, + const mockFeatureProps: ITooltipProperty[] = [ + new TooltipProperty('host.name', 'host.name', 'testPropValue'), ]; test('renders correctly against snapshot', () => { @@ -46,32 +34,6 @@ describe('PointToolTipContent', () => { expect(wrapper.find('PointToolTipContentComponent')).toMatchSnapshot(); }); - test('renders array filter correctly', () => { - const closeTooltip = jest.fn(); - - const wrapper = mount( - - - - ); - expect(wrapper.find('[data-test-subj="add-to-kql-host.name"]').prop('filter')).toEqual({ - meta: { - alias: null, - disabled: false, - key: 'host.name', - negate: false, - params: { query: 'testPropValue1' }, - type: 'phrase', - value: 'testPropValue1', - }, - query: { match: { 'host.name': { query: 'testPropValue1', type: 'phrase' } } }, - }); - }); - describe('#getRenderedFieldValue', () => { test('it returns empty tag if value is empty', () => { expect(getRenderedFieldValue('host.name', '')).toStrictEqual(getEmptyStringTag()); diff --git a/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.tsx b/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.tsx index c691407f6166e..16494c01ac280 100644 --- a/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.tsx +++ b/x-pack/plugins/siem/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.tsx @@ -6,23 +6,19 @@ import React from 'react'; import { sourceDestinationFieldMappings } from '../map_config'; -import { - AddFilterToGlobalSearchBar, - createFilter, -} from '../../../../common/components/add_filter_to_global_search_bar'; import { getEmptyTagValue, getOrEmptyTagFromValue, } from '../../../../common/components/empty_value'; import { DescriptionListStyled } from '../../../../common/components/page'; -import { FeatureProperty } from '../types'; import { HostDetailsLink, IPDetailsLink } from '../../../../common/components/links'; import { DefaultFieldRenderer } from '../../../../timelines/components/field_renderers/field_renderers'; import { FlowTarget } from '../../../../graphql/types'; +import { ITooltipProperty } from '../../../../../../maps/public'; interface PointToolTipContentProps { contextId: string; - featureProps: FeatureProperty[]; + featureProps: ITooltipProperty[]; closeTooltip?(): void; } @@ -31,15 +27,14 @@ export const PointToolTipContentComponent = ({ featureProps, closeTooltip, }: PointToolTipContentProps) => { - const featureDescriptionListItems = featureProps.map( - ({ _propertyKey: key, _rawValue: value }) => ({ + const featureDescriptionListItems = featureProps.map(featureProp => { + const key = featureProp.getPropertyKey(); + const value = featureProp.getRawValue() ?? []; + + return { title: sourceDestinationFieldMappings[key], description: ( - + <> {value != null ? ( + ), - }) - ); + }; + }); return ; }; diff --git a/x-pack/plugins/siem/public/network/components/embeddables/types.ts b/x-pack/plugins/siem/public/network/components/embeddables/types.ts index e111c2728ba7e..9a49046634c3b 100644 --- a/x-pack/plugins/siem/public/network/components/embeddables/types.ts +++ b/x-pack/plugins/siem/public/network/components/embeddables/types.ts @@ -40,16 +40,6 @@ export interface MapFeature { layerId: string; } -export interface LoadFeatureProps { - layerId: string; - featureId: number; -} - -export interface FeatureProperty { - _propertyKey: string; - _rawValue: string | string[]; -} - export interface FeatureGeometry { coordinates: [number]; type: string; From 114a0a13a5a84a7db215b4a3db8de9036397fe63 Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Mon, 18 May 2020 17:13:45 -0700 Subject: [PATCH 018/129] [Reporting] Consolidate Server Type Defs, move some out of Legacy (#66144) * [Reporting] consolidate server types, move some to NP * Revert touching routes code Co-authored-by: Elastic Machine --- .../reporting/common/get_absolute_url.ts | 8 +- .../export_types/common/constants.ts | 5 - .../execute_job/decrypt_job_headers.test.ts | 7 +- .../common/execute_job/decrypt_job_headers.ts | 5 +- .../get_conditional_headers.test.ts | 4 +- .../execute_job/get_conditional_headers.ts | 4 +- .../common/execute_job/get_custom_logo.ts | 4 +- .../common/execute_job/get_full_urls.ts | 2 +- .../common/layouts/create_layout.ts | 4 +- .../export_types/common/layouts/index.ts | 59 +++- .../export_types/common/layouts/layout.ts | 50 +--- .../common/layouts/preserve_layout.ts | 5 +- .../common/layouts/print_layout.ts | 6 +- .../screenshots/get_element_position_data.ts | 12 +- .../lib/screenshots/get_number_of_items.ts | 6 +- .../common/lib/screenshots/get_screenshots.ts | 6 +- .../common/lib/screenshots/get_time_range.ts | 15 +- .../common/lib/screenshots/index.ts | 2 +- .../common/lib/screenshots/inject_css.ts | 4 +- .../common/lib/screenshots/observable.test.ts | 9 +- .../common/lib/screenshots/observable.ts | 23 +- .../common/lib/screenshots/open_url.ts | 7 +- .../common/lib/screenshots/types.ts | 49 ---- .../common/lib/screenshots/wait_for_render.ts | 6 +- .../screenshots/wait_for_visualizations.ts | 6 +- .../reporting/export_types/csv/index.ts | 14 +- .../export_types/csv/server/create_job.ts | 4 +- .../csv/server/execute_job.test.ts | 13 +- .../export_types/csv/server/execute_job.ts | 10 +- .../csv/server/lib/escape_value.ts | 2 +- .../csv/server/lib/field_format_map.ts | 10 +- .../csv/server/lib/format_csv_values.ts | 4 +- .../csv/server/lib/generate_csv.ts | 4 +- .../csv/server/lib/hit_iterator.test.ts | 6 +- .../csv/server/lib/hit_iterator.ts | 5 +- .../reporting/export_types/csv/types.d.ts | 7 +- .../csv_from_savedobject/index.ts | 14 +- .../server/create_job/create_job.ts | 17 +- .../server/create_job/create_job_search.ts | 2 +- .../server/create_job/index.ts | 2 +- .../server/execute_job.ts | 19 +- .../server/lib/generate_csv.ts | 7 +- .../server/lib/generate_csv_search.ts | 10 +- .../server/lib/get_filters.test.ts | 8 +- .../server/lib/get_filters.ts | 10 +- .../server/lib/get_job_params_from_request.ts | 4 +- .../csv_from_savedobject/types.d.ts | 8 +- .../reporting/export_types/png/index.ts | 18 +- .../png/server/create_job/index.ts | 4 +- .../png/server/execute_job/index.test.ts | 14 +- .../png/server/execute_job/index.ts | 5 +- .../png/server/lib/generate_png.ts | 5 +- .../reporting/export_types/png/types.d.ts | 4 +- .../export_types/printable_pdf/index.ts | 18 +- .../printable_pdf/server/create_job/index.ts | 4 +- .../server/execute_job/index.test.ts | 14 +- .../printable_pdf/server/execute_job/index.ts | 5 +- .../printable_pdf/server/lib/generate_pdf.ts | 10 +- .../export_types/printable_pdf/types.d.ts | 4 +- x-pack/legacy/plugins/reporting/index.ts | 3 +- .../chromium/driver/chromium_driver.ts | 31 +- .../browsers/chromium/driver_factory/index.ts | 12 +- .../browsers/create_browser_driver_factory.ts | 6 +- .../browsers/download/ensure_downloaded.ts | 3 +- .../reporting/server/browsers/index.ts | 14 + .../reporting/server/browsers/install.ts | 10 +- .../server/browsers/network_policy.ts | 12 +- .../server/browsers/safe_child_process.ts | 4 +- .../reporting/server/browsers/types.d.ts | 19 -- .../plugins/reporting/server/config/index.ts | 5 +- .../legacy/plugins/reporting/server/core.ts | 35 +-- .../legacy/plugins/reporting/server/index.ts | 5 +- .../legacy/plugins/reporting/server/legacy.ts | 2 +- .../reporting/server/lib/check_license.ts | 3 +- .../reporting/server/lib/create_queue.ts | 30 +- .../server/lib/create_tagged_logger.ts | 4 +- .../server/lib/create_worker.test.ts | 2 +- .../reporting/server/lib/create_worker.ts | 16 +- .../reporting/server/lib/enqueue_job.ts | 31 +- .../__tests__/helpers/cancellation_token.js | 75 ----- .../reporting/server/lib/esqueue/worker.js | 8 +- .../server/lib/export_types_registry.ts | 4 +- .../plugins/reporting/server/lib/get_user.ts | 4 +- .../reporting/server/lib/jobs_query.ts | 4 +- .../reporting/server/lib/once_per_server.ts | 43 --- .../reporting/server/lib/validate/index.ts | 6 +- .../server/lib/validate/validate_browser.ts | 4 +- .../validate/validate_max_content_length.ts | 6 +- .../legacy/plugins/reporting/server/plugin.ts | 3 +- .../server/routes/generate_from_jobparams.ts | 7 +- .../routes/generate_from_savedobject.ts | 12 +- .../generate_from_savedobject_immediate.ts | 17 +- .../server/routes/generation.test.ts | 8 +- .../reporting/server/routes/generation.ts | 6 +- .../plugins/reporting/server/routes/index.ts | 5 +- .../reporting/server/routes/jobs.test.ts | 9 +- .../plugins/reporting/server/routes/jobs.ts | 18 +- .../routes/lib/authorized_user_pre_routing.ts | 4 +- .../server/routes/lib/get_document_payload.ts | 3 +- .../server/routes/lib/job_response_handler.ts | 4 +- .../server/routes/lib/make_request_facade.ts | 2 +- .../lib/reporting_feature_pre_routing.ts | 5 +- .../routes/lib/route_config_factories.ts | 5 +- .../reporting/server/routes/types.d.ts | 4 +- .../plugins/reporting/server/types.d.ts | 45 --- .../legacy/plugins/reporting/server/types.ts | 243 +++++++++++++++ .../server/usage/get_reporting_usage.ts | 15 +- .../usage/reporting_usage_collector.test.ts | 6 +- .../server/usage/reporting_usage_collector.ts | 10 +- .../server/usage/{types.d.ts => types.ts} | 60 ++++ .../create_mock_browserdriverfactory.ts | 7 +- .../create_mock_layoutinstance.ts | 4 +- .../create_mock_reportingplugin.ts | 2 +- .../test_helpers/create_mock_server.ts | 2 +- x-pack/legacy/plugins/reporting/types.d.ts | 277 ------------------ .../common/cancellation_token.test.ts | 0 .../reporting/common/cancellation_token.ts | 0 .../reporting/common/index.ts} | 2 +- x-pack/plugins/reporting/common/poller.ts | 2 +- x-pack/plugins/reporting/common/types.d.ts | 8 - .../reporting/{index.d.ts => common/types.ts} | 3 + .../public/components/job_download_button.tsx | 4 +- .../public/components/job_failure.tsx | 6 +- .../public/components/job_success.tsx | 4 +- .../components/job_warning_formulas.tsx | 4 +- .../components/job_warning_max_size.tsx | 4 +- .../reporting/public/lib/license_check.ts | 3 +- .../public/lib/reporting_api_client.ts | 5 +- .../public/lib/stream_handler.test.ts | 2 +- .../reporting/public/lib/stream_handler.ts | 2 +- x-pack/plugins/reporting/public/plugin.tsx | 5 +- x-pack/plugins/reporting/server/index.ts | 4 +- 132 files changed, 870 insertions(+), 965 deletions(-) delete mode 100644 x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts delete mode 100644 x-pack/legacy/plugins/reporting/server/browsers/types.d.ts delete mode 100644 x-pack/legacy/plugins/reporting/server/lib/esqueue/__tests__/helpers/cancellation_token.js delete mode 100644 x-pack/legacy/plugins/reporting/server/lib/once_per_server.ts delete mode 100644 x-pack/legacy/plugins/reporting/server/types.d.ts create mode 100644 x-pack/legacy/plugins/reporting/server/types.ts rename x-pack/legacy/plugins/reporting/server/usage/{types.d.ts => types.ts} (65%) delete mode 100644 x-pack/legacy/plugins/reporting/types.d.ts rename x-pack/{legacy => }/plugins/reporting/common/cancellation_token.test.ts (100%) rename x-pack/{legacy => }/plugins/reporting/common/cancellation_token.ts (100%) rename x-pack/{legacy/plugins/reporting/export_types/csv/server/lib/types.d.ts => plugins/reporting/common/index.ts} (80%) delete mode 100644 x-pack/plugins/reporting/common/types.d.ts rename x-pack/plugins/reporting/{index.d.ts => common/types.ts} (93%) diff --git a/x-pack/legacy/plugins/reporting/common/get_absolute_url.ts b/x-pack/legacy/plugins/reporting/common/get_absolute_url.ts index 0e350cb1ec011..f996a49e5eadc 100644 --- a/x-pack/legacy/plugins/reporting/common/get_absolute_url.ts +++ b/x-pack/legacy/plugins/reporting/common/get_absolute_url.ts @@ -5,7 +5,13 @@ */ import url from 'url'; -import { AbsoluteURLFactoryOptions } from '../types'; + +interface AbsoluteURLFactoryOptions { + defaultBasePath: string; + protocol: string; + hostname: string; + port: string | number; +} export const getAbsoluteUrlFactory = ({ protocol, diff --git a/x-pack/legacy/plugins/reporting/export_types/common/constants.ts b/x-pack/legacy/plugins/reporting/export_types/common/constants.ts index 6c56c269017e2..76fab923978f8 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/constants.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/constants.ts @@ -4,9 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export const LayoutTypes = { - PRESERVE_LAYOUT: 'preserve_layout', - PRINT: 'print', -}; - export const DEFAULT_PAGELOAD_SELECTOR = '.application'; diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.test.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.test.ts index 9085fb3cbc876..fe3ac16b79fe0 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.test.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.test.ts @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { cryptoFactory } from '../../../server/lib/crypto'; -import { Logger } from '../../../types'; +import { cryptoFactory, LevelLogger } from '../../../server/lib'; import { decryptJobHeaders } from './decrypt_job_headers'; const encryptHeaders = async (encryptionKey: string, headers: Record) => { @@ -23,7 +22,7 @@ describe('headers', () => { }, logger: ({ error: jest.fn(), - } as unknown) as Logger, + } as unknown) as LevelLogger, }); await expect(getDecryptedHeaders()).rejects.toMatchInlineSnapshot( `[Error: Failed to decrypt report job data. Please ensure that xpack.reporting.encryptionKey is set and re-generate this report. Error: Invalid IV length]` @@ -44,7 +43,7 @@ describe('headers', () => { type: 'csv', headers: encryptedHeaders, }, - logger: {} as Logger, + logger: {} as LevelLogger, }); expect(decryptedHeaders).toEqual(headers); }); diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts index 0436f5d5bc843..a13c1fa2a9efb 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts @@ -5,8 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { cryptoFactory } from '../../../server/lib/crypto'; -import { Logger } from '../../../types'; +import { cryptoFactory, LevelLogger } from '../../../server/lib'; interface HasEncryptedHeaders { headers?: string; @@ -23,7 +22,7 @@ export const decryptJobHeaders = async < }: { encryptionKey?: string; job: JobDocPayloadType; - logger: Logger; + logger: LevelLogger; }): Promise> => { try { if (typeof job.headers !== 'string') { diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.test.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.test.ts index 5f5fc94eee830..c09cc8314374e 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.test.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.test.ts @@ -5,9 +5,9 @@ */ import sinon from 'sinon'; +import { ReportingConfig, ReportingCore } from '../../../server'; +import { JobDocPayload } from '../../../server/types'; import { createMockReportingCore } from '../../../test_helpers'; -import { ReportingConfig, ReportingCore } from '../../../server/types'; -import { JobDocPayload } from '../../../types'; import { JobDocPayloadPDF } from '../../printable_pdf/types'; import { getConditionalHeaders, getCustomLogo } from './index'; diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.ts index bd7999d697ca9..808d5db5c57d5 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ReportingConfig } from '../../../server/types'; -import { ConditionalHeaders } from '../../../types'; +import { ReportingConfig } from '../../../server'; +import { ConditionalHeaders } from '../../../server/types'; export const getConditionalHeaders = ({ config, diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.ts index a13f992e7867c..777de317af41e 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.ts @@ -5,8 +5,8 @@ */ import { UI_SETTINGS_CUSTOM_PDF_LOGO } from '../../../common/constants'; -import { ReportingConfig, ReportingCore } from '../../../server/types'; -import { ConditionalHeaders } from '../../../types'; +import { ReportingConfig, ReportingCore } from '../../../server'; +import { ConditionalHeaders } from '../../../server/types'; import { JobDocPayloadPDF } from '../../printable_pdf/types'; // Logo is PDF only export const getCustomLogo = async ({ diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.ts index c4b6f31019fdf..59cb7ce14ca2d 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.ts @@ -12,7 +12,7 @@ import { } from 'url'; import { getAbsoluteUrlFactory } from '../../../common/get_absolute_url'; import { validateUrls } from '../../../common/validate_urls'; -import { ReportingConfig } from '../../../server/types'; +import { ReportingConfig } from '../../../server'; import { JobDocPayloadPNG } from '../../png/types'; import { JobDocPayloadPDF } from '../../printable_pdf/types'; diff --git a/x-pack/legacy/plugins/reporting/export_types/common/layouts/create_layout.ts b/x-pack/legacy/plugins/reporting/export_types/common/layouts/create_layout.ts index 07fceb603e451..d33760fcb4f89 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/layouts/create_layout.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/layouts/create_layout.ts @@ -5,8 +5,8 @@ */ import { CaptureConfig } from '../../../server/types'; -import { LayoutTypes } from '../constants'; -import { Layout, LayoutParams } from './layout'; +import { LayoutParams, LayoutTypes } from './'; +import { Layout } from './layout'; import { PreserveLayout } from './preserve_layout'; import { PrintLayout } from './print_layout'; diff --git a/x-pack/legacy/plugins/reporting/export_types/common/layouts/index.ts b/x-pack/legacy/plugins/reporting/export_types/common/layouts/index.ts index fd35485779ba0..993b8f6cdc9ab 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/layouts/index.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/layouts/index.ts @@ -4,6 +4,63 @@ * you may not use this file except in compliance with the Elastic License. */ +import { HeadlessChromiumDriver } from '../../../server/browsers'; +import { LevelLogger } from '../../../server/lib'; +import { Layout } from './layout'; + export { createLayout } from './create_layout'; -export { PrintLayout } from './print_layout'; +export { Layout } from './layout'; export { PreserveLayout } from './preserve_layout'; +export { PrintLayout } from './print_layout'; + +export const LayoutTypes = { + PRESERVE_LAYOUT: 'preserve_layout', + PRINT: 'print', +}; + +export const getDefaultLayoutSelectors = (): LayoutSelectorDictionary => ({ + screenshot: '[data-shared-items-container]', + renderComplete: '[data-shared-item]', + itemsCountAttribute: 'data-shared-items-count', + timefilterDurationAttribute: 'data-shared-timefilter-duration', +}); + +export interface PageSizeParams { + pageMarginTop: number; + pageMarginBottom: number; + pageMarginWidth: number; + tableBorderWidth: number; + headingHeight: number; + subheadingHeight: number; +} + +export interface LayoutSelectorDictionary { + screenshot: string; + renderComplete: string; + itemsCountAttribute: string; + timefilterDurationAttribute: string; +} + +export interface PdfImageSize { + width: number; + height?: number; +} + +export interface Size { + width: number; + height: number; +} + +export interface LayoutParams { + id: string; + dimensions: Size; +} + +interface LayoutSelectors { + // Fields that are not part of Layout: the instances + // independently implement these fields on their own + selectors: LayoutSelectorDictionary; + positionElements?: (browser: HeadlessChromiumDriver, logger: LevelLogger) => Promise; +} + +export type LayoutInstance = Layout & LayoutSelectors & Size; diff --git a/x-pack/legacy/plugins/reporting/export_types/common/layouts/layout.ts b/x-pack/legacy/plugins/reporting/export_types/common/layouts/layout.ts index 5cd2f3e636a93..433edb35df4cd 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/layouts/layout.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/layouts/layout.ts @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HeadlessChromiumDriver } from '../../../server/browsers/chromium/driver'; -import { LevelLogger } from '../../../server/lib'; +import { PageSizeParams, PdfImageSize, Size } from './'; export interface ViewZoomWidthHeight { zoom: number; @@ -13,34 +12,6 @@ export interface ViewZoomWidthHeight { height: number; } -export interface PageSizeParams { - pageMarginTop: number; - pageMarginBottom: number; - pageMarginWidth: number; - tableBorderWidth: number; - headingHeight: number; - subheadingHeight: number; -} - -export interface LayoutSelectorDictionary { - screenshot: string; - renderComplete: string; - itemsCountAttribute: string; - timefilterDurationAttribute: string; -} - -export interface PdfImageSize { - width: number; - height?: number; -} - -export const getDefaultLayoutSelectors = (): LayoutSelectorDictionary => ({ - screenshot: '[data-shared-items-container]', - renderComplete: '[data-shared-item]', - itemsCountAttribute: 'data-shared-items-count', - timefilterDurationAttribute: 'data-shared-timefilter-duration', -}); - export abstract class Layout { public id: string = ''; @@ -62,22 +33,3 @@ export abstract class Layout { public abstract getCssOverridesPath(): string; } - -export interface Size { - width: number; - height: number; -} - -export interface LayoutParams { - id: string; - dimensions: Size; -} - -interface LayoutSelectors { - // Fields that are not part of Layout: the instances - // independently implement these fields on their own - selectors: LayoutSelectorDictionary; - positionElements?: (browser: HeadlessChromiumDriver, logger: LevelLogger) => Promise; -} - -export type LayoutInstance = Layout & LayoutSelectors & Size; diff --git a/x-pack/legacy/plugins/reporting/export_types/common/layouts/preserve_layout.ts b/x-pack/legacy/plugins/reporting/export_types/common/layouts/preserve_layout.ts index 07dbba7d25883..9041055ddce2d 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/layouts/preserve_layout.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/layouts/preserve_layout.ts @@ -3,15 +3,16 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + import path from 'path'; -import { LayoutTypes } from '../constants'; import { getDefaultLayoutSelectors, Layout, LayoutSelectorDictionary, + LayoutTypes, PageSizeParams, Size, -} from './layout'; +} from './'; // We use a zoom of two to bump up the resolution of the screenshot a bit. const ZOOM: number = 2; diff --git a/x-pack/legacy/plugins/reporting/export_types/common/layouts/print_layout.ts b/x-pack/legacy/plugins/reporting/export_types/common/layouts/print_layout.ts index f6974379253fb..759f07a33e2b6 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/layouts/print_layout.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/layouts/print_layout.ts @@ -6,11 +6,11 @@ import path from 'path'; import { EvaluateFn, SerializableOrJSHandle } from 'puppeteer'; -import { HeadlessChromiumDriver } from '../../../server/browsers'; import { LevelLogger } from '../../../server/lib'; +import { HeadlessChromiumDriver } from '../../../server/browsers'; import { CaptureConfig } from '../../../server/types'; -import { LayoutTypes } from '../constants'; -import { getDefaultLayoutSelectors, Layout, LayoutSelectorDictionary, Size } from './layout'; +import { getDefaultLayoutSelectors, LayoutSelectorDictionary, Size, LayoutTypes } from './'; +import { Layout } from './layout'; export class PrintLayout extends Layout { public readonly selectors: LayoutSelectorDictionary = { diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_element_position_data.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_element_position_data.ts index 3999393600e48..d02e852a3c1b6 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_element_position_data.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_element_position_data.ts @@ -5,16 +5,16 @@ */ import { i18n } from '@kbn/i18n'; -import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers'; -import { LevelLogger as Logger, startTrace } from '../../../../server/lib'; -import { LayoutInstance } from '../../layouts/layout'; +import { HeadlessChromiumDriver } from '../../../../server/browsers'; +import { LevelLogger, startTrace } from '../../../../server/lib'; +import { AttributesMap, ElementsPositionAndAttribute } from '../../../../server/types'; +import { LayoutInstance } from '../../layouts'; import { CONTEXT_ELEMENTATTRIBUTES } from './constants'; -import { AttributesMap, ElementsPositionAndAttribute } from './types'; export const getElementPositionAndAttributes = async ( - browser: HeadlessBrowser, + browser: HeadlessChromiumDriver, layout: LayoutInstance, - logger: Logger + logger: LevelLogger ): Promise => { const endTrace = startTrace('get_element_position_data', 'read'); const { screenshot: screenshotSelector } = layout.selectors; // data-shared-items-container diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_number_of_items.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_number_of_items.ts index d0c1a2a3ce672..9e446f499ab3a 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_number_of_items.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_number_of_items.ts @@ -5,15 +5,15 @@ */ import { i18n } from '@kbn/i18n'; -import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers'; import { LevelLogger, startTrace } from '../../../../server/lib'; +import { HeadlessChromiumDriver } from '../../../../server/browsers'; import { CaptureConfig } from '../../../../server/types'; -import { LayoutInstance } from '../../layouts/layout'; +import { LayoutInstance } from '../../layouts'; import { CONTEXT_GETNUMBEROFITEMS, CONTEXT_READMETADATA } from './constants'; export const getNumberOfItems = async ( captureConfig: CaptureConfig, - browser: HeadlessBrowser, + browser: HeadlessChromiumDriver, layout: LayoutInstance, logger: LevelLogger ): Promise => { diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_screenshots.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_screenshots.ts index bc9e17854b27d..578a4dd0b975c 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_screenshots.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_screenshots.ts @@ -5,12 +5,12 @@ */ import { i18n } from '@kbn/i18n'; -import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers'; +import { HeadlessChromiumDriver } from '../../../../server/browsers'; import { LevelLogger, startTrace } from '../../../../server/lib'; -import { Screenshot, ElementsPositionAndAttribute } from './types'; +import { ElementsPositionAndAttribute, Screenshot } from '../../../../server/types'; export const getScreenshots = async ( - browser: HeadlessBrowser, + browser: HeadlessChromiumDriver, elementsPositionAndAttributes: ElementsPositionAndAttribute[], logger: LevelLogger ): Promise => { diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_time_range.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_time_range.ts index bcd4cf9000df4..7bdb38298c383 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_time_range.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/get_time_range.ts @@ -4,21 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers'; import { LevelLogger, startTrace } from '../../../../server/lib'; -import { LayoutInstance } from '../../layouts/layout'; +import { HeadlessChromiumDriver } from '../../../../server/browsers'; +import { LayoutInstance } from '../../layouts'; import { CONTEXT_GETTIMERANGE } from './constants'; -import { TimeRange } from './types'; export const getTimeRange = async ( - browser: HeadlessBrowser, + browser: HeadlessChromiumDriver, layout: LayoutInstance, logger: LevelLogger -): Promise => { +): Promise => { const endTrace = startTrace('get_time_range', 'read'); logger.debug('getting timeRange'); - const timeRange: TimeRange | null = await browser.evaluate( + const timeRange = await browser.evaluate( { fn: durationAttribute => { const durationElement = document.querySelector(`[${durationAttribute}]`); @@ -32,7 +31,7 @@ export const getTimeRange = async ( return null; } - return { duration }; + return duration; // user-friendly date string }, args: [layout.selectors.timefilterDurationAttribute], }, @@ -41,7 +40,7 @@ export const getTimeRange = async ( ); if (timeRange) { - logger.info(`timeRange: ${timeRange.duration}`); + logger.info(`timeRange: ${timeRange}`); } else { logger.debug('no timeRange'); } diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/index.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/index.ts index 0d75b067fbe63..5a04f1a497abf 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/index.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { screenshotsObservableFactory, ScreenshotsObservableFn } from './observable'; +export { screenshotsObservableFactory } from './observable'; diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/inject_css.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/inject_css.ts index 40bb84870b16d..dae6f3cc6350f 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/inject_css.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/inject_css.ts @@ -7,15 +7,15 @@ import { i18n } from '@kbn/i18n'; import fs from 'fs'; import { promisify } from 'util'; -import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers'; import { LevelLogger, startTrace } from '../../../../server/lib'; +import { HeadlessChromiumDriver } from '../../../../server/browsers'; import { Layout } from '../../layouts/layout'; import { CONTEXT_INJECTCSS } from './constants'; const fsp = { readFile: promisify(fs.readFile) }; export const injectCustomCss = async ( - browser: HeadlessBrowser, + browser: HeadlessChromiumDriver, layout: Layout, logger: LevelLogger ): Promise => { diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.test.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.test.ts index 796bccb360ebd..cc8b438310430 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.test.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.test.ts @@ -18,13 +18,16 @@ jest.mock('../../../../server/browsers/chromium/puppeteer', () => ({ import * as Rx from 'rxjs'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { loggingServiceMock } from '../../../../../../../../src/core/server/mocks'; +import { HeadlessChromiumDriver } from '../../../../server/browsers'; import { LevelLogger } from '../../../../server/lib'; +import { + CaptureConfig, + ConditionalHeaders, + ElementsPositionAndAttribute, +} from '../../../../server/types'; import { createMockBrowserDriverFactory, createMockLayoutInstance } from '../../../../test_helpers'; -import { ConditionalHeaders, HeadlessChromiumDriver } from '../../../../types'; -import { CaptureConfig } from '../../../../server/types'; import * as contexts from './constants'; import { screenshotsObservableFactory } from './observable'; -import { ElementsPositionAndAttribute } from './types'; /* * Mocks diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.ts index 282490a28d591..de27d5ad30014 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/observable.ts @@ -16,29 +16,32 @@ import { tap, toArray, } from 'rxjs/operators'; -import { CaptureConfig } from '../../../../server/types'; +import { HeadlessChromiumDriverFactory } from '../../../../server/browsers'; +import { + CaptureConfig, + ElementsPositionAndAttribute, + ScreenshotObservableOpts, + ScreenshotResults, + ScreenshotsObservableFn, +} from '../../../../server/types'; import { DEFAULT_PAGELOAD_SELECTOR } from '../../constants'; -import { HeadlessChromiumDriverFactory } from '../../../../types'; import { getElementPositionAndAttributes } from './get_element_position_data'; import { getNumberOfItems } from './get_number_of_items'; import { getScreenshots } from './get_screenshots'; import { getTimeRange } from './get_time_range'; import { injectCustomCss } from './inject_css'; import { openUrl } from './open_url'; -import { ScreenSetupData, ScreenshotObservableOpts, ScreenshotResults } from './types'; import { waitForRenderComplete } from './wait_for_render'; import { waitForVisualizations } from './wait_for_visualizations'; const DEFAULT_SCREENSHOT_CLIP_HEIGHT = 1200; const DEFAULT_SCREENSHOT_CLIP_WIDTH = 1800; -export type ScreenshotsObservableFn = ({ - logger, - urls, - conditionalHeaders, - layout, - browserTimezone, -}: ScreenshotObservableOpts) => Rx.Observable; +interface ScreenSetupData { + elementsPositionAndAttributes: ElementsPositionAndAttribute[] | null; + timeRange: string | null; + error?: Error; +} export function screenshotsObservableFactory( captureConfig: CaptureConfig, diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/open_url.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/open_url.ts index a0708b7dba36b..3cf962b8178fd 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/open_url.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/open_url.ts @@ -5,14 +5,13 @@ */ import { i18n } from '@kbn/i18n'; -import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers'; +import { HeadlessChromiumDriver } from '../../../../server/browsers'; import { LevelLogger, startTrace } from '../../../../server/lib'; -import { CaptureConfig } from '../../../../server/types'; -import { ConditionalHeaders } from '../../../../types'; +import { CaptureConfig, ConditionalHeaders } from '../../../../server/types'; export const openUrl = async ( captureConfig: CaptureConfig, - browser: HeadlessBrowser, + browser: HeadlessChromiumDriver, url: string, pageLoadSelector: string, conditionalHeaders: ConditionalHeaders, diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts deleted file mode 100644 index 13ddf5eb74fcf..0000000000000 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts +++ /dev/null @@ -1,49 +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 { LevelLogger } from '../../../../server/lib'; -import { ConditionalHeaders, ElementPosition } from '../../../../types'; -import { LayoutInstance } from '../../layouts/layout'; - -export interface ScreenshotObservableOpts { - logger: LevelLogger; - urls: string[]; - conditionalHeaders: ConditionalHeaders; - layout: LayoutInstance; - browserTimezone: string; -} - -export interface TimeRange { - duration: string; -} - -export interface AttributesMap { - [key: string]: any; -} - -export interface ElementsPositionAndAttribute { - position: ElementPosition; - attributes: AttributesMap; -} - -export interface Screenshot { - base64EncodedData: string; - title: string; - description: string; -} - -export interface ScreenSetupData { - elementsPositionAndAttributes: ElementsPositionAndAttribute[] | null; - timeRange: TimeRange | null; - error?: Error; -} - -export interface ScreenshotResults { - timeRange: TimeRange | null; - screenshots: Screenshot[]; - error?: Error; - elementsPositionAndAttributes?: ElementsPositionAndAttribute[]; // NOTE: for testing -} diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/wait_for_render.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/wait_for_render.ts index fe92fbc9077e6..0e02fa2dacfad 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/wait_for_render.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/wait_for_render.ts @@ -5,15 +5,15 @@ */ import { i18n } from '@kbn/i18n'; -import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers'; import { LevelLogger, startTrace } from '../../../../server/lib'; +import { HeadlessChromiumDriver } from '../../../../server/browsers'; import { CaptureConfig } from '../../../../server/types'; -import { LayoutInstance } from '../../layouts/layout'; +import { LayoutInstance } from '../../layouts'; import { CONTEXT_WAITFORRENDER } from './constants'; export const waitForRenderComplete = async ( captureConfig: CaptureConfig, - browser: HeadlessBrowser, + browser: HeadlessChromiumDriver, layout: LayoutInstance, logger: LevelLogger ) => { diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/wait_for_visualizations.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/wait_for_visualizations.ts index d456c4089ecee..ff84d06956dbc 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/wait_for_visualizations.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/wait_for_visualizations.ts @@ -5,10 +5,10 @@ */ import { i18n } from '@kbn/i18n'; -import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers'; import { LevelLogger, startTrace } from '../../../../server/lib'; +import { HeadlessChromiumDriver } from '../../../../server/browsers'; import { CaptureConfig } from '../../../../server/types'; -import { LayoutInstance } from '../../layouts/layout'; +import { LayoutInstance } from '../../layouts'; import { CONTEXT_WAITFORELEMENTSTOBEINDOM } from './constants'; type SelectorArgs = Record; @@ -24,7 +24,7 @@ const getCompletedItemsCount = ({ renderCompleteSelector }: SelectorArgs) => { */ export const waitForVisualizations = async ( captureConfig: CaptureConfig, - browser: HeadlessBrowser, + browser: HeadlessChromiumDriver, itemsCount: number, layout: LayoutInstance, logger: LevelLogger diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/index.ts b/x-pack/legacy/plugins/reporting/export_types/csv/index.ts index 942cb954785ac..cdb4c36dba3df 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/index.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/index.ts @@ -6,18 +6,22 @@ import { CSV_JOB_TYPE as jobType, - LICENSE_TYPE_TRIAL, LICENSE_TYPE_BASIC, - LICENSE_TYPE_STANDARD, + LICENSE_TYPE_ENTERPRISE, LICENSE_TYPE_GOLD, LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, + LICENSE_TYPE_STANDARD, + LICENSE_TYPE_TRIAL, } from '../../common/constants'; -import { ExportTypeDefinition, ESQueueCreateJobFn, ESQueueWorkerExecuteFn } from '../../types'; +import { + ESQueueCreateJobFn, + ESQueueWorkerExecuteFn, + ExportTypeDefinition, +} from '../../server/types'; import { metadata } from './metadata'; import { createJobFactory } from './server/create_job'; import { executeJobFactory } from './server/execute_job'; -import { JobParamsDiscoverCsv, JobDocPayloadDiscoverCsv } from './types'; +import { JobDocPayloadDiscoverCsv, JobParamsDiscoverCsv } from './types'; export const getExportType = (): ExportTypeDefinition< JobParamsDiscoverCsv, diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/create_job.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/create_job.ts index 0e704a041452a..8320cd05aa2e7 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/create_job.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/create_job.ts @@ -5,13 +5,13 @@ */ import { ReportingCore } from '../../../server'; -import { cryptoFactory } from '../../../server/lib/crypto'; +import { cryptoFactory } from '../../../server/lib'; import { ConditionalHeaders, CreateJobFactory, ESQueueCreateJobFn, RequestFacade, -} from '../../../types'; +} from '../../../server/types'; import { JobParamsDiscoverCsv } from '../types'; export const createJobFactory: CreateJobFactory new Promise(resolve => setTimeout(() => resolve(), ms)); @@ -65,6 +65,7 @@ describe('CSV Execute Job', function() { beforeEach(async function() { configGetStub = sinon.stub(); + configGetStub.withArgs('index').returns('.reporting-foo-test'); configGetStub.withArgs('encryptionKey').returns(encryptionKey); configGetStub.withArgs('csv', 'maxSizeBytes').returns(1024 * 1000); // 1mB configGetStub.withArgs('csv', 'scroll').returns({}); diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts index dbe305bc452db..7d95c45d5d233 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts @@ -7,18 +7,18 @@ import { i18n } from '@kbn/i18n'; import Hapi from 'hapi'; import { IUiSettingsClient, KibanaRequest } from '../../../../../../../src/core/server'; -import { CSV_JOB_TYPE, CSV_BOM_CHARS } from '../../../common/constants'; -import { ReportingCore } from '../../../server/core'; -import { cryptoFactory } from '../../../server/lib'; +import { CSV_BOM_CHARS, CSV_JOB_TYPE } from '../../../common/constants'; +import { ReportingCore } from '../../../server'; +import { cryptoFactory, LevelLogger } from '../../../server/lib'; import { getFieldFormats } from '../../../server/services'; -import { ESQueueWorkerExecuteFn, ExecuteJobFactory, Logger } from '../../../types'; +import { ESQueueWorkerExecuteFn, ExecuteJobFactory } from '../../../server/types'; import { JobDocPayloadDiscoverCsv } from '../types'; import { fieldFormatMapFactory } from './lib/field_format_map'; import { createGenerateCsv } from './lib/generate_csv'; export const executeJobFactory: ExecuteJobFactory> = async function executeJobFactoryFn(reporting: ReportingCore, parentLogger: Logger) { +>> = async function executeJobFactoryFn(reporting: ReportingCore, parentLogger: LevelLogger) { const config = reporting.getConfig(); const crypto = cryptoFactory(config.get('encryptionKey')); const logger = parentLogger.clone([CSV_JOB_TYPE, 'execute-job']); diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/escape_value.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/escape_value.ts index 60e75d74b2f98..344091ee18268 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/escape_value.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/escape_value.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RawValue } from './types'; +import { RawValue } from '../../types'; import { cellHasFormulas } from './cell_has_formula'; const nonAlphaNumRE = /[^a-zA-Z0-9]/; diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/field_format_map.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/field_format_map.ts index dac963635c469..e1459e195d9f6 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/field_format_map.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/field_format_map.ts @@ -9,7 +9,15 @@ import { FieldFormatConfig, IFieldFormatsRegistry, } from '../../../../../../../../src/plugins/data/server'; -import { IndexPatternSavedObject } from '../../../../types'; + +interface IndexPatternSavedObject { + attributes: { + fieldFormatMap: string; + }; + id: string; + type: string; + version: string; +} /** * Create a map of FieldFormat instances for index pattern fields diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/format_csv_values.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/format_csv_values.ts index 0bcf0fc31beae..35093f45fdd5b 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/format_csv_values.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/format_csv_values.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isObject, isNull, isUndefined } from 'lodash'; -import { RawValue } from './types'; +import { isNull, isObject, isUndefined } from 'lodash'; +import { RawValue } from '../../types'; export function createFormatCsvValues( escapeValue: (value: RawValue, index: number, array: RawValue[]) => string, diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/generate_csv.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/generate_csv.ts index c7996ebf832a1..a8fdd8d1a5bbc 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/generate_csv.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/generate_csv.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { Logger } from '../../../../types'; +import { LevelLogger } from '../../../../server/lib'; import { GenerateCsvParams, SavedSearchGeneratorResult } from '../../types'; import { createFlattenHit } from './flatten_hit'; import { createFormatCsvValues } from './format_csv_values'; @@ -14,7 +14,7 @@ import { createHitIterator } from './hit_iterator'; import { MaxSizeStringBuilder } from './max_size_string_builder'; import { checkIfRowsHaveFormulas } from './check_cells_for_formulas'; -export function createGenerateCsv(logger: Logger) { +export function createGenerateCsv(logger: LevelLogger) { const hitIterator = createHitIterator(logger); return async function generateCsv({ diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/hit_iterator.test.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/hit_iterator.test.ts index a9f0015e49360..905d9cd68b128 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/hit_iterator.test.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/hit_iterator.test.ts @@ -6,16 +6,16 @@ import expect from '@kbn/expect'; import sinon from 'sinon'; -import { CancellationToken } from '../../../../common/cancellation_token'; +import { CancellationToken } from '../../../../../../../plugins/reporting/common'; +import { LevelLogger } from '../../../../server/lib'; import { ScrollConfig } from '../../../../server/types'; -import { Logger } from '../../../../types'; import { createHitIterator } from './hit_iterator'; const mockLogger = { error: new Function(), debug: new Function(), warning: new Function(), -} as Logger; +} as LevelLogger; const debugLogStub = sinon.stub(mockLogger, 'debug'); const warnLogStub = sinon.stub(mockLogger, 'warning'); const errorLogStub = sinon.stub(mockLogger, 'error'); 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 index 2ca19dd07a627..803161910443e 100644 --- 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 @@ -6,8 +6,9 @@ import { i18n } from '@kbn/i18n'; import { SearchParams, SearchResponse } from 'elasticsearch'; +import { CancellationToken } from '../../../../../../../plugins/reporting/common'; +import { LevelLogger } from '../../../../server/lib'; import { ScrollConfig } from '../../../../server/types'; -import { CancellationToken, Logger } from '../../../../types'; async function parseResponse(request: SearchResponse) { const response = await request; @@ -35,7 +36,7 @@ async function parseResponse(request: SearchResponse) { }; } -export function createHitIterator(logger: Logger) { +export function createHitIterator(logger: LevelLogger) { return async function* hitIterator( scrollSettings: ScrollConfig, callEndpoint: Function, diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/types.d.ts b/x-pack/legacy/plugins/reporting/export_types/csv/types.d.ts index 40a42db352635..0f6223d8553de 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/types.d.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/types.d.ts @@ -4,9 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CancellationToken } from '../../common/cancellation_token'; -import { ScrollConfig } from '../../server/types'; -import { JobDocPayload, JobParamPostPayload } from '../../types'; +import { CancellationToken } from '../../../../../plugins/reporting/common'; +import { JobDocPayload, JobParamPostPayload, ScrollConfig } from '../../server/types'; + +export type RawValue = string | object | null | undefined; interface DocValueField { field: string; diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/index.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/index.ts index 606630944c604..570b91600cbe0 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/index.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/index.ts @@ -6,25 +6,25 @@ import { CSV_FROM_SAVEDOBJECT_JOB_TYPE, - LICENSE_TYPE_TRIAL, LICENSE_TYPE_BASIC, - LICENSE_TYPE_STANDARD, + LICENSE_TYPE_ENTERPRISE, LICENSE_TYPE_GOLD, LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, + LICENSE_TYPE_STANDARD, + LICENSE_TYPE_TRIAL, } from '../../common/constants'; -import { ExportTypeDefinition, ImmediateCreateJobFn, ImmediateExecuteFn } from '../../types'; -import { createJobFactory } from './server/create_job'; -import { executeJobFactory } from './server/execute_job'; +import { ExportTypeDefinition } from '../../server/types'; import { metadata } from './metadata'; +import { createJobFactory, ImmediateCreateJobFn } from './server/create_job'; +import { executeJobFactory, ImmediateExecuteFn } from './server/execute_job'; import { JobParamsPanelCsv } from './types'; /* * These functions are exported to share with the API route handler that * generates csv from saved object immediately on request. */ -export { executeJobFactory } from './server/execute_job'; export { createJobFactory } from './server/create_job'; +export { executeJobFactory } from './server/execute_job'; export const getExportType = (): ExportTypeDefinition< JobParamsPanelCsv, diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/create_job.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/create_job.ts index 8e0376a190267..ed0e17454260f 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/create_job.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/create_job.ts @@ -8,8 +8,8 @@ import { notFound, notImplemented } from 'boom'; import { get } from 'lodash'; import { CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../../../common/constants'; import { ReportingCore } from '../../../../server'; -import { cryptoFactory } from '../../../../server/lib'; -import { CreateJobFactory, ImmediateCreateJobFn, Logger, RequestFacade } from '../../../../types'; +import { cryptoFactory, LevelLogger } from '../../../../server/lib'; +import { CreateJobFactory, RequestFacade, TimeRangeParams } from '../../../../server/types'; import { JobDocPayloadPanelCsv, JobParamsPanelCsv, @@ -17,11 +17,20 @@ import { SavedObjectServiceError, SavedSearchObjectAttributesJSON, SearchPanel, - TimeRangeParams, VisObjectAttributesJSON, } from '../../types'; import { createJobSearch } from './create_job_search'; +export type ImmediateCreateJobFn = ( + jobParams: JobParamsType, + headers: Record, + req: RequestFacade +) => Promise<{ + type: string | null; + title: string; + jobParams: JobParamsType; +}>; + interface VisData { title: string; visType: string; @@ -30,7 +39,7 @@ interface VisData { export const createJobFactory: CreateJobFactory> = function createJobFactoryFn(reporting: ReportingCore, parentLogger: Logger) { +>> = function createJobFactoryFn(reporting: ReportingCore, parentLogger: LevelLogger) { const config = reporting.getConfig(); const crypto = cryptoFactory(config.get('encryptionKey')); const logger = parentLogger.clone([CSV_FROM_SAVEDOBJECT_JOB_TYPE, 'create-job']); diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/create_job_search.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/create_job_search.ts index 69ffce57489b1..19204ef81c5eb 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/create_job_search.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/create_job_search.ts @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ +import { TimeRangeParams } from '../../../../server/types'; import { SavedObjectMeta, SavedObjectReference, SavedSearchObjectAttributes, SearchPanel, - TimeRangeParams, } from '../../types'; interface SearchPanelData { diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/index.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/index.ts index e129e3e5f47ec..a3674d69ae6a5 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/index.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { createJobFactory } from './create_job'; +export { createJobFactory, ImmediateCreateJobFn } from './create_job'; diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/execute_job.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/execute_job.ts index 8efcdc3bd9f30..5761a98ed160c 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/execute_job.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/execute_job.ts @@ -7,21 +7,30 @@ import { i18n } from '@kbn/i18n'; import { CONTENT_TYPE_CSV, CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../../common/constants'; import { ReportingCore } from '../../../server'; -import { cryptoFactory } from '../../../server/lib'; +import { cryptoFactory, LevelLogger } from '../../../server/lib'; import { ExecuteJobFactory, - ImmediateExecuteFn, JobDocOutput, - Logger, + JobDocPayload, RequestFacade, -} from '../../../types'; +} from '../../../server/types'; import { CsvResultFromSearch } from '../../csv/types'; import { FakeRequest, JobDocPayloadPanelCsv, JobParamsPanelCsv, SearchPanel } from '../types'; import { createGenerateCsv } from './lib'; +/* + * ImmediateExecuteFn receives the job doc payload because the payload was + * generated in the CreateFn + */ +export type ImmediateExecuteFn = ( + jobId: null, + job: JobDocPayload, + request: RequestFacade +) => Promise; + export const executeJobFactory: ExecuteJobFactory> = async function executeJobFactoryFn(reporting: ReportingCore, parentLogger: Logger) { +>> = async function executeJobFactoryFn(reporting: ReportingCore, parentLogger: LevelLogger) { const config = reporting.getConfig(); const crypto = cryptoFactory(config.get('encryptionKey')); const logger = parentLogger.clone([CSV_FROM_SAVEDOBJECT_JOB_TYPE, 'execute-job']); diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv.ts index c81060d8ca05d..8dcdee7ef24c1 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv.ts @@ -5,12 +5,13 @@ */ import { badRequest } from 'boom'; -import { ReportingCore } from '../../../../server/types'; -import { Logger, RequestFacade } from '../../../../types'; +import { ReportingCore } from '../../../../server'; +import { LevelLogger } from '../../../../server/lib'; +import { RequestFacade } from '../../../../server/types'; import { FakeRequest, JobParamsPanelCsv, SearchPanel, VisPanel } from '../../types'; import { generateCsvSearch } from './generate_csv_search'; -export function createGenerateCsv(reporting: ReportingCore, logger: Logger) { +export function createGenerateCsv(reporting: ReportingCore, logger: LevelLogger) { return async function generateCsv( request: RequestFacade | FakeRequest, visType: string, diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts index 2611b74c83de9..506208e4e1aad 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts @@ -11,13 +11,11 @@ import { Filter, IIndexPattern, Query, - // Reporting uses an unconventional directory structure so the linter marks this as a violation, server files should - // be moved under reporting/server/ - // eslint-disable-next-line @kbn/eslint/no-restricted-paths } from '../../../../../../../../src/plugins/data/server'; -import { CancellationToken } from '../../../../common/cancellation_token'; +import { CancellationToken } from '../../../../../../../plugins/reporting/common'; import { ReportingCore } from '../../../../server'; -import { Logger, RequestFacade } from '../../../../types'; +import { LevelLogger } from '../../../../server/lib'; +import { RequestFacade } from '../../../../server/types'; import { createGenerateCsv } from '../../../csv/server/lib/generate_csv'; import { CsvResultFromSearch, @@ -58,7 +56,7 @@ const getUiSettings = async (config: IUiSettingsClient) => { export async function generateCsvSearch( req: RequestFacade, reporting: ReportingCore, - logger: Logger, + logger: LevelLogger, searchPanel: SearchPanel, jobParams: JobParamsDiscoverCsv ): Promise { diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/get_filters.test.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/get_filters.test.ts index 1acb269e75493..110ce91ddfd79 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/get_filters.test.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/get_filters.test.ts @@ -4,12 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - QueryFilter, - SavedSearchObjectAttributes, - SearchSourceFilter, - TimeRangeParams, -} from '../../types'; +import { TimeRangeParams } from '../../../../server/types'; +import { QueryFilter, SavedSearchObjectAttributes, SearchSourceFilter } from '../../types'; import { getFilters } from './get_filters'; interface Args { diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/get_filters.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/get_filters.ts index 0e510eeb4073b..071427f4dab64 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/get_filters.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/get_filters.ts @@ -6,14 +6,8 @@ import { badRequest } from 'boom'; import moment from 'moment-timezone'; - -import { - Filter, - QueryFilter, - SavedSearchObjectAttributes, - SearchSourceFilter, - TimeRangeParams, -} from '../../types'; +import { TimeRangeParams } from '../../../../server/types'; +import { Filter, QueryFilter, SavedSearchObjectAttributes, SearchSourceFilter } from '../../types'; export function getFilters( indexPatternId: string, diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/get_job_params_from_request.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/get_job_params_from_request.ts index 8e5440b700d1e..57d74ee0e1383 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/get_job_params_from_request.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/get_job_params_from_request.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestFacade } from '../../../../types'; -import { JobParamsPostPayloadPanelCsv, JobParamsPanelCsv } from '../../types'; +import { RequestFacade } from '../../../../server/types'; +import { JobParamsPanelCsv, JobParamsPostPayloadPanelCsv } from '../../types'; export function getJobParamsFromRequest( request: RequestFacade, diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/types.d.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/types.d.ts index ab14d2dd8a660..f838268078503 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/types.d.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/types.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { JobDocPayload, JobParamPostPayload } from '../../types'; +import { JobDocPayload, JobParamPostPayload, TimeRangeParams } from '../../server/types'; export interface FakeRequest { headers: Record; @@ -114,12 +114,6 @@ export interface IndexPatternSavedObject { }; } -export interface TimeRangeParams { - timezone: string; - min: Date | string | number; - max: Date | string | number; -} - export interface VisPanel { indexPatternSavedObjectId?: string; savedSearchObjectId?: string; diff --git a/x-pack/legacy/plugins/reporting/export_types/png/index.ts b/x-pack/legacy/plugins/reporting/export_types/png/index.ts index b6206a8bf9599..04f56185d4910 100644 --- a/x-pack/legacy/plugins/reporting/export_types/png/index.ts +++ b/x-pack/legacy/plugins/reporting/export_types/png/index.ts @@ -5,18 +5,22 @@ */ import { - PNG_JOB_TYPE as jobType, - LICENSE_TYPE_TRIAL, - LICENSE_TYPE_STANDARD, + LICENSE_TYPE_ENTERPRISE, LICENSE_TYPE_GOLD, LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, + LICENSE_TYPE_STANDARD, + LICENSE_TYPE_TRIAL, + PNG_JOB_TYPE as jobType, } from '../../common/constants'; -import { ExportTypeDefinition, ESQueueCreateJobFn, ESQueueWorkerExecuteFn } from '../../types'; +import { + ESQueueCreateJobFn, + ESQueueWorkerExecuteFn, + ExportTypeDefinition, +} from '../../server/types'; +import { metadata } from './metadata'; import { createJobFactory } from './server/create_job'; import { executeJobFactory } from './server/execute_job'; -import { metadata } from './metadata'; -import { JobParamsPNG, JobDocPayloadPNG } from './types'; +import { JobDocPayloadPNG, JobParamsPNG } from './types'; export const getExportType = (): ExportTypeDefinition< JobParamsPNG, diff --git a/x-pack/legacy/plugins/reporting/export_types/png/server/create_job/index.ts b/x-pack/legacy/plugins/reporting/export_types/png/server/create_job/index.ts index 1f834bde88a2d..b19513de29eee 100644 --- a/x-pack/legacy/plugins/reporting/export_types/png/server/create_job/index.ts +++ b/x-pack/legacy/plugins/reporting/export_types/png/server/create_job/index.ts @@ -6,13 +6,13 @@ import { validateUrls } from '../../../../common/validate_urls'; import { ReportingCore } from '../../../../server'; -import { cryptoFactory } from '../../../../server/lib/crypto'; +import { cryptoFactory } from '../../../../server/lib'; import { ConditionalHeaders, CreateJobFactory, ESQueueCreateJobFn, RequestFacade, -} from '../../../../types'; +} from '../../../../server/types'; import { JobParamsPNG } from '../../types'; export const createJobFactory: CreateJobFactory { const executeJob = await executeJobFactory(mockReporting, getMockLogger()); const encryptedHeaders = await encryptHeaders({}); - const generatePngObservable = (await generatePngObservableFactory(mockReporting)) as jest.Mock; - generatePngObservable.mockReturnValue(Rx.of('foo')); + const generatePngObservable = await generatePngObservableFactory(mockReporting); + (generatePngObservable as jest.Mock).mockReturnValue(Rx.of('foo')); const { content_type: contentType } = await executeJob( 'pngJobId', @@ -138,9 +137,8 @@ test(`returns content_type of application/png`, async () => { test(`returns content of generatePng getBuffer base64 encoded`, async () => { const testContent = 'raw string from get_screenhots'; - - const generatePngObservable = (await generatePngObservableFactory(mockReporting)) as jest.Mock; - generatePngObservable.mockReturnValue(Rx.of({ base64: testContent })); + const generatePngObservable = await generatePngObservableFactory(mockReporting); + (generatePngObservable as jest.Mock).mockReturnValue(Rx.of({ base64: testContent })); const executeJob = await executeJobFactory(mockReporting, getMockLogger()); const encryptedHeaders = await encryptHeaders({}); diff --git a/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.ts b/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.ts index 88c2d8a9fe4bb..c1a2c12cd9f82 100644 --- a/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.ts +++ b/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.ts @@ -9,7 +9,8 @@ import * as Rx from 'rxjs'; import { catchError, map, mergeMap, takeUntil } from 'rxjs/operators'; import { PNG_JOB_TYPE } from '../../../../common/constants'; import { ReportingCore } from '../../../../server'; -import { ESQueueWorkerExecuteFn, ExecuteJobFactory, JobDocOutput, Logger } from '../../../../types'; +import { LevelLogger } from '../../../../server/lib'; +import { ESQueueWorkerExecuteFn, ExecuteJobFactory, JobDocOutput } from '../../../../server/types'; import { decryptJobHeaders, getConditionalHeaders, @@ -23,7 +24,7 @@ type QueuedPngExecutorFactory = ExecuteJobFactory ({ generatePdfObservableFactory: jest.fn() })); + import * as Rx from 'rxjs'; -import { createMockReportingCore } from '../../../../test_helpers'; -import { cryptoFactory } from '../../../../server/lib/crypto'; -import { LevelLogger } from '../../../../server/lib'; -import { CancellationToken } from '../../../../types'; +import { CancellationToken } from '../../../../../../../plugins/reporting/common'; import { ReportingCore } from '../../../../server'; -import { generatePdfObservableFactory } from '../lib/generate_pdf'; +import { cryptoFactory, LevelLogger } from '../../../../server/lib'; +import { createMockReportingCore } from '../../../../test_helpers'; import { JobDocPayloadPDF } from '../../types'; +import { generatePdfObservableFactory } from '../lib/generate_pdf'; import { executeJobFactory } from './index'; -jest.mock('../lib/generate_pdf', () => ({ generatePdfObservableFactory: jest.fn() })); - let mockReporting: ReportingCore; const cancellationToken = ({ @@ -44,6 +43,7 @@ beforeEach(async () => { 'server.basePath': '/sbp', }; const reportingConfig = { + index: '.reports-test', encryptionKey: mockEncryptionKey, 'kibanaServer.hostname': 'localhost', 'kibanaServer.port': 5601, diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.ts b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.ts index 5aad66c53a998..619e3e9db70ad 100644 --- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.ts +++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.ts @@ -9,7 +9,8 @@ import * as Rx from 'rxjs'; import { catchError, map, mergeMap, takeUntil } from 'rxjs/operators'; import { PDF_JOB_TYPE } from '../../../../common/constants'; import { ReportingCore } from '../../../../server'; -import { ESQueueWorkerExecuteFn, ExecuteJobFactory, JobDocOutput, Logger } from '../../../../types'; +import { LevelLogger } from '../../../../server/lib'; +import { ESQueueWorkerExecuteFn, ExecuteJobFactory, JobDocOutput } from '../../../../server/types'; import { decryptJobHeaders, getConditionalHeaders, @@ -24,7 +25,7 @@ type QueuedPdfExecutorFactory = ExecuteJobFactory { const grouped = groupBy(urlScreenshots.map(u => u.timeRange)); @@ -62,7 +60,7 @@ export async function generatePdfObservableFactory(reporting: ReportingCore) { const pdfOutput = pdf.create(layout, logo); if (title) { const timeRange = getTimeRange(results); - title += timeRange ? ` - ${timeRange.duration}` : ''; + title += timeRange ? ` - ${timeRange}` : ''; pdfOutput.setTitle(title); } tracker.endSetup(); diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/types.d.ts b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/types.d.ts index e8dd3c5207d92..0df01fdc16d1c 100644 --- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/types.d.ts +++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/types.d.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { JobDocPayload } from '../../types'; -import { LayoutInstance, LayoutParams } from '../common/layouts/layout'; +import { JobDocPayload } from '../../server/types'; +import { LayoutInstance, LayoutParams } from '../common/layouts'; // Job params: structure of incoming user request data, after being parsed from RISON export interface JobParamsPDF { diff --git a/x-pack/legacy/plugins/reporting/index.ts b/x-pack/legacy/plugins/reporting/index.ts index fb95e2c2edc24..1ae971b6566b0 100644 --- a/x-pack/legacy/plugins/reporting/index.ts +++ b/x-pack/legacy/plugins/reporting/index.ts @@ -9,7 +9,8 @@ import { Legacy } from 'kibana'; import { resolve } from 'path'; import { PLUGIN_ID, UI_SETTINGS_CUSTOM_PDF_LOGO } from './common/constants'; import { legacyInit } from './server/legacy'; -import { ReportingPluginSpecOptions } from './types'; + +export type ReportingPluginSpecOptions = Legacy.PluginSpecOptions; const kbToBase64Length = (kb: number) => Math.floor((kb * 1024 * 8) / 6); diff --git a/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts b/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts index dd20e849d97a9..3dce8bf4e6819 100644 --- a/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts +++ b/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts @@ -7,18 +7,12 @@ import { i18n } from '@kbn/i18n'; import { map, trunc } from 'lodash'; import open from 'opn'; -import { ElementHandle, EvaluateFn, Page, SerializableOrJSHandle, Response } from 'puppeteer'; +import { ElementHandle, EvaluateFn, Page, Response, SerializableOrJSHandle } from 'puppeteer'; import { parse as parseUrl } from 'url'; import { ViewZoomWidthHeight } from '../../../../export_types/common/layouts/layout'; -import { LevelLogger } from '../../../../server/lib'; -import { - ConditionalHeaders, - ConditionalHeadersConditions, - ElementPosition, - InterceptedRequest, - NetworkPolicy, -} from '../../../../types'; -import { allowRequest } from '../../network_policy'; +import { LevelLogger } from '../../../lib'; +import { ConditionalHeaders, ElementPosition } from '../../../types'; +import { allowRequest, NetworkPolicy } from '../../network_policy'; export interface ChromiumDriverOptions { inspect: boolean; @@ -38,6 +32,23 @@ interface EvaluateMetaOpts { context: string; } +type ConditionalHeadersConditions = ConditionalHeaders['conditions']; + +interface InterceptedRequest { + requestId: string; + request: { + url: string; + method: string; + headers: { + [key: string]: string; + }; + initialPriority: string; + referrerPolicy: string; + }; + frameId: string; + resourceType: string; +} + const WAIT_FOR_DELAY_MS: number = 100; export class HeadlessChromiumDriver { diff --git a/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver_factory/index.ts b/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver_factory/index.ts index cb228150efbcd..3189b262ea1bd 100644 --- a/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver_factory/index.ts +++ b/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver_factory/index.ts @@ -21,7 +21,7 @@ import { InnerSubscriber } from 'rxjs/internal/InnerSubscriber'; import { ignoreElements, map, mergeMap, tap } from 'rxjs/operators'; import { BROWSER_TYPE } from '../../../../common/constants'; import { CaptureConfig } from '../../../../server/types'; -import { LevelLogger as Logger } from '../../../lib/level_logger'; +import { LevelLogger } from '../../../lib'; import { safeChildProcess } from '../../safe_child_process'; import { HeadlessChromiumDriver } from '../driver'; import { getChromeLogLocation } from '../paths'; @@ -39,7 +39,7 @@ export class HeadlessChromiumDriverFactory { private userDataDir: string; private getChromiumArgs: (viewport: ViewportConfig) => string[]; - constructor(binaryPath: binaryPath, logger: Logger, captureConfig: CaptureConfig) { + constructor(binaryPath: binaryPath, logger: LevelLogger, captureConfig: CaptureConfig) { this.binaryPath = binaryPath; this.captureConfig = captureConfig; this.browserConfig = captureConfig.browser.chromium; @@ -56,7 +56,7 @@ export class HeadlessChromiumDriverFactory { type = BROWSER_TYPE; - test(logger: Logger) { + test(logger: LevelLogger) { const chromiumArgs = args({ userDataDir: this.userDataDir, viewport: { width: 800, height: 600 }, @@ -84,7 +84,7 @@ export class HeadlessChromiumDriverFactory { */ createPage( { viewport, browserTimezone }: { viewport: ViewportConfig; browserTimezone: string }, - pLogger: Logger + pLogger: LevelLogger ): Rx.Observable<{ driver: HeadlessChromiumDriver; exit$: Rx.Observable }> { return Rx.Observable.create(async (observer: InnerSubscriber) => { const logger = pLogger.clone(['browser-driver']); @@ -172,7 +172,7 @@ export class HeadlessChromiumDriverFactory { }); } - getBrowserLogger(page: Page, logger: Logger): Rx.Observable { + getBrowserLogger(page: Page, logger: LevelLogger): Rx.Observable { const consoleMessages$ = Rx.fromEvent(page, 'console').pipe( map(line => { if (line.type() === 'error') { @@ -197,7 +197,7 @@ export class HeadlessChromiumDriverFactory { return Rx.merge(consoleMessages$, pageRequestFailed$); } - getProcessLogger(browser: Browser, logger: Logger): Rx.Observable { + getProcessLogger(browser: Browser, logger: LevelLogger): Rx.Observable { const childProcess = browser.process(); // NOTE: The browser driver can not observe stdout and stderr of the child process // Puppeteer doesn't give a handle to the original ChildProcess object diff --git a/x-pack/legacy/plugins/reporting/server/browsers/create_browser_driver_factory.ts b/x-pack/legacy/plugins/reporting/server/browsers/create_browser_driver_factory.ts index af3b86919dc50..7b4407890652c 100644 --- a/x-pack/legacy/plugins/reporting/server/browsers/create_browser_driver_factory.ts +++ b/x-pack/legacy/plugins/reporting/server/browsers/create_browser_driver_factory.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Logger } from '../../types'; -import { ReportingConfig } from '../types'; +import { ReportingConfig } from '../'; +import { LevelLogger } from '../lib'; import { HeadlessChromiumDriverFactory } from './chromium/driver_factory'; import { ensureBrowserDownloaded } from './download'; import { chromium } from './index'; @@ -13,7 +13,7 @@ import { installBrowser } from './install'; export async function createBrowserDriverFactory( config: ReportingConfig, - logger: Logger + logger: LevelLogger ): Promise { const captureConfig = config.get('capture'); const browserConfig = captureConfig.browser.chromium; diff --git a/x-pack/legacy/plugins/reporting/server/browsers/download/ensure_downloaded.ts b/x-pack/legacy/plugins/reporting/server/browsers/download/ensure_downloaded.ts index 3697c4b86ce3c..1170e53669e33 100644 --- a/x-pack/legacy/plugins/reporting/server/browsers/download/ensure_downloaded.ts +++ b/x-pack/legacy/plugins/reporting/server/browsers/download/ensure_downloaded.ts @@ -6,9 +6,8 @@ import { existsSync } from 'fs'; import { resolve as resolvePath } from 'path'; +import { BrowserDownload, chromium } from '../'; import { BROWSER_TYPE } from '../../../common/constants'; -import { chromium } from '../index'; -import { BrowserDownload } from '../types'; import { md5 } from './checksum'; import { clean } from './clean'; import { download } from './download'; diff --git a/x-pack/legacy/plugins/reporting/server/browsers/index.ts b/x-pack/legacy/plugins/reporting/server/browsers/index.ts index 7f902c84308f6..7f6e40fb433b6 100644 --- a/x-pack/legacy/plugins/reporting/server/browsers/index.ts +++ b/x-pack/legacy/plugins/reporting/server/browsers/index.ts @@ -16,3 +16,17 @@ export const chromium = { paths: chromiumDefinition.paths, createDriverFactory: chromiumDefinition.createDriverFactory, }; + +export interface BrowserDownload { + paths: { + archivesPath: string; + baseUrl: string; + packages: Array<{ + archiveChecksum: string; + archiveFilename: string; + binaryChecksum: string; + binaryRelativePath: string; + platforms: string[]; + }>; + }; +} diff --git a/x-pack/legacy/plugins/reporting/server/browsers/install.ts b/x-pack/legacy/plugins/reporting/server/browsers/install.ts index 6f099c36e69f2..01526af307022 100644 --- a/x-pack/legacy/plugins/reporting/server/browsers/install.ts +++ b/x-pack/legacy/plugins/reporting/server/browsers/install.ts @@ -7,12 +7,12 @@ import fs from 'fs'; import path from 'path'; import { promisify } from 'util'; -import { LevelLogger as Logger } from '../lib/level_logger'; -// @ts-ignore -import { extract } from './extract'; +import { LevelLogger } from '../lib'; +import { BrowserDownload } from './'; // @ts-ignore import { md5 } from './download/checksum'; -import { BrowserDownload } from './types'; +// @ts-ignore +import { extract } from './extract'; const chmod = promisify(fs.chmod); @@ -28,7 +28,7 @@ interface PathResponse { * archive. If there is an error extracting the archive an `ExtractError` is thrown */ export async function installBrowser( - logger: Logger, + logger: LevelLogger, browser: BrowserDownload, installsPath: string ): Promise { diff --git a/x-pack/legacy/plugins/reporting/server/browsers/network_policy.ts b/x-pack/legacy/plugins/reporting/server/browsers/network_policy.ts index 9714c5965a5db..158362cee3c7e 100644 --- a/x-pack/legacy/plugins/reporting/server/browsers/network_policy.ts +++ b/x-pack/legacy/plugins/reporting/server/browsers/network_policy.ts @@ -6,7 +6,17 @@ import * as _ from 'lodash'; import { parse } from 'url'; -import { NetworkPolicyRule } from '../../types'; + +interface NetworkPolicyRule { + allow: boolean; + protocol?: string; + host?: string; +} + +export interface NetworkPolicy { + enabled: boolean; + rules: NetworkPolicyRule[]; +} const isHostMatch = (actualHost: string, ruleHost: string) => { const hostParts = actualHost.split('.').reverse(); diff --git a/x-pack/legacy/plugins/reporting/server/browsers/safe_child_process.ts b/x-pack/legacy/plugins/reporting/server/browsers/safe_child_process.ts index e22d3662a33b4..6f86a62c21575 100644 --- a/x-pack/legacy/plugins/reporting/server/browsers/safe_child_process.ts +++ b/x-pack/legacy/plugins/reporting/server/browsers/safe_child_process.ts @@ -6,7 +6,7 @@ import * as Rx from 'rxjs'; import { take, share, mapTo, delay, tap } from 'rxjs/operators'; -import { Logger } from '../../types'; +import { LevelLogger } from '../lib'; interface IChild { kill: (signal: string) => Promise; @@ -15,7 +15,7 @@ interface IChild { // Our process can get sent various signals, and when these occur we wish to // kill the subprocess and then kill our process as long as the observer isn't cancelled export function safeChildProcess( - logger: Logger, + logger: LevelLogger, childProcess: IChild ): { terminate$: Rx.Observable } { const ownTerminateSignal$ = Rx.merge( diff --git a/x-pack/legacy/plugins/reporting/server/browsers/types.d.ts b/x-pack/legacy/plugins/reporting/server/browsers/types.d.ts deleted file mode 100644 index f096073ec2f5f..0000000000000 --- a/x-pack/legacy/plugins/reporting/server/browsers/types.d.ts +++ /dev/null @@ -1,19 +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. - */ - -export interface BrowserDownload { - paths: { - archivesPath: string; - baseUrl: string; - packages: Array<{ - archiveChecksum: string; - archiveFilename: string; - binaryChecksum: string; - binaryRelativePath: string; - platforms: string[]; - }>; - }; -} diff --git a/x-pack/legacy/plugins/reporting/server/config/index.ts b/x-pack/legacy/plugins/reporting/server/config/index.ts index c6b915be3a94a..3ec5aab4d451b 100644 --- a/x-pack/legacy/plugins/reporting/server/config/index.ts +++ b/x-pack/legacy/plugins/reporting/server/config/index.ts @@ -5,10 +5,9 @@ */ import { Legacy } from 'kibana'; -import { CoreSetup } from 'src/core/server'; import { get } from 'lodash'; +import { CoreSetup } from 'src/core/server'; import { ConfigType as ReportingConfigType } from '../../../../../plugins/reporting/server'; -export { ReportingConfigType }; // make config.get() aware of the value type it returns interface Config { @@ -85,3 +84,5 @@ export const buildConfig = ( }, }; }; + +export { ReportingConfigType }; diff --git a/x-pack/legacy/plugins/reporting/server/core.ts b/x-pack/legacy/plugins/reporting/server/core.ts index 0b243f13adb80..8fb948a253c16 100644 --- a/x-pack/legacy/plugins/reporting/server/core.ts +++ b/x-pack/legacy/plugins/reporting/server/core.ts @@ -8,26 +8,25 @@ import * as Rx from 'rxjs'; import { first, mapTo } from 'rxjs/operators'; import { ElasticsearchServiceSetup, - IUiSettingsClient, KibanaRequest, SavedObjectsClient, SavedObjectsServiceStart, UiSettingsServiceStart, } from 'src/core/server'; +import { ReportingPluginSpecOptions } from '../'; // @ts-ignore no module definition import { mirrorPluginStatus } from '../../../server/lib/mirror_plugin_status'; import { XPackMainPlugin } from '../../xpack_main/server/xpack_main'; import { PLUGIN_ID } from '../common/constants'; -import { EnqueueJobFn, ESQueueInstance, ReportingPluginSpecOptions, ServerFacade } from '../types'; +import { screenshotsObservableFactory } from '../export_types/common/lib/screenshots'; +import { ServerFacade } from '../server/types'; +import { ReportingConfig } from './'; import { HeadlessChromiumDriverFactory } from './browsers/chromium/driver_factory'; -import { ReportingConfig, ReportingConfigType } from './config'; import { checkLicenseFactory, getExportTypesRegistry, LevelLogger } from './lib'; +import { ESQueueInstance } from './lib/create_queue'; +import { EnqueueJobFn } from './lib/enqueue_job'; import { registerRoutes } from './routes'; import { ReportingSetupDeps } from './types'; -import { - screenshotsObservableFactory, - ScreenshotsObservableFn, -} from '../export_types/common/lib/screenshots'; interface ReportingInternalSetup { browserDriverFactory: HeadlessChromiumDriverFactory; @@ -40,8 +39,6 @@ interface ReportingInternalStart { uiSettings: UiSettingsServiceStart; } -export { ReportingConfig, ReportingConfigType }; - export class ReportingCore { private pluginSetupDeps?: ReportingInternalSetup; private pluginStartDeps?: ReportingInternalStart; @@ -91,18 +88,18 @@ export class ReportingCore { return this.exportTypesRegistry; } - public async getEsqueue(): Promise { + public async getEsqueue() { return (await this.getPluginStartDeps()).esqueue; } - public async getEnqueueJob(): Promise { + public async getEnqueueJob() { return (await this.getPluginStartDeps()).enqueueJob; } - public getConfig(): ReportingConfig { + public getConfig() { return this.config; } - public async getScreenshotsObservable(): Promise { + public async getScreenshotsObservable() { const { browserDriverFactory } = await this.getPluginSetupDeps(); return screenshotsObservableFactory(this.config.get('capture'), browserDriverFactory); } @@ -110,32 +107,30 @@ export class ReportingCore { /* * Outside dependencies */ - private async getPluginSetupDeps(): Promise { + private async getPluginSetupDeps() { if (this.pluginSetupDeps) { return this.pluginSetupDeps; } return await this.pluginSetup$.pipe(first()).toPromise(); } - private async getPluginStartDeps(): Promise { + private async getPluginStartDeps() { if (this.pluginStartDeps) { return this.pluginStartDeps; } return await this.pluginStart$.pipe(first()).toPromise(); } - public async getElasticsearchService(): Promise { + public async getElasticsearchService() { return (await this.getPluginSetupDeps()).elasticsearch; } - public async getSavedObjectsClient(fakeRequest: KibanaRequest): Promise { + public async getSavedObjectsClient(fakeRequest: KibanaRequest) { const { savedObjects } = await this.getPluginStartDeps(); return savedObjects.getScopedClient(fakeRequest) as SavedObjectsClient; } - public async getUiSettingsServiceFactory( - savedObjectsClient: SavedObjectsClient - ): Promise { + public async getUiSettingsServiceFactory(savedObjectsClient: SavedObjectsClient) { const { uiSettings: uiSettingsService } = await this.getPluginStartDeps(); const scopedUiSettingsService = uiSettingsService.asScopedToClient(savedObjectsClient); return scopedUiSettingsService; diff --git a/x-pack/legacy/plugins/reporting/server/index.ts b/x-pack/legacy/plugins/reporting/server/index.ts index 4288a37fe6adc..2388eac48f8cc 100644 --- a/x-pack/legacy/plugins/reporting/server/index.ts +++ b/x-pack/legacy/plugins/reporting/server/index.ts @@ -5,8 +5,9 @@ */ import { PluginInitializerContext } from 'src/core/server'; +import { ReportingConfig } from './config'; +import { ReportingCore } from './core'; import { ReportingPlugin as Plugin } from './plugin'; -import { ReportingConfig, ReportingCore } from './core'; export const plugin = (context: PluginInitializerContext, config: ReportingConfig) => { return new Plugin(context, config); @@ -14,5 +15,3 @@ export const plugin = (context: PluginInitializerContext, config: ReportingConfi export { ReportingPlugin } from './plugin'; export { ReportingConfig, ReportingCore }; - -export { PreserveLayout, PrintLayout } from '../export_types/common/layouts'; diff --git a/x-pack/legacy/plugins/reporting/server/legacy.ts b/x-pack/legacy/plugins/reporting/server/legacy.ts index d044dc866ed0e..87ffe75e454b1 100644 --- a/x-pack/legacy/plugins/reporting/server/legacy.ts +++ b/x-pack/legacy/plugins/reporting/server/legacy.ts @@ -7,9 +7,9 @@ import { Legacy } from 'kibana'; import { take } from 'rxjs/operators'; import { PluginInitializerContext } from 'src/core/server'; +import { ReportingPluginSpecOptions } from '../'; import { PluginsSetup } from '../../../../plugins/reporting/server'; import { SecurityPluginSetup } from '../../../../plugins/security/server'; -import { ReportingPluginSpecOptions } from '../types'; import { buildConfig } from './config'; import { plugin } from './index'; import { LegacySetup, ReportingStartDeps } from './types'; diff --git a/x-pack/legacy/plugins/reporting/server/lib/check_license.ts b/x-pack/legacy/plugins/reporting/server/lib/check_license.ts index 02e1196f1d00d..b25021c2ed09b 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/check_license.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/check_license.ts @@ -6,7 +6,8 @@ import { XPackInfo } from '../../../xpack_main/server/lib/xpack_info'; import { XPackInfoLicense } from '../../../xpack_main/server/lib/xpack_info_license'; -import { ExportTypesRegistry, ExportTypeDefinition } from '../../types'; +import { ExportTypeDefinition } from '../types'; +import { ExportTypesRegistry } from './export_types_registry'; interface LicenseCheckResult { showLinks: boolean; diff --git a/x-pack/legacy/plugins/reporting/server/lib/create_queue.ts b/x-pack/legacy/plugins/reporting/server/lib/create_queue.ts index 560cc943ed45e..2cac4bd654487 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/create_queue.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/create_queue.ts @@ -4,16 +4,42 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ESQueueInstance, Logger } from '../../types'; import { ReportingCore } from '../core'; +import { JobDocOutput, JobSource } from '../types'; import { createTaggedLogger } from './create_tagged_logger'; // TODO remove createTaggedLogger once esqueue is removed import { createWorkerFactory } from './create_worker'; +import { Job } from './enqueue_job'; // @ts-ignore import { Esqueue } from './esqueue'; +import { LevelLogger } from './level_logger'; + +interface ESQueueWorker { + on: (event: string, handler: any) => void; +} + +export interface ESQueueInstance { + addJob: (type: string, payload: unknown, options: object) => Job; + registerWorker: ( + pluginId: string, + workerFn: GenericWorkerFn, + workerOptions: { + kibanaName: string; + kibanaId: string; + interval: number; + intervalErrorMultiplier: number; + } + ) => ESQueueWorker; +} + +// GenericWorkerFn is a generic for ImmediateExecuteFn | ESQueueWorkerExecuteFn, +type GenericWorkerFn = ( + jobSource: JobSource, + ...workerRestArgs: any[] +) => void | Promise; export async function createQueueFactory( reporting: ReportingCore, - logger: Logger + logger: LevelLogger ): Promise { const config = reporting.getConfig(); const queueIndexInterval = config.get('queue', 'indexInterval'); diff --git a/x-pack/legacy/plugins/reporting/server/lib/create_tagged_logger.ts b/x-pack/legacy/plugins/reporting/server/lib/create_tagged_logger.ts index 97b34dfe40830..aaed46e629ccc 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/create_tagged_logger.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/create_tagged_logger.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Logger } from '../../types'; +import { LevelLogger } from './level_logger'; -export function createTaggedLogger(logger: Logger, tags: string[]) { +export function createTaggedLogger(logger: LevelLogger, tags: string[]) { return (msg: string, additionalTags = []) => { const allTags = [...tags, ...additionalTags]; diff --git a/x-pack/legacy/plugins/reporting/server/lib/create_worker.test.ts b/x-pack/legacy/plugins/reporting/server/lib/create_worker.test.ts index ad8db3201844e..1193091075e3e 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/create_worker.test.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/create_worker.test.ts @@ -5,7 +5,7 @@ */ import * as sinon from 'sinon'; -import { ReportingConfig, ReportingCore } from '../../server/types'; +import { ReportingConfig, ReportingCore } from '../../server'; import { createMockReportingCore } from '../../test_helpers'; import { createWorkerFactory } from './create_worker'; // @ts-ignore diff --git a/x-pack/legacy/plugins/reporting/server/lib/create_worker.ts b/x-pack/legacy/plugins/reporting/server/lib/create_worker.ts index ad0f05c02a1f4..57bd61aee7195 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/create_worker.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/create_worker.ts @@ -4,20 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CancellationToken } from '../../common/cancellation_token'; +import { CancellationToken } from '../../../../../plugins/reporting/common'; import { PLUGIN_ID } from '../../common/constants'; -import { ReportingCore } from '../../server/types'; -import { - ESQueueInstance, - ESQueueWorkerExecuteFn, - ExportTypeDefinition, - JobSource, - Logger, -} from '../../types'; +import { ReportingCore } from '../../server'; +import { LevelLogger } from '../../server/lib'; +import { ESQueueWorkerExecuteFn, ExportTypeDefinition, JobSource } from '../../server/types'; +import { ESQueueInstance } from './create_queue'; // @ts-ignore untyped dependency import { events as esqueueEvents } from './esqueue'; -export function createWorkerFactory(reporting: ReportingCore, logger: Logger) { +export function createWorkerFactory(reporting: ReportingCore, logger: LevelLogger) { const config = reporting.getConfig(); const queueConfig = config.get('queue'); const kibanaName = config.kbnConfig.get('server', 'name'); diff --git a/x-pack/legacy/plugins/reporting/server/lib/enqueue_job.ts b/x-pack/legacy/plugins/reporting/server/lib/enqueue_job.ts index 8f33d9b73566c..8ffb99f7a14c8 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/enqueue_job.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/enqueue_job.ts @@ -4,18 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EventEmitter } from 'events'; import { get } from 'lodash'; -import { - ConditionalHeaders, - EnqueueJobFn, - ESQueueCreateJobFn, - Job, - Logger, - RequestFacade, -} from '../../types'; +import { ConditionalHeaders, ESQueueCreateJobFn, RequestFacade } from '../../server/types'; import { ReportingCore } from '../core'; // @ts-ignore import { events as esqueueEvents } from './esqueue'; +import { LevelLogger } from './level_logger'; interface ConfirmedJob { id: string; @@ -24,7 +19,25 @@ interface ConfirmedJob { _primary_term: number; } -export function enqueueJobFactory(reporting: ReportingCore, parentLogger: Logger): EnqueueJobFn { +export type Job = EventEmitter & { + id: string; + toJSON: () => { + id: string; + }; +}; + +export type EnqueueJobFn = ( + exportTypeId: string, + jobParams: JobParamsType, + user: string, + headers: Record, + request: RequestFacade +) => Promise; + +export function enqueueJobFactory( + reporting: ReportingCore, + parentLogger: LevelLogger +): EnqueueJobFn { const config = reporting.getConfig(); const queueTimeout = config.get('queue', 'timeout'); const browserType = config.get('capture', 'browser', 'type'); diff --git a/x-pack/legacy/plugins/reporting/server/lib/esqueue/__tests__/helpers/cancellation_token.js b/x-pack/legacy/plugins/reporting/server/lib/esqueue/__tests__/helpers/cancellation_token.js deleted file mode 100644 index 4b77b936db8a8..0000000000000 --- a/x-pack/legacy/plugins/reporting/server/lib/esqueue/__tests__/helpers/cancellation_token.js +++ /dev/null @@ -1,75 +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 expect from '@kbn/expect'; -import sinon from 'sinon'; -import { CancellationToken } from '../../../../../common/cancellation_token'; - -describe('CancellationToken', function() { - let cancellationToken; - beforeEach(function() { - cancellationToken = new CancellationToken(); - }); - - describe('on', function() { - [true, null, undefined, 1, 'string', {}, []].forEach(function(value) { - it(`should throw an Error if value is ${value}`, function() { - expect(cancellationToken.on) - .withArgs(value) - .to.throwError(); - }); - }); - - it('accepts a function', function() { - expect(cancellationToken.on) - .withArgs(function() {}) - .not.to.throwError(); - }); - - it(`calls function if cancel has previously been called`, function() { - const spy = sinon.spy(); - cancellationToken.cancel(); - cancellationToken.on(spy); - expect(spy.calledOnce).to.be(true); - }); - }); - - describe('cancel', function() { - it('should be a function accepting no parameters', function() { - expect(cancellationToken.cancel) - .withArgs() - .to.not.throwError(); - }); - - it('should call a single callback', function() { - const spy = sinon.spy(); - cancellationToken.on(spy); - cancellationToken.cancel(); - expect(spy.calledOnce).to.be(true); - }); - - it('should call two callbacks', function() { - const spy1 = sinon.spy(); - const spy2 = sinon.spy(); - cancellationToken.on(spy1); - cancellationToken.on(spy2); - cancellationToken.cancel(); - expect(spy1.calledOnce).to.be(true); - expect(spy2.calledOnce).to.be(true); - }); - }); - - describe('isCancelled', function() { - it('should default to false', function() { - expect(cancellationToken.isCancelled()).to.be(false); - }); - - it('should switch to true after call to cancel', function() { - cancellationToken.cancel(); - expect(cancellationToken.isCancelled()).to.be(true); - }); - }); -}); diff --git a/x-pack/legacy/plugins/reporting/server/lib/esqueue/worker.js b/x-pack/legacy/plugins/reporting/server/lib/esqueue/worker.js index ab0bb6740f078..17a7fd0e9a26f 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/esqueue/worker.js +++ b/x-pack/legacy/plugins/reporting/server/lib/esqueue/worker.js @@ -5,12 +5,12 @@ */ import events from 'events'; -import Puid from 'puid'; import moment from 'moment'; -import { constants } from './constants'; -import { WorkerTimeoutError, UnspecifiedWorkerError } from './helpers/errors'; -import { CancellationToken } from '../../../common/cancellation_token'; +import Puid from 'puid'; +import { CancellationToken } from '../../../../../../plugins/reporting/common'; import { Poller } from '../../../../../common/poller'; +import { constants } from './constants'; +import { UnspecifiedWorkerError, WorkerTimeoutError } from './helpers/errors'; const puid = new Puid(); diff --git a/x-pack/legacy/plugins/reporting/server/lib/export_types_registry.ts b/x-pack/legacy/plugins/reporting/server/lib/export_types_registry.ts index d553cc07ae3ef..ecaabb305e23e 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/export_types_registry.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/export_types_registry.ts @@ -4,13 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import memoizeOne from 'memoize-one'; import { isString } from 'lodash'; +import memoizeOne from 'memoize-one'; import { getExportType as getTypeCsv } from '../../export_types/csv'; import { getExportType as getTypeCsvFromSavedObject } from '../../export_types/csv_from_savedobject'; import { getExportType as getTypePng } from '../../export_types/png'; import { getExportType as getTypePrintablePdf } from '../../export_types/printable_pdf'; -import { ExportTypeDefinition } from '../../types'; +import { ExportTypeDefinition } from '../types'; type GetCallbackFn = ( item: ExportTypeDefinition diff --git a/x-pack/legacy/plugins/reporting/server/lib/get_user.ts b/x-pack/legacy/plugins/reporting/server/lib/get_user.ts index 5e73fe77ecb79..8e8b1c83d5a40 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/get_user.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/get_user.ts @@ -6,10 +6,10 @@ import { Legacy } from 'kibana'; import { KibanaRequest } from '../../../../../../src/core/server'; -import { Logger } from '../../types'; import { ReportingSetupDeps } from '../types'; +import { LevelLogger } from './level_logger'; -export function getUserFactory(security: ReportingSetupDeps['security'], logger: Logger) { +export function getUserFactory(security: ReportingSetupDeps['security'], logger: LevelLogger) { /* * Legacy.Request because this is called from routing middleware */ diff --git a/x-pack/legacy/plugins/reporting/server/lib/jobs_query.ts b/x-pack/legacy/plugins/reporting/server/lib/jobs_query.ts index 0affc111c1368..e0c9fc05ea2b4 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/jobs_query.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/jobs_query.ts @@ -9,8 +9,8 @@ import Boom from 'boom'; import { errors as elasticsearchErrors } from 'elasticsearch'; import { ElasticsearchServiceSetup } from 'kibana/server'; import { get } from 'lodash'; -import { JobSource } from '../../types'; -import { ReportingConfig } from '../types'; +import { ReportingConfig } from '../'; +import { JobSource } from '../types'; const esErrors = elasticsearchErrors as Record; const defaultSize = 10; diff --git a/x-pack/legacy/plugins/reporting/server/lib/once_per_server.ts b/x-pack/legacy/plugins/reporting/server/lib/once_per_server.ts deleted file mode 100644 index ae3636079a9bb..0000000000000 --- a/x-pack/legacy/plugins/reporting/server/lib/once_per_server.ts +++ /dev/null @@ -1,43 +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 { memoize, MemoizedFunction } from 'lodash'; -import { ServerFacade } from '../../types'; - -type ServerFn = (server: ServerFacade) => any; -type Memo = ((server: ServerFacade) => any) & MemoizedFunction; - -/** - * allow this function to be called multiple times, but - * ensure that it only received one argument, the server, - * and cache the return value so that subsequent calls get - * the exact same value. - * - * This is intended to be used by service factories like getObjectQueueFactory - * - * @param {Function} fn - the factory function - * @return {any} - */ -export function oncePerServer(fn: ServerFn) { - const memoized: Memo = memoize(function(server: ServerFacade) { - if (arguments.length !== 1) { - throw new TypeError('This function expects to be called with a single argument'); - } - - // @ts-ignore - return fn.call(this, server); - }); - - // @ts-ignore - // Type 'WeakMap' is not assignable to type 'MapCache - - // use a weak map a the cache so that: - // 1. return values mapped to the actual server instance - // 2. return value lifecycle matches that of the server - memoized.cache = new WeakMap(); - - return memoized; -} diff --git a/x-pack/legacy/plugins/reporting/server/lib/validate/index.ts b/x-pack/legacy/plugins/reporting/server/lib/validate/index.ts index 85d9f727d7fa7..404cbcda31a09 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/validate/index.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/validate/index.ts @@ -6,9 +6,9 @@ import { i18n } from '@kbn/i18n'; import { ElasticsearchServiceSetup } from 'kibana/server'; -import { Logger } from '../../../types'; +import { ReportingConfig } from '../../'; +import { LevelLogger } from '../../lib'; import { HeadlessChromiumDriverFactory } from '../../browsers/chromium/driver_factory'; -import { ReportingConfig } from '../../types'; import { validateBrowser } from './validate_browser'; import { validateMaxContentLength } from './validate_max_content_length'; @@ -16,7 +16,7 @@ export async function runValidations( config: ReportingConfig, elasticsearch: ElasticsearchServiceSetup, browserFactory: HeadlessChromiumDriverFactory, - logger: Logger + logger: LevelLogger ) { try { await Promise.all([ diff --git a/x-pack/legacy/plugins/reporting/server/lib/validate/validate_browser.ts b/x-pack/legacy/plugins/reporting/server/lib/validate/validate_browser.ts index d6512d5eb718b..d29aa522dad90 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/validate/validate_browser.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/validate/validate_browser.ts @@ -6,8 +6,8 @@ import { Browser } from 'puppeteer'; import { BROWSER_TYPE } from '../../../common/constants'; -import { Logger } from '../../../types'; import { HeadlessChromiumDriverFactory } from '../../browsers/chromium/driver_factory'; +import { LevelLogger } from '../'; /* * Validate the Reporting headless browser can launch, and that it can connect @@ -15,7 +15,7 @@ import { HeadlessChromiumDriverFactory } from '../../browsers/chromium/driver_fa */ export const validateBrowser = async ( browserFactory: HeadlessChromiumDriverFactory, - logger: Logger + logger: LevelLogger ) => { if (browserFactory.type === BROWSER_TYPE) { return browserFactory.test(logger).then((browser: Browser | null) => { diff --git a/x-pack/legacy/plugins/reporting/server/lib/validate/validate_max_content_length.ts b/x-pack/legacy/plugins/reporting/server/lib/validate/validate_max_content_length.ts index a20905ba093d4..f6acf72612e01 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/validate/validate_max_content_length.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/validate/validate_max_content_length.ts @@ -7,8 +7,8 @@ import numeral from '@elastic/numeral'; import { ElasticsearchServiceSetup } from 'kibana/server'; import { defaults, get } from 'lodash'; -import { Logger } from '../../../types'; -import { ReportingConfig } from '../../types'; +import { ReportingConfig } from '../../'; +import { LevelLogger } from '../../lib'; const KIBANA_MAX_SIZE_BYTES_PATH = 'csv.maxSizeBytes'; const ES_MAX_SIZE_BYTES_PATH = 'http.max_content_length'; @@ -16,7 +16,7 @@ const ES_MAX_SIZE_BYTES_PATH = 'http.max_content_length'; export async function validateMaxContentLength( config: ReportingConfig, elasticsearch: ElasticsearchServiceSetup, - logger: Logger + logger: LevelLogger ) { const { callAsInternalUser } = elasticsearch.dataClient; diff --git a/x-pack/legacy/plugins/reporting/server/plugin.ts b/x-pack/legacy/plugins/reporting/server/plugin.ts index e0fa99106a93e..78c2ce5b9b106 100644 --- a/x-pack/legacy/plugins/reporting/server/plugin.ts +++ b/x-pack/legacy/plugins/reporting/server/plugin.ts @@ -6,7 +6,8 @@ import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'src/core/server'; import { createBrowserDriverFactory } from './browsers'; -import { ReportingCore, ReportingConfig } from './core'; +import { ReportingConfig } from './config'; +import { ReportingCore } from './core'; import { createQueueFactory, enqueueJobFactory, LevelLogger, runValidations } from './lib'; import { setFieldFormats } from './services'; import { ReportingSetup, ReportingSetupDeps, ReportingStart, ReportingStartDeps } from './types'; diff --git a/x-pack/legacy/plugins/reporting/server/routes/generate_from_jobparams.ts b/x-pack/legacy/plugins/reporting/server/routes/generate_from_jobparams.ts index 6b4f5dbd9203a..70a1a32e76a65 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/generate_from_jobparams.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/generate_from_jobparams.ts @@ -8,16 +8,17 @@ import boom from 'boom'; import Joi from 'joi'; import { Legacy } from 'kibana'; import rison from 'rison-node'; +import { ReportingCore } from '../'; import { API_BASE_URL } from '../../common/constants'; -import { Logger, ReportingResponseToolkit, ServerFacade } from '../../types'; -import { ReportingCore, ReportingSetupDeps } from '../types'; +import { LevelLogger as Logger } from '../lib'; +import { ReportingSetupDeps, ServerFacade } from '../types'; import { makeRequestFacade } from './lib/make_request_facade'; import { GetRouteConfigFactoryFn, getRouteConfigFactoryReportingPre, RouteConfigFactory, } from './lib/route_config_factories'; -import { HandlerErrorFunction, HandlerFunction } from './types'; +import { HandlerErrorFunction, HandlerFunction, ReportingResponseToolkit } from './types'; const BASE_GENERATE = `${API_BASE_URL}/generate`; diff --git a/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject.ts b/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject.ts index 830953d532243..03a893d1abeb4 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject.ts @@ -6,13 +6,19 @@ import { Legacy } from 'kibana'; import { get } from 'lodash'; +import { ReportingCore } from '../'; import { API_BASE_GENERATE_V1, CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../common/constants'; import { getJobParamsFromRequest } from '../../export_types/csv_from_savedobject/server/lib/get_job_params_from_request'; -import { Logger, ReportingResponseToolkit, ServerFacade } from '../../types'; -import { ReportingCore, ReportingSetupDeps } from '../types'; +import { LevelLogger as Logger } from '../lib'; +import { ReportingSetupDeps, ServerFacade } from '../types'; import { makeRequestFacade } from './lib/make_request_facade'; import { getRouteOptionsCsv } from './lib/route_config_factories'; -import { HandlerErrorFunction, HandlerFunction, QueuedJobPayload } from './types'; +import { + HandlerErrorFunction, + HandlerFunction, + QueuedJobPayload, + ReportingResponseToolkit, +} from './types'; /* * This function registers API Endpoints for queuing Reporting jobs. The API inputs are: diff --git a/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject_immediate.ts b/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject_immediate.ts index 519e49f56c377..22aebb05cdf49 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject_immediate.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject_immediate.ts @@ -4,21 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ +import { ResponseObject } from 'hapi'; import { Legacy } from 'kibana'; +import { ReportingCore } from '../'; import { API_BASE_GENERATE_V1 } from '../../common/constants'; import { createJobFactory, executeJobFactory } from '../../export_types/csv_from_savedobject'; import { getJobParamsFromRequest } from '../../export_types/csv_from_savedobject/server/lib/get_job_params_from_request'; import { JobDocPayloadPanelCsv } from '../../export_types/csv_from_savedobject/types'; -import { - JobDocOutput, - Logger, - ReportingResponseToolkit, - ResponseFacade, - ServerFacade, -} from '../../types'; -import { ReportingCore, ReportingSetupDeps } from '../types'; +import { LevelLogger as Logger } from '../lib'; +import { JobDocOutput, ReportingSetupDeps, ServerFacade } from '../types'; import { makeRequestFacade } from './lib/make_request_facade'; import { getRouteOptionsCsv } from './lib/route_config_factories'; +import { ReportingResponseToolkit } from './types'; + +type ResponseFacade = ResponseObject & { + isBoom: boolean; +}; /* * This function registers API Endpoints for immediate Reporting jobs. The API inputs are: diff --git a/x-pack/legacy/plugins/reporting/server/routes/generation.test.ts b/x-pack/legacy/plugins/reporting/server/routes/generation.test.ts index 8e54feac3c8a6..74401f8228f7d 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/generation.test.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/generation.test.ts @@ -5,9 +5,11 @@ */ import Hapi from 'hapi'; +import { ReportingConfig, ReportingCore } from '../'; import { createMockReportingCore } from '../../test_helpers'; -import { Logger, ServerFacade } from '../../types'; -import { ReportingConfig, ReportingCore, ReportingSetupDeps } from '../types'; +import { LevelLogger as Logger } from '../lib'; +import { ReportingSetupDeps, ServerFacade } from '../types'; +import { registerJobGenerationRoutes } from './generation'; jest.mock('./lib/authorized_user_pre_routing', () => ({ authorizedUserPreRoutingFactory: () => () => ({}), @@ -18,8 +20,6 @@ jest.mock('./lib/reporting_feature_pre_routing', () => ({ }), })); -import { registerJobGenerationRoutes } from './generation'; - let mockServer: Hapi.Server; let mockReportingPlugin: ReportingCore; let mockReportingConfig: ReportingConfig; diff --git a/x-pack/legacy/plugins/reporting/server/routes/generation.ts b/x-pack/legacy/plugins/reporting/server/routes/generation.ts index 1c6129313db4b..56faa37d5fcbd 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/generation.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/generation.ts @@ -7,13 +7,15 @@ import boom from 'boom'; import { errors as elasticsearchErrors } from 'elasticsearch'; import { Legacy } from 'kibana'; +import { ReportingCore } from '../'; import { API_BASE_URL } from '../../common/constants'; -import { Logger, ReportingResponseToolkit, ServerFacade } from '../../types'; -import { ReportingCore, ReportingSetupDeps } from '../types'; +import { LevelLogger as Logger } from '../lib'; +import { ReportingSetupDeps, ServerFacade } from '../types'; import { registerGenerateFromJobParams } from './generate_from_jobparams'; import { registerGenerateCsvFromSavedObject } from './generate_from_savedobject'; import { registerGenerateCsvFromSavedObjectImmediate } from './generate_from_savedobject_immediate'; import { makeRequestFacade } from './lib/make_request_facade'; +import { ReportingResponseToolkit } from './types'; const esErrors = elasticsearchErrors as Record; diff --git a/x-pack/legacy/plugins/reporting/server/routes/index.ts b/x-pack/legacy/plugins/reporting/server/routes/index.ts index 610ab4907d369..556f4e12b077e 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/index.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/index.ts @@ -4,8 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Logger, ServerFacade } from '../../types'; -import { ReportingCore, ReportingSetupDeps } from '../types'; +import { ReportingCore } from '../'; +import { LevelLogger as Logger } from '../lib'; +import { ReportingSetupDeps, ServerFacade } from '../types'; import { registerJobGenerationRoutes } from './generation'; import { registerJobInfoRoutes } from './jobs'; diff --git a/x-pack/legacy/plugins/reporting/server/routes/jobs.test.ts b/x-pack/legacy/plugins/reporting/server/routes/jobs.test.ts index 5c58a7dfa0110..4f597bcee858e 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/jobs.test.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/jobs.test.ts @@ -5,11 +5,12 @@ */ import Hapi from 'hapi'; +import { ReportingConfig, ReportingCore } from '../'; +import { LevelLogger } from '../lib'; import { createMockReportingCore } from '../../test_helpers'; -import { ExportTypeDefinition } from '../../types'; import { ExportTypesRegistry } from '../lib/export_types_registry'; -import { LevelLogger } from '../lib/level_logger'; -import { ReportingConfig, ReportingCore, ReportingSetupDeps } from '../types'; +import { ExportTypeDefinition, ReportingSetupDeps } from '../types'; +import { registerJobInfoRoutes } from './jobs'; jest.mock('./lib/authorized_user_pre_routing', () => ({ authorizedUserPreRoutingFactory: () => () => ({}), @@ -20,8 +21,6 @@ jest.mock('./lib/reporting_feature_pre_routing', () => ({ }), })); -import { registerJobInfoRoutes } from './jobs'; - let mockServer: any; let exportTypesRegistry: ExportTypesRegistry; let mockReportingPlugin: ReportingCore; diff --git a/x-pack/legacy/plugins/reporting/server/routes/jobs.ts b/x-pack/legacy/plugins/reporting/server/routes/jobs.ts index f6f98b2377db6..59090961998af 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/jobs.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/jobs.ts @@ -7,17 +7,11 @@ import Boom from 'boom'; import { ResponseObject } from 'hapi'; import { Legacy } from 'kibana'; +import { ReportingCore } from '../'; import { API_BASE_URL } from '../../common/constants'; -import { - JobDocOutput, - JobSource, - ListQuery, - Logger, - ReportingResponseToolkit, - ServerFacade, -} from '../../types'; +import { LevelLogger as Logger } from '../lib'; import { jobsQueryFactory } from '../lib/jobs_query'; -import { ReportingCore, ReportingSetupDeps } from '../types'; +import { JobDocOutput, JobSource, ReportingSetupDeps, ServerFacade } from '../types'; import { deleteJobResponseHandlerFactory, downloadJobResponseHandlerFactory, @@ -28,7 +22,13 @@ import { getRouteConfigFactoryDownloadPre, getRouteConfigFactoryManagementPre, } from './lib/route_config_factories'; +import { ReportingResponseToolkit } from './types'; +interface ListQuery { + page: string; + size: string; + ids?: string; // optional field forbids us from extending RequestQuery +} const MAIN_ENTRY = `${API_BASE_URL}/jobs`; function isResponse(response: Boom | ResponseObject): response is ResponseObject { diff --git a/x-pack/legacy/plugins/reporting/server/routes/lib/authorized_user_pre_routing.ts b/x-pack/legacy/plugins/reporting/server/routes/lib/authorized_user_pre_routing.ts index 1ca28ca62a7f2..0d297a60a3559 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/lib/authorized_user_pre_routing.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/lib/authorized_user_pre_routing.ts @@ -8,9 +8,9 @@ import Boom from 'boom'; import { Legacy } from 'kibana'; import { AuthenticatedUser } from '../../../../../../plugins/security/server'; import { ReportingConfig } from '../../../server'; -import { Logger } from '../../../types'; +import { LevelLogger as Logger } from '../../../server/lib'; +import { ReportingSetupDeps } from '../../../server/types'; import { getUserFactory } from '../../lib/get_user'; -import { ReportingSetupDeps } from '../../types'; const superuserRole = 'superuser'; diff --git a/x-pack/legacy/plugins/reporting/server/routes/lib/get_document_payload.ts b/x-pack/legacy/plugins/reporting/server/routes/lib/get_document_payload.ts index c243d0b4266ea..6a228c1915615 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/lib/get_document_payload.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/lib/get_document_payload.ts @@ -8,8 +8,9 @@ import contentDisposition from 'content-disposition'; import * as _ from 'lodash'; import { CSV_JOB_TYPE } from '../../../common/constants'; -import { ExportTypeDefinition, ExportTypesRegistry, JobDocOutput, JobSource } from '../../../types'; import { statuses } from '../../lib/esqueue/constants/statuses'; +import { ExportTypesRegistry } from '../../lib/export_types_registry'; +import { ExportTypeDefinition, JobDocOutput, JobSource } from '../../types'; interface ICustomHeaders { [x: string]: any; diff --git a/x-pack/legacy/plugins/reporting/server/routes/lib/job_response_handler.ts b/x-pack/legacy/plugins/reporting/server/routes/lib/job_response_handler.ts index e7e7c866db96a..59aa7d904dcf4 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/lib/job_response_handler.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/lib/job_response_handler.ts @@ -7,10 +7,10 @@ import Boom from 'boom'; import { ResponseToolkit } from 'hapi'; import { ElasticsearchServiceSetup } from 'kibana/server'; +import { ReportingConfig } from '../../'; import { WHITELISTED_JOB_CONTENT_TYPES } from '../../../common/constants'; -import { ExportTypesRegistry } from '../../../types'; +import { ExportTypesRegistry } from '../../lib/export_types_registry'; import { jobsQueryFactory } from '../../lib/jobs_query'; -import { ReportingConfig } from '../../types'; import { getDocumentPayloadFactory } from './get_document_payload'; interface JobResponseHandlerParams { diff --git a/x-pack/legacy/plugins/reporting/server/routes/lib/make_request_facade.ts b/x-pack/legacy/plugins/reporting/server/routes/lib/make_request_facade.ts index fb8a2dbbff17b..5dd62711f2565 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/lib/make_request_facade.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/lib/make_request_facade.ts @@ -11,7 +11,7 @@ import { ReportingRequestPayload, ReportingRequestPre, ReportingRequestQuery, -} from '../../../types'; +} from '../../../server/types'; export function makeRequestFacade(request: Legacy.Request): RequestFacade { // This condition is for unit tests diff --git a/x-pack/legacy/plugins/reporting/server/routes/lib/reporting_feature_pre_routing.ts b/x-pack/legacy/plugins/reporting/server/routes/lib/reporting_feature_pre_routing.ts index 8a79566aafae2..f9c7571e25bac 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/lib/reporting_feature_pre_routing.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/lib/reporting_feature_pre_routing.ts @@ -6,8 +6,9 @@ import Boom from 'boom'; import { Legacy } from 'kibana'; -import { Logger } from '../../../types'; -import { ReportingConfig, ReportingSetupDeps } from '../../types'; +import { ReportingConfig } from '../../'; +import { LevelLogger as Logger } from '../../lib'; +import { ReportingSetupDeps } from '../../types'; export type GetReportingFeatureIdFn = (request: Legacy.Request) => string; diff --git a/x-pack/legacy/plugins/reporting/server/routes/lib/route_config_factories.ts b/x-pack/legacy/plugins/reporting/server/routes/lib/route_config_factories.ts index 06f7efaa9dcbb..0ee9db4678684 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/lib/route_config_factories.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/lib/route_config_factories.ts @@ -5,9 +5,10 @@ */ import Joi from 'joi'; +import { ReportingConfig } from '../../'; +import { LevelLogger as Logger } from '../../lib'; import { CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../../common/constants'; -import { Logger } from '../../../types'; -import { ReportingConfig, ReportingSetupDeps } from '../../types'; +import { ReportingSetupDeps } from '../../types'; import { authorizedUserPreRoutingFactory } from './authorized_user_pre_routing'; import { GetReportingFeatureIdFn, diff --git a/x-pack/legacy/plugins/reporting/server/routes/types.d.ts b/x-pack/legacy/plugins/reporting/server/routes/types.d.ts index 28862a765d666..2ebe1ada418dc 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/types.d.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/types.d.ts @@ -5,7 +5,7 @@ */ import { Legacy } from 'kibana'; -import { JobDocPayload, ReportingResponseToolkit } from '../../types'; +import { JobDocPayload } from '../types'; export type HandlerFunction = ( exportType: string, @@ -24,3 +24,5 @@ export interface QueuedJobPayload { }; }; } + +export type ReportingResponseToolkit = Legacy.ResponseToolkit; diff --git a/x-pack/legacy/plugins/reporting/server/types.d.ts b/x-pack/legacy/plugins/reporting/server/types.d.ts deleted file mode 100644 index fb77eae4e7eea..0000000000000 --- a/x-pack/legacy/plugins/reporting/server/types.d.ts +++ /dev/null @@ -1,45 +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 { Legacy } from 'kibana'; -import { ElasticsearchServiceSetup } from 'src/core/server'; -import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { PluginStart as DataPluginStart } from '../../../../../src/plugins/data/server'; -import { SecurityPluginSetup } from '../../../../plugins/security/server'; -import { XPackMainPlugin } from '../../xpack_main/server/xpack_main'; -import { ReportingPluginSpecOptions } from '../types'; -import { ReportingConfigType } from './core'; - -export interface ReportingSetupDeps { - elasticsearch: ElasticsearchServiceSetup; - security: SecurityPluginSetup; - usageCollection?: UsageCollectionSetup; - __LEGACY: LegacySetup; -} - -export interface ReportingStartDeps { - data: DataPluginStart; - __LEGACY: LegacySetup; -} - -export type ReportingSetup = object; - -export type ReportingStart = object; - -export interface LegacySetup { - plugins: { - xpack_main: XPackMainPlugin & { - status?: any; - }; - reporting: ReportingPluginSpecOptions; - }; - route: Legacy.Server['route']; -} - -export { ReportingConfig, ReportingConfigType, ReportingCore } from './core'; - -export type CaptureConfig = ReportingConfigType['capture']; -export type ScrollConfig = ReportingConfigType['csv']['scroll']; diff --git a/x-pack/legacy/plugins/reporting/server/types.ts b/x-pack/legacy/plugins/reporting/server/types.ts new file mode 100644 index 0000000000000..1417f1d7b50cb --- /dev/null +++ b/x-pack/legacy/plugins/reporting/server/types.ts @@ -0,0 +1,243 @@ +/* + * 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 { Legacy } from 'kibana'; +import { ElasticsearchServiceSetup } from 'kibana/server'; +import * as Rx from 'rxjs'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { DataPluginStart } from 'src/plugins/data/server/plugin'; +import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { ReportingPluginSpecOptions } from '../'; +import { CancellationToken } from '../../../../plugins/reporting/common'; +import { JobStatus } from '../../../../plugins/reporting/common/types'; +import { SecurityPluginSetup } from '../../../../plugins/security/server'; +import { XPackMainPlugin } from '../../xpack_main/server/xpack_main'; +import { LayoutInstance } from '../export_types/common/layouts'; +import { ReportingConfigType } from './config'; +import { ReportingCore } from './core'; +import { LevelLogger } from './lib'; + +/* + * Routing / API types + */ + +interface ListQuery { + page: string; + size: string; + ids?: string; // optional field forbids us from extending RequestQuery +} + +interface GenerateQuery { + jobParams: string; +} + +export type ReportingRequestQuery = ListQuery | GenerateQuery; + +export interface ReportingRequestPre { + management: { + jobTypes: any; + }; + user: string; +} + +// generate a report with unparsed jobParams +export interface GenerateExportTypePayload { + jobParams: string; +} + +export type ReportingRequestPayload = GenerateExportTypePayload | JobParamPostPayload; + +export interface TimeRangeParams { + timezone: string; + min: Date | string | number; + max: Date | string | number; +} + +export interface JobParamPostPayload { + timerange: TimeRangeParams; +} + +export interface JobDocPayload { + headers?: string; // serialized encrypted headers + jobParams: JobParamsType; + title: string; + type: string | null; +} + +export interface JobSource { + _id: string; + _index: string; + _source: { + jobtype: string; + output: JobDocOutput; + payload: JobDocPayload; + status: JobStatus; + }; +} + +export interface JobDocOutput { + content_type: string; + content: string | null; + size: number; + max_size_reached?: boolean; + warnings?: string[]; +} + +interface ConditionalHeadersConditions { + protocol: string; + hostname: string; + port: number; + basePath: string; +} + +export interface ConditionalHeaders { + headers: Record; + conditions: ConditionalHeadersConditions; +} + +/* + * Screenshots + */ + +export interface ScreenshotObservableOpts { + logger: LevelLogger; + urls: string[]; + conditionalHeaders: ConditionalHeaders; + layout: LayoutInstance; + browserTimezone: string; +} + +export interface AttributesMap { + [key: string]: any; +} + +export interface ElementPosition { + boundingClientRect: { + // modern browsers support x/y, but older ones don't + top: number; + left: number; + width: number; + height: number; + }; + scroll: { + x: number; + y: number; + }; +} + +export interface ElementsPositionAndAttribute { + position: ElementPosition; + attributes: AttributesMap; +} + +export interface Screenshot { + base64EncodedData: string; + title: string; + description: string; +} + +export interface ScreenshotResults { + timeRange: string | null; + screenshots: Screenshot[]; + error?: Error; + elementsPositionAndAttributes?: ElementsPositionAndAttribute[]; // NOTE: for testing +} + +export type ScreenshotsObservableFn = ({ + logger, + urls, + conditionalHeaders, + layout, + browserTimezone, +}: ScreenshotObservableOpts) => Rx.Observable; + +/* + * Plugin Contract + */ + +export interface ReportingSetupDeps { + elasticsearch: ElasticsearchServiceSetup; + security: SecurityPluginSetup; + usageCollection?: UsageCollectionSetup; + __LEGACY: LegacySetup; +} + +export interface ReportingStartDeps { + data: DataPluginStart; + __LEGACY: LegacySetup; +} + +export type ReportingStart = object; +export type ReportingSetup = object; + +export interface LegacySetup { + plugins: { + xpack_main: XPackMainPlugin & { + status?: any; + }; + reporting: ReportingPluginSpecOptions; + }; + route: Legacy.Server['route']; +} + +/* + * Internal Types + */ + +export interface RequestFacade { + getBasePath: Legacy.Request['getBasePath']; + getSavedObjectsClient: Legacy.Request['getSavedObjectsClient']; + headers: Legacy.Request['headers']; + params: Legacy.Request['params']; + payload: JobParamPostPayload | GenerateExportTypePayload; + query: ReportingRequestQuery; + route: Legacy.Request['route']; + pre: ReportingRequestPre; + getRawRequest: () => Legacy.Request; +} + +export type ESQueueCreateJobFn = ( + jobParams: JobParamsType, + headers: Record, + request: RequestFacade +) => Promise; + +export type ESQueueWorkerExecuteFn = ( + jobId: string, + job: JobDocPayloadType, + cancellationToken?: CancellationToken +) => Promise; + +export type ServerFacade = LegacySetup; + +export type CaptureConfig = ReportingConfigType['capture']; +export type ScrollConfig = ReportingConfigType['csv']['scroll']; + +export type CreateJobFactory = ( + reporting: ReportingCore, + logger: LevelLogger +) => CreateJobFnType; + +export type ExecuteJobFactory = ( + reporting: ReportingCore, + logger: LevelLogger +) => Promise; // FIXME: does not "need" to be async + +export interface ExportTypeDefinition< + JobParamsType, + CreateJobFnType, + JobPayloadType, + ExecuteJobFnType +> { + id: string; + name: string; + jobType: string; + jobContentEncoding?: string; + jobContentExtension: string; + createJobFactory: CreateJobFactory; + executeJobFactory: ExecuteJobFactory; + validLicenses: string[]; +} diff --git a/x-pack/legacy/plugins/reporting/server/usage/get_reporting_usage.ts b/x-pack/legacy/plugins/reporting/server/usage/get_reporting_usage.ts index eb907d52c5f96..6771d61bf263d 100644 --- a/x-pack/legacy/plugins/reporting/server/usage/get_reporting_usage.ts +++ b/x-pack/legacy/plugins/reporting/server/usage/get_reporting_usage.ts @@ -5,23 +5,24 @@ */ import { get } from 'lodash'; +import { CallCluster } from 'src/legacy/core_plugins/elasticsearch'; +import { ReportingConfig } from '../'; import { XPackMainPlugin } from '../../../xpack_main/server/xpack_main'; -import { ESCallCluster, ExportTypesRegistry } from '../../types'; -import { ReportingConfig } from '../types'; -import { decorateRangeStats } from './decorate_range_stats'; -import { getExportTypesHandler } from './get_export_type_handler'; +import { ExportTypesRegistry } from '../lib/export_types_registry'; import { AggregationResultBuckets, + AppCounts, FeatureAvailabilityMap, JobTypes, KeyCountBucket, + LayoutCounts, RangeStats, ReportingUsageType, SearchResponse, StatusByAppBucket, - AppCounts, - LayoutCounts, } from './types'; +import { decorateRangeStats } from './decorate_range_stats'; +import { getExportTypesHandler } from './get_export_type_handler'; type XPackInfo = XPackMainPlugin['info']; @@ -123,7 +124,7 @@ async function handleResponse(response: SearchResponse): Promise + fetch: (callCluster: CallCluster) => getReportingUsage(config, xpackMainInfo, callCluster, exportTypesRegistry), isReady, diff --git a/x-pack/legacy/plugins/reporting/server/usage/types.d.ts b/x-pack/legacy/plugins/reporting/server/usage/types.ts similarity index 65% rename from x-pack/legacy/plugins/reporting/server/usage/types.d.ts rename to x-pack/legacy/plugins/reporting/server/usage/types.ts index 4d7a1a33239b2..5430a1cfc33bd 100644 --- a/x-pack/legacy/plugins/reporting/server/usage/types.d.ts +++ b/x-pack/legacy/plugins/reporting/server/usage/types.ts @@ -107,3 +107,63 @@ export type ReportingUsageType = RangeStats & { export type ExportType = 'csv' | 'printable_pdf' | 'PNG'; export type FeatureAvailabilityMap = { [F in ExportType]: boolean }; + +/* + * 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. + */ + +export interface KeyCountBucket { + key: string; + doc_count: number; +} + +export interface AggregationBuckets { + buckets: KeyCountBucket[]; +} + +export interface StatusByAppBucket { + key: string; + doc_count: number; + jobTypes: { + buckets: Array<{ + doc_count: number; + key: string; + appNames: AggregationBuckets; + }>; + }; +} + +export interface AggregationResultBuckets { + jobTypes: AggregationBuckets; + layoutTypes: { + doc_count: number; + pdf: AggregationBuckets; + }; + objectTypes: { + doc_count: number; + pdf: AggregationBuckets; + }; + statusTypes: AggregationBuckets; + statusByApp: { + buckets: StatusByAppBucket[]; + }; + doc_count: number; +} + +export interface SearchResponse { + aggregations: { + ranges: { + buckets: { + all: AggregationResultBuckets; + last7Days: AggregationResultBuckets; + }; + }; + }; +} + +export interface AvailableTotal { + available: boolean; + total: number; +} diff --git a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_browserdriverfactory.ts b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_browserdriverfactory.ts index aafe17d970187..260c94c31df1c 100644 --- a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_browserdriverfactory.ts +++ b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_browserdriverfactory.ts @@ -7,11 +7,10 @@ import { Page } from 'puppeteer'; import * as Rx from 'rxjs'; import * as contexts from '../export_types/common/lib/screenshots/constants'; -import { ElementsPositionAndAttribute } from '../export_types/common/lib/screenshots/types'; import { HeadlessChromiumDriver, HeadlessChromiumDriverFactory } from '../server/browsers'; import { createDriverFactory } from '../server/browsers/chromium'; -import { CaptureConfig } from '../server/types'; -import { Logger } from '../types'; +import { LevelLogger } from '../server/lib'; +import { CaptureConfig, ElementsPositionAndAttribute } from '../server/types'; interface CreateMockBrowserDriverFactoryOpts { evaluate: jest.Mock, any[]>; @@ -93,7 +92,7 @@ const defaultOpts: CreateMockBrowserDriverFactoryOpts = { }; export const createMockBrowserDriverFactory = async ( - logger: Logger, + logger: LevelLogger, opts: Partial = {} ): Promise => { const captureConfig: CaptureConfig = { diff --git a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_layoutinstance.ts b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_layoutinstance.ts index 81090e7616501..7f4330e7f6bc6 100644 --- a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_layoutinstance.ts +++ b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_layoutinstance.ts @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LayoutTypes } from '../export_types/common/constants'; -import { createLayout } from '../export_types/common/layouts'; -import { LayoutInstance } from '../export_types/common/layouts/layout'; +import { createLayout, LayoutInstance, LayoutTypes } from '../export_types/common/layouts'; import { CaptureConfig } from '../server/types'; export const createMockLayoutInstance = (captureConfig: CaptureConfig) => { diff --git a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_reportingplugin.ts b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_reportingplugin.ts index ec00023b4d449..274f7344c7261 100644 --- a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_reportingplugin.ts +++ b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_reportingplugin.ts @@ -15,7 +15,7 @@ jest.mock('../server/lib/validate'); import { EventEmitter } from 'events'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { coreMock } from 'src/core/server/mocks'; -import { ReportingPlugin, ReportingCore, ReportingConfig } from '../server'; +import { ReportingConfig, ReportingCore, ReportingPlugin } from '../server'; import { ReportingSetupDeps, ReportingStartDeps } from '../server/types'; const createMockSetupDeps = (setupMock?: any): ReportingSetupDeps => { diff --git a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_server.ts b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_server.ts index 531e1dcaf84e0..819636b714631 100644 --- a/x-pack/legacy/plugins/reporting/test_helpers/create_mock_server.ts +++ b/x-pack/legacy/plugins/reporting/test_helpers/create_mock_server.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ServerFacade } from '../types'; +import { ServerFacade } from '../server/types'; export const createMockServer = (): ServerFacade => { const mockServer = {}; diff --git a/x-pack/legacy/plugins/reporting/types.d.ts b/x-pack/legacy/plugins/reporting/types.d.ts deleted file mode 100644 index 2e7da6663ab03..0000000000000 --- a/x-pack/legacy/plugins/reporting/types.d.ts +++ /dev/null @@ -1,277 +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 { EventEmitter } from 'events'; -import { ResponseObject } from 'hapi'; -import { Legacy } from 'kibana'; -import { CallCluster } from '../../../../src/legacy/core_plugins/elasticsearch'; -import { JobStatus } from '../../../plugins/reporting'; // reporting new platform -import { CancellationToken } from './common/cancellation_token'; -import { ReportingCore } from './server/core'; -import { LevelLogger } from './server/lib/level_logger'; -import { LegacySetup } from './server/types'; - -export type Job = EventEmitter & { - id: string; - toJSON: () => { - id: string; - }; -}; - -export interface NetworkPolicyRule { - allow: boolean; - protocol?: string; - host?: string; -} - -export interface NetworkPolicy { - enabled: boolean; - rules: NetworkPolicyRule[]; -} - -export interface ListQuery { - page: string; - size: string; - ids?: string; // optional field forbids us from extending RequestQuery -} -interface GenerateQuery { - jobParams: string; -} -interface GenerateExportTypePayload { - jobParams: string; -} - -/* - * Legacy System - * TODO: move to server/types - */ - -export type ServerFacade = LegacySetup; - -export type ReportingPluginSpecOptions = Legacy.PluginSpecOptions; - -export type EnqueueJobFn = ( - exportTypeId: string, - jobParams: JobParamsType, - user: string, - headers: Record, - request: RequestFacade -) => Promise; - -export type ReportingRequestPayload = GenerateExportTypePayload | JobParamPostPayload; -export type ReportingRequestQuery = ListQuery | GenerateQuery; - -export interface ReportingRequestPre { - management: { - jobTypes: any; - }; - user: any; // TODO import AuthenticatedUser from security/server -} - -export interface RequestFacade { - getBasePath: Legacy.Request['getBasePath']; - getSavedObjectsClient: Legacy.Request['getSavedObjectsClient']; - headers: Legacy.Request['headers']; - params: Legacy.Request['params']; - payload: JobParamPostPayload | GenerateExportTypePayload; - query: ReportingRequestQuery; - route: Legacy.Request['route']; - pre: ReportingRequestPre; - getRawRequest: () => Legacy.Request; -} - -export type ResponseFacade = ResponseObject & { - isBoom: boolean; -}; - -export type ReportingResponseToolkit = Legacy.ResponseToolkit; - -export type ESCallCluster = CallCluster; - -export interface ElementPosition { - boundingClientRect: { - // modern browsers support x/y, but older ones don't - top: number; - left: number; - width: number; - height: number; - }; - scroll: { - x: number; - y: number; - }; -} - -export interface ConditionalHeaders { - headers: Record; - conditions: ConditionalHeadersConditions; -} - -export interface ConditionalHeadersConditions { - protocol: string; - hostname: string; - port: number; - basePath: string; -} - -export interface IndexPatternSavedObject { - attributes: { - fieldFormatMap: string; - }; - id: string; - type: string; - version: string; -} - -export interface TimeRangeParams { - timezone: string; - min: Date | string | number; - max: Date | string | number; -} - -// retain POST payload data, needed for async -export interface JobParamPostPayload { - timerange: TimeRangeParams; -} - -export interface JobDocPayload { - headers?: string; // serialized encrypted headers - jobParams: JobParamsType; - title: string; - type: string | null; -} - -export interface JobSource { - _id: string; - _index: string; - _source: { - jobtype: string; - output: JobDocOutput; - payload: JobDocPayload; - status: JobStatus; - }; -} - -export interface JobDocOutput { - content_type: string; - content: string | null; - size: number; - max_size_reached?: boolean; - warnings?: string[]; -} - -export interface ESQueueWorker { - on: (event: string, handler: any) => void; -} - -export type ESQueueCreateJobFn = ( - jobParams: JobParamsType, - headers: Record, - request: RequestFacade -) => Promise; - -export type ImmediateCreateJobFn = ( - jobParams: JobParamsType, - headers: Record, - req: RequestFacade -) => Promise<{ - type: string | null; - title: string; - jobParams: JobParamsType; -}>; - -export type ESQueueWorkerExecuteFn = ( - jobId: string, - job: JobDocPayloadType, - cancellationToken?: CancellationToken -) => Promise; - -/* - * ImmediateExecuteFn receives the job doc payload because the payload was - * generated in the CreateFn - */ -export type ImmediateExecuteFn = ( - jobId: null, - job: JobDocPayload, - request: RequestFacade -) => Promise; - -export interface ESQueueWorkerOptions { - kibanaName: string; - kibanaId: string; - interval: number; - intervalErrorMultiplier: number; -} - -// GenericWorkerFn is a generic for ImmediateExecuteFn | ESQueueWorkerExecuteFn, -type GenericWorkerFn = ( - jobSource: JobSource, - ...workerRestArgs: any[] -) => void | Promise; - -export interface ESQueueInstance { - addJob: (type: string, payload: unknown, options: object) => Job; - registerWorker: ( - pluginId: string, - workerFn: GenericWorkerFn, - workerOptions: ESQueueWorkerOptions - ) => ESQueueWorker; -} - -export type CreateJobFactory = ( - reporting: ReportingCore, - logger: LevelLogger -) => CreateJobFnType; -export type ExecuteJobFactory = ( - reporting: ReportingCore, - logger: LevelLogger -) => Promise; // FIXME: does not "need" to be async - -export interface ExportTypeDefinition< - JobParamsType, - CreateJobFnType, - JobPayloadType, - ExecuteJobFnType -> { - id: string; - name: string; - jobType: string; - jobContentEncoding?: string; - jobContentExtension: string; - createJobFactory: CreateJobFactory; - executeJobFactory: ExecuteJobFactory; - validLicenses: string[]; -} - -export { CancellationToken } from './common/cancellation_token'; - -export { HeadlessChromiumDriver, HeadlessChromiumDriverFactory } from './server/browsers'; - -export { ExportTypesRegistry } from './server/lib/export_types_registry'; -// Prefer to import this type using: `import { LevelLogger } from 'relative/path/server/lib';` -export { LevelLogger as Logger }; - -export interface AbsoluteURLFactoryOptions { - defaultBasePath: string; - protocol: string; - hostname: string; - port: string | number; -} - -export interface InterceptedRequest { - requestId: string; - request: { - url: string; - method: string; - headers: { - [key: string]: string; - }; - initialPriority: string; - referrerPolicy: string; - }; - frameId: string; - resourceType: string; -} diff --git a/x-pack/legacy/plugins/reporting/common/cancellation_token.test.ts b/x-pack/plugins/reporting/common/cancellation_token.test.ts similarity index 100% rename from x-pack/legacy/plugins/reporting/common/cancellation_token.test.ts rename to x-pack/plugins/reporting/common/cancellation_token.test.ts diff --git a/x-pack/legacy/plugins/reporting/common/cancellation_token.ts b/x-pack/plugins/reporting/common/cancellation_token.ts similarity index 100% rename from x-pack/legacy/plugins/reporting/common/cancellation_token.ts rename to x-pack/plugins/reporting/common/cancellation_token.ts diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/types.d.ts b/x-pack/plugins/reporting/common/index.ts similarity index 80% rename from x-pack/legacy/plugins/reporting/export_types/csv/server/lib/types.d.ts rename to x-pack/plugins/reporting/common/index.ts index b4dc743664995..36c896fb4f7b8 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/types.d.ts +++ b/x-pack/plugins/reporting/common/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export type RawValue = string | object | null | undefined; +export { CancellationToken } from './cancellation_token'; diff --git a/x-pack/plugins/reporting/common/poller.ts b/x-pack/plugins/reporting/common/poller.ts index 919d7273062a8..1aeaca001cf1e 100644 --- a/x-pack/plugins/reporting/common/poller.ts +++ b/x-pack/plugins/reporting/common/poller.ts @@ -5,7 +5,7 @@ */ import _ from 'lodash'; -import { PollerOptions } from '..'; +import { PollerOptions } from './types'; // @TODO Maybe move to observables someday export class Poller { diff --git a/x-pack/plugins/reporting/common/types.d.ts b/x-pack/plugins/reporting/common/types.d.ts deleted file mode 100644 index 7ab9a15e1773a..0000000000000 --- a/x-pack/plugins/reporting/common/types.d.ts +++ /dev/null @@ -1,8 +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. - */ - -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -export { ConfigType } from '../server/config'; diff --git a/x-pack/plugins/reporting/index.d.ts b/x-pack/plugins/reporting/common/types.ts similarity index 93% rename from x-pack/plugins/reporting/index.d.ts rename to x-pack/plugins/reporting/common/types.ts index 77faf837e6505..5b9ddfb1bbdea 100644 --- a/x-pack/plugins/reporting/index.d.ts +++ b/x-pack/plugins/reporting/common/types.ts @@ -4,6 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +export { ConfigType } from '../server/config'; + export type JobId = string; export type JobStatus = | 'completed' diff --git a/x-pack/plugins/reporting/public/components/job_download_button.tsx b/x-pack/plugins/reporting/public/components/job_download_button.tsx index 911a19c0176c2..7dff2cafa047b 100644 --- a/x-pack/plugins/reporting/public/components/job_download_button.tsx +++ b/x-pack/plugins/reporting/public/components/job_download_button.tsx @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; import { EuiButton } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { JobId, JobSummary } from '../../index.d'; +import React from 'react'; +import { JobId, JobSummary } from '../../common/types'; interface Props { getUrl: (jobId: JobId) => string; diff --git a/x-pack/plugins/reporting/public/components/job_failure.tsx b/x-pack/plugins/reporting/public/components/job_failure.tsx index 628ecb56b9c21..0da67ea367437 100644 --- a/x-pack/plugins/reporting/public/components/job_failure.tsx +++ b/x-pack/plugins/reporting/public/components/job_failure.tsx @@ -4,13 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment } from 'react'; +import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiCallOut, EuiSpacer } from '@elastic/eui'; +import React, { Fragment } from 'react'; import { ToastInput } from 'src/core/public'; import { toMountPoint } from '../../../../../src/plugins/kibana_react/public'; -import { JobSummary, ManagementLinkFn } from '../../index.d'; +import { JobSummary, ManagementLinkFn } from '../../common/types'; export const getFailureToast = ( errorText: string, diff --git a/x-pack/plugins/reporting/public/components/job_success.tsx b/x-pack/plugins/reporting/public/components/job_success.tsx index ad16a506aeb70..7f33321ee3645 100644 --- a/x-pack/plugins/reporting/public/components/job_success.tsx +++ b/x-pack/plugins/reporting/public/components/job_success.tsx @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; +import React, { Fragment } from 'react'; import { ToastInput } from 'src/core/public'; import { toMountPoint } from '../../../../../src/plugins/kibana_react/public'; -import { JobId, JobSummary } from '../../index.d'; +import { JobId, JobSummary } from '../../common/types'; import { DownloadButton } from './job_download_button'; import { ReportLink } from './report_link'; diff --git a/x-pack/plugins/reporting/public/components/job_warning_formulas.tsx b/x-pack/plugins/reporting/public/components/job_warning_formulas.tsx index 8717ae16d1ba1..e2afae1feaa01 100644 --- a/x-pack/plugins/reporting/public/components/job_warning_formulas.tsx +++ b/x-pack/plugins/reporting/public/components/job_warning_formulas.tsx @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; +import React, { Fragment } from 'react'; import { ToastInput } from 'src/core/public'; import { toMountPoint } from '../../../../../src/plugins/kibana_react/public'; -import { JobId, JobSummary } from '../../index.d'; +import { JobId, JobSummary } from '../../common/types'; import { DownloadButton } from './job_download_button'; import { ReportLink } from './report_link'; diff --git a/x-pack/plugins/reporting/public/components/job_warning_max_size.tsx b/x-pack/plugins/reporting/public/components/job_warning_max_size.tsx index 83fa129f0715a..6c0d6118dfff2 100644 --- a/x-pack/plugins/reporting/public/components/job_warning_max_size.tsx +++ b/x-pack/plugins/reporting/public/components/job_warning_max_size.tsx @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; +import React, { Fragment } from 'react'; import { ToastInput } from 'src/core/public'; import { toMountPoint } from '../../../../../src/plugins/kibana_react/public'; -import { JobId, JobSummary } from '../../index.d'; +import { JobId, JobSummary } from '../../common/types'; import { DownloadButton } from './job_download_button'; import { ReportLink } from './report_link'; diff --git a/x-pack/plugins/reporting/public/lib/license_check.ts b/x-pack/plugins/reporting/public/lib/license_check.ts index 0c16ead0b116d..bf4dfeeb8fe31 100644 --- a/x-pack/plugins/reporting/public/lib/license_check.ts +++ b/x-pack/plugins/reporting/public/lib/license_check.ts @@ -3,8 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { LicenseCheckResults } from '../..'; + import { LicenseCheck } from '../../../licensing/public'; +import { LicenseCheckResults } from '../../common/types'; export const checkLicense = (checkResults: LicenseCheck): LicenseCheckResults => { switch (checkResults.state) { diff --git a/x-pack/plugins/reporting/public/lib/reporting_api_client.ts b/x-pack/plugins/reporting/public/lib/reporting_api_client.ts index b6c33860752d6..54bdc99532320 100644 --- a/x-pack/plugins/reporting/public/lib/reporting_api_client.ts +++ b/x-pack/plugins/reporting/public/lib/reporting_api_client.ts @@ -6,11 +6,10 @@ import { stringify } from 'query-string'; import rison from 'rison-node'; - import { HttpSetup } from 'src/core/public'; +import { JobId, SourceJob } from '../../common/types'; +import { API_BASE_GENERATE, API_LIST_URL, REPORTING_MANAGEMENT_HOME } from '../../constants'; import { add } from './job_completion_notifications'; -import { API_LIST_URL, API_BASE_GENERATE, REPORTING_MANAGEMENT_HOME } from '../../constants'; -import { JobId, SourceJob } from '../..'; export interface JobQueueEntry { _id: string; diff --git a/x-pack/plugins/reporting/public/lib/stream_handler.test.ts b/x-pack/plugins/reporting/public/lib/stream_handler.test.ts index 3a2c7de9ad0f0..96f284ae282b9 100644 --- a/x-pack/plugins/reporting/public/lib/stream_handler.test.ts +++ b/x-pack/plugins/reporting/public/lib/stream_handler.test.ts @@ -6,7 +6,7 @@ import sinon, { stub } from 'sinon'; import { NotificationsStart } from 'src/core/public'; -import { SourceJob, JobSummary } from '../../index.d'; +import { JobSummary, SourceJob } from '../../common/types'; import { ReportingAPIClient } from './reporting_api_client'; import { ReportingNotifierStreamHandler } from './stream_handler'; diff --git a/x-pack/plugins/reporting/public/lib/stream_handler.ts b/x-pack/plugins/reporting/public/lib/stream_handler.ts index eed6d5dd141e7..41e5353badfe5 100644 --- a/x-pack/plugins/reporting/public/lib/stream_handler.ts +++ b/x-pack/plugins/reporting/public/lib/stream_handler.ts @@ -8,13 +8,13 @@ import { i18n } from '@kbn/i18n'; import * as Rx from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { NotificationsSetup } from 'src/core/public'; +import { JobId, JobStatusBuckets, JobSummary, SourceJob } from '../../common/types'; import { JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY, JOB_STATUS_COMPLETED, JOB_STATUS_FAILED, JOB_STATUS_WARNINGS, } from '../../constants'; -import { JobId, JobStatusBuckets, JobSummary, SourceJob } from '../../index.d'; import { getFailureToast, getGeneralErrorToast, diff --git a/x-pack/plugins/reporting/public/plugin.tsx b/x-pack/plugins/reporting/public/plugin.tsx index f600b1ebbb96c..ac8ea661a21ab 100644 --- a/x-pack/plugins/reporting/public/plugin.tsx +++ b/x-pack/plugins/reporting/public/plugin.tsx @@ -18,16 +18,15 @@ import { PluginInitializerContext, } from 'src/core/public'; import { UiActionsSetup } from 'src/plugins/ui_actions/public'; -import { JobId, JobStatusBuckets } from '../'; -import { ManagementSetup, ManagementSectionId } from '../../../../src/plugins/management/public'; import { CONTEXT_MENU_TRIGGER } from '../../../../src/plugins/embeddable/public'; import { FeatureCatalogueCategory, HomePublicPluginSetup, } from '../../../../src/plugins/home/public'; +import { ManagementSectionId, ManagementSetup } from '../../../../src/plugins/management/public'; import { SharePluginSetup } from '../../../../src/plugins/share/public'; import { LicensingPluginSetup } from '../../licensing/public'; -import { ConfigType } from '../common/types'; +import { ConfigType, JobId, JobStatusBuckets } from '../common/types'; import { JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY } from '../constants'; import { getGeneralErrorToast } from './components'; import { ReportListing } from './components/report_listing'; diff --git a/x-pack/plugins/reporting/server/index.ts b/x-pack/plugins/reporting/server/index.ts index 2b1844cf2e10e..9d34eba70d0f4 100644 --- a/x-pack/plugins/reporting/server/index.ts +++ b/x-pack/plugins/reporting/server/index.ts @@ -7,8 +7,8 @@ import { PluginInitializerContext } from 'src/core/server'; import { ReportingPlugin } from './plugin'; -export { config, ConfigSchema } from './config'; -export { ConfigType, PluginsSetup } from './plugin'; +export { config, ConfigSchema, ConfigType } from './config'; +export { PluginsSetup } from './plugin'; export const plugin = (initializerContext: PluginInitializerContext) => new ReportingPlugin(initializerContext); From f7f7f0b0e229e202149e383d8ba3f1054e326a95 Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Mon, 18 May 2020 19:10:45 -0700 Subject: [PATCH 019/129] Warning and link to support matrix for IE11 (#66512) * Warning and link to support matrix for IE11 * snaps * i18n feedback Co-authored-by: Elastic Machine --- src/core/public/chrome/chrome_service.test.ts | 214 +++++++++--------- src/core/public/chrome/chrome_service.tsx | 46 +++- 2 files changed, 148 insertions(+), 112 deletions(-) diff --git a/src/core/public/chrome/chrome_service.test.ts b/src/core/public/chrome/chrome_service.test.ts index 327be61cc63e3..b5cf900d9c39f 100644 --- a/src/core/public/chrome/chrome_service.test.ts +++ b/src/core/public/chrome/chrome_service.test.ts @@ -97,7 +97,9 @@ describe('start', () => { expect(startDeps.notifications.toasts.addWarning.mock.calls).toMatchInlineSnapshot(` Array [ Array [ - "Your browser does not meet the security requirements for Kibana.", + Object { + "title": [Function], + }, ], ] `); @@ -146,18 +148,18 @@ describe('start', () => { service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` - Array [ - Object {}, - Object { - "logo": "big logo", - "smallLogo": "not so big logo", - }, - Object { - "logo": "big logo without small logo", - "smallLogo": undefined, - }, - ] - `); + Array [ + Object {}, + Object { + "logo": "big logo", + "smallLogo": "not so big logo", + }, + Object { + "logo": "big logo without small logo", + "smallLogo": undefined, + }, + ] + `); }); }); @@ -175,13 +177,13 @@ describe('start', () => { service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` - Array [ - false, - false, - false, - false, - ] - `); + Array [ + false, + false, + false, + false, + ] + `); }); it('emits false until manually overridden when in embed mode', async () => { @@ -203,13 +205,13 @@ describe('start', () => { service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` - Array [ - false, - false, - true, - false, - ] - `); + Array [ + false, + false, + true, + false, + ] + `); }); it('application-specified visibility on mount', async () => { @@ -230,13 +232,13 @@ describe('start', () => { service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` - Array [ - false, - true, - false, - true, - ] - `); + Array [ + false, + true, + false, + true, + ] + `); }); it('changing visibility has no effect on chrome-hiding application', async () => { @@ -253,12 +255,12 @@ describe('start', () => { service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` - Array [ - false, - false, - false, - ] - `); + Array [ + false, + false, + false, + ] + `); }); }); @@ -280,36 +282,36 @@ describe('start', () => { service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` - Array [ - Array [], - Array [ - "foo", - ], - Array [ - "foo", - ], - Array [ - "foo", - "bar", - ], - Array [ - "foo", - "bar", - ], - Array [ - "foo", - "bar", - "baz", - ], - Array [ - "foo", - "baz", - ], - Array [ - "baz", - ], - ] - `); + Array [ + Array [], + Array [ + "foo", + ], + Array [ + "foo", + ], + Array [ + "foo", + "bar", + ], + Array [ + "foo", + "bar", + ], + Array [ + "foo", + "bar", + "baz", + ], + Array [ + "foo", + "baz", + ], + Array [ + "baz", + ], + ] + `); }); }); @@ -327,19 +329,19 @@ describe('start', () => { service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` - Array [ - undefined, - Object { - "text": "foo", - "tooltip": "foo's tooltip", - }, - Object { - "text": "bar", - "tooltip": "bar's tooltip", - }, - undefined, - ] - `); + Array [ + undefined, + Object { + "text": "foo", + "tooltip": "foo's tooltip", + }, + Object { + "text": "bar", + "tooltip": "bar's tooltip", + }, + undefined, + ] + `); }); }); @@ -358,29 +360,29 @@ describe('start', () => { service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` - Array [ - Array [], - Array [ - Object { - "text": "foo", - }, - Object { - "text": "bar", - }, - ], - Array [ - Object { - "text": "foo", - }, - ], - Array [ - Object { - "text": "bar", - }, - ], - Array [], - ] - `); + Array [ + Array [], + Array [ + Object { + "text": "foo", + }, + Object { + "text": "bar", + }, + ], + Array [ + Object { + "text": "foo", + }, + ], + Array [ + Object { + "text": "bar", + }, + ], + Array [], + ] + `); }); }); diff --git a/src/core/public/chrome/chrome_service.tsx b/src/core/public/chrome/chrome_service.tsx index bf1a764e85882..a921e514050b2 100644 --- a/src/core/public/chrome/chrome_service.tsx +++ b/src/core/public/chrome/chrome_service.tsx @@ -18,11 +18,13 @@ */ import { Breadcrumb as EuiBreadcrumb, IconType } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import React from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; import { BehaviorSubject, combineLatest, merge, Observable, of, ReplaySubject } from 'rxjs'; import { flatMap, map, takeUntil } from 'rxjs/operators'; import { parse } from 'url'; +import { EuiLink } from '@elastic/eui'; +import { mountReactNode } from '../utils/mount'; import { InternalApplicationStart } from '../application'; import { DocLinksStart } from '../doc_links'; import { HttpStart } from '../http'; @@ -165,12 +167,44 @@ export class ChromeService { // Can delete const getNavType$ = uiSettings.get$('pageNavigation').pipe(takeUntil(this.stop$)); + const isIE = () => { + const ua = window.navigator.userAgent; + const msie = ua.indexOf('MSIE '); // IE 10 or older + const trident = ua.indexOf('Trident/'); // IE 11 + + return msie > 0 || trident > 0; + }; + if (!this.params.browserSupportsCsp && injectedMetadata.getCspConfig().warnLegacyBrowsers) { - notifications.toasts.addWarning( - i18n.translate('core.chrome.legacyBrowserWarning', { - defaultMessage: 'Your browser does not meet the security requirements for Kibana.', - }) - ); + notifications.toasts.addWarning({ + title: mountReactNode( + + ), + }); + + if (isIE()) { + notifications.toasts.addWarning({ + title: mountReactNode( + + + + ), + }} + /> + ), + }); + } } return { From f7181a95dc42db2145769cf4df858c834f8c795b Mon Sep 17 00:00:00 2001 From: Matthew Kime Date: Mon, 18 May 2020 22:25:20 -0500 Subject: [PATCH 020/129] Index pattern management to Kibana platform (#65026) * index pattern management to kibana platform --- src/core/MIGRATION.md | 1 + .../kibana/public/management/index.js | 1 - .../angular_template.html | 5 - .../components/header/header.tsx | 110 ---- .../create_index_pattern_wizard/index.js | 58 -- .../create_index_pattern_wizard/render.js | 45 -- .../render.test.js | 63 -- .../edit_index_pattern/create_edit_field.html | 5 - .../edit_index_pattern.html | 12 - .../edit_index_pattern/index.js | 177 ------ .../header/__snapshots__/header.test.tsx.snap | 44 -- .../sections/index_patterns/index.html | 5 - .../sections/index_patterns/index.js | 173 ------ .../index_pattern_table.tsx | 154 ----- .../sections/index_patterns/list.html | 5 - .../server/lib/__tests__/relationships.js | 12 +- src/legacy/ui/public/_index.scss | 2 - src/legacy/ui/public/field_editor/_index.scss | 2 - .../editors/url/icons/index.js | 26 - .../field_format_editor/register.ts | 43 -- .../field_format_editor/samples/_index.scss | 1 - .../ui/ui_exports/ui_export_defaults.js | 4 +- .../ensure_default_index_pattern.tsx | 6 +- .../index_patterns/index_pattern.ts | 2 +- .../server/saved_objects/index_patterns.ts | 4 +- .../components/fetch_error/fetch_error.tsx | 2 +- .../__snapshots__/add_data.test.js.snap | 8 +- .../public/application/components/add_data.js | 2 +- .../index_pattern_management/kibana.json | 2 +- .../public/assets}/icons/LICENSE.txt | 0 .../public/assets}/icons/cv.png | Bin .../public/assets}/icons/de.png | Bin .../public/assets}/icons/go.png | Bin .../public/assets}/icons/ne.png | Bin .../public/assets}/icons/ni.png | Bin .../public/assets}/icons/stop.png | Bin .../public/assets}/icons/us.png | Bin .../__snapshots__/utils.test.ts.snap | 20 + .../public/components/breadcrumbs.ts} | 29 +- .../create_button/create_button.tsx | 15 +- .../public/components}/create_button/index.ts | 0 .../create_index_pattern_prompt/index.tsx | 18 +- .../CREATE_INDEX_PATTERN.md | 0 .../create_index_pattern_wizard.test.tsx.snap | 47 +- .../__snapshots__/empty_state.test.tsx.snap | 12 +- .../empty_state/empty_state.test.tsx | 0 .../components/empty_state/empty_state.tsx | 12 +- .../components/empty_state/index.ts | 0 .../header/__snapshots__/header.test.tsx.snap | 36 +- .../components/header/header.test.tsx | 3 + .../components/header/header.tsx | 118 ++++ .../components/header/index.ts | 0 .../__snapshots__/loading_state.test.tsx.snap | 2 +- .../components/loading_state/index.ts | 0 .../loading_state/loading_state.test.tsx | 0 .../loading_state/loading_state.tsx | 2 +- .../step_index_pattern.test.tsx.snap | 0 .../header/__snapshots__/header.test.tsx.snap | 20 +- .../components/header/header.test.tsx | 0 .../components/header/header.tsx | 12 +- .../components/header/index.ts | 0 .../__snapshots__/indices_list.test.tsx.snap | 10 +- .../components/indices_list/index.ts | 0 .../indices_list/indices_list.test.tsx | 0 .../components/indices_list/indices_list.tsx | 2 +- .../loading_indices.test.tsx.snap | 4 +- .../components/loading_indices/index.ts | 0 .../loading_indices/loading_indices.test.tsx | 0 .../loading_indices/loading_indices.tsx | 4 +- .../status_message.test.tsx.snap | 20 +- .../components/status_message/index.ts | 0 .../status_message/status_message.test.tsx | 0 .../status_message/status_message.tsx | 20 +- .../components/step_index_pattern/index.ts | 0 .../step_index_pattern.test.tsx | 8 +- .../step_index_pattern/step_index_pattern.tsx | 12 +- .../step_time_field.test.tsx.snap | 8 +- .../action_buttons/action_buttons.tsx | 4 +- .../components/action_buttons/index.ts | 0 .../advanced_options.test.tsx.snap | 8 +- .../advanced_options.test.tsx | 0 .../advanced_options/advanced_options.tsx | 10 +- .../components/advanced_options/index.ts | 0 .../header/__snapshots__/header.test.tsx.snap | 4 +- .../components/header/header.test.tsx | 0 .../components/header/header.tsx | 4 +- .../components/header/index.ts | 0 .../__snapshots__/time_field.test.tsx.snap | 24 +- .../components/time_field/index.ts | 0 .../components/time_field/time_field.scss} | 3 +- .../components/time_field/time_field.test.tsx | 0 .../components/time_field/time_field.tsx | 16 +- .../components/step_time_field/index.ts | 0 .../step_time_field/step_time_field.test.tsx | 7 +- .../step_time_field/step_time_field.tsx | 10 +- .../constants/index.ts | 0 .../create_index_pattern_wizard.test.tsx | 56 +- .../create_index_pattern_wizard.tsx | 123 ++-- .../create_index_pattern_wizard/index.ts | 20 + .../lib/can_append_wildcard.test.ts | 0 .../lib/can_append_wildcard.ts | 0 .../lib/contains_illegal_characters.ts | 0 .../lib/contains_invalid_characters.test.ts | 0 .../lib/ensure_minimum_time.test.ts | 0 .../lib/ensure_minimum_time.ts | 0 .../lib/extract_time_fields.test.ts | 0 .../lib/extract_time_fields.ts | 13 +- .../lib/get_indices.test.ts | 4 +- .../lib/get_indices.ts | 4 +- .../lib/get_matched_indices.test.ts | 0 .../lib/get_matched_indices.ts | 0 .../create_index_pattern_wizard/lib/index.ts | 0 .../create_index_pattern_wizard/types.ts | 0 .../edit_index_pattern/constants.ts | 0 .../create_edit_field/create_edit_field.tsx | 87 +-- .../create_edit_field_container.tsx | 95 +++ .../create_edit_field/index.ts | 21 + .../edit_index_pattern/edit_index_pattern.tsx | 185 +++--- .../edit_index_pattern_container.tsx | 73 +++ .../edit_index_pattern_state_container.ts | 2 +- .../components/edit_index_pattern/index.tsx | 23 + .../edit_index_pattern/index_header/index.ts | 0 .../index_header/index_header.tsx | 36 +- .../indexed_fields_table.test.tsx.snap | 0 .../table/__snapshots__/table.test.tsx.snap | 0 .../components/table/index.ts | 0 .../components/table/table.test.tsx | 2 +- .../components/table/table.tsx | 68 +- .../indexed_fields_table/index.ts | 0 .../indexed_fields_table.test.tsx | 2 +- .../indexed_fields_table.tsx | 3 +- .../lib/get_field_format.test.ts | 2 +- .../lib/get_field_format.ts | 2 +- .../indexed_fields_table/lib/index.ts | 0 .../indexed_fields_table/types.ts | 2 +- .../scripted_field_table.test.tsx.snap | 20 +- .../__snapshots__/call_outs.test.tsx.snap | 6 +- .../components/call_outs/call_outs.test.tsx | 0 .../components/call_outs/call_outs.tsx | 6 +- .../components/call_outs/index.ts | 0 .../confirmation_modal.test.tsx.snap | 0 .../confirmation_modal.test.tsx | 0 .../confirmation_modal/confirmation_modal.tsx | 15 +- .../components/confirmation_modal/index.ts | 0 .../header/__snapshots__/header.test.tsx.snap | 49 ++ .../components/header/header.test.tsx | 12 +- .../components/header/header.tsx | 22 +- .../components/header/index.ts | 0 .../scripted_fields_table/components/index.ts | 0 .../table/__snapshots__/table.test.tsx.snap | 0 .../components/table/index.ts | 0 .../components/table/table.test.tsx | 2 +- .../components/table/table.tsx | 54 +- .../scripted_fields_table/index.ts | 0 .../scripted_field_table.test.tsx | 28 +- .../scripted_fields_table.tsx | 23 +- .../scripted_fields_table/types.ts | 0 .../source_filters_table.test.tsx.snap | 0 .../__snapshots__/add_filter.test.tsx.snap | 4 +- .../components/add_filter/add_filter.test.tsx | 0 .../components/add_filter/add_filter.tsx | 13 +- .../components/add_filter/index.ts | 0 .../confirmation_modal.test.tsx.snap | 6 +- .../confirmation_modal.test.tsx | 0 .../confirmation_modal/confirmation_modal.tsx | 6 +- .../components/confirmation_modal/index.ts | 0 .../header/__snapshots__/header.test.tsx.snap | 6 +- .../components/header/header.test.tsx | 0 .../components/header/header.tsx | 6 +- .../components/header/index.ts | 0 .../source_filters_table/components/index.ts | 0 .../table/__snapshots__/table.test.tsx.snap | 2 +- .../components/table/index.ts | 0 .../components/table/table.test.tsx | 2 +- .../components/table/table.tsx | 49 +- .../source_filters_table/index.ts | 0 .../source_filters_table.test.tsx | 2 +- .../source_filters_table.tsx | 2 +- .../source_filters_table/types.ts | 0 .../edit_index_pattern/tabs/index.ts | 0 .../edit_index_pattern/tabs/tabs.tsx | 31 +- .../edit_index_pattern/tabs/utils.ts | 30 +- .../__snapshots__/field_editor.test.tsx.snap | 229 +++---- .../field_format_editor.test.tsx.snap | 0 .../bytes/__snapshots__/bytes.test.tsx.snap | 4 +- .../editors/bytes/bytes.test.tsx | 1 - .../editors/bytes/bytes.ts | 0 .../editors/bytes/index.ts | 0 .../color/__snapshots__/color.test.tsx.snap | 30 +- .../editors/color/color.test.tsx | 5 +- .../editors/color/color.tsx | 20 +- .../editors/color/index.ts | 0 .../date/__snapshots__/date.test.tsx.snap | 4 +- .../editors/date/date.test.tsx | 1 - .../field_format_editor/editors/date/date.tsx | 4 +- .../field_format_editor/editors/date/index.ts | 0 .../__snapshots__/date_nanos.test.tsx.snap | 4 +- .../editors/date_nanos/date_nanos.test.tsx | 3 +- .../editors/date_nanos/date_nanos.tsx | 4 +- .../editors/date_nanos/index.ts | 0 .../__snapshots__/default.test.tsx.snap | 0 .../editors/default/default.test.tsx | 3 - .../editors/default/default.tsx | 4 +- .../editors/default/index.ts | 0 .../__snapshots__/duration.test.tsx.snap | 10 +- .../editors/duration/duration.test.tsx | 2 - .../editors/duration/duration.tsx | 8 +- .../editors/duration/index.tsx | 0 .../field_format_editor/editors/index.ts | 31 + .../number/__snapshots__/number.test.tsx.snap | 4 +- .../editors/number/index.ts | 0 .../editors/number/number.test.tsx | 1 - .../editors/number/number.tsx | 4 +- .../__snapshots__/percent.test.tsx.snap | 4 +- .../editors/percent/index.ts | 0 .../editors/percent/percent.test.tsx | 3 +- .../editors/percent/percent.tsx | 0 .../__snapshots__/static_lookup.test.tsx.snap | 16 +- .../editors/static_lookup/index.ts | 0 .../static_lookup/static_lookup.test.tsx | 6 +- .../editors/static_lookup/static_lookup.tsx | 19 +- .../string/__snapshots__/string.test.tsx.snap | 2 +- .../editors/string/index.ts | 0 .../editors/string/string.test.tsx | 1 - .../editors/string/string.tsx | 2 +- .../__snapshots__/truncate.test.tsx.snap | 2 +- .../editors/truncate/index.ts | 0 .../editors/truncate/sample.ts | 0 .../editors/truncate/truncate.test.tsx | 3 - .../editors/truncate/truncate.tsx | 2 +- .../label_template_flyout.test.tsx.snap | 10 +- .../url/__snapshots__/url.test.tsx.snap | 44 +- .../url_template_flyout.test.tsx.snap | 12 +- .../field_format_editor/editors/url/index.ts | 0 .../url/label_template_flyout.test.tsx | 0 .../editors/url/label_template_flyout.tsx | 26 +- .../editors/url/url.test.tsx | 8 - .../field_format_editor/editors/url/url.tsx | 25 +- .../editors/url/url_template_flyout.test.tsx | 0 .../editors/url/url_template_flyout.tsx | 18 +- .../field_format_editor.test.tsx | 1 + .../field_format_editor.tsx | 4 +- .../components/field_format_editor/index.ts | 1 + .../__snapshots__/samples.test.tsx.snap | 2 +- .../field_format_editor/samples/index.ts | 0 .../field_format_editor/samples/samples.scss} | 0 .../samples/samples.test.tsx | 0 .../field_format_editor/samples/samples.tsx | 8 +- .../disabled_call_out.test.tsx.snap | 4 +- .../warning_call_out.test.tsx.snap | 10 +- .../disabled_call_out.test.tsx | 0 .../scripting_call_outs/disabled_call_out.tsx | 4 +- .../components/scripting_call_outs/index.ts | 0 .../warning_call_out.test.tsx | 2 +- .../scripting_call_outs/warning_call_out.tsx | 10 +- .../__snapshots__/help_flyout.test.tsx.snap | 40 +- .../scripting_help/help_flyout.test.tsx | 19 +- .../components/scripting_help/help_flyout.tsx | 16 +- .../components/scripting_help/index.ts | 0 .../scripting_help/scripting_syntax.tsx | 46 +- .../scripting_help/test_script.scss} | 0 .../components/scripting_help/test_script.tsx | 43 +- .../field_editor/constants/index.ts | 2 +- .../field_editor/field_editor.test.tsx | 53 +- .../components}/field_editor/field_editor.tsx | 169 ++--- .../public/components}/field_editor/index.ts | 0 .../components}/field_editor/lib/index.ts | 0 .../field_editor/lib/validate_script.ts | 9 +- .../public/components}/field_editor/types.ts | 2 +- .../public/components/index.ts | 27 + .../components/index_pattern_table/index.ts} | 2 +- .../index_pattern_table.tsx | 207 +++++++ .../public/components/types.ts | 32 + .../public/components/utils.test.ts | 51 ++ .../public/components/utils.ts | 69 +++ .../index_pattern_management/public/index.ts | 6 +- .../public/management_app/index.tsx} | 2 +- .../mount_management_section.tsx | 143 +++++ .../index_pattern_management/public/mocks.ts | 21 +- .../index_pattern_management/public/plugin.ts | 67 +- .../public/scripting_languages/index.ts | 13 +- .../public/service/creation/config.ts | 8 +- .../public/service/creation/index.ts | 2 +- .../public/service/creation/manager.ts | 84 +-- .../field_format_editors.ts | 43 ++ .../service/field_format_editors}/index.ts | 2 +- .../public/service/index.ts | 2 +- .../index_pattern_management_service.ts | 41 +- .../public/service/list/config.ts | 20 +- .../public/service/list/manager.ts | 72 +-- .../url/kbn_url_storage.test.ts | 36 +- .../state_management/url/kbn_url_storage.ts | 8 +- .../saved_objects_table.test.tsx.snap | 4 +- .../__snapshots__/relationships.test.tsx.snap | 4 +- .../__snapshots__/table.test.tsx.snap | 8 +- .../components/relationships.test.tsx | 8 +- .../objects_table/components/table.test.tsx | 8 +- .../saved_objects_table.test.tsx | 4 +- .../objects_table/saved_objects_table.tsx | 2 +- .../apis/saved_objects_management/find.ts | 5 +- .../saved_objects_management/relationships.ts | 10 +- .../_index_pattern_create_delete.js | 2 +- test/functional/page_objects/settings_page.ts | 4 +- .../guidance_panel/guidance_panel.tsx | 2 +- .../components/no_index_pattern_callout.js | 2 +- .../results_links/results_links.tsx | 4 +- .../rollup_index_pattern_creation_config.js | 2 +- ...ndex_patterns_missing_prompt.test.tsx.snap | 2 +- .../index_patterns_missing_prompt.tsx | 2 +- .../translations/translations/ja-JP.json | 584 +++++++++--------- .../translations/translations/zh-CN.json | 584 +++++++++--------- .../index_patterns_security.ts | 8 +- .../feature_controls/index_patterns_spaces.ts | 8 +- 313 files changed, 3134 insertions(+), 2822 deletions(-) delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/angular_template.html delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/header.tsx delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/index.js delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/render.js delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/render.test.js delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field.html delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.html delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index.js delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/__snapshots__/header.test.tsx.snap delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.html delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.js delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index_pattern_table/index_pattern_table.tsx delete mode 100644 src/legacy/core_plugins/kibana/public/management/sections/index_patterns/list.html delete mode 100644 src/legacy/ui/public/field_editor/_index.scss delete mode 100644 src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/icons/index.js delete mode 100644 src/legacy/ui/public/field_editor/components/field_format_editor/register.ts delete mode 100644 src/legacy/ui/public/field_editor/components/field_format_editor/samples/_index.scss rename src/{legacy/ui/public/field_editor/components/field_format_editor/editors/url => plugins/index_pattern_management/public/assets}/icons/LICENSE.txt (100%) rename src/{legacy/ui/public/field_editor/components/field_format_editor/editors/url => plugins/index_pattern_management/public/assets}/icons/cv.png (100%) rename src/{legacy/ui/public/field_editor/components/field_format_editor/editors/url => plugins/index_pattern_management/public/assets}/icons/de.png (100%) rename src/{legacy/ui/public/field_editor/components/field_format_editor/editors/url => plugins/index_pattern_management/public/assets}/icons/go.png (100%) rename src/{legacy/ui/public/field_editor/components/field_format_editor/editors/url => plugins/index_pattern_management/public/assets}/icons/ne.png (100%) rename src/{legacy/ui/public/field_editor/components/field_format_editor/editors/url => plugins/index_pattern_management/public/assets}/icons/ni.png (100%) rename src/{legacy/ui/public/field_editor/components/field_format_editor/editors/url => plugins/index_pattern_management/public/assets}/icons/stop.png (100%) rename src/{legacy/ui/public/field_editor/components/field_format_editor/editors/url => plugins/index_pattern_management/public/assets}/icons/us.png (100%) create mode 100644 src/plugins/index_pattern_management/public/components/__snapshots__/utils.test.ts.snap rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns/breadcrumbs.js => plugins/index_pattern_management/public/components/breadcrumbs.ts} (62%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_button/create_button.tsx (88%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_button/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_prompt/index.tsx (84%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/CREATE_INDEX_PATTERN.md (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap (94%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/empty_state/__snapshots__/empty_state.test.tsx.snap (75%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/empty_state/empty_state.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/empty_state/empty_state.tsx (82%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/empty_state/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/header/__snapshots__/header.test.tsx.snap (71%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/header/header.test.tsx (95%) create mode 100644 src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.tsx rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/header/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/loading_state/__snapshots__/loading_state.test.tsx.snap (88%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/loading_state/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/loading_state/loading_state.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/loading_state/loading_state.tsx (94%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/__snapshots__/step_index_pattern.test.tsx.snap (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/header/__snapshots__/header.test.tsx.snap (85%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/header/header.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/header/header.tsx (87%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/header/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/__snapshots__/indices_list.test.tsx.snap (97%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/indices_list.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/indices_list.tsx (98%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/__snapshots__/loading_indices.test.tsx.snap (85%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.tsx (91%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/status_message/__snapshots__/status_message.test.tsx.snap (80%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/status_message/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.tsx (83%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx (95%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx (95%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/__snapshots__/step_time_field.test.tsx.snap (95%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/action_buttons/action_buttons.tsx (91%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/action_buttons/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/advanced_options/__snapshots__/advanced_options.test.tsx.snap (81%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.tsx (85%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/advanced_options/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/header/__snapshots__/header.test.tsx.snap (83%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/header/header.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/header/header.tsx (92%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/header/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/time_field/__snapshots__/time_field.test.tsx.snap (84%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/time_field/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.css => plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.scss} (84%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.tsx (87%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx (98%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx (94%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/constants/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx (73%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/create_index_pattern_wizard.tsx (68%) create mode 100644 src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/index.ts rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/can_append_wildcard.test.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/can_append_wildcard.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/contains_illegal_characters.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/contains_invalid_characters.test.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/ensure_minimum_time.test.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/ensure_minimum_time.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/extract_time_fields.test.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/extract_time_fields.ts (80%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/get_indices.test.ts (95%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/get_indices.ts (93%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/get_matched_indices.test.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/get_matched_indices.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/lib/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/create_index_pattern_wizard/types.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/constants.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/create_edit_field/create_edit_field.tsx (52%) create mode 100644 src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field_container.tsx create mode 100644 src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/index.ts rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/edit_index_pattern.tsx (51%) create mode 100644 src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_container.tsx rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/edit_index_pattern_state_container.ts (97%) create mode 100644 src/plugins/index_pattern_management/public/components/edit_index_pattern/index.tsx rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/index_header/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/index_header/index_header.tsx (78%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/indexed_fields_table/__snapshots__/indexed_fields_table.test.tsx.snap (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/indexed_fields_table/components/table/__snapshots__/table.test.tsx.snap (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/indexed_fields_table/components/table/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/indexed_fields_table/components/table/table.test.tsx (97%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/indexed_fields_table/components/table/table.tsx (78%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/indexed_fields_table/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/indexed_fields_table/indexed_fields_table.test.tsx (97%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx (98%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/indexed_fields_table/lib/get_field_format.test.ts (95%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/indexed_fields_table/lib/get_field_format.ts (92%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/indexed_fields_table/lib/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/indexed_fields_table/types.ts (92%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/__snapshots__/scripted_field_table.test.tsx.snap (82%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/call_outs/__snapshots__/call_outs.test.tsx.snap (78%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.tsx (87%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/call_outs/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/confirmation_modal/__snapshots__/confirmation_modal.test.tsx.snap (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/confirmation_modal/confirmation_modal.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/confirmation_modal/confirmation_modal.tsx (83%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/confirmation_modal/index.ts (100%) create mode 100644 src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/header/__snapshots__/header.test.tsx.snap rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/header/header.test.tsx (71%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/header/header.tsx (72%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/header/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/table/__snapshots__/table.test.tsx.snap (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/table/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/table/table.test.tsx (97%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/components/table/table.tsx (68%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/scripted_field_table.test.tsx (89%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/scripted_fields_table.tsx (88%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/scripted_fields_table/types.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/__snapshots__/source_filters_table.test.tsx.snap (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/add_filter/__snapshots__/add_filter.test.tsx.snap (88%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/add_filter/add_filter.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/add_filter/add_filter.tsx (85%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/add_filter/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/confirmation_modal/__snapshots__/confirmation_modal.test.tsx.snap (72%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/confirmation_modal/confirmation_modal.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/confirmation_modal/confirmation_modal.tsx (89%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/confirmation_modal/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/header/__snapshots__/header.test.tsx.snap (85%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/header/header.test.tsx (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/header/header.tsx (90%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/header/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/table/__snapshots__/table.test.tsx.snap (95%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/table/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/table/table.test.tsx (99%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/components/table/table.tsx (85%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/source_filters_table.test.tsx (98%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/source_filters_table.tsx (98%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/source_filters_table/types.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/tabs/index.ts (100%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/tabs/tabs.tsx (92%) rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns => plugins/index_pattern_management/public/components}/edit_index_pattern/tabs/utils.ts (82%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/__snapshots__/field_editor.test.tsx.snap (72%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/__snapshots__/field_format_editor.test.tsx.snap (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.tsx.snap (92%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/bytes/bytes.test.tsx (98%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/bytes/bytes.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/bytes/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/color/__snapshots__/color.test.tsx.snap (87%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/color/color.test.tsx (94%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/color/color.tsx (90%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/color/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/date/__snapshots__/date.test.tsx.snap (93%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/date/date.test.tsx (98%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/date/date.tsx (95%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/date/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/date_nanos/__snapshots__/date_nanos.test.tsx.snap (93%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/date_nanos/date_nanos.test.tsx (94%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/date_nanos/date_nanos.tsx (95%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/date_nanos/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/default/__snapshots__/default.test.tsx.snap (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/default/default.test.tsx (98%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/default/default.tsx (96%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/default/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.tsx.snap (94%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/duration/duration.test.tsx (98%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/duration/duration.tsx (94%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/duration/index.tsx (100%) create mode 100644 src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/index.ts rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/number/__snapshots__/number.test.tsx.snap (92%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/number/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/number/number.test.tsx (98%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/number/number.tsx (95%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/percent/__snapshots__/percent.test.tsx.snap (92%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/percent/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/percent/percent.test.tsx (94%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/percent/percent.tsx (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/static_lookup/__snapshots__/static_lookup.test.tsx.snap (88%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/static_lookup/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/static_lookup/static_lookup.test.tsx (93%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/static_lookup/static_lookup.tsx (88%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/string/__snapshots__/string.test.tsx.snap (96%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/string/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/string/string.test.tsx (98%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/string/string.tsx (97%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/truncate/__snapshots__/truncate.test.tsx.snap (96%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/truncate/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/truncate/sample.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/truncate/truncate.test.tsx (98%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/truncate/truncate.tsx (97%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/url/__snapshots__/label_template_flyout.test.tsx.snap (90%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/url/__snapshots__/url.test.tsx.snap (89%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/url/__snapshots__/url_template_flyout.test.tsx.snap (88%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/url/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/url/label_template_flyout.test.tsx (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/url/label_template_flyout.tsx (80%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/url/url.test.tsx (94%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/url/url.tsx (88%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/url/url_template_flyout.test.tsx (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/editors/url/url_template_flyout.tsx (84%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/field_format_editor.test.tsx (98%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/field_format_editor.tsx (93%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/index.ts (96%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/samples/__snapshots__/samples.test.tsx.snap (96%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/samples/index.ts (100%) rename src/{legacy/ui/public/field_editor/components/field_format_editor/samples/_samples.scss => plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/samples.scss} (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/samples/samples.test.tsx (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/field_format_editor/samples/samples.tsx (90%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_call_outs/__snapshots__/disabled_call_out.test.tsx.snap (87%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_call_outs/__snapshots__/warning_call_out.test.tsx.snap (82%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_call_outs/disabled_call_out.test.tsx (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_call_outs/disabled_call_out.tsx (93%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_call_outs/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_call_outs/warning_call_out.test.tsx (93%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_call_outs/warning_call_out.tsx (88%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_help/__snapshots__/help_flyout.test.tsx.snap (59%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_help/help_flyout.test.tsx (77%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_help/help_flyout.tsx (85%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_help/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_help/scripting_syntax.tsx (79%) rename src/{legacy/ui/public/field_editor/components/scripting_help/_test_script.scss => plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.scss} (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/components/scripting_help/test_script.tsx (85%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/constants/index.ts (93%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/field_editor.test.tsx (84%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/field_editor.tsx (81%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/lib/index.ts (100%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/lib/validate_script.ts (95%) rename src/{legacy/ui/public => plugins/index_pattern_management/public/components}/field_editor/types.ts (97%) create mode 100644 src/plugins/index_pattern_management/public/components/index.ts rename src/{legacy/core_plugins/kibana/public/management/sections/index.js => plugins/index_pattern_management/public/components/index_pattern_table/index.ts} (92%) create mode 100644 src/plugins/index_pattern_management/public/components/index_pattern_table/index_pattern_table.tsx create mode 100644 src/plugins/index_pattern_management/public/components/types.ts create mode 100644 src/plugins/index_pattern_management/public/components/utils.test.ts create mode 100644 src/plugins/index_pattern_management/public/components/utils.ts rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns/index_pattern_table/index.js => plugins/index_pattern_management/public/management_app/index.tsx} (92%) create mode 100644 src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx rename src/{legacy/ui => plugins/index_pattern_management}/public/scripting_languages/index.ts (80%) create mode 100644 src/plugins/index_pattern_management/public/service/field_format_editors/field_format_editors.ts rename src/{legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field => plugins/index_pattern_management/public/service/field_format_editors}/index.ts (92%) diff --git a/src/core/MIGRATION.md b/src/core/MIGRATION.md index 02d46b1583b59..ce2d652257e1f 100644 --- a/src/core/MIGRATION.md +++ b/src/core/MIGRATION.md @@ -1240,6 +1240,7 @@ import { npStart: { plugins } } from 'ui/new_platform'; | `ui/filter_manager` | `plugins.data.filter` | -- | | `ui/index_patterns` | `plugins.data.indexPatterns` | | `import 'ui/management'` | `plugins.management.sections` | | +| `import 'ui/registry/field_format_editors'` | `plugins.indexPatternManagement.fieldFormatEditors` | | | `ui/registry/field_formats` | `plugins.data.fieldFormats` | | | `ui/registry/feature_catalogue` | `plugins.home.featureCatalogue.register` | Must add `home` as a dependency in your kibana.json. | | `ui/registry/vis_types` | `plugins.visualizations` | -- | diff --git a/src/legacy/core_plugins/kibana/public/management/index.js b/src/legacy/core_plugins/kibana/public/management/index.js index 2cba9fab7be22..ff253629a4825 100644 --- a/src/legacy/core_plugins/kibana/public/management/index.js +++ b/src/legacy/core_plugins/kibana/public/management/index.js @@ -21,7 +21,6 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { FormattedMessage } from '@kbn/i18n/react'; -import './sections'; import uiRoutes from 'ui/routes'; import { I18nContext } from 'ui/i18n'; import { uiModules } from 'ui/modules'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/angular_template.html b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/angular_template.html deleted file mode 100644 index a2bc83db904a4..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/angular_template.html +++ /dev/null @@ -1,5 +0,0 @@ - -
-
-
-
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/header.tsx b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/header.tsx deleted file mode 100644 index 928c1ef2b6299..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/header.tsx +++ /dev/null @@ -1,110 +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 React, { Fragment } from 'react'; - -import { - EuiBetaBadge, - EuiSpacer, - EuiTitle, - EuiFlexGroup, - EuiFlexItem, - EuiText, - EuiTextColor, - EuiSwitch, -} from '@elastic/eui'; - -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; - -export const Header = ({ - prompt, - indexPatternName, - showSystemIndices = false, - isIncludingSystemIndices, - onChangeIncludingSystemIndices, - isBeta = false, -}: { - prompt?: React.ReactNode; - indexPatternName: string; - showSystemIndices?: boolean; - isIncludingSystemIndices: boolean; - onChangeIncludingSystemIndices: () => void; - isBeta?: boolean; -}) => ( -
- -

- - {isBeta ? ( - - {' '} - - - ) : null} -

-
- - - -

- - - -

-
-
- {showSystemIndices ? ( - - - } - id="checkboxShowSystemIndices" - checked={isIncludingSystemIndices} - onChange={onChangeIncludingSystemIndices} - /> - - ) : null} -
- {prompt ? ( - - - {prompt} - - ) : null} - -
-); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/index.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/index.js deleted file mode 100644 index 2762a4f6e8726..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/index.js +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import uiRoutes from 'ui/routes'; -import angularTemplate from './angular_template.html'; -import { npStart } from 'ui/new_platform'; -import { getCreateBreadcrumbs } from '../breadcrumbs'; - -import { renderCreateIndexPatternWizard, destroyCreateIndexPatternWizard } from './render'; - -uiRoutes.when('/management/kibana/index_pattern', { - template: angularTemplate, - k7Breadcrumbs: getCreateBreadcrumbs, - controller: function($scope, $injector) { - // Wait for the directives to execute - const kbnUrl = $injector.get('kbnUrl'); - $scope.$$postDigest(() => { - const $routeParams = $injector.get('$routeParams'); - const indexPatternCreationType = npStart.plugins.indexPatternManagement.creation.getType( - $routeParams.type - ); - const services = { - uiSettings: npStart.core.uiSettings, - es: npStart.plugins.data.search.__LEGACY.esClient, - indexPatterns: npStart.plugins.data.indexPatterns, - savedObjectsClient: npStart.core.savedObjects.client, - indexPatternCreationType, - changeUrl: url => { - $scope.$evalAsync(() => kbnUrl.changePath(url)); - }, - openConfirm: npStart.core.overlays.openConfirm, - prependBasePath: npStart.core.http.basePath.prepend, - }; - - const initialQuery = $routeParams.id ? decodeURIComponent($routeParams.id) : undefined; - - renderCreateIndexPatternWizard(initialQuery, services); - }); - - $scope.$on('$destroy', destroyCreateIndexPatternWizard); - }, -}); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/render.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/render.js deleted file mode 100644 index d09ad3f63f0a2..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/render.js +++ /dev/null @@ -1,45 +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 React from 'react'; -import { render, unmountComponentAtNode } from 'react-dom'; -import { CreateIndexPatternWizard } from './create_index_pattern_wizard'; - -import { I18nContext } from 'ui/i18n'; - -const CREATE_INDEX_PATTERN_DOM_ELEMENT_ID = 'createIndexPatternReact'; - -export function renderCreateIndexPatternWizard(initialQuery, services) { - const node = document.getElementById(CREATE_INDEX_PATTERN_DOM_ELEMENT_ID); - if (!node) { - return; - } - - render( - - - , - node - ); -} - -export function destroyCreateIndexPatternWizard() { - const node = document.getElementById(CREATE_INDEX_PATTERN_DOM_ELEMENT_ID); - node && unmountComponentAtNode(node); -} diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/render.test.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/render.test.js deleted file mode 100644 index 1b9dafb6daf23..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/render.test.js +++ /dev/null @@ -1,63 +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. - */ - -const render = jest.fn(); -const unmountComponentAtNode = jest.fn(); - -jest.doMock('react-dom', () => ({ render, unmountComponentAtNode })); - -jest.mock('ui/chrome', () => ({ - getUiSettingsClient: () => ({ - get: () => '', - }), - addBasePath: () => {}, -})); - -jest.mock('ui/i18n', () => ({ - I18nContext: () => {}, -})); - -const { renderCreateIndexPatternWizard, destroyCreateIndexPatternWizard } = require('./render'); - -describe('CreateIndexPatternWizardRender', () => { - beforeEach(() => { - jest.spyOn(document, 'getElementById').mockImplementation(() => ({})); - render.mockClear(); - unmountComponentAtNode.mockClear(); - }); - - it('should call render', () => { - renderCreateIndexPatternWizard('', { - es: {}, - indexPatterns: {}, - savedObjectsClient: {}, - config: {}, - changeUrl: () => {}, - indexPatternCreationType: {}, - openConfirm: jest.fn(), - }); - - expect(render.mock.calls.length).toBe(1); - }); - - it('should call unmountComponentAtNode', () => { - destroyCreateIndexPatternWizard(); - expect(unmountComponentAtNode.mock.calls.length).toBe(1); - }); -}); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field.html b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field.html deleted file mode 100644 index 2decaf423183e..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field.html +++ /dev/null @@ -1,5 +0,0 @@ - -
-
-
-
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.html b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.html deleted file mode 100644 index 0bf7c7f0bdfbe..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.html +++ /dev/null @@ -1,12 +0,0 @@ - -
-
-
-
-
-
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index.js deleted file mode 100644 index ab1fa546e5ea8..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index.js +++ /dev/null @@ -1,177 +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 React from 'react'; -import { HashRouter } from 'react-router-dom'; -import { render, unmountComponentAtNode } from 'react-dom'; -import { RegistryFieldFormatEditorsProvider } from 'ui/registry/field_format_editors'; -import uiRoutes from 'ui/routes'; -import { uiModules } from 'ui/modules'; -import { I18nContext } from 'ui/i18n'; -import { npStart } from 'ui/new_platform'; -import template from './edit_index_pattern.html'; -import createEditFieldtemplate from './create_edit_field.html'; -import { - getEditBreadcrumbs, - getEditFieldBreadcrumbs, - getCreateFieldBreadcrumbs, -} from '../breadcrumbs'; -import { EditIndexPattern } from './edit_index_pattern'; -import { CreateEditField } from './create_edit_field'; - -const REACT_EDIT_INDEX_PATTERN_DOM_ELEMENT_ID = 'reactEditIndexPattern'; - -function destroyEditIndexPattern() { - const node = document.getElementById(REACT_EDIT_INDEX_PATTERN_DOM_ELEMENT_ID); - node && unmountComponentAtNode(node); -} - -function renderEditIndexPattern($scope, config, $route) { - $scope.$$postDigest(() => { - const node = document.getElementById(REACT_EDIT_INDEX_PATTERN_DOM_ELEMENT_ID); - if (!node) { - return; - } - - render( - - - - - , - node - ); - }); -} - -uiRoutes.when('/management/kibana/index_patterns/:indexPatternId', { - template, - k7Breadcrumbs: getEditBreadcrumbs, - resolve: { - indexPattern: function($route, Promise, redirectWhenMissing) { - const { indexPatterns } = npStart.plugins.data; - return Promise.resolve(indexPatterns.get($route.current.params.indexPatternId)).catch( - redirectWhenMissing('/management/kibana/index_patterns') - ); - }, - }, -}); - -uiModules - .get('apps/management') - .controller('managementIndexPatternsEdit', function($scope, $route, config) { - $scope.$on('$destroy', () => { - destroyEditIndexPattern(); - }); - - renderEditIndexPattern($scope, config, $route); - }); - -// routes for create edit field. Will be removed after migartion all component to react. -const REACT_FIELD_EDITOR_ID = 'reactFieldEditor'; -const renderCreateEditField = ($scope, $route, getConfig, fieldFormatEditors) => { - $scope.$$postDigest(() => { - const node = document.getElementById(REACT_FIELD_EDITOR_ID); - if (!node) { - return; - } - - render( - - - npStart.core.http, - notifications: npStart.core.notifications, - docTitle: npStart.core.chrome.docTitle, - docLinksScriptedFields: npStart.core.docLinks.links.scriptedFields, - }} - /> - - , - node - ); - }); -}; - -const destroyCreateEditField = () => { - const node = document.getElementById(REACT_FIELD_EDITOR_ID); - node && unmountComponentAtNode(node); -}; - -uiRoutes - .when('/management/kibana/index_patterns/:indexPatternId/field/:fieldName*', { - mode: 'edit', - k7Breadcrumbs: getEditFieldBreadcrumbs, - }) - .when('/management/kibana/index_patterns/:indexPatternId/create-field/', { - mode: 'create', - k7Breadcrumbs: getCreateFieldBreadcrumbs, - }) - .defaults(/management\/kibana\/index_patterns\/[^\/]+\/(field|create-field)(\/|$)/, { - template: createEditFieldtemplate, - mapBreadcrumbs($route, breadcrumbs) { - const { indexPattern } = $route.current.locals; - return breadcrumbs.map(crumb => { - if (crumb.id !== indexPattern.id) { - return crumb; - } - - return { - ...crumb, - display: indexPattern.title, - }; - }); - }, - resolve: { - indexPattern: function($route, Promise, redirectWhenMissing) { - const { indexPatterns } = npStart.plugins.data; - return Promise.resolve(indexPatterns.get($route.current.params.indexPatternId)).catch( - redirectWhenMissing('/management/kibana/index_patterns') - ); - }, - }, - controllerAs: 'fieldSettings', - controller: function FieldEditorPageController($scope, $route, Private, config) { - const getConfig = (...args) => config.get(...args); - const fieldFormatEditors = Private(RegistryFieldFormatEditorsProvider); - - renderCreateEditField($scope, $route, getConfig, fieldFormatEditors); - - $scope.$on('$destroy', () => { - destroyCreateEditField(); - }); - }, - }); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/__snapshots__/header.test.tsx.snap b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/__snapshots__/header.test.tsx.snap deleted file mode 100644 index 2e694b6363117..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/__snapshots__/header.test.tsx.snap +++ /dev/null @@ -1,44 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Header should render normally 1`] = ` - - - -

- -

-
- -

- -

-
-
- - - - - -
-`; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.html b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.html deleted file mode 100644 index 1af0fc2c33782..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.html +++ /dev/null @@ -1,5 +0,0 @@ -
-
-
-
-
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.js deleted file mode 100644 index 24bc4ba8fba5b..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.js +++ /dev/null @@ -1,173 +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 { management } from 'ui/management'; -import { ManagementSectionId } from '../../../../../../../plugins/management/public'; -import './create_index_pattern_wizard'; -import './edit_index_pattern'; -import uiRoutes from 'ui/routes'; -import { uiModules } from 'ui/modules'; -import indexTemplate from './index.html'; -import indexPatternListTemplate from './list.html'; -import { IndexPatternTable } from './index_pattern_table'; -import { npStart } from 'ui/new_platform'; -import { i18n } from '@kbn/i18n'; -import { I18nContext } from 'ui/i18n'; -import { UICapabilitiesProvider } from 'ui/capabilities/react'; -import { getListBreadcrumbs } from './breadcrumbs'; - -import React from 'react'; -import { render, unmountComponentAtNode } from 'react-dom'; - -const INDEX_PATTERN_LIST_DOM_ELEMENT_ID = 'indexPatternListReact'; - -export function updateIndexPatternList(indexPatterns, kbnUrl, indexPatternCreationOptions) { - const node = document.getElementById(INDEX_PATTERN_LIST_DOM_ELEMENT_ID); - if (!node) { - return; - } - - render( - - - - - , - node - ); -} - -export const destroyIndexPatternList = () => { - const node = document.getElementById(INDEX_PATTERN_LIST_DOM_ELEMENT_ID); - node && unmountComponentAtNode(node); -}; - -const indexPatternsResolutions = { - indexPatterns: function() { - const savedObjectsClient = npStart.core.savedObjects.client; - - return savedObjectsClient - .find({ - type: 'index-pattern', - fields: ['title', 'type'], - perPage: 10000, - }) - .then(response => response.savedObjects); - }, -}; - -// add a dependency to all of the subsection routes -uiRoutes.defaults(/management\/kibana\/(index_patterns|index_pattern)/, { - resolve: indexPatternsResolutions, - requireUICapability: 'management.kibana.index_patterns', - badge: uiCapabilities => { - if (uiCapabilities.indexPatterns.save) { - return undefined; - } - - return { - text: i18n.translate('kbn.management.indexPatterns.badge.readOnly.text', { - defaultMessage: 'Read only', - }), - tooltip: i18n.translate('kbn.management.indexPatterns.badge.readOnly.tooltip', { - defaultMessage: 'Unable to save index patterns', - }), - iconType: 'glasses', - }; - }, -}); - -uiRoutes.when('/management/kibana/index_patterns', { - template: indexPatternListTemplate, - k7Breadcrumbs: getListBreadcrumbs, -}); - -// wrapper directive, which sets some global stuff up like the left nav -uiModules - .get('apps/management') - .directive('kbnManagementIndexPatterns', function($route, config, kbnUrl) { - return { - restrict: 'E', - transclude: true, - template: indexTemplate, - link: async function($scope) { - const indexPatternCreationOptions = await npStart.plugins.indexPatternManagement.creation.getIndexPatternCreationOptions( - url => { - $scope.$evalAsync(() => kbnUrl.change(url)); - } - ); - - const renderList = () => { - $scope.indexPatternList = - $route.current.locals.indexPatterns - .map(pattern => { - const id = pattern.id; - const title = pattern.get('title'); - const isDefault = $scope.defaultIndex === id; - const tags = npStart.plugins.indexPatternManagement.list.getIndexPatternTags( - pattern, - isDefault - ); - - return { - id, - title, - url: kbnUrl.eval('#/management/kibana/index_patterns/{{id}}', { id: id }), - active: $scope.editingId === id, - default: isDefault, - tags, - //the prepending of 0 at the default pattern takes care of prioritization - //so the sorting will but the default index on top - //or on bottom of a the table - sort: `${isDefault ? '0' : '1'}${title}`, - }; - }) - .sort((a, b) => { - if (a.sort < b.sort) { - return -1; - } else if (a.sort > b.sort) { - return 1; - } else { - return 0; - } - }) || []; - - updateIndexPatternList($scope.indexPatternList, kbnUrl, indexPatternCreationOptions); - }; - - $scope.$on('$destroy', destroyIndexPatternList); - $scope.editingId = $route.current.params.indexPatternId; - $scope.$watch('defaultIndex', () => renderList()); - config.bindToScope($scope, 'defaultIndex'); - $scope.$apply(); - }, - }; - }); - -management.getSection(ManagementSectionId.Kibana).register('index_patterns', { - display: i18n.translate('kbn.management.indexPattern.sectionsHeader', { - defaultMessage: 'Index Patterns', - }), - order: 0, - url: '#/management/kibana/index_patterns/', -}); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index_pattern_table/index_pattern_table.tsx b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index_pattern_table/index_pattern_table.tsx deleted file mode 100644 index f254a6bc22a0d..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index_pattern_table/index_pattern_table.tsx +++ /dev/null @@ -1,154 +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 { - EuiBadge, - EuiButtonEmpty, - EuiButtonIcon, - EuiFlexGroup, - EuiFlexItem, - // @ts-ignore - EuiInMemoryTable, - EuiPanel, - EuiSpacer, - EuiText, -} from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; -import React from 'react'; -import { CreateButton } from '../create_button'; -import { CreateIndexPatternPrompt } from '../create_index_pattern_prompt'; -import { IndexPattern, IndexPatternCreationOption } from '../types'; - -const columns = [ - { - field: 'title', - name: 'Pattern', - render: ( - name: string, - index: { - id: string; - tags?: Array<{ - key: string; - name: string; - }>; - } - ) => ( - - {name} - {index.tags && - index.tags.map(({ key: tagKey, name: tagName }) => ( - - {tagName} - - ))} - - ), - dataType: 'string' as const, - sortable: ({ sort }: { sort: string }) => sort, - }, -]; - -const pagination = { - initialPageSize: 10, - pageSizeOptions: [5, 10, 25, 50], -}; - -const sorting = { - sort: { - field: 'title', - direction: 'asc' as const, - }, -}; - -const search = { - box: { - incremental: true, - schema: { - fields: { title: { type: 'string' } }, - }, - }, -}; - -interface Props { - indexPatterns: IndexPattern[]; - indexPatternCreationOptions: IndexPatternCreationOption[]; -} - -interface State { - showFlyout: boolean; -} - -export class IndexPatternTable extends React.Component { - public readonly state = { - showFlyout: this.props.indexPatterns.length === 0, - }; - - public render() { - return ( - - {this.state.showFlyout && ( - this.setState({ showFlyout: false })} /> - )} - - - - - -

- -

-
-
- - this.setState({ showFlyout: true })} - aria-label="Help" - /> - -
-
- - - - - -
- - -
- ); - } -} diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/list.html b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/list.html deleted file mode 100644 index 928fb75384be1..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/list.html +++ /dev/null @@ -1,5 +0,0 @@ - - - - diff --git a/src/legacy/core_plugins/kibana/server/lib/__tests__/relationships.js b/src/legacy/core_plugins/kibana/server/lib/__tests__/relationships.js index e5d43fec4e59c..64676b1bce75c 100644 --- a/src/legacy/core_plugins/kibana/server/lib/__tests__/relationships.js +++ b/src/legacy/core_plugins/kibana/server/lib/__tests__/relationships.js @@ -65,11 +65,11 @@ const savedObjectsManagement = getManagementaMock({ return obj.attributes.title; }, getEditUrl(obj) { - return `/management/kibana/index_patterns/${encodeURIComponent(obj.id)}`; + return `/management/kibana/indexPatterns/patterns/${encodeURIComponent(obj.id)}`; }, getInAppUrl(obj) { return { - path: `/app/kibana#/management/kibana/index_patterns/${encodeURIComponent(obj.id)}`, + path: `/app/kibana#/management/kibana/indexPatterns/patterns/${encodeURIComponent(obj.id)}`, uiCapabilitiesPath: 'management.kibana.index_patterns', }; }, @@ -323,9 +323,9 @@ describe('findRelationships', () => { meta: { icon: 'indexPatternApp', title: 'My Index Pattern', - editUrl: '/management/kibana/index_patterns/1', + editUrl: '/management/kibana/indexPatterns/patterns/1', inAppUrl: { - path: '/app/kibana#/management/kibana/index_patterns/1', + path: '/app/kibana#/management/kibana/indexPatterns/patterns/1', uiCapabilitiesPath: 'management.kibana.index_patterns', }, }, @@ -437,9 +437,9 @@ describe('findRelationships', () => { meta: { icon: 'indexPatternApp', title: 'My Index Pattern', - editUrl: '/management/kibana/index_patterns/1', + editUrl: '/management/kibana/indexPatterns/patterns/1', inAppUrl: { - path: '/app/kibana#/management/kibana/index_patterns/1', + path: '/app/kibana#/management/kibana/indexPatterns/patterns/1', uiCapabilitiesPath: 'management.kibana.index_patterns', }, }, diff --git a/src/legacy/ui/public/_index.scss b/src/legacy/ui/public/_index.scss index 15a70e0ef7f5a..d258ef190a100 100644 --- a/src/legacy/ui/public/_index.scss +++ b/src/legacy/ui/public/_index.scss @@ -11,5 +11,3 @@ @import './accessibility/index'; @import './directives/index'; @import './error_url_overflow/index'; -@import './field_editor/index'; -@import '../../../plugins/management/public/components/index'; diff --git a/src/legacy/ui/public/field_editor/_index.scss b/src/legacy/ui/public/field_editor/_index.scss deleted file mode 100644 index 39f69c013d428..0000000000000 --- a/src/legacy/ui/public/field_editor/_index.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import './components/field_format_editor/samples/index'; -@import './components/scripting_help/test_script'; diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/icons/index.js b/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/icons/index.js deleted file mode 100644 index 2dc9a1835f582..0000000000000 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/icons/index.js +++ /dev/null @@ -1,26 +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 '!!file-loader?name=[path][name].[ext]!ui/field_editor/components/field_format_editor/editors/url/icons/go.png'; -import '!!file-loader?name=[path][name].[ext]!ui/field_editor/components/field_format_editor/editors/url/icons/stop.png'; -import '!!file-loader?name=[path][name].[ext]!ui/field_editor/components/field_format_editor/editors/url/icons/de.png'; -import '!!file-loader?name=[path][name].[ext]!ui/field_editor/components/field_format_editor/editors/url/icons/ne.png'; -import '!!file-loader?name=[path][name].[ext]!ui/field_editor/components/field_format_editor/editors/url/icons/us.png'; -import '!!file-loader?name=[path][name].[ext]!ui/field_editor/components/field_format_editor/editors/url/icons/ni.png'; -import '!!file-loader?name=[path][name].[ext]!ui/field_editor/components/field_format_editor/editors/url/icons/cv.png'; diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/register.ts b/src/legacy/ui/public/field_editor/components/field_format_editor/register.ts deleted file mode 100644 index 3062a3ba8ac14..0000000000000 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/register.ts +++ /dev/null @@ -1,43 +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 { RegistryFieldFormatEditorsProvider } from 'ui/registry/field_format_editors'; -import { BytesFormatEditor } from './editors/bytes'; -import { ColorFormatEditor } from './editors/color'; -import { DateFormatEditor } from './editors/date'; -import { DateNanosFormatEditor } from './editors/date_nanos'; -import { DurationFormatEditor } from './editors/duration'; -import { NumberFormatEditor } from './editors/number'; -import { PercentFormatEditor } from './editors/percent'; -import { StaticLookupFormatEditor } from './editors/static_lookup'; -import { StringFormatEditor } from './editors/string'; -import { TruncateFormatEditor } from './editors/truncate'; -import { UrlFormatEditor } from './editors/url/url'; - -RegistryFieldFormatEditorsProvider.register(() => BytesFormatEditor); -RegistryFieldFormatEditorsProvider.register(() => ColorFormatEditor); -RegistryFieldFormatEditorsProvider.register(() => DateFormatEditor); -RegistryFieldFormatEditorsProvider.register(() => DateNanosFormatEditor); -RegistryFieldFormatEditorsProvider.register(() => DurationFormatEditor); -RegistryFieldFormatEditorsProvider.register(() => NumberFormatEditor); -RegistryFieldFormatEditorsProvider.register(() => PercentFormatEditor); -RegistryFieldFormatEditorsProvider.register(() => StaticLookupFormatEditor); -RegistryFieldFormatEditorsProvider.register(() => StringFormatEditor); -RegistryFieldFormatEditorsProvider.register(() => TruncateFormatEditor); -RegistryFieldFormatEditorsProvider.register(() => UrlFormatEditor); diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/samples/_index.scss b/src/legacy/ui/public/field_editor/components/field_format_editor/samples/_index.scss deleted file mode 100644 index 7a50cd118bfb2..0000000000000 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/samples/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './samples'; diff --git a/src/legacy/ui/ui_exports/ui_export_defaults.js b/src/legacy/ui/ui_exports/ui_export_defaults.js index 35e1f8b7d2127..1341777bc0991 100644 --- a/src/legacy/ui/ui_exports/ui_export_defaults.js +++ b/src/legacy/ui/ui_exports/ui_export_defaults.js @@ -43,7 +43,5 @@ export const UI_EXPORT_DEFAULTS = { }, })), - appExtensions: { - fieldFormatEditors: ['ui/field_editor/components/field_format_editor/register'], - }, + appExtensions: {}, }; diff --git a/src/plugins/data/public/index_patterns/index_patterns/ensure_default_index_pattern.tsx b/src/plugins/data/public/index_patterns/index_patterns/ensure_default_index_pattern.tsx index 2a6ef13f66dda..9115e523f5302 100644 --- a/src/plugins/data/public/index_patterns/index_patterns/ensure_default_index_pattern.tsx +++ b/src/plugins/data/public/index_patterns/index_patterns/ensure_default_index_pattern.tsx @@ -61,7 +61,7 @@ export const createEnsureDefaultIndexPattern = (core: CoreStart) => { core.uiSettings.set('defaultIndex', defaultId); } else { const canManageIndexPatterns = core.application.capabilities.management.kibana.index_patterns; - const redirectTarget = canManageIndexPatterns ? 'management' : 'home'; + const redirectTarget = canManageIndexPatterns ? '/management/kibana/indexPatterns' : '/home'; if (timeoutId) { clearTimeout(timeoutId); @@ -88,11 +88,11 @@ export const createEnsureDefaultIndexPattern = (core: CoreStart) => { timeoutId = undefined; }, 15000); - if (redirectTarget === 'home') { + if (redirectTarget === '/home') { core.application.navigateToApp('home'); } else { window.location.href = core.http.basePath.prepend( - `/app/kibana#/management/kibana/index_pattern?bannerMessage=${bannerMessage}` + `/app/kibana#/management/kibana/indexPatterns?bannerMessage=${bannerMessage}` ); } diff --git a/src/plugins/data/public/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/public/index_patterns/index_patterns/index_pattern.ts index ecbfceac14b66..3780557db50d3 100644 --- a/src/plugins/data/public/index_patterns/index_patterns/index_pattern.ts +++ b/src/plugins/data/public/index_patterns/index_patterns/index_pattern.ts @@ -174,7 +174,7 @@ export class IndexPattern implements IIndexPattern { private updateFromElasticSearch(response: any, forceFieldRefresh: boolean = false) { if (!response.found) { - throw new SavedObjectNotFound(type, this.id, '#/management/kibana/index_pattern'); + throw new SavedObjectNotFound(type, this.id, '#/management/kibana/indexPatterns'); } _.forOwn(this.mapping, (fieldMapping: FieldMappingSpec, name: string | undefined) => { diff --git a/src/plugins/data/server/saved_objects/index_patterns.ts b/src/plugins/data/server/saved_objects/index_patterns.ts index 497dbb7d6f630..a212d7f88e4eb 100644 --- a/src/plugins/data/server/saved_objects/index_patterns.ts +++ b/src/plugins/data/server/saved_objects/index_patterns.ts @@ -32,11 +32,11 @@ export const indexPatternSavedObjectType: SavedObjectsType = { return obj.attributes.title; }, getEditUrl(obj) { - return `/management/kibana/index_patterns/${encodeURIComponent(obj.id)}`; + return `/management/kibana/indexPatterns/patterns/${encodeURIComponent(obj.id)}`; }, getInAppUrl(obj) { return { - path: `/app/kibana#/management/kibana/index_patterns/${encodeURIComponent(obj.id)}`, + path: `/app/kibana#/management/kibana/indexPatterns/patterns/${encodeURIComponent(obj.id)}`, uiCapabilitiesPath: 'management.kibana.index_patterns', }; }, diff --git a/src/plugins/discover/public/application/components/fetch_error/fetch_error.tsx b/src/plugins/discover/public/application/components/fetch_error/fetch_error.tsx index 0bae2456f743c..880a493983adf 100644 --- a/src/plugins/discover/public/application/components/fetch_error/fetch_error.tsx +++ b/src/plugins/discover/public/application/components/fetch_error/fetch_error.tsx @@ -42,7 +42,7 @@ const DiscoverFetchError = ({ fetchError }: Props) => { const { chrome } = getServices(); const mangagementUrlObj = chrome.navLinks.get('kibana:stack_management'); const managementUrl = mangagementUrlObj ? mangagementUrlObj.url : ''; - const url = `${managementUrl}/kibana/index_patterns`; + const url = `${managementUrl}/kibana/indexPatterns`; body = (

diff --git a/src/plugins/home/public/application/components/__snapshots__/add_data.test.js.snap b/src/plugins/home/public/application/components/__snapshots__/add_data.test.js.snap index dea33022fa429..924de9bbd0994 100644 --- a/src/plugins/home/public/application/components/__snapshots__/add_data.test.js.snap +++ b/src/plugins/home/public/application/components/__snapshots__/add_data.test.js.snap @@ -277,7 +277,7 @@ exports[`apmUiEnabled 1`] = ` /> { void; }>; - uiCapabilities: UICapabilities; } -class CreateButtonComponent extends Component { +export class CreateButton extends Component { public state = { isPopoverOpen: false, }; public render() { - const { options, children, uiCapabilities } = this.props; + const { options, children } = this.props; const { isPopoverOpen } = this.state; if (!options || !options.length) { return null; } - if (!uiCapabilities.indexPatterns.save) { - return null; - } - if (options.length === 1) { return ( { return ( ); }; } - -export const CreateButton = injectUICapabilities(CreateButtonComponent); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_button/index.ts b/src/plugins/index_pattern_management/public/components/create_button/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_button/index.ts rename to src/plugins/index_pattern_management/public/components/create_button/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_prompt/index.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_prompt/index.tsx similarity index 84% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_prompt/index.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_prompt/index.tsx index 174b3af930550..ab3b90177bcfd 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_prompt/index.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_prompt/index.tsx @@ -37,7 +37,7 @@ export const CreateIndexPatternPrompt = ({ onClose }: { onClose: () => void }) =

@@ -47,7 +47,7 @@ export const CreateIndexPatternPrompt = ({ onClose }: { onClose: () => void }) =

@@ -57,7 +57,7 @@ export const CreateIndexPatternPrompt = ({ onClose }: { onClose: () => void }) =

@@ -66,38 +66,38 @@ export const CreateIndexPatternPrompt = ({ onClose }: { onClose: () => void }) = diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/CREATE_INDEX_PATTERN.md b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/CREATE_INDEX_PATTERN.md similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/CREATE_INDEX_PATTERN.md rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/CREATE_INDEX_PATTERN.md diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap similarity index 94% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap index 9763cd9f638fd..9a390f84ef5dc 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/__snapshots__/create_index_pattern_wizard.test.tsx.snap @@ -1,9 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`CreateIndexPatternWizard defaults to the loading state 1`] = ` - +
- + `; exports[`CreateIndexPatternWizard renders index pattern step when there are indices 1`] = ` - +
- + `; exports[`CreateIndexPatternWizard renders the empty state when there are no indices 1`] = ` - +
-
+ `; exports[`CreateIndexPatternWizard renders time field step when step is set to 2 1`] = ` - +
- + `; exports[`CreateIndexPatternWizard renders when there are no indices but there are remote clusters 1`] = ` - +
- + `; exports[`CreateIndexPatternWizard shows system indices even if there are no other indices if the include system indices is toggled 1`] = ` - +
- + `; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/empty_state/__snapshots__/empty_state.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/__snapshots__/empty_state.test.tsx.snap similarity index 75% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/empty_state/__snapshots__/empty_state.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/__snapshots__/empty_state.test.tsx.snap index 3ecab05a8459b..4ebb5db05753b 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/empty_state/__snapshots__/empty_state.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/__snapshots__/empty_state.test.tsx.snap @@ -7,7 +7,7 @@ exports[`EmptyState should render normally 1`] = ` title={ } @@ -15,7 +15,7 @@ exports[`EmptyState should render normally 1`] = `

, @@ -32,7 +32,7 @@ exports[`EmptyState should render normally 1`] = ` > , @@ -41,7 +41,7 @@ exports[`EmptyState should render normally 1`] = ` > , @@ -57,7 +57,7 @@ exports[`EmptyState should render normally 1`] = ` > diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/empty_state/empty_state.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/empty_state.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/empty_state/empty_state.test.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/empty_state.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/empty_state/empty_state.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/empty_state.tsx similarity index 82% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/empty_state/empty_state.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/empty_state.tsx index 3ee5d1a0e96f1..43c3bf79026fe 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/empty_state/empty_state.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/empty_state.tsx @@ -36,20 +36,20 @@ export const EmptyState = ({ color="warning" title={ } >

@@ -57,7 +57,7 @@ export const EmptyState = ({ learnHowLink: ( @@ -65,7 +65,7 @@ export const EmptyState = ({ getStartedLink: ( @@ -81,7 +81,7 @@ export const EmptyState = ({ color="warning" > diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/empty_state/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/empty_state/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/empty_state/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/__snapshots__/header.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/__snapshots__/header.test.tsx.snap similarity index 71% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/__snapshots__/header.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/__snapshots__/header.test.tsx.snap index a6b22ebf32a43..bdfdd2e7ad0a6 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/__snapshots__/header.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/__snapshots__/header.test.tsx.snap @@ -4,15 +4,7 @@ exports[`Header should render a different name, prompt, and beta tag if provided

- + Create test index pattern @@ -59,15 +51,7 @@ exports[`Header should render normally 1`] = `

- + Create test index pattern

@@ -104,15 +88,7 @@ exports[`Header should render without including system indices 1`] = `

- + Create test index pattern

diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/header.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.test.tsx similarity index 95% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/header.test.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.test.tsx index 06b8b38e2d8bc..d70746dd930e4 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/header.test.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.test.tsx @@ -29,6 +29,7 @@ describe('Header', () => { indexPatternName={indexPatternName} isIncludingSystemIndices={true} onChangeIncludingSystemIndices={() => {}} + changeTitle={() => {}} /> ); @@ -41,6 +42,7 @@ describe('Header', () => { indexPatternName={indexPatternName} isIncludingSystemIndices={false} onChangeIncludingSystemIndices={() => {}} + changeTitle={() => {}} /> ); @@ -55,6 +57,7 @@ describe('Header', () => { prompt={
Test prompt
} indexPatternName={indexPatternName} isBeta={true} + changeTitle={() => {}} /> ); diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.tsx new file mode 100644 index 0000000000000..1be33e3edc3bc --- /dev/null +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/header.tsx @@ -0,0 +1,118 @@ +/* + * 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, { Fragment } from 'react'; + +import { + EuiBetaBadge, + EuiSpacer, + EuiTitle, + EuiFlexGroup, + EuiFlexItem, + EuiText, + EuiTextColor, + EuiSwitch, +} from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +export const Header = ({ + prompt, + indexPatternName, + showSystemIndices = false, + isIncludingSystemIndices, + onChangeIncludingSystemIndices, + isBeta = false, + changeTitle, +}: { + prompt?: React.ReactNode; + indexPatternName: string; + showSystemIndices?: boolean; + isIncludingSystemIndices: boolean; + onChangeIncludingSystemIndices: () => void; + isBeta?: boolean; + changeTitle: (title: string) => void; +}) => { + const createIndexPatternHeader = i18n.translate( + 'indexPatternManagement.createIndexPatternHeader', + { + defaultMessage: 'Create {indexPatternName}', + values: { indexPatternName }, + } + ); + + changeTitle(createIndexPatternHeader); + + return ( +
+ +

+ {createIndexPatternHeader} + {isBeta ? ( + + {' '} + + + ) : null} +

+
+ + + +

+ + + +

+
+
+ {showSystemIndices ? ( + + + } + id="checkboxShowSystemIndices" + checked={isIncludingSystemIndices} + onChange={onChangeIncludingSystemIndices} + /> + + ) : null} +
+ {prompt ? ( + + + {prompt} + + ) : null} + +
+ ); +}; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/header/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/header/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/loading_state/__snapshots__/loading_state.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/loading_state/__snapshots__/loading_state.test.tsx.snap similarity index 88% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/loading_state/__snapshots__/loading_state.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/loading_state/__snapshots__/loading_state.test.tsx.snap index 3adc497a639c4..1e6ac56d437e1 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/loading_state/__snapshots__/loading_state.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/loading_state/__snapshots__/loading_state.test.tsx.snap @@ -22,7 +22,7 @@ exports[`LoadingState should render normally 1`] = ` >

diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/loading_state/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/loading_state/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/loading_state/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/loading_state/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/loading_state/loading_state.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/loading_state/loading_state.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/loading_state/loading_state.test.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/loading_state/loading_state.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/loading_state/loading_state.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/loading_state/loading_state.tsx similarity index 94% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/loading_state/loading_state.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/loading_state/loading_state.tsx index e9b68033090cf..26653adfd14a6 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/loading_state/loading_state.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/loading_state/loading_state.tsx @@ -29,7 +29,7 @@ export const LoadingState = () => (

diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/__snapshots__/step_index_pattern.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/__snapshots__/step_index_pattern.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/__snapshots__/step_index_pattern.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/__snapshots__/step_index_pattern.test.tsx.snap diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/header/__snapshots__/header.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/__snapshots__/header.test.tsx.snap similarity index 85% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/header/__snapshots__/header.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/__snapshots__/header.test.tsx.snap index f2fb17cdb0d60..3021292953ff5 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/header/__snapshots__/header.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/__snapshots__/header.test.tsx.snap @@ -8,7 +8,7 @@ exports[`Header should mark the input as invalid 1`] = `

@@ -42,7 +42,7 @@ exports[`Header should mark the input as invalid 1`] = `

@@ -55,7 +55,7 @@ exports[`Header should mark the input as invalid 1`] = `

@@ -71,7 +71,7 @@ exports[`Header should mark the input as invalid 1`] = ` label={ } @@ -99,7 +99,7 @@ exports[`Header should mark the input as invalid 1`] = ` > @@ -116,7 +116,7 @@ exports[`Header should render normally 1`] = `

@@ -146,7 +146,7 @@ exports[`Header should render normally 1`] = `

@@ -159,7 +159,7 @@ exports[`Header should render normally 1`] = `

@@ -175,7 +175,7 @@ exports[`Header should render normally 1`] = ` label={ } @@ -203,7 +203,7 @@ exports[`Header should render normally 1`] = ` > diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/header/header.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/header.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/header/header.test.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/header.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/header/header.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/header.tsx similarity index 87% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/header/header.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/header.tsx index f9d86d5d9d53d..9ce72aeeea6e3 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/header/header.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/header.tsx @@ -57,7 +57,7 @@ export const Header: React.FC = ({

@@ -69,7 +69,7 @@ export const Header: React.FC = ({ } @@ -79,14 +79,14 @@ export const Header: React.FC = ({

* }} />

{characterList} }} /> @@ -97,7 +97,7 @@ export const Header: React.FC = ({ = ({ data-test-subj="createIndexPatternGoToStep2Button" > diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/header/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/header/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/header/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/__snapshots__/indices_list.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/__snapshots__/indices_list.test.tsx.snap similarity index 97% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/__snapshots__/indices_list.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/__snapshots__/indices_list.test.tsx.snap index a759b3b3e9881..598de4d90e893 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/__snapshots__/indices_list.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/indices_list/__snapshots__/indices_list.test.tsx.snap @@ -44,7 +44,7 @@ exports[`IndicesList should change pages 1`] = ` > diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/__snapshots__/loading_indices.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/__snapshots__/loading_indices.test.tsx.snap similarity index 85% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/__snapshots__/loading_indices.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/__snapshots__/loading_indices.test.tsx.snap index d8b4253de78bb..9d67ca913d415 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/__snapshots__/loading_indices.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/__snapshots__/loading_indices.test.tsx.snap @@ -21,7 +21,7 @@ exports[`LoadingIndices should render normally 1`] = ` > @@ -39,7 +39,7 @@ exports[`LoadingIndices should render normally 1`] = ` > diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.test.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.tsx similarity index 91% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.tsx index 2f91f961b6c18..16e8d1a9f3e98 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/loading_indices/loading_indices.tsx @@ -33,7 +33,7 @@ export const LoadingIndices = ({ ...rest }) => ( @@ -42,7 +42,7 @@ export const LoadingIndices = ({ ...rest }) => ( diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/__snapshots__/status_message.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/__snapshots__/status_message.test.tsx.snap similarity index 80% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/__snapshots__/status_message.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/__snapshots__/status_message.test.tsx.snap index eb99424cb12a8..4a063f1430d1c 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/__snapshots__/status_message.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/__snapshots__/status_message.test.tsx.snap @@ -15,13 +15,13 @@ exports[`StatusMessage should render with exact matches 1`] = `   , @@ -55,14 +55,14 @@ exports[`StatusMessage should render with no partial matches 1`] = ` @@ -149,7 +149,7 @@ exports[`StatusMessage should show that no indices exist 1`] = ` @@ -168,7 +168,7 @@ exports[`StatusMessage should show that system indices exist 1`] = ` diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.test.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.tsx similarity index 83% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.tsx index ad7f58fa4e879..ccdd1833ea9bf 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/components/status_message/status_message.tsx @@ -55,7 +55,7 @@ export const StatusMessage: React.FC = ({ statusMessage = ( {allIndicesLength} indices }} /> @@ -65,7 +65,7 @@ export const StatusMessage: React.FC = ({ statusMessage = ( @@ -75,7 +75,7 @@ export const StatusMessage: React.FC = ({ statusMessage = ( @@ -88,13 +88,13 @@ export const StatusMessage: React.FC = ({   @@ -102,7 +102,7 @@ export const StatusMessage: React.FC = ({ strongIndices: ( @@ -118,7 +118,7 @@ export const StatusMessage: React.FC = ({ statusMessage = ( = ({ strongIndices: ( @@ -142,14 +142,14 @@ export const StatusMessage: React.FC = ({ statusMessage = ( diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx similarity index 95% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx index 40471b95d774c..68afd64ae848c 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx @@ -21,10 +21,10 @@ import React from 'react'; import { StepIndexPattern } from '../step_index_pattern'; import { shallowWithI18nProvider } from 'test_utils/enzyme_helpers'; import { Header } from './components/header'; -import { IndexPatternCreationConfig } from '../../../../../../../../../../plugins/index_pattern_management/public'; -import { coreMock } from '../../../../../../../../../../core/public/mocks'; -import { dataPluginMock } from '../../../../../../../../../../plugins/data/public/mocks'; -import { SavedObjectsFindResponsePublic } from '../../../../../../../../../../core/public'; +import { IndexPatternCreationConfig } from '../../../../../../../plugins/index_pattern_management/public'; +import { coreMock } from '../../../../../../../core/public/mocks'; +import { dataPluginMock } from '../../../../../../../plugins/data/public/mocks'; +import { SavedObjectsFindResponsePublic } from 'src/core/public'; jest.mock('../../lib/ensure_minimum_time', () => ({ ensureMinimumTime: async (promises: Array>) => diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx similarity index 95% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx index d8f677b7f6089..5c8fa92d355a3 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx @@ -25,8 +25,8 @@ import { indexPatterns, DataPublicPluginStart, IndexPatternAttributes, -} from '../../../../../../../../../../plugins/data/public'; -import { SavedObjectsClient, IUiSettingsClient } from '../../../../../../../../../../core/public'; +} from '../../../../../../../plugins/data/public'; +import { SavedObjectsClientContract, IUiSettingsClient } from '../../../../../../../core/public'; import { MAX_SEARCH_SIZE } from '../../constants'; import { getIndices, @@ -39,14 +39,14 @@ import { LoadingIndices } from './components/loading_indices'; import { StatusMessage } from './components/status_message'; import { IndicesList } from './components/indices_list'; import { Header } from './components/header'; -import { IndexPatternCreationConfig } from '../../../../../../../../../../plugins/index_pattern_management/public'; +import { IndexPatternCreationConfig } from '../../../../../../../plugins/index_pattern_management/public'; import { MatchedIndex } from '../../types'; interface StepIndexPatternProps { allIndices: MatchedIndex[]; isIncludingSystemIndices: boolean; esService: DataPublicPluginStart['search']['__LEGACY']['esClient']; - savedObjectsClient: SavedObjectsClient; + savedObjectsClient: SavedObjectsClientContract; indexPatternCreationType: IndexPatternCreationConfig; goToNextStep: (query: string) => void; initialQuery?: string; @@ -237,7 +237,7 @@ export class StepIndexPattern extends Component @@ -270,7 +270,7 @@ export class StepIndexPattern extends Component } @@ -60,7 +60,7 @@ exports[`StepTimeField should render "Custom index pattern ID already exists" wh

@@ -92,7 +92,7 @@ exports[`StepTimeField should render a loading state when creating the index pat @@ -269,7 +269,7 @@ exports[`StepTimeField should render any error message 1`] = ` title={ } diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/action_buttons/action_buttons.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/action_buttons/action_buttons.tsx similarity index 91% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/action_buttons/action_buttons.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/action_buttons/action_buttons.tsx index 342876712eb28..d7c55f2573a17 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/action_buttons/action_buttons.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/action_buttons/action_buttons.tsx @@ -36,7 +36,7 @@ export const ActionButtons = ({ @@ -49,7 +49,7 @@ export const ActionButtons = ({ onClick={createIndexPattern} > diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/action_buttons/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/action_buttons/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/action_buttons/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/action_buttons/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/advanced_options/__snapshots__/advanced_options.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/__snapshots__/advanced_options.test.tsx.snap similarity index 81% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/advanced_options/__snapshots__/advanced_options.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/__snapshots__/advanced_options.test.tsx.snap index 02ceed3454a00..d1b10fb532020 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/advanced_options/__snapshots__/advanced_options.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/__snapshots__/advanced_options.test.tsx.snap @@ -8,7 +8,7 @@ exports[`AdvancedOptions should hide if not showing 1`] = ` > @@ -26,7 +26,7 @@ exports[`AdvancedOptions should render normally 1`] = ` > @@ -43,14 +43,14 @@ exports[`AdvancedOptions should render normally 1`] = ` helpText={ } label={ } diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.test.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.tsx similarity index 85% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.tsx index fd2c1db1eacd7..b8f34095743ba 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/advanced_options.tsx @@ -44,12 +44,12 @@ export const AdvancedOptions: React.FC = ({ > {isVisible ? ( ) : ( )} @@ -60,13 +60,13 @@ export const AdvancedOptions: React.FC = ({ } helpText={ @@ -78,7 +78,7 @@ export const AdvancedOptions: React.FC = ({ value={indexPatternId} onChange={onChangeIndexPatternId} placeholder={i18n.translate( - 'kbn.management.createIndexPattern.stepTime.options.patternPlaceholder', + 'indexPatternManagement.createIndexPattern.stepTime.options.patternPlaceholder', { defaultMessage: 'custom-index-pattern-id', } diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/advanced_options/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/advanced_options/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/advanced_options/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/header/__snapshots__/header.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/__snapshots__/header.test.tsx.snap similarity index 83% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/header/__snapshots__/header.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/__snapshots__/header.test.tsx.snap index 5c53558286b0d..63008ec5b52e7 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/header/__snapshots__/header.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/__snapshots__/header.test.tsx.snap @@ -8,7 +8,7 @@ exports[`Header should render normally 1`] = `

@@ -21,7 +21,7 @@ exports[`Header should render normally 1`] = ` > diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/header/header.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/header.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/header/header.test.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/header.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/header/header.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/header.tsx similarity index 92% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/header/header.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/header.tsx index 5c2f184e8038b..22e245f7ac137 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/header/header.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/header.tsx @@ -33,7 +33,7 @@ export const Header: React.FC = ({ indexPattern, indexPatternName }

@@ -41,7 +41,7 @@ export const Header: React.FC = ({ indexPattern, indexPatternName } {indexPattern}
, diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/header/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/header/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/header/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/__snapshots__/time_field.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/__snapshots__/time_field.test.tsx.snap similarity index 84% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/__snapshots__/time_field.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/__snapshots__/time_field.test.tsx.snap index e997cb80a2a14..7d056433f55df 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/__snapshots__/time_field.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/__snapshots__/time_field.test.tsx.snap @@ -13,14 +13,14 @@ exports[`TimeField should render a loading state 1`] = `

@@ -38,7 +38,7 @@ exports[`TimeField should render a loading state 1`] = ` @@ -84,14 +84,14 @@ exports[`TimeField should render a selected time field 1`] = `

@@ -109,7 +109,7 @@ exports[`TimeField should render a selected time field 1`] = ` @@ -123,7 +123,7 @@ exports[`TimeField should render a selected time field 1`] = ` > @@ -165,14 +165,14 @@ exports[`TimeField should render normally 1`] = `

@@ -190,7 +190,7 @@ exports[`TimeField should render normally 1`] = ` @@ -204,7 +204,7 @@ exports[`TimeField should render normally 1`] = ` > @@ -239,7 +239,7 @@ exports[`TimeField should render something if hiding time field 1`] = `

diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.css b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.scss similarity index 84% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.css rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.scss index d0a2652d7e045..5bd60e8b76afc 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.css +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.scss @@ -1,6 +1,7 @@ /** * 1. Bring the line-height down or else this link expands its container when it becomes visible. */ - .timeFieldRefreshButton { + +.timeFieldRefreshButton { line-height: 1 !important; /* 1 */ } diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.test.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.tsx similarity index 87% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.tsx index 876a3b79a8812..b4ed37118966b 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/components/time_field/time_field.tsx @@ -17,9 +17,9 @@ * under the License. */ -import React from 'react'; +import './time_field.scss'; -import './time_field.css'; +import React from 'react'; import { EuiForm, @@ -60,7 +60,7 @@ export const TimeField: React.FC = ({ @@ -71,7 +71,7 @@ export const TimeField: React.FC = ({ ) : ( @@ -83,13 +83,13 @@ export const TimeField: React.FC = ({

@@ -103,7 +103,7 @@ export const TimeField: React.FC = ({ options={[ { text: i18n.translate( - 'kbn.management.createIndexPattern.stepTime.field.loadingDropDown', + 'indexPatternManagement.createIndexPattern.stepTime.field.loadingDropDown', { defaultMessage: 'Loading…', } @@ -129,7 +129,7 @@ export const TimeField: React.FC = ({

diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx similarity index 98% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx index b23b1e3ad9051..939b0d006b4aa 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx @@ -19,8 +19,8 @@ import React from 'react'; import { shallowWithI18nProvider } from 'test_utils/enzyme_helpers'; -import { IndexPatternCreationConfig } from '../../../../../../../../../../plugins/index_pattern_management/public'; -import { IFieldType } from '../../../../../../../../../../plugins/data/public'; +import { IndexPatternCreationConfig } from '../../../../../../../plugins/index_pattern_management/public'; +import { IFieldType } from '../../../../../../../plugins/data/public'; import { StepTimeField } from '../step_time_field'; @@ -32,9 +32,6 @@ jest.mock('./../../lib', () => ({ extractTimeFields: require.requireActual('./../../lib').extractTimeFields, ensureMinimumTime: async (fields: IFieldType) => Promise.resolve(fields), })); -jest.mock('ui/chrome', () => ({ - addBasePath: () => {}, -})); const mockIndexPatternCreationType = new IndexPatternCreationConfig({ type: 'default', diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx similarity index 94% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx index a58bf10c9dab8..d22b503937290 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx @@ -34,8 +34,8 @@ import { Header } from './components/header'; import { TimeField } from './components/time_field'; import { AdvancedOptions } from './components/advanced_options'; import { ActionButtons } from './components/action_buttons'; -import { IndexPatternCreationConfig } from '../../../../../../../../../../plugins/index_pattern_management/public'; -import { DataPublicPluginStart } from '../../../../../../../../../../plugins/data/public'; +import { IndexPatternCreationConfig } from '../../../..'; +import { DataPublicPluginStart } from '../../../../../../data/public'; interface StepTimeFieldProps { indexPattern: string; @@ -157,7 +157,7 @@ export class StepTimeField extends Component ) : ( @@ -187,7 +187,7 @@ export class StepTimeField extends Component @@ -218,7 +218,7 @@ export class StepTimeField extends Component } diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/constants/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/constants/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/constants/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/constants/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx similarity index 73% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx index 36d251e4f41a6..f526aa35c2afe 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.test.tsx @@ -20,12 +20,15 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { CreateIndexPatternWizard } from './create_index_pattern_wizard'; -import { coreMock } from '../../../../../../../../core/public/mocks'; -import { dataPluginMock } from '../../../../../../../../plugins/data/public/mocks'; -import { IndexPatternCreationConfig } from '../../../../../../../../plugins/index_pattern_management/public'; -import { IndexPattern } from '../../../../../../../../plugins/data/public'; -import { SavedObjectsClient } from '../../../../../../../../core/public'; +import { + CreateIndexPatternWizard, + CreateIndexPatternWizardProps, +} from './create_index_pattern_wizard'; +import { coreMock } from '../../../../../core/public/mocks'; +import { dataPluginMock } from '../../../../../plugins/data/public/mocks'; +import { IndexPattern } from '../../../../../plugins/data/public'; +import { SavedObjectsClient } from '../../../../../core/public'; +import { IndexPatternCreationConfig } from '../../service/creation'; jest.mock('./components/step_index_pattern', () => ({ StepIndexPattern: 'StepIndexPattern' })); jest.mock('./components/step_time_field', () => ({ StepTimeField: 'StepTimeField' })); @@ -37,33 +40,42 @@ jest.mock('./lib/get_indices', () => ({ return [{ name: 'kibana' }]; }, })); -jest.mock('ui/chrome', () => ({ - addBasePath: () => {}, -})); -const { savedObjects, overlays, uiSettings } = coreMock.createStart(); +const { savedObjects, overlays, uiSettings, chrome, http } = coreMock.createStart(); const { indexPatterns, search } = dataPluginMock.createStartContract(); + const mockIndexPatternCreationType = new IndexPatternCreationConfig({ type: 'default', name: 'name', }); -const initialQuery = ''; -const services = { +const services = ({ + indexPatternCreation: { + getType: jest.fn(() => mockIndexPatternCreationType), + }, es: search.__LEGACY.esClient, indexPatterns, savedObjectsClient: savedObjects.client as SavedObjectsClient, uiSettings, changeUrl: jest.fn(), openConfirm: overlays.openConfirm, - indexPatternCreationType: mockIndexPatternCreationType, - prependBasePath: jest.fn(x => x), + setBreadcrumbs: jest.fn(), + docTitle: chrome.docTitle, + prependBasePath: http.basePath.prepend, +} as unknown) as CreateIndexPatternWizardProps['services']; + +const routeComponentPropsMock = { + history: { + push: jest.fn(), + } as any, + location: {} as any, + match: {} as any, }; describe('CreateIndexPatternWizard', () => { test(`defaults to the loading state`, () => { const component = shallow( - + ); expect(component).toMatchSnapshot(); @@ -71,7 +83,7 @@ describe('CreateIndexPatternWizard', () => { test('renders the empty state when there are no indices', async () => { const component = shallow( - + ); component.setState({ @@ -86,7 +98,7 @@ describe('CreateIndexPatternWizard', () => { test('renders when there are no indices but there are remote clusters', async () => { const component = shallow( - + ); component.setState({ @@ -101,7 +113,7 @@ describe('CreateIndexPatternWizard', () => { test('shows system indices even if there are no other indices if the include system indices is toggled', async () => { const component = shallow( - + ); component.setState({ @@ -116,7 +128,7 @@ describe('CreateIndexPatternWizard', () => { test('renders index pattern step when there are indices', async () => { const component = shallow( - + ); component.setState({ @@ -130,7 +142,7 @@ describe('CreateIndexPatternWizard', () => { test('renders time field step when step is set to 2', async () => { const component = shallow( - + ); component.setState({ @@ -159,7 +171,7 @@ describe('CreateIndexPatternWizard', () => { }; const component = shallow( - + ); component.setState({ indexPattern: 'foo' }); @@ -167,6 +179,6 @@ describe('CreateIndexPatternWizard', () => { expect(services.uiSettings.get).toBeCalled(); expect(create).toBeCalled(); expect(clear).toBeCalledWith('id'); - expect(services.changeUrl).toBeCalledWith(`/management/kibana/index_patterns/id`); + expect(routeComponentPropsMock.history.push).toBeCalledWith(`/patterns/id`); }); }); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/create_index_pattern_wizard.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx similarity index 68% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/create_index_pattern_wizard.tsx rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx index a1a263fe88923..62bf47546e103 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/create_index_pattern_wizard.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx @@ -19,38 +19,42 @@ import React, { ReactElement, Component } from 'react'; -import { EuiGlobalToastList, EuiGlobalToastListToast } from '@elastic/eui'; +import { EuiGlobalToastList, EuiGlobalToastListToast, EuiPanel } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; +import { withRouter, RouteComponentProps } from 'react-router-dom'; +import { + SavedObjectsClientContract, + IUiSettingsClient, + OverlayStart, + ChromeDocTitle, + IBasePath, +} from 'src/core/public'; +import { DataPublicPluginStart } from 'src/plugins/data/public'; +import { ManagementAppMountParams } from '../../../../management/public'; import { StepIndexPattern } from './components/step_index_pattern'; import { StepTimeField } from './components/step_time_field'; import { Header } from './components/header'; import { LoadingState } from './components/loading_state'; import { EmptyState } from './components/empty_state'; +import { getCreateBreadcrumbs } from '../breadcrumbs'; import { MAX_SEARCH_SIZE } from './constants'; import { ensureMinimumTime, getIndices } from './lib'; -import { - SavedObjectsClient, - IUiSettingsClient, - OverlayStart, - IBasePath, -} from '../../../../../../../../core/public'; -import { DataPublicPluginStart } from '../../../../../../../../plugins/data/public'; -import { IndexPatternCreationConfig } from '../../../../../../../../plugins/index_pattern_management/public'; +import { IndexPatternCreationConfig, IndexPatternManagementStart } from '../..'; import { MatchedIndex } from './types'; -interface CreateIndexPatternWizardProps { - initialQuery: string; +export interface CreateIndexPatternWizardProps extends RouteComponentProps { services: { - indexPatternCreationType: IndexPatternCreationConfig; + indexPatternCreation: IndexPatternManagementStart['creation']; es: DataPublicPluginStart['search']['__LEGACY']['esClient']; indexPatterns: DataPublicPluginStart['indexPatterns']; - savedObjectsClient: SavedObjectsClient; + savedObjectsClient: SavedObjectsClientContract; uiSettings: IUiSettingsClient; - changeUrl: (url: string) => void; openConfirm: OverlayStart['openConfirm']; + setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs']; + docTitle: ChromeDocTitle; prependBasePath: IBasePath['prepend']; }; } @@ -63,21 +67,35 @@ interface CreateIndexPatternWizardState { isInitiallyLoadingIndices: boolean; isIncludingSystemIndices: boolean; toasts: EuiGlobalToastListToast[]; + indexPatternCreationType: IndexPatternCreationConfig; } export class CreateIndexPatternWizard extends Component< CreateIndexPatternWizardProps, CreateIndexPatternWizardState > { - state = { - step: 1, - indexPattern: '', - allIndices: [], - remoteClustersExist: false, - isInitiallyLoadingIndices: true, - isIncludingSystemIndices: false, - toasts: [], - }; + constructor(props: CreateIndexPatternWizardProps) { + super(props); + const { + services: { indexPatternCreation, setBreadcrumbs }, + location, + } = props; + + setBreadcrumbs(getCreateBreadcrumbs()); + + const type = new URLSearchParams(location.search).get('type') || undefined; + + this.state = { + step: 1, + indexPattern: '', + allIndices: [], + remoteClustersExist: false, + isInitiallyLoadingIndices: true, + isIncludingSystemIndices: false, + toasts: [], + indexPatternCreationType: indexPatternCreation.getType(type), + }; + } async UNSAFE_componentWillMount() { this.fetchData(); @@ -116,14 +134,14 @@ export class CreateIndexPatternWizard extends Component< const indicesFailMsg = ( ); const clustersFailMsg = ( ); @@ -131,7 +149,7 @@ export class CreateIndexPatternWizard extends Component< // query local and remote indices, updating state independently ensureMinimumTime( this.catchAndWarn( - getIndices(services.es, services.indexPatternCreationType, `*`, MAX_SEARCH_SIZE), + getIndices(services.es, this.state.indexPatternCreationType, `*`, MAX_SEARCH_SIZE), [], indicesFailMsg ) @@ -142,7 +160,7 @@ export class CreateIndexPatternWizard extends Component< this.catchAndWarn( // if we get an error from remote cluster query, supply fallback value that allows user entry. // ['a'] is fallback value - getIndices(services.es, services.indexPatternCreationType, `*:*`, 1), + getIndices(services.es, this.state.indexPatternCreationType, `*:*`, 1), ['a'], clustersFailMsg ).then((remoteIndices: string[] | MatchedIndex[]) => @@ -151,7 +169,7 @@ export class CreateIndexPatternWizard extends Component< }; createIndexPattern = async (timeFieldName: string | undefined, indexPatternId: string) => { - const { services } = this.props; + const { services, history } = this.props; const { indexPattern } = this.state; const emptyPattern = await services.indexPatterns.make(); @@ -160,24 +178,30 @@ export class CreateIndexPatternWizard extends Component< id: indexPatternId, title: indexPattern, timeFieldName, - ...services.indexPatternCreationType.getIndexPatternMappings(), + ...this.state.indexPatternCreationType.getIndexPatternMappings(), }); const createdId = await emptyPattern.create(); if (!createdId) { - const confirmMessage = i18n.translate('kbn.management.indexPattern.titleExistsLabel', { - values: { title: emptyPattern.title }, - defaultMessage: "An index pattern with the title '{title}' already exists.", - }); + const confirmMessage = i18n.translate( + 'indexPatternManagement.indexPattern.titleExistsLabel', + { + values: { title: emptyPattern.title }, + defaultMessage: "An index pattern with the title '{title}' already exists.", + } + ); const isConfirmed = await services.openConfirm(confirmMessage, { - confirmButtonText: i18n.translate('kbn.management.indexPattern.goToPatternButtonLabel', { - defaultMessage: 'Go to existing pattern', - }), + confirmButtonText: i18n.translate( + 'indexPatternManagement.indexPattern.goToPatternButtonLabel', + { + defaultMessage: 'Go to existing pattern', + } + ), }); if (isConfirmed) { - return services.changeUrl(`/management/kibana/index_patterns/${indexPatternId}`); + return history.push(`/patterns/${indexPatternId}`); } else { return false; } @@ -188,7 +212,7 @@ export class CreateIndexPatternWizard extends Component< } services.indexPatterns.clearCache(createdId); - services.changeUrl(`/management/kibana/index_patterns/${createdId}`); + history.push(`/patterns/${createdId}`); }; goToTimeFieldStep = (indexPattern: string) => { @@ -211,12 +235,13 @@ export class CreateIndexPatternWizard extends Component< return (
); } @@ -246,7 +271,9 @@ export class CreateIndexPatternWizard extends Component< } if (step === 1) { - const { services, initialQuery } = this.props; + const { services, location } = this.props; + const initialQuery = new URLSearchParams(location.search).get('id') || undefined; + return ( @@ -269,7 +296,7 @@ export class CreateIndexPatternWizard extends Component< indexPatternsService={services.indexPatterns} goToPreviousStep={this.goToIndexPatternStep} createIndexPattern={this.createIndexPattern} - indexPatternCreationType={services.indexPatternCreationType} + indexPatternCreationType={this.state.indexPatternCreationType} /> ); } @@ -288,7 +315,7 @@ export class CreateIndexPatternWizard extends Component< const content = this.renderContent(); return ( - +
{header} {content} @@ -300,7 +327,9 @@ export class CreateIndexPatternWizard extends Component< }} toastLifeTimeMs={6000} /> - + ); } } + +export const CreateIndexPatternWizardWithRouter = withRouter(CreateIndexPatternWizard); diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/index.ts new file mode 100644 index 0000000000000..893021141aa24 --- /dev/null +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/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 { CreateIndexPatternWizardWithRouter } from './create_index_pattern_wizard'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/can_append_wildcard.test.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/can_append_wildcard.test.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/can_append_wildcard.test.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/can_append_wildcard.test.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/can_append_wildcard.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/can_append_wildcard.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/can_append_wildcard.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/can_append_wildcard.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/contains_illegal_characters.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/contains_illegal_characters.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/contains_illegal_characters.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/contains_illegal_characters.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/contains_invalid_characters.test.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/contains_invalid_characters.test.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/contains_invalid_characters.test.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/contains_invalid_characters.test.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/ensure_minimum_time.test.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/ensure_minimum_time.test.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/ensure_minimum_time.test.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/ensure_minimum_time.test.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/ensure_minimum_time.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/ensure_minimum_time.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/ensure_minimum_time.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/ensure_minimum_time.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/extract_time_fields.test.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.test.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/extract_time_fields.test.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.test.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/extract_time_fields.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.ts similarity index 80% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/extract_time_fields.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.ts index 0b95ec0a120da..809c9f77b2832 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/extract_time_fields.ts +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/extract_time_fields.ts @@ -18,13 +18,16 @@ */ import { i18n } from '@kbn/i18n'; -import { IFieldType } from '../../../../../../../../../plugins/data/public'; +import { IFieldType } from '../../../../../../plugins/data/public'; export function extractTimeFields(fields: IFieldType[]) { const dateFields = fields.filter(field => field.type === 'date'); - const label = i18n.translate('kbn.management.createIndexPattern.stepTime.noTimeFieldsLabel', { - defaultMessage: "The indices which match this index pattern don't contain any time fields.", - }); + const label = i18n.translate( + 'indexPatternManagement.createIndexPattern.stepTime.noTimeFieldsLabel', + { + defaultMessage: "The indices which match this index pattern don't contain any time fields.", + } + ); if (dateFields.length === 0) { return [ @@ -40,7 +43,7 @@ export function extractTimeFields(fields: IFieldType[]) { fieldName: '', }; const noTimeFieldLabel = i18n.translate( - 'kbn.management.createIndexPattern.stepTime.noTimeFieldOptionLabel', + 'indexPatternManagement.createIndexPattern.stepTime.noTimeFieldOptionLabel', { defaultMessage: "I don't want to use the Time Filter", } diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.test.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.test.ts similarity index 95% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.test.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.test.ts index b1500f8303b66..1c67fea9fa352 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.test.ts +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.test.ts @@ -18,9 +18,9 @@ */ import { getIndices } from './get_indices'; -import { IndexPatternCreationConfig } from '../../../../../../../../../plugins/index_pattern_management/public'; +import { IndexPatternCreationConfig } from '../../../../../index_pattern_management/public'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LegacyApiCaller } from '../../../../../../../../../plugins/data/public/search/legacy'; +import { LegacyApiCaller } from '../../../../../data/public/search/legacy'; export const successfulResponse = { hits: { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.ts similarity index 93% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.ts index 3b1b7a3b52a5b..9f75dc39a654c 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.ts +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_indices.ts @@ -18,8 +18,8 @@ */ import { get, sortBy } from 'lodash'; -import { IndexPatternCreationConfig } from '../../../../../../../../../plugins/index_pattern_management/public'; -import { DataPublicPluginStart } from '../../../../../../../../../plugins/data/public'; +import { IndexPatternCreationConfig } from '../../../../../index_pattern_management/public'; +import { DataPublicPluginStart } from '../../../../../data/public'; import { MatchedIndex } from '../types'; export async function getIndices( diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_matched_indices.test.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_matched_indices.test.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_matched_indices.test.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_matched_indices.test.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_matched_indices.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_matched_indices.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_matched_indices.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/get_matched_indices.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/index.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/index.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/lib/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/types.ts b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/types.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/types.ts rename to src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/types.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/constants.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/constants.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/constants.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/constants.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field.tsx similarity index 52% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field.tsx index 3b865f7d5e1ea..fb5c27774f506 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field.tsx @@ -18,34 +18,36 @@ */ import React from 'react'; import { withRouter, RouteComponentProps } from 'react-router-dom'; -// @ts-ignore -import { FieldEditor } from 'ui/field_editor'; -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { HttpStart, DocLinksStart } from 'src/core/public'; -import { IndexPattern, DataPublicPluginStart } from 'src/plugins/data/public'; +import { ChromeDocTitle, NotificationsStart, IUiSettingsClient } from 'src/core/public'; +import { IndexPattern, DataPublicPluginStart } from '../../../../../../plugins/data/public'; import { IndexHeader } from '../index_header'; -import { ChromeDocTitle, NotificationsStart } from '../../../../../../../../../core/public'; import { TAB_SCRIPTED_FIELDS, TAB_INDEXED_FIELDS } from '../constants'; +import { FieldEditor } from '../../field_editor'; + interface CreateEditFieldProps extends RouteComponentProps { indexPattern: IndexPattern; mode?: string; fieldName?: string; fieldFormatEditors: any; - getConfig: (name: string) => any; services: { - dataStart: DataPublicPluginStart; - notifications: NotificationsStart; + uiSettings: IUiSettingsClient; docTitle: ChromeDocTitle; - getHttpStart: () => HttpStart; + http: HttpStart; docLinksScriptedFields: DocLinksStart['links']['scriptedFields']; + SearchBar: DataPublicPluginStart['ui']['SearchBar']; + toasts: NotificationsStart['toasts']; + fieldFormats: DataPublicPluginStart['fieldFormats']; + indexPatterns: DataPublicPluginStart['indexPatterns']; }; } const newFieldPlaceholder = i18n.translate( - 'kbn.management.editIndexPattern.scripted.newFieldPlaceholder', + 'indexPatternManagement.editIndexPattern.scripted.newFieldPlaceholder', { defaultMessage: 'New Scripted Field', } @@ -57,14 +59,13 @@ export const CreateEditField = withRouter( mode, fieldName, fieldFormatEditors, - getConfig, services, history, }: CreateEditFieldProps) => { const field = mode === 'edit' && fieldName ? indexPattern.fields.getByName(fieldName) - : services.dataStart.indexPatterns.createField( + : services.indexPatterns.createField( indexPattern, { scripted: true, @@ -73,15 +74,18 @@ export const CreateEditField = withRouter( false ); - const url = `/management/kibana/index_patterns/${indexPattern.id}`; + const url = `/patterns/${indexPattern.id}`; if (mode === 'edit' && !field) { - const message = i18n.translate('kbn.management.editIndexPattern.scripted.noFieldLabel', { - defaultMessage: - "'{indexPatternTitle}' index pattern doesn't have a scripted field called '{fieldName}'", - values: { indexPatternTitle: indexPattern.title, fieldName }, - }); - services.notifications.toasts.addWarning(message); + const message = i18n.translate( + 'indexPatternManagement.editIndexPattern.scripted.noFieldLabel', + { + defaultMessage: + "'{indexPatternTitle}' index pattern doesn't have a scripted field called '{fieldName}'", + values: { indexPatternTitle: indexPattern.title, fieldName }, + } + ); + services.toasts.addWarning(message); history.push(url); } @@ -95,24 +99,33 @@ export const CreateEditField = withRouter( if (field) { return ( - - - - - - - - + + + + + + + + + + ); } else { return <>; diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field_container.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field_container.tsx new file mode 100644 index 0000000000000..70851b712d756 --- /dev/null +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field_container.tsx @@ -0,0 +1,95 @@ +/* + * 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, { useEffect, useState } from 'react'; +import { withRouter, RouteComponentProps } from 'react-router-dom'; + +import { + HttpStart, + DocLinksStart, + ChromeDocTitle, + NotificationsStart, + IUiSettingsClient, +} from 'src/core/public'; + +import { IndexPattern, DataPublicPluginStart } from '../../../../../../plugins/data/public'; +import { ManagementAppMountParams } from '../../../../../management/public'; +import { getEditFieldBreadcrumbs, getCreateFieldBreadcrumbs } from '../../breadcrumbs'; +import { CreateEditField } from './create_edit_field'; + +export interface CreateEditFieldContainerProps + extends RouteComponentProps<{ id: string; fieldName: string }> { + getIndexPattern: (id: string) => Promise; + fieldFormatEditors: any; + getConfig: IUiSettingsClient; + services: { + uiSettings: IUiSettingsClient; + notifications: NotificationsStart; + docTitle: ChromeDocTitle; + http: HttpStart; + docLinksScriptedFields: DocLinksStart['links']['scriptedFields']; + SearchBar: DataPublicPluginStart['ui']['SearchBar']; + toasts: NotificationsStart['toasts']; + fieldFormats: DataPublicPluginStart['fieldFormats']; + indexPatterns: DataPublicPluginStart['indexPatterns']; + setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs']; + }; +} + +const CreateEditFieldCont: React.FC = ({ ...props }) => { + const [indexPattern, setIndexPattern] = useState(); + + useEffect(() => { + props.getIndexPattern(props.match.params.id).then((ip: IndexPattern) => { + setIndexPattern(ip); + if (ip) { + props.services.setBreadcrumbs( + props.match.params.fieldName + ? getEditFieldBreadcrumbs(ip, props.match.params.fieldName) + : getCreateFieldBreadcrumbs(ip) + ); + } + }); + }, [props.match.params.id, props.getIndexPattern, props]); + + if (indexPattern) { + return ( + + ); + } else { + return <>; + } +}; + +export const CreateEditFieldContainer = withRouter(CreateEditFieldCont); diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/index.ts new file mode 100644 index 0000000000000..84dce3b0f8301 --- /dev/null +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { CreateEditField } from './create_edit_field'; +export { CreateEditFieldContainer } from './create_edit_field_container'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx similarity index 51% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx index e869ac84c2db2..f1c020cc409e0 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx @@ -29,69 +29,75 @@ import { EuiLink, EuiIcon, EuiCallOut, + EuiPanel, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { IndexPattern, IndexPatternField } from '../../../../../../../../plugins/data/public'; import { ChromeDocTitle, NotificationsStart, OverlayStart, -} from '../../../../../../../../core/public'; -import { IndexPatternManagementStart } from '../../../../../../../../plugins/index_pattern_management/public'; + IUiSettingsClient, + SavedObjectsClientContract, +} from 'src/core/public'; +import { IndexPattern, IndexPatternField } from '../../../../../plugins/data/public'; +import { IndexPatternManagementStart } from '../..'; import { Tabs } from './tabs'; import { IndexHeader } from './index_header'; +import { IndexPatternTableItem } from '../types'; +import { getIndexPatterns } from '../utils'; interface EditIndexPatternProps extends RouteComponentProps { indexPattern: IndexPattern; - indexPatterns: IndexPattern[]; - config: Record; + config: IUiSettingsClient; services: { notifications: NotificationsStart; docTitle: ChromeDocTitle; overlays: OverlayStart; + savedObjectsClient: SavedObjectsClientContract; indexPatternManagement: IndexPatternManagementStart; + painlessDocLink: string; }; } const mappingAPILink = i18n.translate( - 'kbn.management.editIndexPattern.timeFilterLabel.mappingAPILink', + 'indexPatternManagement.editIndexPattern.timeFilterLabel.mappingAPILink', { defaultMessage: 'Mapping API', } ); const mappingConflictHeader = i18n.translate( - 'kbn.management.editIndexPattern.mappingConflictHeader', + 'indexPatternManagement.editIndexPattern.mappingConflictHeader', { defaultMessage: 'Mapping conflict', } ); -const confirmMessage = i18n.translate('kbn.management.editIndexPattern.refreshLabel', { +const confirmMessage = i18n.translate('indexPatternManagement.editIndexPattern.refreshLabel', { defaultMessage: 'This action resets the popularity counter of each field.', }); const confirmModalOptionsRefresh = { - confirmButtonText: i18n.translate('kbn.management.editIndexPattern.refreshButton', { + confirmButtonText: i18n.translate('indexPatternManagement.editIndexPattern.refreshButton', { defaultMessage: 'Refresh', }), - title: i18n.translate('kbn.management.editIndexPattern.refreshHeader', { + title: i18n.translate('indexPatternManagement.editIndexPattern.refreshHeader', { defaultMessage: 'Refresh field list?', }), }; const confirmModalOptionsDelete = { - confirmButtonText: i18n.translate('kbn.management.editIndexPattern.deleteButton', { + confirmButtonText: i18n.translate('indexPatternManagement.editIndexPattern.deleteButton', { defaultMessage: 'Delete', }), - title: i18n.translate('kbn.management.editIndexPattern.deleteHeader', { + title: i18n.translate('indexPatternManagement.editIndexPattern.deleteHeader', { defaultMessage: 'Delete index pattern?', }), }; export const EditIndexPattern = withRouter( - ({ indexPattern, indexPatterns, config, services, history, location }: EditIndexPatternProps) => { + ({ indexPattern, config, services, history, location }: EditIndexPatternProps) => { const [fields, setFields] = useState(indexPattern.getNonScriptedFields()); const [conflictedFields, setConflictedFields] = useState( indexPattern.fields.filter(field => field.type === 'conflict') @@ -102,7 +108,7 @@ export const EditIndexPattern = withRouter( useEffect(() => { setFields(indexPattern.getNonScriptedFields()); setConflictedFields(indexPattern.fields.filter(field => field.type === 'conflict')); - }, [indexPattern, indexPattern.fields]); + }, [indexPattern]); useEffect(() => { const indexPatternTags = @@ -129,9 +135,14 @@ export const EditIndexPattern = withRouter( }); }; - const removePattern = () => { - function doRemove() { + const removePatternClick = () => { + async function doRemove() { if (indexPattern.id === defaultIndex) { + const indexPatterns: IndexPatternTableItem[] = await getIndexPatterns( + services.savedObjectsClient, + config.get('defaultIndex'), + services.indexPatternManagement + ); config.remove('defaultIndex'); const otherPatterns = filter(indexPatterns, pattern => { return pattern.id !== indexPattern.id; @@ -143,7 +154,7 @@ export const EditIndexPattern = withRouter( } Promise.resolve(indexPattern.destroy()).then(function() { - history.push('/management/kibana/index_patterns'); + history.push(''); }); } @@ -154,13 +165,16 @@ export const EditIndexPattern = withRouter( }); }; - const timeFilterHeader = i18n.translate('kbn.management.editIndexPattern.timeFilterHeader', { - defaultMessage: "Time Filter field name: '{timeFieldName}'", - values: { timeFieldName: indexPattern.timeFieldName }, - }); + const timeFilterHeader = i18n.translate( + 'indexPatternManagement.editIndexPattern.timeFilterHeader', + { + defaultMessage: "Time Filter field name: '{timeFieldName}'", + values: { timeFieldName: indexPattern.timeFieldName }, + } + ); const mappingConflictLabel = i18n.translate( - 'kbn.management.editIndexPattern.mappingConflictLabel', + 'indexPatternManagement.editIndexPattern.mappingConflictLabel', { defaultMessage: '{conflictFieldsLength, plural, one {A field is} other {# fields are}} defined as several types (string, integer, etc) across the indices that match this pattern. You may still be able to use these conflict fields in parts of Kibana, but they will be unavailable for functions that require Kibana to know their type. Correcting this issue will require reindexing your data.', @@ -168,71 +182,80 @@ export const EditIndexPattern = withRouter( } ); + const headingAriaLabel = i18n.translate('indexPatternManagement.editIndexPattern.detailsAria', { + defaultMessage: 'Index pattern details', + }); + services.docTitle.change(indexPattern.title); const showTagsSection = Boolean(indexPattern.timeFieldName || (tags && tags.length > 0)); return ( - - - - - {showTagsSection && ( - - {Boolean(indexPattern.timeFieldName) && ( - - {timeFilterHeader} - + +
+ + + + + {showTagsSection && ( + + {Boolean(indexPattern.timeFieldName) && ( + + {timeFilterHeader} + + )} + {tags.map((tag: any) => ( + + {tag.name} + + ))} + + )} + + +

+ {indexPattern.title} }} + />{' '} + + {mappingAPILink} + + +

+ + {conflictedFields.length > 0 && ( + +

{mappingConflictLabel}

+
)} - {tags.map((tag: any) => ( - - {tag.name} - - ))} - - )} - - -

- {indexPattern.title} }} - />{' '} - - {mappingAPILink} - - -

-
- {conflictedFields.length > 0 && ( - -

{mappingConflictLabel}

-
- )} - - - - - + + + + + +
+ ); } ); diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_container.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_container.tsx new file mode 100644 index 0000000000000..2f02765cd0596 --- /dev/null +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_container.tsx @@ -0,0 +1,73 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useEffect, useState } from 'react'; +import { withRouter, RouteComponentProps } from 'react-router-dom'; +import { + ChromeDocTitle, + NotificationsStart, + OverlayStart, + IUiSettingsClient, + SavedObjectsClientContract, +} from 'src/core/public'; +import { IndexPattern } from '../../../../../plugins/data/public'; +import { ManagementAppMountParams } from '../../../../management/public'; +import { IndexPatternManagementStart } from '../..'; +import { getEditBreadcrumbs } from '../breadcrumbs'; + +import { EditIndexPattern } from '../edit_index_pattern'; + +interface EditIndexPatternContainerProps extends RouteComponentProps<{ id: string }> { + getIndexPattern: (id: string) => Promise; + config: IUiSettingsClient; + services: { + notifications: NotificationsStart; + docTitle: ChromeDocTitle; + overlays: OverlayStart; + savedObjectsClient: SavedObjectsClientContract; + setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs']; + indexPatternManagement: IndexPatternManagementStart; + painlessDocLink: string; + }; +} + +const EditIndexPatternCont: React.FC = ({ ...props }) => { + const [indexPattern, setIndexPattern] = useState(); + + useEffect(() => { + props.getIndexPattern(props.match.params.id).then((ip: IndexPattern) => { + setIndexPattern(ip); + props.services.setBreadcrumbs(getEditBreadcrumbs(ip)); + }); + }, [props.match.params.id, props.getIndexPattern, props]); + + if (indexPattern) { + return ( + + ); + } else { + return <>; + } +}; + +export const EditIndexPatternContainer = withRouter(EditIndexPatternCont); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern_state_container.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_state_container.ts similarity index 97% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern_state_container.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_state_container.ts index 5723a596f95d5..f99a5b072b423 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern_state_container.ts +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_state_container.ts @@ -22,7 +22,7 @@ import { createStateContainer, syncState, createKbnUrlStateStorage, -} from '../../../../../../../../plugins/kibana_utils/public'; +} from '../../../../../plugins/kibana_utils/public'; interface IEditIndexPatternState { tab: string; diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/index.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/index.tsx new file mode 100644 index 0000000000000..288ce115a7803 --- /dev/null +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/index.tsx @@ -0,0 +1,23 @@ +/* + * 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 { EditIndexPattern } from './edit_index_pattern'; +export { EditIndexPatternContainer } from './edit_index_pattern_container'; +export { CreateEditField } from './create_edit_field'; +export { CreateEditFieldContainer } from './create_edit_field/create_edit_field_container'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index_header.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index_header.tsx similarity index 78% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index_header.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index_header.tsx index a06671ef6a470..4cf43d63d5839 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index_header.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index_header.tsx @@ -27,37 +27,43 @@ import { EuiTitle, EuiButtonIcon, } from '@elastic/eui'; -import { IIndexPattern } from '../../../../../../../../../plugins/data/public'; +import { IIndexPattern } from 'src/plugins/data/public'; interface IndexHeaderProps { indexPattern: IIndexPattern; defaultIndex?: string; setDefault?: () => void; refreshFields?: () => void; - deleteIndexPattern?: () => void; + deleteIndexPatternClick?: () => void; } -const setDefaultAriaLabel = i18n.translate('kbn.management.editIndexPattern.setDefaultAria', { - defaultMessage: 'Set as default index.', -}); +const setDefaultAriaLabel = i18n.translate( + 'indexPatternManagement.editIndexPattern.setDefaultAria', + { + defaultMessage: 'Set as default index.', + } +); -const setDefaultTooltip = i18n.translate('kbn.management.editIndexPattern.setDefaultTooltip', { - defaultMessage: 'Set as default index.', -}); +const setDefaultTooltip = i18n.translate( + 'indexPatternManagement.editIndexPattern.setDefaultTooltip', + { + defaultMessage: 'Set as default index.', + } +); -const refreshAriaLabel = i18n.translate('kbn.management.editIndexPattern.refreshAria', { +const refreshAriaLabel = i18n.translate('indexPatternManagement.editIndexPattern.refreshAria', { defaultMessage: 'Reload field list.', }); -const refreshTooltip = i18n.translate('kbn.management.editIndexPattern.refreshTooltip', { +const refreshTooltip = i18n.translate('indexPatternManagement.editIndexPattern.refreshTooltip', { defaultMessage: 'Refresh field list.', }); -const removeAriaLabel = i18n.translate('kbn.management.editIndexPattern.removeAria', { +const removeAriaLabel = i18n.translate('indexPatternManagement.editIndexPattern.removeAria', { defaultMessage: 'Remove index pattern.', }); -const removeTooltip = i18n.translate('kbn.management.editIndexPattern.removeTooltip', { +const removeTooltip = i18n.translate('indexPatternManagement.editIndexPattern.removeTooltip', { defaultMessage: 'Remove index pattern.', }); @@ -66,7 +72,7 @@ export function IndexHeader({ indexPattern, setDefault, refreshFields, - deleteIndexPattern, + deleteIndexPatternClick, }: IndexHeaderProps) { return ( @@ -114,12 +120,12 @@ export function IndexHeader({ )} - {deleteIndexPattern && ( + {deleteIndexPatternClick && ( ({ diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx similarity index 98% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx index c69063967b1e2..6b1048d3c9d0c 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx @@ -23,7 +23,7 @@ import { IndexPatternField, IIndexPattern, IFieldType, -} from '../../../../../../../../../plugins/data/public'; +} from '../../../../../../plugins/data/public'; import { Table } from './components/table'; import { getFieldFormat } from './lib'; import { IndexedFieldItem } from './types'; @@ -108,7 +108,6 @@ export class IndexedFieldsTable extends Component< render() { const { indexPattern } = this.props; - const fields = this.getFilteredFields(this.state, this.props); return ( diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/lib/get_field_format.test.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/lib/get_field_format.test.ts similarity index 95% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/lib/get_field_format.test.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/lib/get_field_format.test.ts index fc7477c074ac2..2786df641fdb2 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/lib/get_field_format.test.ts +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/lib/get_field_format.test.ts @@ -17,7 +17,7 @@ * under the License. */ -import { IIndexPattern } from '../../../../../../../../../../plugins/data/public'; +import { IIndexPattern } from '../../../../../../data/public'; import { getFieldFormat } from './get_field_format'; const indexPattern = ({ diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/lib/get_field_format.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/lib/get_field_format.ts similarity index 92% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/lib/get_field_format.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/lib/get_field_format.ts index 1d6f267430f07..861017d99962e 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/lib/get_field_format.ts +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/lib/get_field_format.ts @@ -18,7 +18,7 @@ */ import { get } from 'lodash'; -import { IIndexPattern } from '../../../../../../../../../../plugins/data/public'; +import { IIndexPattern } from '../../../../../../data/public'; export function getFieldFormat(indexPattern?: IIndexPattern, fieldName?: string): string { return indexPattern && fieldName diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/lib/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/lib/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/lib/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/lib/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/types.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/types.ts similarity index 92% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/types.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/types.ts index f27f4608bf5d5..30466bc57bada 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/types.ts +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/types.ts @@ -17,7 +17,7 @@ * under the License. */ -import { IFieldType } from '../../../../../../../../../plugins/data/public'; +import { IFieldType } from '../../../../../../plugins/data/public'; export interface IndexedFieldItem extends IFieldType { info: string[]; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/__snapshots__/scripted_field_table.test.tsx.snap b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/__snapshots__/scripted_field_table.test.tsx.snap similarity index 82% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/__snapshots__/scripted_field_table.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/__snapshots__/scripted_field_table.test.tsx.snap index 202b09ddc6066..c0ecc441e9018 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/__snapshots__/scripted_field_table.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/__snapshots__/scripted_field_table.test.tsx.snap @@ -3,7 +3,7 @@ exports[`ScriptedFieldsTable should filter based on the lang filter 1`] = `
} @@ -16,7 +16,7 @@ exports[`CallOuts should render normally 1`] = `

, diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.test.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.test.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.tsx similarity index 87% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.tsx index 8e38b569a32fa..31d1e4e40bcd5 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.tsx @@ -37,7 +37,7 @@ export const CallOuts = ({ deprecatedLangsInUse, painlessDocLink }: CallOutsProp } @@ -46,7 +46,7 @@ export const CallOuts = ({ deprecatedLangsInUse, painlessDocLink }: CallOutsProp >

diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/call_outs/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/call_outs/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/confirmation_modal/__snapshots__/confirmation_modal.test.tsx.snap b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/confirmation_modal/__snapshots__/confirmation_modal.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/confirmation_modal/__snapshots__/confirmation_modal.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/confirmation_modal/__snapshots__/confirmation_modal.test.tsx.snap diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/confirmation_modal/confirmation_modal.test.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/confirmation_modal/confirmation_modal.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/confirmation_modal/confirmation_modal.test.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/confirmation_modal/confirmation_modal.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/confirmation_modal/confirmation_modal.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/confirmation_modal/confirmation_modal.tsx similarity index 83% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/confirmation_modal/confirmation_modal.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/confirmation_modal/confirmation_modal.tsx index 1e82174f863b0..ece706798a55f 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/confirmation_modal/confirmation_modal.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/confirmation_modal/confirmation_modal.tsx @@ -35,16 +35,19 @@ export const DeleteScritpedFieldConfirmationModal = ({ hideDeleteConfirmationModal, deleteField, }: DeleteScritpedFieldConfirmationModalProps) => { - const title = i18n.translate('kbn.management.editIndexPattern.scripted.deleteFieldLabel', { - defaultMessage: "Delete scripted field '{fieldName}'?", - values: { fieldName: field.name }, - }); + const title = i18n.translate( + 'indexPatternManagement.editIndexPattern.scripted.deleteFieldLabel', + { + defaultMessage: "Delete scripted field '{fieldName}'?", + values: { fieldName: field.name }, + } + ); const cancelButtonText = i18n.translate( - 'kbn.management.editIndexPattern.scripted.deleteField.cancelButton', + 'indexPatternManagement.editIndexPattern.scripted.deleteField.cancelButton', { defaultMessage: 'Cancel' } ); const confirmButtonText = i18n.translate( - 'kbn.management.editIndexPattern.scripted.deleteField.deleteButton', + 'indexPatternManagement.editIndexPattern.scripted.deleteField.deleteButton', { defaultMessage: 'Delete' } ); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/confirmation_modal/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/confirmation_modal/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/confirmation_modal/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/confirmation_modal/index.ts diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/header/__snapshots__/header.test.tsx.snap b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/header/__snapshots__/header.test.tsx.snap new file mode 100644 index 0000000000000..6261ea2c90793 --- /dev/null +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/header/__snapshots__/header.test.tsx.snap @@ -0,0 +1,49 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Header should render normally 1`] = ` +

+
+

+ + Scripted fields + +

+
+

+ + You can use scripted fields in visualizations and display them in your documents. However, you cannot search scripted fields. + +

+
+
+
+ +
+
+`; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/header.test.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/header/header.test.tsx similarity index 71% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/header.test.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/header/header.test.tsx index 19479de8f2aa4..11fdae39aee3c 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/header.test.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/header/header.test.tsx @@ -18,13 +18,21 @@ */ import React from 'react'; -import { shallow } from 'enzyme'; +import { render } from 'enzyme'; +import { RouteComponentProps } from 'react-router-dom'; import { Header } from './header'; describe('Header', () => { test('should render normally', () => { - const component = shallow(
); + const component = render( + + ); expect(component).toMatchSnapshot(); }); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/header.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/header/header.tsx similarity index 72% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/header.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/header/header.tsx index b8f832dad72af..dc48f61d1aa65 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/header.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/header/header.tsx @@ -18,21 +18,22 @@ */ import React from 'react'; +import { withRouter, RouteComponentProps } from 'react-router-dom'; import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -interface HeaderProps { - addScriptedFieldUrl: string; +interface HeaderProps extends RouteComponentProps { + indexPatternId: string; } -export const Header = ({ addScriptedFieldUrl }: HeaderProps) => ( +export const Header = withRouter(({ indexPatternId, history }: HeaderProps) => (

@@ -40,7 +41,7 @@ export const Header = ({ addScriptedFieldUrl }: HeaderProps) => (

@@ -49,12 +50,17 @@ export const Header = ({ addScriptedFieldUrl }: HeaderProps) => ( - + { + history.push(`${indexPatternId}/create-field/`); + }} + > -); +)); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/header/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/header/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/__snapshots__/table.test.tsx.snap b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/table/__snapshots__/table.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/__snapshots__/table.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/table/__snapshots__/table.test.tsx.snap diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/table/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/table/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/table.test.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/table/table.test.tsx similarity index 97% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/table.test.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/table/table.test.tsx index 13b3875f58687..26044f910159a 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/table.test.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/table/table.test.tsx @@ -22,7 +22,7 @@ import { shallow } from 'enzyme'; import { Table } from '../table'; import { ScriptedFieldItem } from '../../types'; -import { IIndexPattern } from '../../../../../../../../../../../plugins/data/public'; +import { IIndexPattern } from 'src/plugins/data/public'; const getIndexPatternMock = (mockedFields: any = {}) => ({ ...mockedFields } as IIndexPattern); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/table.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/table/table.tsx similarity index 68% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/table.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/table/table.tsx index 14aed11b32203..51ca59ee7b032 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/table.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/components/table/table.tsx @@ -23,7 +23,7 @@ import { i18n } from '@kbn/i18n'; import { EuiInMemoryTable, EuiBasicTableColumn } from '@elastic/eui'; import { ScriptedFieldItem } from '../../types'; -import { IIndexPattern } from '../../../../../../../../../../../plugins/data/public'; +import { IIndexPattern } from '../../../../../../../data/public'; interface TableProps { indexPattern: IIndexPattern; @@ -46,11 +46,11 @@ export class Table extends PureComponent { const columns: Array> = [ { field: 'displayName', - name: i18n.translate('kbn.management.editIndexPattern.scripted.table.nameHeader', { + name: i18n.translate('indexPatternManagement.editIndexPattern.scripted.table.nameHeader', { defaultMessage: 'Name', }), description: i18n.translate( - 'kbn.management.editIndexPattern.scripted.table.nameDescription', + 'indexPatternManagement.editIndexPattern.scripted.table.nameDescription', { defaultMessage: 'Name of the field' } ), dataType: 'string', @@ -59,11 +59,11 @@ export class Table extends PureComponent { }, { field: 'lang', - name: i18n.translate('kbn.management.editIndexPattern.scripted.table.langHeader', { + name: i18n.translate('indexPatternManagement.editIndexPattern.scripted.table.langHeader', { defaultMessage: 'Lang', }), description: i18n.translate( - 'kbn.management.editIndexPattern.scripted.table.langDescription', + 'indexPatternManagement.editIndexPattern.scripted.table.langDescription', { defaultMessage: 'Language used for the field' } ), dataType: 'string', @@ -72,11 +72,14 @@ export class Table extends PureComponent { }, { field: 'script', - name: i18n.translate('kbn.management.editIndexPattern.scripted.table.scriptHeader', { - defaultMessage: 'Script', - }), + name: i18n.translate( + 'indexPatternManagement.editIndexPattern.scripted.table.scriptHeader', + { + defaultMessage: 'Script', + } + ), description: i18n.translate( - 'kbn.management.editIndexPattern.scripted.table.scriptDescription', + 'indexPatternManagement.editIndexPattern.scripted.table.scriptDescription', { defaultMessage: 'Script for the field' } ), dataType: 'string', @@ -84,11 +87,14 @@ export class Table extends PureComponent { }, { field: 'name', - name: i18n.translate('kbn.management.editIndexPattern.scripted.table.formatHeader', { - defaultMessage: 'Format', - }), + name: i18n.translate( + 'indexPatternManagement.editIndexPattern.scripted.table.formatHeader', + { + defaultMessage: 'Format', + } + ), description: i18n.translate( - 'kbn.management.editIndexPattern.scripted.table.formatDescription', + 'indexPatternManagement.editIndexPattern.scripted.table.formatDescription', { defaultMessage: 'Format used for the field' } ), render: this.renderFormatCell, @@ -99,11 +105,14 @@ export class Table extends PureComponent { actions: [ { type: 'icon', - name: i18n.translate('kbn.management.editIndexPattern.scripted.table.editHeader', { - defaultMessage: 'Edit', - }), + name: i18n.translate( + 'indexPatternManagement.editIndexPattern.scripted.table.editHeader', + { + defaultMessage: 'Edit', + } + ), description: i18n.translate( - 'kbn.management.editIndexPattern.scripted.table.editDescription', + 'indexPatternManagement.editIndexPattern.scripted.table.editDescription', { defaultMessage: 'Edit this field' } ), icon: 'pencil', @@ -111,11 +120,14 @@ export class Table extends PureComponent { }, { type: 'icon', - name: i18n.translate('kbn.management.editIndexPattern.scripted.table.deleteHeader', { - defaultMessage: 'Delete', - }), + name: i18n.translate( + 'indexPatternManagement.editIndexPattern.scripted.table.deleteHeader', + { + defaultMessage: 'Delete', + } + ), description: i18n.translate( - 'kbn.management.editIndexPattern.scripted.table.deleteDescription', + 'indexPatternManagement.editIndexPattern.scripted.table.deleteDescription', { defaultMessage: 'Delete this field' } ), icon: 'trash', diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/scripted_field_table.test.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/scripted_field_table.test.tsx similarity index 89% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/scripted_field_table.test.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/scripted_field_table.test.tsx index 914d80f9f61d7..80132167b7f58 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/scripted_field_table.test.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/scripted_field_table.test.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import { ScriptedFieldsTable } from '../scripted_fields_table'; -import { IIndexPattern } from '../../../../../../../../../plugins/data/common/index_patterns'; +import { IIndexPattern } from '../../../../../../plugins/data/common/index_patterns'; jest.mock('@elastic/eui', () => ({ EuiTitle: 'eui-title', @@ -46,11 +46,6 @@ jest.mock('./components/table', () => ({ }, })); -jest.mock('ui/scripting_languages', () => ({ - getSupportedScriptingLanguages: () => ['painless'], - getDeprecatedScriptingLanguages: () => [], -})); - jest.mock('ui/documentation_links', () => ({ documentationLinks: { scriptedFields: { @@ -80,7 +75,11 @@ describe('ScriptedFieldsTable', () => { test('should render normally', async () => { const component = shallow( - + ); // Allow the componentWillMount code to execute @@ -93,7 +92,11 @@ describe('ScriptedFieldsTable', () => { test('should filter based on the query bar', async () => { const component = shallow( - + ); // Allow the componentWillMount code to execute @@ -117,6 +120,7 @@ describe('ScriptedFieldsTable', () => { { name: 'Bad', lang: 'somethingElse', script: 'z++' }, ], })} + painlessDocLink={'painlessDoc'} helpers={helpers} /> ); @@ -138,6 +142,7 @@ describe('ScriptedFieldsTable', () => { indexPattern={getIndexPatternMock({ getScriptedFields: () => [], })} + painlessDocLink={'painlessDoc'} helpers={helpers} /> ); @@ -152,7 +157,11 @@ describe('ScriptedFieldsTable', () => { test('should show a delete modal', async () => { const component = shallow( - + ); await component.update(); // Fire `componentWillMount()` @@ -172,6 +181,7 @@ describe('ScriptedFieldsTable', () => { removeScriptedField, }} helpers={helpers} + painlessDocLink={'painlessDoc'} /> ); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/scripted_fields_table.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/scripted_fields_table.tsx similarity index 88% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/scripted_fields_table.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/scripted_fields_table.tsx index f2c2727c5c0bb..32520eadaf199 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/scripted_fields_table.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/scripted_fields_table.tsx @@ -18,18 +18,16 @@ */ import React, { Component } from 'react'; +import { EuiSpacer } from '@elastic/eui'; import { getSupportedScriptingLanguages, getDeprecatedScriptingLanguages, -} from 'ui/scripting_languages'; -import { documentationLinks } from 'ui/documentation_links'; - -import { EuiSpacer } from '@elastic/eui'; +} from '../../../scripting_languages'; import { Table, Header, CallOuts, DeleteScritpedFieldConfirmationModal } from './components'; import { ScriptedFieldItem } from './types'; -import { IIndexPattern } from '../../../../../../../../../plugins/data/public'; +import { IIndexPattern } from '../../../../../../plugins/data/public'; interface ScriptedFieldsTableProps { indexPattern: IIndexPattern; @@ -40,6 +38,7 @@ interface ScriptedFieldsTableProps { getRouteHref?: Function; }; onRemoveField?: () => void; + painlessDocLink: string; } interface ScriptedFieldsTableState { @@ -136,24 +135,16 @@ export class ScriptedFieldsTable extends Component< }; render() { - const { indexPattern } = this.props; + const { indexPattern, painlessDocLink } = this.props; const { fieldToDelete, deprecatedLangsInUse } = this.state; const items = this.getFilteredItems(); return ( <> -

+
- + diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/types.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/types.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/types.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/types.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/__snapshots__/source_filters_table.test.tsx.snap b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/__snapshots__/source_filters_table.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/__snapshots__/source_filters_table.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/__snapshots__/source_filters_table.test.tsx.snap diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/__snapshots__/add_filter.test.tsx.snap b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/add_filter/__snapshots__/add_filter.test.tsx.snap similarity index 88% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/__snapshots__/add_filter.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/add_filter/__snapshots__/add_filter.test.tsx.snap index 879ea555d3300..92998bc3f07e3 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/__snapshots__/add_filter.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/add_filter/__snapshots__/add_filter.test.tsx.snap @@ -19,7 +19,7 @@ exports[`AddFilter should ignore strings with just spaces 1`] = ` > @@ -46,7 +46,7 @@ exports[`AddFilter should render normally 1`] = ` > diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/add_filter.test.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/add_filter/add_filter.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/add_filter.test.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/add_filter/add_filter.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/add_filter.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/add_filter/add_filter.tsx similarity index 85% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/add_filter.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/add_filter/add_filter.tsx index d0f397637de33..2a5e29827ccc5 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/add_filter.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/add_filter/add_filter.tsx @@ -27,10 +27,13 @@ interface AddFilterProps { onAddFilter: (filter: string) => void; } -const sourcePlaceholder = i18n.translate('kbn.management.editIndexPattern.sourcePlaceholder', { - defaultMessage: - "source filter, accepts wildcards (e.g., `user*` to filter fields starting with 'user')", -}); +const sourcePlaceholder = i18n.translate( + 'indexPatternManagement.editIndexPattern.sourcePlaceholder', + { + defaultMessage: + "source filter, accepts wildcards (e.g., `user*` to filter fields starting with 'user')", + } +); export const AddFilter = ({ onAddFilter }: AddFilterProps) => { const [filter, setFilter] = useState(''); @@ -53,7 +56,7 @@ export const AddFilter = ({ onAddFilter }: AddFilterProps) => { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/add_filter/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/add_filter/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/confirmation_modal/__snapshots__/confirmation_modal.test.tsx.snap b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/confirmation_modal/__snapshots__/confirmation_modal.test.tsx.snap similarity index 72% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/confirmation_modal/__snapshots__/confirmation_modal.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/confirmation_modal/__snapshots__/confirmation_modal.test.tsx.snap index 62376b498d887..0020adb19983d 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/confirmation_modal/__snapshots__/confirmation_modal.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/confirmation_modal/__snapshots__/confirmation_modal.test.tsx.snap @@ -7,14 +7,14 @@ exports[`Header should render normally 1`] = ` cancelButtonText={ } confirmButtonText={ } @@ -24,7 +24,7 @@ exports[`Header should render normally 1`] = ` title={ } buttonColor="danger" confirmButtonText={ } diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/confirmation_modal/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/confirmation_modal/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/confirmation_modal/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/confirmation_modal/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/__snapshots__/header.test.tsx.snap b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/header/__snapshots__/header.test.tsx.snap similarity index 85% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/__snapshots__/header.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/header/__snapshots__/header.test.tsx.snap index cde0de79caacd..1f380d68a5af5 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/__snapshots__/header.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/header/__snapshots__/header.test.tsx.snap @@ -8,7 +8,7 @@ exports[`Header should render normally 1`] = `

@@ -17,14 +17,14 @@ exports[`Header should render normally 1`] = `

diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/header.test.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/header/header.test.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/header.test.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/header/header.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/header.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/header/header.tsx similarity index 90% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/header.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/header/header.tsx index 7b37f75043dd5..709908a1bb253 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/header.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/header/header.tsx @@ -27,7 +27,7 @@ export const Header = () => (

@@ -35,7 +35,7 @@ export const Header = () => (

diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/header/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/header/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/__snapshots__/table.test.tsx.snap b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/table/__snapshots__/table.test.tsx.snap similarity index 95% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/__snapshots__/table.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/table/__snapshots__/table.test.tsx.snap index c70d0871bb854..cb8abdefec266 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/__snapshots__/table.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/table/__snapshots__/table.test.tsx.snap @@ -29,7 +29,7 @@ exports[`Table editing should update the matches dynamically as input value is c diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/table/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/table/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/table.test.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/table/table.test.tsx similarity index 99% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/table.test.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/table/table.test.tsx index 4705ecd2d1685..421b5b67c2288 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/table.test.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/table/table.test.tsx @@ -22,7 +22,7 @@ import { shallow, ShallowWrapper } from 'enzyme'; import { Table, TableProps, TableState } from './table'; import { EuiTableFieldDataColumnType, keyCodes } from '@elastic/eui'; -import { IIndexPattern } from '../../../../../../../../../../../plugins/data/public'; +import { IIndexPattern } from 'src/plugins/data/public'; import { SourceFiltersTableFilter } from '../../types'; const indexPattern = {} as IIndexPattern; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/table.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/table/table.tsx similarity index 85% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/table.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/table/table.tsx index db2b74bbc9824..04998d9f7dafe 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/table.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/components/table/table.tsx @@ -30,43 +30,54 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { IIndexPattern } from 'src/plugins/data/public'; import { SourceFiltersTableFilter } from '../../types'; -import { IIndexPattern } from '../../../../../../../../../../../plugins/data/public'; - -const filterHeader = i18n.translate('kbn.management.editIndexPattern.source.table.filterHeader', { - defaultMessage: 'Filter', -}); +const filterHeader = i18n.translate( + 'indexPatternManagement.editIndexPattern.source.table.filterHeader', + { + defaultMessage: 'Filter', + } +); const filterDescription = i18n.translate( - 'kbn.management.editIndexPattern.source.table.filterDescription', + 'indexPatternManagement.editIndexPattern.source.table.filterDescription', { defaultMessage: 'Filter name' } ); -const matchesHeader = i18n.translate('kbn.management.editIndexPattern.source.table.matchesHeader', { - defaultMessage: 'Matches', -}); +const matchesHeader = i18n.translate( + 'indexPatternManagement.editIndexPattern.source.table.matchesHeader', + { + defaultMessage: 'Matches', + } +); const matchesDescription = i18n.translate( - 'kbn.management.editIndexPattern.source.table.matchesDescription', + 'indexPatternManagement.editIndexPattern.source.table.matchesDescription', { defaultMessage: 'Language used for the field' } ); -const editAria = i18n.translate('kbn.management.editIndexPattern.source.table.editAria', { +const editAria = i18n.translate('indexPatternManagement.editIndexPattern.source.table.editAria', { defaultMessage: 'Edit', }); -const saveAria = i18n.translate('kbn.management.editIndexPattern.source.table.saveAria', { +const saveAria = i18n.translate('indexPatternManagement.editIndexPattern.source.table.saveAria', { defaultMessage: 'Save', }); -const deleteAria = i18n.translate('kbn.management.editIndexPattern.source.table.deleteAria', { - defaultMessage: 'Delete', -}); +const deleteAria = i18n.translate( + 'indexPatternManagement.editIndexPattern.source.table.deleteAria', + { + defaultMessage: 'Delete', + } +); -const cancelAria = i18n.translate('kbn.management.editIndexPattern.source.table.cancelAria', { - defaultMessage: 'Cancel', -}); +const cancelAria = i18n.translate( + 'indexPatternManagement.editIndexPattern.source.table.cancelAria', + { + defaultMessage: 'Cancel', + } +); export interface TableProps { indexPattern: IIndexPattern; @@ -161,7 +172,7 @@ export class Table extends Component { return ( diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/source_filters_table.test.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/source_filters_table.test.tsx similarity index 98% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/source_filters_table.test.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/source_filters_table.test.tsx index 1b68dd13566d3..fa048af7c7a70 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/source_filters_table.test.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/source_filters_table.test.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import { SourceFiltersTable } from './source_filters_table'; -import { IIndexPattern } from '../../../../../../../../../plugins/data/public'; +import { IIndexPattern } from 'src/plugins/data/public'; jest.mock('@elastic/eui', () => ({ EuiButton: 'eui-button', diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/source_filters_table.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/source_filters_table.tsx similarity index 98% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/source_filters_table.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/source_filters_table.tsx index dcf8ae9e1323f..ccdda3915e979 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/source_filters_table.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/source_filters_table.tsx @@ -22,7 +22,7 @@ import { createSelector } from 'reselect'; import { EuiSpacer } from '@elastic/eui'; import { AddFilter, Table, Header, DeleteFilterConfirmationModal } from './components'; -import { IIndexPattern } from '../../../../../../../../../plugins/data/public'; +import { IIndexPattern } from '../../../../../../plugins/data/public'; import { SourceFiltersTableFilter } from './types'; export interface SourceFiltersTableProps { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/types.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/types.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/types.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/source_filters_table/types.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/tabs/index.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/tabs/index.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/index.ts diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/tabs/tabs.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/tabs.tsx similarity index 92% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/tabs/tabs.tsx rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/tabs.tsx index c727dcd3e3c65..5cf7fd9b2af06 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/tabs/tabs.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/tabs.tsx @@ -30,10 +30,10 @@ import { EuiSelectOption, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { fieldWildcardMatcher } from '../../../../../../../../../plugins/kibana_utils/public'; -import { IndexPatternManagementStart } from '../../../../../../../../../plugins/index_pattern_management/public'; -import { IndexPattern, IndexPatternField } from '../../../../../../../../../plugins/data/public'; -import { META_FIELDS_SETTING } from '../../../../../../../../../plugins/data/common'; +import { fieldWildcardMatcher } from '../../../../../kibana_utils/public'; +import { IndexPatternManagementStart } from '../../../../../index_pattern_management/public'; +import { IndexPattern, IndexPatternField } from '../../../../../data/public'; +import { META_FIELDS_SETTING } from '../../../../../data/common'; import { createEditIndexPatternPageStateContainer } from '../edit_index_pattern_state_container'; import { TAB_INDEXED_FIELDS, TAB_SCRIPTED_FIELDS, TAB_SOURCE_FILTERS } from '../constants'; import { SourceFiltersTable } from '../source_filters_table'; @@ -47,19 +47,26 @@ interface TabsProps extends Pick { fields: IndexPatternField[]; services: { indexPatternManagement: IndexPatternManagementStart; + painlessDocLink: string; }; } -const searchAriaLabel = i18n.translate('kbn.management.editIndexPattern.fields.searchAria', { - defaultMessage: 'Search fields', -}); +const searchAriaLabel = i18n.translate( + 'indexPatternManagement.editIndexPattern.fields.searchAria', + { + defaultMessage: 'Search fields', + } +); -const filterAriaLabel = i18n.translate('kbn.management.editIndexPattern.fields.filterAria', { - defaultMessage: 'Filter field types', -}); +const filterAriaLabel = i18n.translate( + 'indexPatternManagement.editIndexPattern.fields.filterAria', + { + defaultMessage: 'Filter field types', + } +); const filterPlaceholder = i18n.translate( - 'kbn.management.editIndexPattern.fields.filterPlaceholder', + 'indexPatternManagement.editIndexPattern.fields.filterPlaceholder', { defaultMessage: 'Search', } @@ -189,6 +196,7 @@ export function Tabs({ config, indexPattern, fields, services, history, location }, }} onRemoveField={refreshFilters} + painlessDocLink={services.painlessDocLink} /> ); @@ -219,6 +227,7 @@ export function Tabs({ config, indexPattern, fields, services, history, location refreshFilters, scriptedFieldLanguageFilter, services.indexPatternManagement.list.getFieldInfo, + services.painlessDocLink, ] ); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/tabs/utils.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/utils.ts similarity index 82% rename from src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/tabs/utils.ts rename to src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/utils.ts index 83335a6fabfeb..b9b59142290dc 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/tabs/utils.ts +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/utils.ts @@ -19,8 +19,8 @@ import { Dictionary, countBy, defaults, unique } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { IndexPattern, IndexPatternField } from '../../../../../../../../../plugins/data/public'; -import { IndexPatternManagementStart } from '../../../../../../../../../plugins/index_pattern_management/public'; +import { IndexPattern, IndexPatternField } from '../../../../../../plugins/data/public'; +import { IndexPatternManagementStart } from '../../../../../../plugins/index_pattern_management/public'; import { TAB_INDEXED_FIELDS, TAB_SCRIPTED_FIELDS, TAB_SOURCE_FILTERS } from '../constants'; function filterByName(items: IndexPatternField[], filter: string) { @@ -56,17 +56,17 @@ function getTitle(type: string, filteredCount: Dictionary, totalCount: D let title = ''; switch (type) { case 'indexed': - title = i18n.translate('kbn.management.editIndexPattern.tabs.fieldsHeader', { + title = i18n.translate('indexPatternManagement.editIndexPattern.tabs.fieldsHeader', { defaultMessage: 'Fields', }); break; case 'scripted': - title = i18n.translate('kbn.management.editIndexPattern.tabs.scriptedHeader', { + title = i18n.translate('indexPatternManagement.editIndexPattern.tabs.scriptedHeader', { defaultMessage: 'Scripted fields', }); break; case 'sourceFilters': - title = i18n.translate('kbn.management.editIndexPattern.tabs.sourceHeader', { + title = i18n.translate('indexPatternManagement.editIndexPattern.tabs.sourceHeader', { defaultMessage: 'Source filters', }); break; @@ -117,16 +117,22 @@ export function getTabs( } export function getPath(field: IndexPatternField) { - return `/management/kibana/index_patterns/${field.indexPattern?.id}/field/${field.name}`; + return `${field.indexPattern?.id}/field/${field.name}`; } -const allTypesDropDown = i18n.translate('kbn.management.editIndexPattern.fields.allTypesDropDown', { - defaultMessage: 'All field types', -}); +const allTypesDropDown = i18n.translate( + 'indexPatternManagement.editIndexPattern.fields.allTypesDropDown', + { + defaultMessage: 'All field types', + } +); -const allLangsDropDown = i18n.translate('kbn.management.editIndexPattern.fields.allLangsDropDown', { - defaultMessage: 'All languages', -}); +const allLangsDropDown = i18n.translate( + 'indexPatternManagement.editIndexPattern.fields.allLangsDropDown', + { + defaultMessage: 'All languages', + } +); export function convertToEuiSelectOption(options: string[], type: string) { const euiOptions = diff --git a/src/legacy/ui/public/field_editor/__snapshots__/field_editor.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap similarity index 72% rename from src/legacy/ui/public/field_editor/__snapshots__/field_editor.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap index dc11bdfefa46b..a7ed4e1c9cafd 100644 --- a/src/legacy/ui/public/field_editor/__snapshots__/field_editor.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap @@ -6,7 +6,7 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = `

@@ -19,31 +19,14 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = ` isVisible={false} /> } label={ } @@ -168,7 +152,7 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = ` error={ } @@ -188,7 +172,7 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = ` @@ -205,7 +189,7 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = ` > @@ -224,7 +208,7 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = ` > @@ -238,7 +222,7 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = ` > @@ -258,7 +242,7 @@ exports[`FieldEditor should render edit scripted field correctly 1`] = `

} label={ } @@ -435,7 +403,7 @@ exports[`FieldEditor should render edit scripted field correctly 1`] = ` @@ -452,7 +420,7 @@ exports[`FieldEditor should render edit scripted field correctly 1`] = ` > @@ -471,7 +439,7 @@ exports[`FieldEditor should render edit scripted field correctly 1`] = ` > @@ -485,7 +453,7 @@ exports[`FieldEditor should render edit scripted field correctly 1`] = ` > @@ -503,7 +471,7 @@ exports[`FieldEditor should render edit scripted field correctly 1`] = ` > @@ -525,7 +493,7 @@ exports[`FieldEditor should show conflict field warning 1`] = `

@@ -538,31 +506,14 @@ exports[`FieldEditor should show conflict field warning 1`] = ` isVisible={false} /> @@ -614,7 +566,7 @@ exports[`FieldEditor should show conflict field warning 1`] = ` "mappingConflict": , @@ -690,14 +642,14 @@ exports[`FieldEditor should show conflict field warning 1`] = ` helpText={ } label={ } @@ -731,7 +683,7 @@ exports[`FieldEditor should show conflict field warning 1`] = ` error={ } @@ -751,7 +703,7 @@ exports[`FieldEditor should show conflict field warning 1`] = ` @@ -768,7 +720,7 @@ exports[`FieldEditor should show conflict field warning 1`] = ` > @@ -787,7 +739,7 @@ exports[`FieldEditor should show conflict field warning 1`] = ` > @@ -801,7 +753,7 @@ exports[`FieldEditor should show conflict field warning 1`] = ` > @@ -821,7 +773,7 @@ exports[`FieldEditor should show deprecated lang warning 1`] = `

  testlang , "painlessLink": , @@ -1032,14 +967,14 @@ exports[`FieldEditor should show deprecated lang warning 1`] = ` helpText={ } label={ } @@ -1088,7 +1023,7 @@ exports[`FieldEditor should show deprecated lang warning 1`] = ` @@ -1105,7 +1040,7 @@ exports[`FieldEditor should show deprecated lang warning 1`] = ` > @@ -1124,7 +1059,7 @@ exports[`FieldEditor should show deprecated lang warning 1`] = ` > @@ -1138,7 +1073,7 @@ exports[`FieldEditor should show deprecated lang warning 1`] = ` > @@ -1156,7 +1091,7 @@ exports[`FieldEditor should show deprecated lang warning 1`] = ` > @@ -1178,7 +1113,7 @@ exports[`FieldEditor should show multiple type field warning with a table contai

@@ -1191,31 +1126,14 @@ exports[`FieldEditor should show multiple type field warning with a table contai isVisible={false} /> @@ -1267,7 +1186,7 @@ exports[`FieldEditor should show multiple type field warning with a table contai "mappingConflict": , @@ -1350,14 +1269,14 @@ exports[`FieldEditor should show multiple type field warning with a table contai title={ } > @@ -1399,14 +1318,14 @@ exports[`FieldEditor should show multiple type field warning with a table contai helpText={ } label={ } @@ -1440,7 +1359,7 @@ exports[`FieldEditor should show multiple type field warning with a table contai error={ } @@ -1460,7 +1379,7 @@ exports[`FieldEditor should show multiple type field warning with a table contai @@ -1477,7 +1396,7 @@ exports[`FieldEditor should show multiple type field warning with a table contai > @@ -1496,7 +1415,7 @@ exports[`FieldEditor should show multiple type field warning with a table contai > @@ -1510,7 +1429,7 @@ exports[`FieldEditor should show multiple type field warning with a table contai > diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/__snapshots__/field_format_editor.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/__snapshots__/field_format_editor.test.tsx.snap similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/__snapshots__/field_format_editor.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/__snapshots__/field_format_editor.test.tsx.snap diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.tsx.snap similarity index 92% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.tsx.snap index bf1682faf9a9d..f3e529a8a1e1b 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.tsx.snap @@ -16,7 +16,7 @@ exports[`BytesFormatEditor should render normally 1`] = ` >   @@ -30,7 +30,7 @@ exports[`BytesFormatEditor should render normally 1`] = ` label={ diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/bytes/bytes.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/bytes/bytes.test.tsx similarity index 98% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/bytes/bytes.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/bytes/bytes.test.tsx index 40443ec262182..99c3d3d55a8bc 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/bytes/bytes.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/bytes/bytes.test.tsx @@ -44,7 +44,6 @@ describe('BytesFormatEditor', () => { it('should render normally', async () => { const component = shallow( , "render": [Function], @@ -18,7 +18,7 @@ exports[`ColorFormatEditor should render multiple colors 1`] = ` "field": "text", "name": , "render": [Function], @@ -27,7 +27,7 @@ exports[`ColorFormatEditor should render multiple colors 1`] = ` "field": "background", "name": , "render": [Function], @@ -35,7 +35,7 @@ exports[`ColorFormatEditor should render multiple colors 1`] = ` Object { "name": , "render": [Function], @@ -89,7 +89,7 @@ exports[`ColorFormatEditor should render multiple colors 1`] = ` > @@ -108,7 +108,7 @@ exports[`ColorFormatEditor should render other type normally (range field) 1`] = "field": "range", "name": , "render": [Function], @@ -117,7 +117,7 @@ exports[`ColorFormatEditor should render other type normally (range field) 1`] = "field": "text", "name": , "render": [Function], @@ -126,7 +126,7 @@ exports[`ColorFormatEditor should render other type normally (range field) 1`] = "field": "background", "name": , "render": [Function], @@ -134,7 +134,7 @@ exports[`ColorFormatEditor should render other type normally (range field) 1`] = Object { "name": , "render": [Function], @@ -181,7 +181,7 @@ exports[`ColorFormatEditor should render other type normally (range field) 1`] = > @@ -200,7 +200,7 @@ exports[`ColorFormatEditor should render string type normally (regex field) 1`] "field": "regex", "name": , "render": [Function], @@ -209,7 +209,7 @@ exports[`ColorFormatEditor should render string type normally (regex field) 1`] "field": "text", "name": , "render": [Function], @@ -218,7 +218,7 @@ exports[`ColorFormatEditor should render string type normally (regex field) 1`] "field": "background", "name": , "render": [Function], @@ -226,7 +226,7 @@ exports[`ColorFormatEditor should render string type normally (regex field) 1`] Object { "name": , "render": [Function], @@ -273,7 +273,7 @@ exports[`ColorFormatEditor should render string type normally (regex field) 1`] > diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/color/color.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/color/color.test.tsx similarity index 94% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/color/color.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/color/color.test.tsx index 549831e9c3fb2..f13cb0975c8d2 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/color/color.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/color/color.test.tsx @@ -22,7 +22,7 @@ import { shallowWithI18nProvider } from 'test_utils/enzyme_helpers'; import { FieldFormat } from 'src/plugins/data/public'; import { ColorFormatEditor } from './color'; -import { fieldFormats } from '../../../../../../../../plugins/data/public'; +import { fieldFormats } from '../../../../../../../../data/public'; const fieldType = 'string'; const format = { @@ -42,7 +42,6 @@ describe('ColorFormatEditor', () => { it('should render string type normally (regex field)', async () => { const component = shallowWithI18nProvider( { it('should render other type normally (range field)', async () => { const component = shallowWithI18nProvider( { it('should render multiple colors', async () => { const component = shallowWithI18nProvider( ), @@ -121,7 +121,7 @@ export class ColorFormatEditor extends DefaultFormatEditor ), @@ -145,7 +145,7 @@ export class ColorFormatEditor extends DefaultFormatEditor ), @@ -169,7 +169,7 @@ export class ColorFormatEditor extends DefaultFormatEditor ), @@ -192,7 +192,7 @@ export class ColorFormatEditor extends DefaultFormatEditor ), @@ -211,15 +211,15 @@ export class ColorFormatEditor extends DefaultFormatEditor { @@ -240,7 +240,7 @@ export class ColorFormatEditor extends DefaultFormatEditor diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/color/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/color/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/color/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/color/index.ts diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/date/__snapshots__/date.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date/__snapshots__/date.test.tsx.snap similarity index 93% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/date/__snapshots__/date.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date/__snapshots__/date.test.tsx.snap index 2d73f775e316c..a4d780c59ca74 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/date/__snapshots__/date.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date/__snapshots__/date.test.tsx.snap @@ -16,7 +16,7 @@ exports[`DateFormatEditor should render normally 1`] = ` >   @@ -30,7 +30,7 @@ exports[`DateFormatEditor should render normally 1`] = ` label={ diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/date/date.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date/date.test.tsx similarity index 98% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/date/date.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date/date.test.tsx index 746cb7c7fe302..c3114dacd118d 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/date/date.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date/date.test.tsx @@ -44,7 +44,6 @@ describe('DateFormatEditor', () => { it('should render normally', async () => { const component = shallow( {defaultPattern}, @@ -69,7 +69,7 @@ export class DateFormatEditor extends DefaultFormatEditor   diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/date/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/date/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date/index.ts diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/date_nanos/__snapshots__/date_nanos.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date_nanos/__snapshots__/date_nanos.test.tsx.snap similarity index 93% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/date_nanos/__snapshots__/date_nanos.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date_nanos/__snapshots__/date_nanos.test.tsx.snap index 1456deaa13e47..8c6397ea3adeb 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/date_nanos/__snapshots__/date_nanos.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date_nanos/__snapshots__/date_nanos.test.tsx.snap @@ -16,7 +16,7 @@ exports[`DateFormatEditor should render normally 1`] = ` >   @@ -30,7 +30,7 @@ exports[`DateFormatEditor should render normally 1`] = ` label={ diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/date_nanos/date_nanos.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date_nanos/date_nanos.test.tsx similarity index 94% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/date_nanos/date_nanos.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date_nanos/date_nanos.test.tsx index e6b15c741af4e..bc9a8704e7c7d 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/date_nanos/date_nanos.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date_nanos/date_nanos.test.tsx @@ -19,7 +19,7 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { FieldFormat } from '../../../../../../../../plugins/data/public'; +import { FieldFormat } from '../../../../../../../../data/public'; import { DateNanosFormatEditor } from './date_nanos'; @@ -46,7 +46,6 @@ describe('DateFormatEditor', () => { it('should render normally', async () => { const component = shallow( {defaultPattern}, @@ -64,7 +64,7 @@ export class DateNanosFormatEditor extends DefaultFormatEditor   diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/date_nanos/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date_nanos/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/date_nanos/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/date_nanos/index.ts diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/default/__snapshots__/default.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/default/__snapshots__/default.test.tsx.snap similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/default/__snapshots__/default.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/default/__snapshots__/default.test.tsx.snap diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/default/default.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/default/default.test.tsx similarity index 98% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/default/default.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/default/default.test.tsx index 3f30af97dc063..6af441b9ba751 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/default/default.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/default/default.test.tsx @@ -69,7 +69,6 @@ describe('DefaultFormatEditor', () => { it('should render nothing', async () => { const component = shallow( { it('should call prop onChange()', async () => { const component = shallow( { shallow( { formatParams: { type?: string } & P; onChange: (newParams: Record) => void; onError: FieldFormatEditorProps['onError']; - basePath: string; } export interface FormatEditorState { @@ -86,6 +85,7 @@ export class DefaultFormatEditor

extends PureComponent< FormatEditorProps

, FormatEditorState & S > { + static formatId = 'default'; state = defaultState as FormatEditorState & S; static getDerivedStateFromProps(nextProps: FormatEditorProps<{}>, state: FormatEditorState) { diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/default/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/default/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/default/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/default/index.ts diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.tsx.snap similarity index 94% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.tsx.snap index dbebd324b16b6..b606e60949af5 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.tsx.snap @@ -12,7 +12,7 @@ exports[`DurationFormatEditor should render human readable output normally 1`] = label={ } @@ -42,7 +42,7 @@ exports[`DurationFormatEditor should render human readable output normally 1`] = label={ } @@ -124,7 +124,7 @@ exports[`DurationFormatEditor should render non-human readable output normally 1 label={ } @@ -154,7 +154,7 @@ exports[`DurationFormatEditor should render non-human readable output normally 1 label={ } @@ -189,7 +189,7 @@ exports[`DurationFormatEditor should render non-human readable output normally 1 label={ } diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/duration/duration.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/duration/duration.test.tsx similarity index 98% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/duration/duration.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/duration/duration.test.tsx index 3ab69d12d8c0e..b181d6fa4466d 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/duration/duration.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/duration/duration.test.tsx @@ -71,7 +71,6 @@ describe('DurationFormatEditor', () => { it('should render human readable output normally', async () => { const component = shallow( { }; const component = shallow( 20 ) { - error = i18n.translate('common.ui.fieldEditor.durationErrorMessage', { + error = i18n.translate('indexPatternManagement.durationErrorMessage', { defaultMessage: 'Decimal places must be between 0 and 20', }); nextProps.onError(error); @@ -101,7 +101,7 @@ export class DurationFormatEditor extends DefaultFormatEditor< } @@ -125,7 +125,7 @@ export class DurationFormatEditor extends DefaultFormatEditor< } @@ -149,7 +149,7 @@ export class DurationFormatEditor extends DefaultFormatEditor< } diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/duration/index.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/duration/index.tsx similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/duration/index.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/duration/index.tsx diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/index.ts new file mode 100644 index 0000000000000..6961cbf8d831c --- /dev/null +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/index.ts @@ -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. + */ +export { DefaultFormatEditor } from './default'; + +export { BytesFormatEditor } from './bytes'; +export { ColorFormatEditor } from './color'; +export { DateFormatEditor } from './date'; +export { DateNanosFormatEditor } from './date_nanos'; +export { DurationFormatEditor } from './duration'; +export { NumberFormatEditor } from './number'; +export { PercentFormatEditor } from './percent'; +export { StaticLookupFormatEditor } from './static_lookup'; +export { StringFormatEditor } from './string'; +export { TruncateFormatEditor } from './truncate'; +export { UrlFormatEditor } from './url'; diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/number/__snapshots__/number.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/number/__snapshots__/number.test.tsx.snap similarity index 92% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/number/__snapshots__/number.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/number/__snapshots__/number.test.tsx.snap index cf04dd19428e5..42c2323e56979 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/number/__snapshots__/number.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/number/__snapshots__/number.test.tsx.snap @@ -16,7 +16,7 @@ exports[`NumberFormatEditor should render normally 1`] = ` >   @@ -30,7 +30,7 @@ exports[`NumberFormatEditor should render normally 1`] = ` label={ diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/number/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/number/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/number/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/number/index.ts diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/number/number.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/number/number.test.tsx similarity index 98% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/number/number.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/number/number.test.tsx index c07c866359305..fddd1d5a8c7c3 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/number/number.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/number/number.test.tsx @@ -44,7 +44,6 @@ describe('NumberFormatEditor', () => { it('should render normally', async () => { const component = shallow( {defaultPattern} }} /> @@ -56,7 +56,7 @@ export class NumberFormatEditor extends DefaultFormatEditor   diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/percent/__snapshots__/percent.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/percent/__snapshots__/percent.test.tsx.snap similarity index 92% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/percent/__snapshots__/percent.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/percent/__snapshots__/percent.test.tsx.snap index 0784a3f5e407d..ac512402b4d41 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/percent/__snapshots__/percent.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/percent/__snapshots__/percent.test.tsx.snap @@ -16,7 +16,7 @@ exports[`PercentFormatEditor should render normally 1`] = ` >   @@ -30,7 +30,7 @@ exports[`PercentFormatEditor should render normally 1`] = ` label={ diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/percent/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/percent/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/percent/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/percent/index.ts diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/percent/percent.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/percent/percent.test.tsx similarity index 94% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/percent/percent.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/percent/percent.test.tsx index ddeb79538cda1..c23e940dadea7 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/percent/percent.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/percent/percent.test.tsx @@ -19,7 +19,7 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { FieldFormat } from '../../../../../../../../plugins/data/public'; +import { FieldFormat } from '../../../../../../../../data/public'; import { PercentFormatEditor } from './percent'; @@ -44,7 +44,6 @@ describe('PercentFormatEditor', () => { it('should render normally', async () => { const component = shallow( , "render": [Function], @@ -18,7 +18,7 @@ exports[`StaticLookupFormatEditor should render multiple lookup entries and unkn "field": "value", "name": , "render": [Function], @@ -73,7 +73,7 @@ exports[`StaticLookupFormatEditor should render multiple lookup entries and unkn > @@ -89,7 +89,7 @@ exports[`StaticLookupFormatEditor should render multiple lookup entries and unkn label={ } @@ -116,7 +116,7 @@ exports[`StaticLookupFormatEditor should render normally 1`] = ` "field": "key", "name": , "render": [Function], @@ -125,7 +125,7 @@ exports[`StaticLookupFormatEditor should render normally 1`] = ` "field": "value", "name": , "render": [Function], @@ -174,7 +174,7 @@ exports[`StaticLookupFormatEditor should render normally 1`] = ` > @@ -190,7 +190,7 @@ exports[`StaticLookupFormatEditor should render normally 1`] = ` label={ } diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/static_lookup/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/static_lookup/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/static_lookup/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/static_lookup/index.ts diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/static_lookup/static_lookup.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/static_lookup/static_lookup.test.tsx similarity index 93% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/static_lookup/static_lookup.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/static_lookup/static_lookup.test.tsx index 2e2b1c3ae2357..a8356923eb381 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/static_lookup/static_lookup.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/static_lookup/static_lookup.test.tsx @@ -18,9 +18,9 @@ */ import React from 'react'; -import { shallowWithI18nProvider } from '../../../../../../../../test_utils/public/enzyme_helpers'; +import { shallowWithI18nProvider } from '../../../../../../../../../test_utils/public/enzyme_helpers'; import { StaticLookupFormatEditorFormatParams } from './static_lookup'; -import { FieldFormat } from '../../../../../../../../plugins/data/public'; +import { FieldFormat } from '../../../../../../../../data/public'; import { StaticLookupFormatEditor } from './static_lookup'; @@ -43,7 +43,6 @@ describe('StaticLookupFormatEditor', () => { it('should render normally', async () => { const component = shallowWithI18nProvider( { it('should render multiple lookup entries and unknown key value', async () => { const component = shallowWithI18nProvider( + ), render: (value: number, item: StaticLookupItem) => { return ( @@ -106,7 +109,7 @@ export class StaticLookupFormatEditor extends DefaultFormatEditor< field: 'value', name: ( ), @@ -128,15 +131,15 @@ export class StaticLookupFormatEditor extends DefaultFormatEditor< }, { field: 'actions', - name: i18n.translate('common.ui.fieldEditor.staticLookup.actions', { + name: i18n.translate('indexPatternManagement.staticLookup.actions', { defaultMessage: 'actions', }), actions: [ { - name: i18n.translate('common.ui.fieldEditor.staticLookup.deleteAria', { + name: i18n.translate('indexPatternManagement.staticLookup.deleteAria', { defaultMessage: 'Delete', }), - description: i18n.translate('common.ui.fieldEditor.staticLookup.deleteTitle', { + description: i18n.translate('indexPatternManagement.staticLookup.deleteTitle', { defaultMessage: 'Delete entry', }), onClick: (item: StaticLookupItem) => { @@ -158,7 +161,7 @@ export class StaticLookupFormatEditor extends DefaultFormatEditor< @@ -166,7 +169,7 @@ export class StaticLookupFormatEditor extends DefaultFormatEditor< } @@ -174,7 +177,7 @@ export class StaticLookupFormatEditor extends DefaultFormatEditor< } diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/string/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/string/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/string/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/string/index.ts diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/string/string.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/string/string.test.tsx similarity index 98% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/string/string.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/string/string.test.tsx index d0fa0935b2664..ccaa12222281f 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/string/string.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/string/string.test.tsx @@ -52,7 +52,6 @@ describe('StringFormatEditor', () => { it('should render normally', async () => { const component = shallow( } diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/truncate/__snapshots__/truncate.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/truncate/__snapshots__/truncate.test.tsx.snap similarity index 96% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/truncate/__snapshots__/truncate.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/truncate/__snapshots__/truncate.test.tsx.snap index f646d5b4afca8..2d1ee496d2786 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/truncate/__snapshots__/truncate.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/truncate/__snapshots__/truncate.test.tsx.snap @@ -12,7 +12,7 @@ exports[`TruncateFormatEditor should render normally 1`] = ` label={ } diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/truncate/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/truncate/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/truncate/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/truncate/index.ts diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/truncate/sample.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/truncate/sample.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/truncate/sample.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/truncate/sample.ts diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/truncate/truncate.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/truncate/truncate.test.tsx similarity index 98% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/truncate/truncate.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/truncate/truncate.test.tsx index bb723386ff777..149b78c85e5da 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/truncate/truncate.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/truncate/truncate.test.tsx @@ -50,7 +50,6 @@ describe('TruncateFormatEditor', () => { it('should render normally', async () => { const component = shallow( { it('should fire error, when input is invalid', async () => { const component = shallow( { it('should fire change, when input changed and is valid', async () => { const component = shallow( } diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/label_template_flyout.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/__snapshots__/label_template_flyout.test.tsx.snap similarity index 90% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/label_template_flyout.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/__snapshots__/label_template_flyout.test.tsx.snap index f0766df176c0d..69b192a81d097 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/label_template_flyout.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/__snapshots__/label_template_flyout.test.tsx.snap @@ -11,14 +11,14 @@ exports[`LabelTemplateFlyout should render normally 1`] = `

@@ -36,7 +36,7 @@ exports[`LabelTemplateFlyout should render normally 1`] = ` —  @@ -47,7 +47,7 @@ exports[`LabelTemplateFlyout should render normally 1`] = ` —  @@ -55,7 +55,7 @@ exports[`LabelTemplateFlyout should render normally 1`] = `

diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/url.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/__snapshots__/url.test.tsx.snap similarity index 89% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/url.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/__snapshots__/url.test.tsx.snap index a3418077ad258..aa69b8da6cf60 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/url.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/__snapshots__/url.test.tsx.snap @@ -19,7 +19,7 @@ exports[`UrlFormatEditor should render label template help 1`] = ` label={ } @@ -58,7 +58,7 @@ exports[`UrlFormatEditor should render label template help 1`] = ` > @@ -67,7 +67,7 @@ exports[`UrlFormatEditor should render label template help 1`] = ` label={ } @@ -91,7 +91,7 @@ exports[`UrlFormatEditor should render label template help 1`] = ` > @@ -100,7 +100,7 @@ exports[`UrlFormatEditor should render label template help 1`] = ` label={ } @@ -138,7 +138,7 @@ exports[`UrlFormatEditor should render normally 1`] = ` label={ } @@ -177,7 +177,7 @@ exports[`UrlFormatEditor should render normally 1`] = ` > @@ -186,7 +186,7 @@ exports[`UrlFormatEditor should render normally 1`] = ` label={ } @@ -210,7 +210,7 @@ exports[`UrlFormatEditor should render normally 1`] = ` > @@ -219,7 +219,7 @@ exports[`UrlFormatEditor should render normally 1`] = ` label={ } @@ -257,7 +257,7 @@ exports[`UrlFormatEditor should render url template help 1`] = ` label={ } @@ -296,7 +296,7 @@ exports[`UrlFormatEditor should render url template help 1`] = ` > @@ -305,7 +305,7 @@ exports[`UrlFormatEditor should render url template help 1`] = ` label={ } @@ -329,7 +329,7 @@ exports[`UrlFormatEditor should render url template help 1`] = ` > @@ -338,7 +338,7 @@ exports[`UrlFormatEditor should render url template help 1`] = ` label={ } @@ -376,7 +376,7 @@ exports[`UrlFormatEditor should render width and height fields if image 1`] = ` label={ } @@ -416,7 +416,7 @@ exports[`UrlFormatEditor should render width and height fields if image 1`] = ` > @@ -425,7 +425,7 @@ exports[`UrlFormatEditor should render width and height fields if image 1`] = ` label={ } @@ -449,7 +449,7 @@ exports[`UrlFormatEditor should render width and height fields if image 1`] = ` > @@ -458,7 +458,7 @@ exports[`UrlFormatEditor should render width and height fields if image 1`] = ` label={ } @@ -479,7 +479,7 @@ exports[`UrlFormatEditor should render width and height fields if image 1`] = ` label={ } @@ -500,7 +500,7 @@ exports[`UrlFormatEditor should render width and height fields if image 1`] = ` label={ } diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/url_template_flyout.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/__snapshots__/url_template_flyout.test.tsx.snap similarity index 88% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/url_template_flyout.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/__snapshots__/url_template_flyout.test.tsx.snap index fd697a2a4c70a..14e5012e9a554 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/__snapshots__/url_template_flyout.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/__snapshots__/url_template_flyout.test.tsx.snap @@ -11,14 +11,14 @@ exports[`UrlTemplateFlyout should render normally 1`] = `

@@ -27,7 +27,7 @@ exports[`UrlTemplateFlyout should render normally 1`] = ` "strongUrlTemplate": , @@ -43,7 +43,7 @@ exports[`UrlTemplateFlyout should render normally 1`] = ` —  @@ -54,7 +54,7 @@ exports[`UrlTemplateFlyout should render normally 1`] = ` —  @@ -62,7 +62,7 @@ exports[`UrlTemplateFlyout should render normally 1`] = `

diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/index.ts diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/label_template_flyout.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/label_template_flyout.test.tsx similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/label_template_flyout.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/label_template_flyout.test.tsx diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/label_template_flyout.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/label_template_flyout.tsx similarity index 80% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/label_template_flyout.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/label_template_flyout.tsx index 1ce7bec579e16..d04ee58f26b0a 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/label_template_flyout.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/label_template_flyout.tsx @@ -35,13 +35,13 @@ const items: LabelTemplateExampleItem[] = [ { input: 1234, urlTemplate: 'http://company.net/profiles?user_id={{value}}', - labelTemplate: i18n.translate('common.ui.fieldEditor.labelTemplate.example.idLabel', { + labelTemplate: i18n.translate('indexPatternManagement.labelTemplate.example.idLabel', { defaultMessage: 'User #{value}', values: { value: '{{value}}' }, }), output: '' + - i18n.translate('common.ui.fieldEditor.labelTemplate.example.output.idLabel', { + i18n.translate('indexPatternManagement.labelTemplate.example.output.idLabel', { defaultMessage: 'User', }) + ' #1234', @@ -49,12 +49,12 @@ const items: LabelTemplateExampleItem[] = [ { input: '/assets/main.css', urlTemplate: 'http://site.com{{rawValue}}', - labelTemplate: i18n.translate('common.ui.fieldEditor.labelTemplate.example.pathLabel', { + labelTemplate: i18n.translate('indexPatternManagement.labelTemplate.example.pathLabel', { defaultMessage: 'View Asset', }), output: '' + - i18n.translate('common.ui.fieldEditor.labelTemplate.example.output.pathLabel', { + i18n.translate('indexPatternManagement.labelTemplate.example.output.pathLabel', { defaultMessage: 'View Asset', }) + '', @@ -68,13 +68,13 @@ export const LabelTemplateFlyout = ({ isVisible = false, onClose = () => {} }) =

{} }) =

  • value — 
  • url — 
  • @@ -108,26 +108,26 @@ export const LabelTemplateFlyout = ({ isVisible = false, onClose = () => {} }) = columns={[ { field: 'input', - name: i18n.translate('common.ui.fieldEditor.labelTemplate.inputHeader', { + name: i18n.translate('indexPatternManagement.labelTemplate.inputHeader', { defaultMessage: 'Input', }), width: '160px', }, { field: 'urlTemplate', - name: i18n.translate('common.ui.fieldEditor.labelTemplate.urlHeader', { + name: i18n.translate('indexPatternManagement.labelTemplate.urlHeader', { defaultMessage: 'URL Template', }), }, { field: 'labelTemplate', - name: i18n.translate('common.ui.fieldEditor.labelTemplate.labelHeader', { + name: i18n.translate('indexPatternManagement.labelTemplate.labelHeader', { defaultMessage: 'Label Template', }), }, { field: 'output', - name: i18n.translate('common.ui.fieldEditor.labelTemplate.outputHeader', { + name: i18n.translate('indexPatternManagement.labelTemplate.outputHeader', { defaultMessage: 'Output', }), render: (value: LabelTemplateExampleItem['output']) => { diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/url.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/url.test.tsx similarity index 94% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/url.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/url.test.tsx index 4d09da84edfb6..a1a1655949432 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/url.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/url.test.tsx @@ -46,10 +46,6 @@ const formatParams = { const onChange = jest.fn(); const onError = jest.fn(); -jest.mock('ui/chrome', () => ({ - getBasePath: () => 'http://localhost/', -})); - describe('UrlFormatEditor', () => { it('should have a formatId', () => { expect(UrlFormatEditor.formatId).toEqual('url'); @@ -58,7 +54,6 @@ describe('UrlFormatEditor', () => { it('should render normally', async () => { const component = shallow( { it('should render url template help', async () => { const component = shallow( { it('should render label template help', async () => { const component = shallow( { it('should render width and height fields if image', async () => { const component = shallow( ) { super(props); - this.iconPattern = `${props.basePath}/bundles/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/icons/{{value}}.png`; + this.iconPattern = `/plugins/indexPatternManagement/assets/icons/{{value}}.png`; + this.state = { ...this.state, sampleInputsByType: { @@ -146,7 +145,7 @@ export class UrlFormatEditor extends DefaultFormatEditor< + } > + } > + } > } @@ -220,9 +219,9 @@ export class UrlFormatEditor extends DefaultFormatEditor< + ) : ( - + ) } checked={!formatParams.openLinkInCurrentTab} @@ -236,14 +235,14 @@ export class UrlFormatEditor extends DefaultFormatEditor< } helpText={ @@ -263,14 +262,14 @@ export class UrlFormatEditor extends DefaultFormatEditor< } helpText={ diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/url_template_flyout.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/url_template_flyout.test.tsx similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/url_template_flyout.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/url_template_flyout.test.tsx diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/url_template_flyout.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/url_template_flyout.tsx similarity index 84% rename from src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/url_template_flyout.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/url_template_flyout.tsx index 8194bb731ad14..c1b144b0d9eac 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/editors/url/url_template_flyout.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/url/url_template_flyout.tsx @@ -31,13 +31,13 @@ export const UrlTemplateFlyout = ({ isVisible = false, onClose = () => {} }) =>

    {} }) => strongUrlTemplate: ( @@ -58,21 +58,21 @@ export const UrlTemplateFlyout = ({ isVisible = false, onClose = () => {} }) =>

  • value — 
  • rawValue — 
  • @@ -97,20 +97,20 @@ export const UrlTemplateFlyout = ({ isVisible = false, onClose = () => {} }) => columns={[ { field: 'input', - name: i18n.translate('common.ui.fieldEditor.urlTemplate.inputHeader', { + name: i18n.translate('indexPatternManagement.urlTemplate.inputHeader', { defaultMessage: 'Input', }), width: '160px', }, { field: 'template', - name: i18n.translate('common.ui.fieldEditor.urlTemplate.templateHeader', { + name: i18n.translate('indexPatternManagement.urlTemplate.templateHeader', { defaultMessage: 'Template', }), }, { field: 'output', - name: i18n.translate('common.ui.fieldEditor.urlTemplate.outputHeader', { + name: i18n.translate('indexPatternManagement.urlTemplate.outputHeader', { defaultMessage: 'Output', }), }, diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/field_format_editor.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/field_format_editor.test.tsx similarity index 98% rename from src/legacy/ui/public/field_editor/components/field_format_editor/field_format_editor.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/field_format_editor.test.tsx index f6e631c8b7ac0..c94d2e2f861dc 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/field_format_editor.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/field_format_editor.test.tsx @@ -37,6 +37,7 @@ const formatEditors = { ip: TestEditor, number: TestEditor, }, + getById: jest.fn(() => TestEditor), }; describe('FieldFormatEditor', () => { diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/field_format_editor.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/field_format_editor.tsx similarity index 93% rename from src/legacy/ui/public/field_editor/components/field_format_editor/field_format_editor.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/field_format_editor.tsx index 2de6dff5d251a..05aeba1ca107b 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/field_format_editor.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/field_format_editor.tsx @@ -49,13 +49,13 @@ export class FieldFormatEditor extends PureComponent< constructor(props: FieldFormatEditorProps) { super(props); this.state = { - EditorComponent: props.fieldFormatEditors.byFormatId[props.fieldFormatId], + EditorComponent: props.fieldFormatEditors.getById(props.fieldFormatId), }; } static getDerivedStateFromProps(nextProps: FieldFormatEditorProps) { return { - EditorComponent: nextProps.fieldFormatEditors.byFormatId[nextProps.fieldFormatId] || null, + EditorComponent: nextProps.fieldFormatEditors.getById(nextProps.fieldFormatId) || null, }; } diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/index.ts similarity index 96% rename from src/legacy/ui/public/field_editor/components/field_format_editor/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/index.ts index ccfc98b2d5882..83b36274f40e2 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/index.ts +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/index.ts @@ -18,3 +18,4 @@ */ export { FieldFormatEditor } from './field_format_editor'; +export * from './editors'; diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/samples/__snapshots__/samples.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/__snapshots__/samples.test.tsx.snap similarity index 96% rename from src/legacy/ui/public/field_editor/components/field_format_editor/samples/__snapshots__/samples.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/__snapshots__/samples.test.tsx.snap index 2883ffb6bc8a1..ce8c9e70433c8 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/samples/__snapshots__/samples.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/__snapshots__/samples.test.tsx.snap @@ -10,7 +10,7 @@ exports[`FormatEditorSamples should render normally 1`] = ` label={ } diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/samples/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/samples/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/index.ts diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/samples/_samples.scss b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/samples.scss similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/samples/_samples.scss rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/samples.scss diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/samples/samples.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/samples.test.tsx similarity index 100% rename from src/legacy/ui/public/field_editor/components/field_format_editor/samples/samples.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/samples.test.tsx diff --git a/src/legacy/ui/public/field_editor/components/field_format_editor/samples/samples.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/samples.tsx similarity index 90% rename from src/legacy/ui/public/field_editor/components/field_format_editor/samples/samples.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/samples.tsx index d63674bf4d205..f2814664c185d 100644 --- a/src/legacy/ui/public/field_editor/components/field_format_editor/samples/samples.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/samples/samples.tsx @@ -17,6 +17,8 @@ * under the License. */ +import './samples.scss'; + import React, { PureComponent } from 'react'; import { EuiBasicTable, EuiFormRow } from '@elastic/eui'; @@ -41,7 +43,7 @@ export class FormatEditorSamples extends PureComponent const columns = [ { field: 'input', - name: i18n.translate('common.ui.fieldEditor.samples.inputHeader', { + name: i18n.translate('indexPatternManagement.samples.inputHeader', { defaultMessage: 'Input', }), render: (input: {} | string) => { @@ -50,7 +52,7 @@ export class FormatEditorSamples extends PureComponent }, { field: 'output', - name: i18n.translate('common.ui.fieldEditor.samples.outputHeader', { + name: i18n.translate('indexPatternManagement.samples.outputHeader', { defaultMessage: 'Output', }), render: (output: string) => { @@ -72,7 +74,7 @@ export class FormatEditorSamples extends PureComponent return samples.length ? ( + } > diff --git a/src/legacy/ui/public/field_editor/components/scripting_call_outs/__snapshots__/disabled_call_out.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/__snapshots__/disabled_call_out.test.tsx.snap similarity index 87% rename from src/legacy/ui/public/field_editor/components/scripting_call_outs/__snapshots__/disabled_call_out.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/__snapshots__/disabled_call_out.test.tsx.snap index 87e1341b47355..648f68edcbb10 100644 --- a/src/legacy/ui/public/field_editor/components/scripting_call_outs/__snapshots__/disabled_call_out.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/__snapshots__/disabled_call_out.test.tsx.snap @@ -9,7 +9,7 @@ exports[`ScriptingDisabledCallOut should render normally 1`] = ` } @@ -17,7 +17,7 @@ exports[`ScriptingDisabledCallOut should render normally 1`] = `

    diff --git a/src/legacy/ui/public/field_editor/components/scripting_call_outs/__snapshots__/warning_call_out.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/__snapshots__/warning_call_out.test.tsx.snap similarity index 82% rename from src/legacy/ui/public/field_editor/components/scripting_call_outs/__snapshots__/warning_call_out.test.tsx.snap rename to src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/__snapshots__/warning_call_out.test.tsx.snap index b331c1e38eb34..c9b5c84939bc6 100644 --- a/src/legacy/ui/public/field_editor/components/scripting_call_outs/__snapshots__/warning_call_out.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/__snapshots__/warning_call_out.test.tsx.snap @@ -8,7 +8,7 @@ exports[`ScriptingWarningCallOut should render normally 1`] = ` title={ } @@ -16,7 +16,7 @@ exports[`ScriptingWarningCallOut should render normally 1`] = `

      @@ -37,7 +37,7 @@ exports[`ScriptingWarningCallOut should render normally 1`] = ` >   @@ -52,7 +52,7 @@ exports[`ScriptingWarningCallOut should render normally 1`] = `

    diff --git a/src/legacy/ui/public/field_editor/components/scripting_call_outs/disabled_call_out.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/disabled_call_out.test.tsx similarity index 100% rename from src/legacy/ui/public/field_editor/components/scripting_call_outs/disabled_call_out.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/disabled_call_out.test.tsx diff --git a/src/legacy/ui/public/field_editor/components/scripting_call_outs/disabled_call_out.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/disabled_call_out.tsx similarity index 93% rename from src/legacy/ui/public/field_editor/components/scripting_call_outs/disabled_call_out.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/disabled_call_out.tsx index 9abca813fe434..0bfec7a54a662 100644 --- a/src/legacy/ui/public/field_editor/components/scripting_call_outs/disabled_call_out.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/disabled_call_out.tsx @@ -29,7 +29,7 @@ export const ScriptingDisabledCallOut = ({ isVisible = false }) => { @@ -39,7 +39,7 @@ export const ScriptingDisabledCallOut = ({ isVisible = false }) => { >

    diff --git a/src/legacy/ui/public/field_editor/components/scripting_call_outs/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/scripting_call_outs/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/index.ts diff --git a/src/legacy/ui/public/field_editor/components/scripting_call_outs/warning_call_out.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.test.tsx similarity index 93% rename from src/legacy/ui/public/field_editor/components/scripting_call_outs/warning_call_out.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.test.tsx index 8568c2c79816b..d659ac83d7b79 100644 --- a/src/legacy/ui/public/field_editor/components/scripting_call_outs/warning_call_out.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.test.tsx @@ -22,7 +22,7 @@ import { shallow } from 'enzyme'; import { ScriptingWarningCallOut } from './warning_call_out'; // eslint-disable-next-line -import { docLinksServiceMock } from '../../../../../../core/public/doc_links/doc_links_service.mock'; +import { docLinksServiceMock } from '../../../../../../../core/public/doc_links/doc_links_service.mock'; describe('ScriptingWarningCallOut', () => { const docLinksScriptedFields = docLinksServiceMock.createStartContract().links.scriptedFields; diff --git a/src/legacy/ui/public/field_editor/components/scripting_call_outs/warning_call_out.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.tsx similarity index 88% rename from src/legacy/ui/public/field_editor/components/scripting_call_outs/warning_call_out.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.tsx index 7dac6681fa1ea..fed756f11f08b 100644 --- a/src/legacy/ui/public/field_editor/components/scripting_call_outs/warning_call_out.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_call_outs/warning_call_out.tsx @@ -38,7 +38,7 @@ export const ScriptingWarningCallOut = ({ } @@ -47,13 +47,13 @@ export const ScriptingWarningCallOut = ({ >

      @@ -63,7 +63,7 @@ export const ScriptingWarningCallOut = ({ scriptsInAggregation: (   @@ -75,7 +75,7 @@ export const ScriptingWarningCallOut = ({

    , "data-test-subj": "testTab", "id": "test", @@ -76,10 +94,28 @@ exports[`ScriptingHelpFlyout should render nothing if not visible 1`] = ` }, Object { "content": , "data-test-subj": "testTab", "id": "test", diff --git a/src/legacy/ui/public/field_editor/components/scripting_help/help_flyout.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.test.tsx similarity index 77% rename from src/legacy/ui/public/field_editor/components/scripting_help/help_flyout.test.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.test.tsx index 4106eb7b283ee..fa2d97be60000 100644 --- a/src/legacy/ui/public/field_editor/components/scripting_help/help_flyout.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.test.tsx @@ -21,20 +21,26 @@ import React from 'react'; import { shallow } from 'enzyme'; import { HttpStart } from 'src/core/public'; // eslint-disable-next-line -import { docLinksServiceMock } from '../../../../../../core/public/doc_links/doc_links_service.mock'; +import { docLinksServiceMock } from '../../../../../../../core/public/doc_links/doc_links_service.mock'; import { ScriptingHelpFlyout } from './help_flyout'; -import { IndexPattern } from '../../../../../../plugins/data/public'; +import { IndexPattern } from '../../../../../../data/public'; import { ExecuteScript } from '../../types'; +import { coreMock } from '../../../../../../../core/public/mocks'; +import { dataPluginMock } from '../../../../../../../plugins/data/public/mocks'; + jest.mock('./test_script', () => ({ TestScript: () => { return `

    mockTestScript
    `; }, })); +const { uiSettings } = coreMock.createStart(); +const { ui } = dataPluginMock.createStartContract(); + const indexPatternMock = {} as IndexPattern; describe('ScriptingHelpFlyout', () => { @@ -47,9 +53,10 @@ describe('ScriptingHelpFlyout', () => { lang="painless" executeScript={((() => {}) as unknown) as ExecuteScript} onClose={() => {}} - getHttpStart={() => (({} as unknown) as HttpStart)} - // docLinksScriptedFields={docLinksScriptedFields} + http={({} as unknown) as HttpStart} docLinksScriptedFields={{} as typeof docLinksScriptedFields} + uiSettings={uiSettings} + SearchBar={ui.SearchBar} /> ); @@ -64,8 +71,10 @@ describe('ScriptingHelpFlyout', () => { lang="painless" executeScript={((() => {}) as unknown) as ExecuteScript} onClose={() => {}} - getHttpStart={() => (({} as unknown) as HttpStart)} + http={({} as unknown) as HttpStart} docLinksScriptedFields={{} as typeof docLinksScriptedFields} + uiSettings={uiSettings} + SearchBar={ui.SearchBar} /> ); diff --git a/src/legacy/ui/public/field_editor/components/scripting_help/help_flyout.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.tsx similarity index 85% rename from src/legacy/ui/public/field_editor/components/scripting_help/help_flyout.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.tsx index 6f51379c796d4..b74d56e1c2878 100644 --- a/src/legacy/ui/public/field_editor/components/scripting_help/help_flyout.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/help_flyout.tsx @@ -18,15 +18,15 @@ */ import React from 'react'; -import { HttpStart, DocLinksStart } from 'src/core/public'; +import { HttpStart, DocLinksStart, IUiSettingsClient } from 'src/core/public'; import { EuiFlyout, EuiFlyoutBody, EuiTabbedContent } from '@elastic/eui'; import { ScriptingSyntax } from './scripting_syntax'; import { TestScript } from './test_script'; -import { IndexPattern } from '../../../../../../plugins/data/public'; import { ExecuteScript } from '../../types'; +import { IndexPattern, DataPublicPluginStart } from '../../../../../../data/public'; interface ScriptingHelpFlyoutProps { indexPattern: IndexPattern; @@ -36,8 +36,10 @@ interface ScriptingHelpFlyoutProps { executeScript: ExecuteScript; isVisible: boolean; onClose: () => void; - getHttpStart: () => HttpStart; + http: HttpStart; docLinksScriptedFields: DocLinksStart['links']['scriptedFields']; + uiSettings: IUiSettingsClient; + SearchBar: DataPublicPluginStart['ui']['SearchBar']; } export const ScriptingHelpFlyout: React.FC = ({ @@ -48,8 +50,10 @@ export const ScriptingHelpFlyout: React.FC = ({ name, script, executeScript, - getHttpStart, + http, docLinksScriptedFields, + uiSettings, + SearchBar, }) => { const tabs = [ { @@ -69,7 +73,9 @@ export const ScriptingHelpFlyout: React.FC = ({ name={name} script={script} executeScript={executeScript} - getHttpStart={getHttpStart} + http={http} + uiSettings={uiSettings} + SearchBar={SearchBar} /> ), }, diff --git a/src/legacy/ui/public/field_editor/components/scripting_help/index.ts b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/index.ts similarity index 100% rename from src/legacy/ui/public/field_editor/components/scripting_help/index.ts rename to src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/index.ts diff --git a/src/legacy/ui/public/field_editor/components/scripting_help/scripting_syntax.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/scripting_syntax.tsx similarity index 79% rename from src/legacy/ui/public/field_editor/components/scripting_help/scripting_syntax.tsx rename to src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/scripting_syntax.tsx index 8158c6881acf9..9a78c3695ea7c 100644 --- a/src/legacy/ui/public/field_editor/components/scripting_help/scripting_syntax.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/scripting_syntax.tsx @@ -33,18 +33,18 @@ export const ScriptingSyntax = ({ docLinksScriptedFields }: ScriptingSyntaxProps

    - +

    {' '} @@ -56,21 +56,21 @@ export const ScriptingSyntax = ({ docLinksScriptedFields }: ScriptingSyntaxProps

      @@ -80,7 +80,7 @@ export const ScriptingSyntax = ({ docLinksScriptedFields }: ScriptingSyntaxProps syntax: (   @@ -92,21 +92,21 @@ export const ScriptingSyntax = ({ docLinksScriptedFields }: ScriptingSyntaxProps

      @@ -118,26 +118,26 @@ export const ScriptingSyntax = ({ docLinksScriptedFields }: ScriptingSyntaxProps

    • @@ -145,21 +145,21 @@ export const ScriptingSyntax = ({ docLinksScriptedFields }: ScriptingSyntaxProps

    - +

    - + `; exports[`PageView component should display only body if not header props used 1`] = ` @@ -315,7 +315,7 @@ exports[`PageView component should display only body if not header props used 1` background: none; } - - + `; exports[`PageView component should display only header left 1`] = ` @@ -383,7 +383,7 @@ exports[`PageView component should display only header left 1`] = ` background: none; } - @@ -413,7 +413,7 @@ exports[`PageView component should display only header left 1`] = ` className="euiPageHeaderSection" data-test-subj="pageViewHeaderLeft" > - + @@ -424,7 +424,7 @@ exports[`PageView component should display only header left 1`] = ` page title - +
    @@ -457,7 +457,7 @@ exports[`PageView component should display only header left 1`] = `
    - + `; exports[`PageView component should display only header right but include an empty left side 1`] = ` @@ -481,7 +481,7 @@ exports[`PageView component should display only header right but include an empt background: none; } - @@ -552,7 +552,7 @@ exports[`PageView component should display only header right but include an empt
    - + `; exports[`PageView component should pass through EuiPage props 1`] = ` @@ -576,7 +576,7 @@ exports[`PageView component should pass through EuiPage props 1`] = ` background: none; } - - + `; exports[`PageView component should use custom element for header left and not wrap in EuiTitle 1`] = ` @@ -661,7 +661,7 @@ exports[`PageView component should use custom element for header left and not wr background: none; } - title here @@ -730,5 +730,5 @@ exports[`PageView component should use custom element for header left and not wr
    - + `; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/formatted_date_time.tsx b/x-pack/plugins/siem/public/common/components/endpoint/formatted_date_time.tsx similarity index 100% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/formatted_date_time.tsx rename to x-pack/plugins/siem/public/common/components/endpoint/formatted_date_time.tsx diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/components/link_to_app.test.tsx b/x-pack/plugins/siem/public/common/components/endpoint/link_to_app.test.tsx similarity index 92% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/components/link_to_app.test.tsx rename to x-pack/plugins/siem/public/common/components/endpoint/link_to_app.test.tsx index 2d4d1ca8a1b5b..0c3467d8f363c 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/components/link_to_app.test.tsx +++ b/x-pack/plugins/siem/public/common/components/endpoint/link_to_app.test.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { mount } from 'enzyme'; import { LinkToApp } from './link_to_app'; import { CoreStart } from 'kibana/public'; -import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public'; -import { coreMock } from '../../../../../../../../src/core/public/mocks'; +import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public'; +import { coreMock } from '../../../../../../../src/core/public/mocks'; type LinkToAppOnClickMock = jest.Mock< Return, @@ -31,13 +31,13 @@ describe('LinkToApp component', () => { }); it('should render with minimum input', () => { - expect(render(link)).toMatchSnapshot(); + expect(render({'link'})).toMatchSnapshot(); }); it('should render with href', () => { expect( render( - link + {'link'} ) ).toMatchSnapshot(); @@ -47,7 +47,7 @@ describe('LinkToApp component', () => { const spyOnClickHandler: LinkToAppOnClickMock = jest.fn(_event => {}); const renderResult = render( - link + {'link'} ); @@ -65,7 +65,7 @@ describe('LinkToApp component', () => { it('should navigate to App with specific path', () => { const renderResult = render( - link + {'link'} ); renderResult.find('EuiLink').simulate('click', { button: 0 }); @@ -84,7 +84,7 @@ describe('LinkToApp component', () => { color="primary" data-test-subj="my-test-subject" > - link + {'link'} ); expect(renderResult.find('EuiLink').props()).toEqual({ @@ -103,7 +103,7 @@ describe('LinkToApp component', () => { }); const renderResult = render( - link + {'link'} ); expect(() => renderResult.find('EuiLink').simulate('click')).toThrow(); @@ -116,21 +116,21 @@ describe('LinkToApp component', () => { }); const renderResult = render( - link + {'link'} ); renderResult.find('EuiLink').simulate('click', { button: 0 }); expect(fakeCoreStart.application.navigateToApp).not.toHaveBeenCalled(); }); it('should not to navigate if it was not left click', () => { - const renderResult = render(link); + const renderResult = render({'link'}); renderResult.find('EuiLink').simulate('click', { button: 1 }); expect(fakeCoreStart.application.navigateToApp).not.toHaveBeenCalled(); }); it('should not to navigate if it includes an anchor target', () => { const renderResult = render( - link + {'link'} ); renderResult.find('EuiLink').simulate('click', { button: 0 }); @@ -139,7 +139,7 @@ describe('LinkToApp component', () => { it('should not to navigate if if meta|alt|ctrl|shift keys are pressed', () => { const renderResult = render( - link + {'link'} ); const euiLink = renderResult.find('EuiLink'); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/components/link_to_app.tsx b/x-pack/plugins/siem/public/common/components/endpoint/link_to_app.tsx similarity index 83% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/components/link_to_app.tsx rename to x-pack/plugins/siem/public/common/components/endpoint/link_to_app.tsx index 6a3cf5e78f4bf..d6d8859b280b8 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/components/link_to_app.tsx +++ b/x-pack/plugins/siem/public/common/components/endpoint/link_to_app.tsx @@ -5,15 +5,15 @@ */ import React, { memo, MouseEventHandler } from 'react'; -import { EuiLink } from '@elastic/eui'; -import { EuiLinkProps } from '@elastic/eui'; -import { useNavigateToAppEventHandler } from '../hooks/use_navigate_to_app_event_handler'; +import { EuiLink, EuiLinkProps } from '@elastic/eui'; +import { useNavigateToAppEventHandler } from '../../hooks/endpoint/use_navigate_to_app_event_handler'; type LinkToAppProps = EuiLinkProps & { /** the app id - normally the value of the `id` in that plugin's `kibana.json` */ appId: string; /** Any app specific path (route) */ appPath?: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any appState?: any; onClick?: MouseEventHandler; }; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/components/page_view.test.tsx b/x-pack/plugins/siem/public/common/components/endpoint/page_view.test.tsx similarity index 80% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/components/page_view.test.tsx rename to x-pack/plugins/siem/public/common/components/endpoint/page_view.test.tsx index 4007477a088fa..2c14f66b64865 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/components/page_view.test.tsx +++ b/x-pack/plugins/siem/public/common/components/endpoint/page_view.test.tsx @@ -7,20 +7,20 @@ import React from 'react'; import { mount } from 'enzyme'; import { PageView } from './page_view'; -import { EuiThemeProvider } from '../../../../../../../legacy/common/eui_styled_components'; +import { EuiThemeProvider } from '../../../../../../legacy/common/eui_styled_components'; describe('PageView component', () => { const render = (ui: Parameters[0]) => mount(ui, { wrappingComponent: EuiThemeProvider }); it('should display only body if not header props used', () => { - expect(render(body content)).toMatchSnapshot(); + expect(render({'body content'})).toMatchSnapshot(); }); it('should display header left and right', () => { expect( render( - body content + {'body content'} ) ).toMatchSnapshot(); @@ -29,7 +29,7 @@ describe('PageView component', () => { expect( render( - body content + {'body content'} ) ).toMatchSnapshot(); @@ -38,7 +38,7 @@ describe('PageView component', () => { expect( render( - body content + {'body content'} ) ).toMatchSnapshot(); @@ -46,8 +46,8 @@ describe('PageView component', () => { it(`should use custom element for header left and not wrap in EuiTitle`, () => { expect( render( - title here

    }> - body content + {'title here'}

    }> + {'body content'}
    ) ).toMatchSnapshot(); @@ -56,7 +56,7 @@ describe('PageView component', () => { expect( render( - body content + {'body content'} ) ).toMatchSnapshot(); @@ -64,8 +64,8 @@ describe('PageView component', () => { it('should display body header custom element', () => { expect( render( - body header

    }> - body content + {'body header'}

    }> + {'body content'}
    ) ).toMatchSnapshot(); @@ -80,7 +80,7 @@ describe('PageView component', () => { aria-label="test-aria-label-here" data-test-subj="test-data-test-subj-here" > - body content + {'body content'}
    ) ).toMatchSnapshot(); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/components/page_view.tsx b/x-pack/plugins/siem/public/common/components/endpoint/page_view.tsx similarity index 96% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/components/page_view.tsx rename to x-pack/plugins/siem/public/common/components/endpoint/page_view.tsx index 6da352b68f890..b2b8078c3fe97 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/components/page_view.tsx +++ b/x-pack/plugins/siem/public/common/components/endpoint/page_view.tsx @@ -56,6 +56,8 @@ export const PageViewHeaderTitle = memo<{ children: ReactNode }>(({ children }) ); }); +PageViewHeaderTitle.displayName = 'PageViewHeaderTitle'; + /** * The `PageView` component used to render `bodyHeader` when it is set as a `string` * Can be used when wanting to customize the `bodyHeader` value but still use the standard @@ -70,6 +72,7 @@ export const PageViewBodyHeaderTitle = memo<{ children: ReactNode }>( ); } ); +PageViewBodyHeaderTitle.displayName = 'PageViewBodyHeaderTitle'; /** * Page View layout for use in Endpoint @@ -135,3 +138,5 @@ export const PageView = memo< ); }); + +PageView.displayName = 'PageView'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/route_capture.tsx b/x-pack/plugins/siem/public/common/components/endpoint/route_capture.tsx similarity index 77% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/route_capture.tsx rename to x-pack/plugins/siem/public/common/components/endpoint/route_capture.tsx index 28d2019b56888..7340d639070ab 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/route_capture.tsx +++ b/x-pack/plugins/siem/public/common/components/endpoint/route_capture.tsx @@ -7,15 +7,18 @@ import React, { memo } from 'react'; import { useLocation } from 'react-router-dom'; import { useDispatch } from 'react-redux'; -import { EndpointAppLocation, AppAction } from '../types'; +import { AppLocation } from '../../../../common/endpoint/types'; +import { AppAction } from '../../store/actions'; /** * This component should be used above all routes, but below the Provider. * It dispatches actions when the URL is changed. */ export const RouteCapture = memo(({ children }) => { - const location: EndpointAppLocation = useLocation(); + const location: AppLocation = useLocation(); const dispatch: (action: AppAction) => unknown = useDispatch(); dispatch({ type: 'userChangedUrl', payload: location }); return <>{children}; }); + +RouteCapture.displayName = 'RouteCapture'; diff --git a/x-pack/plugins/siem/public/common/components/navigation/breadcrumbs/index.ts b/x-pack/plugins/siem/public/common/components/navigation/breadcrumbs/index.ts index 16ae1b1e096ca..a202407b1270c 100644 --- a/x-pack/plugins/siem/public/common/components/navigation/breadcrumbs/index.ts +++ b/x-pack/plugins/siem/public/common/components/navigation/breadcrumbs/index.ts @@ -9,7 +9,7 @@ import { getOr, omit } from 'lodash/fp'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ChromeBreadcrumb } from '../../../../../../../../src/core/public'; import { APP_NAME } from '../../../../../common/constants'; -import { StartServices } from '../../../../plugin'; +import { StartServices } from '../../../../types'; import { getBreadcrumbs as getHostDetailsBreadcrumbs } from '../../../../hosts/pages/details/utils'; import { getBreadcrumbs as getIPDetailsBreadcrumbs } from '../../../../network/pages/ip_details'; import { getBreadcrumbs as getCaseDetailsBreadcrumbs } from '../../../../cases/pages/utils'; diff --git a/x-pack/plugins/siem/public/common/hooks/api/api.tsx b/x-pack/plugins/siem/public/common/hooks/api/api.tsx index 12863bffcf515..4c2cf031f781f 100644 --- a/x-pack/plugins/siem/public/common/hooks/api/api.tsx +++ b/x-pack/plugins/siem/public/common/hooks/api/api.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { StartServices } from '../../../plugin'; +import { StartServices } from '../../../types'; import { IndexPatternSavedObject, IndexPatternSavedObjectAttributes } from '../types'; /** diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hooks/use_navigate_by_router_event_handler.test.tsx b/x-pack/plugins/siem/public/common/hooks/endpoint/use_navigate_by_router_event_handler.test.tsx similarity index 97% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hooks/use_navigate_by_router_event_handler.test.tsx rename to x-pack/plugins/siem/public/common/hooks/endpoint/use_navigate_by_router_event_handler.test.tsx index b1f09617f0174..f7e433361118f 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/hooks/use_navigate_by_router_event_handler.test.tsx +++ b/x-pack/plugins/siem/public/common/hooks/endpoint/use_navigate_by_router_event_handler.test.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; -import { AppContextTestRender, createAppRootMockRenderer } from '../../mocks'; +import { AppContextTestRender, createAppRootMockRenderer } from '../../mock/endpoint'; import { useNavigateByRouterEventHandler } from './use_navigate_by_router_event_handler'; import { act, fireEvent, cleanup } from '@testing-library/react'; @@ -19,6 +19,7 @@ describe('useNavigateByRouterEventHandler hook', () => { let renderResult: ReturnType; let linkEle: HTMLAnchorElement; let clickHandlerSpy: ClickHandlerMock; + // eslint-disable-next-line react/display-name const Link = React.memo<{ routeTo: Parameters[0]; onClick?: Parameters[1]; @@ -26,7 +27,7 @@ describe('useNavigateByRouterEventHandler hook', () => { const onClickHandler = useNavigateByRouterEventHandler(routeTo, onClick); return (
    - mock link + {'mock link'} ); }); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hooks/use_navigate_by_router_event_handler.ts b/x-pack/plugins/siem/public/common/hooks/endpoint/use_navigate_by_router_event_handler.ts similarity index 100% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hooks/use_navigate_by_router_event_handler.ts rename to x-pack/plugins/siem/public/common/hooks/endpoint/use_navigate_by_router_event_handler.ts diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hooks/use_navigate_to_app_event_handler.ts b/x-pack/plugins/siem/public/common/hooks/endpoint/use_navigate_to_app_event_handler.ts similarity index 96% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hooks/use_navigate_to_app_event_handler.ts rename to x-pack/plugins/siem/public/common/hooks/endpoint/use_navigate_to_app_event_handler.ts index ec9a8691c481e..5fbfa5e0e58a8 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/hooks/use_navigate_to_app_event_handler.ts +++ b/x-pack/plugins/siem/public/common/hooks/endpoint/use_navigate_to_app_event_handler.ts @@ -6,7 +6,7 @@ import { MouseEventHandler, useCallback } from 'react'; import { ApplicationStart } from 'kibana/public'; -import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; +import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; type NavigateToAppHandlerProps = Parameters; type EventHandlerCallback = MouseEventHandler; diff --git a/x-pack/plugins/siem/public/common/lib/kibana/kibana_react.ts b/x-pack/plugins/siem/public/common/lib/kibana/kibana_react.ts index 42738c6bbe7d8..075f06084384b 100644 --- a/x-pack/plugins/siem/public/common/lib/kibana/kibana_react.ts +++ b/x-pack/plugins/siem/public/common/lib/kibana/kibana_react.ts @@ -12,7 +12,7 @@ import { useUiSetting$, withKibana, } from '../../../../../../../src/plugins/kibana_react/public'; -import { StartServices } from '../../../plugin'; +import { StartServices } from '../../../types'; export type KibanaContext = KibanaReactContextValue; export interface WithKibanaProps { diff --git a/x-pack/plugins/siem/public/common/lib/telemetry/index.ts b/x-pack/plugins/siem/public/common/lib/telemetry/index.ts index 0ed524c2ae548..e79ef0d128225 100644 --- a/x-pack/plugins/siem/public/common/lib/telemetry/index.ts +++ b/x-pack/plugins/siem/public/common/lib/telemetry/index.ts @@ -6,7 +6,7 @@ import { METRIC_TYPE, UiStatsMetricType } from '@kbn/analytics'; -import { SetupPlugins } from '../../../plugin'; +import { SetupPlugins } from '../../../types'; export { telemetryMiddleware } from './middleware'; export { METRIC_TYPE }; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/mocks/app_context_render.tsx b/x-pack/plugins/siem/public/common/mock/endpoint/app_context_render.tsx similarity index 54% rename from x-pack/plugins/endpoint/public/applications/endpoint/mocks/app_context_render.tsx rename to x-pack/plugins/siem/public/common/mock/endpoint/app_context_render.tsx index 639b1f7252d7f..73ac5fdf51529 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/mocks/app_context_render.tsx +++ b/x-pack/plugins/siem/public/common/mock/endpoint/app_context_render.tsx @@ -7,12 +7,20 @@ import React from 'react'; import { createMemoryHistory } from 'history'; import { render as reactRender, RenderOptions, RenderResult } from '@testing-library/react'; -import { appStoreFactory } from '../store'; +import { Store } from 'redux'; + import { coreMock } from '../../../../../../../src/core/public/mocks'; -import { EndpointPluginStartDependencies } from '../../../plugin'; +import { StartPlugins } from '../../../types'; import { depsStartMock } from './dependencies_start_mock'; -import { AppRootProvider } from '../view/app_root_provider'; -import { createSpyMiddleware, MiddlewareActionSpyHelper } from '../store/test_utils'; +import { MiddlewareActionSpyHelper, createSpyMiddleware } from '../../store/test_utils'; +import { apolloClientObservable } from '../test_providers'; +import { createStore, State, substateMiddlewareFactory } from '../../store'; +import { hostMiddlewareFactory } from '../../../endpoint_hosts/store/middleware'; +import { policyListMiddlewareFactory } from '../../../endpoint_policy/store/policy_list/middleware'; +import { policyDetailsMiddlewareFactory } from '../../../endpoint_policy/store/policy_details/middleware'; +import { alertMiddlewareFactory } from '../../../endpoint_alerts/store/middleware'; +import { AppRootProvider } from './app_root_provider'; +import { SUB_PLUGINS_REDUCER, mockGlobalState } from '..'; type UiRender = (ui: React.ReactElement, options?: RenderOptions) => RenderResult; @@ -20,15 +28,16 @@ type UiRender = (ui: React.ReactElement, options?: RenderOptions) => RenderResul * Mocked app root context renderer */ export interface AppContextTestRender { - store: ReturnType; + store: Store; history: ReturnType; coreStart: ReturnType; - depsStart: EndpointPluginStartDependencies; + depsStart: Pick; middlewareSpy: MiddlewareActionSpyHelper; /** * A wrapper around `AppRootContext` component. Uses the mocked modules as input to the * `AppRootContext` */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any AppWrapper: React.FC; /** * Renders the given UI within the created `AppWrapper` providing the given UI a mocked @@ -48,12 +57,28 @@ export const createAppRootMockRenderer = (): AppContextTestRender => { const coreStart = coreMock.createStart({ basePath: '/mock' }); const depsStart = depsStartMock(); const middlewareSpy = createSpyMiddleware(); - const store = appStoreFactory({ - coreStart, - depsStart, - additionalMiddleware: [middlewareSpy.actionSpyMiddleware], - }); - const AppWrapper: React.FunctionComponent<{ children: React.ReactElement }> = ({ children }) => ( + const state: State = mockGlobalState; + const store = createStore(state, SUB_PLUGINS_REDUCER, apolloClientObservable, [ + substateMiddlewareFactory( + globalState => globalState.hostList, + hostMiddlewareFactory(coreStart, depsStart) + ), + substateMiddlewareFactory( + globalState => globalState.policyList, + policyListMiddlewareFactory(coreStart, depsStart) + ), + substateMiddlewareFactory( + globalState => globalState.policyDetails, + policyDetailsMiddlewareFactory(coreStart, depsStart) + ), + substateMiddlewareFactory( + globalState => globalState.alertList, + alertMiddlewareFactory(coreStart, depsStart) + ), + middlewareSpy.actionSpyMiddleware, + ]); + + const AppWrapper: React.FC<{ children: React.ReactElement }> = ({ children }) => ( {children} @@ -61,7 +86,7 @@ export const createAppRootMockRenderer = (): AppContextTestRender => { const render: UiRender = (ui, options) => { // @ts-ignore return reactRender(ui, { - wrapper: AppWrapper, + wrapper: AppWrapper as React.ComponentType, ...options, }); }; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/app_root_provider.tsx b/x-pack/plugins/siem/public/common/mock/endpoint/app_root_provider.tsx similarity index 83% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/app_root_provider.tsx rename to x-pack/plugins/siem/public/common/mock/endpoint/app_root_provider.tsx index ca27831ee90b5..73c0f00573911 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/app_root_provider.tsx +++ b/x-pack/plugins/siem/public/common/mock/endpoint/app_root_provider.tsx @@ -9,22 +9,22 @@ import { Provider } from 'react-redux'; import { I18nProvider } from '@kbn/i18n/react'; import { Router } from 'react-router-dom'; import { History } from 'history'; -import { CoreStart } from 'kibana/public'; import { useObservable } from 'react-use'; +import { Store } from 'redux'; import { EuiThemeProvider } from '../../../../../../legacy/common/eui_styled_components'; import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public'; -import { appStoreFactory } from '../store'; -import { RouteCapture } from './route_capture'; -import { EndpointPluginStartDependencies } from '../../../plugin'; +import { RouteCapture } from '../../components/endpoint/route_capture'; +import { StartPlugins } from '../../../types'; +import { CoreStart } from '../../../../../../../src/core/public'; /** * Provides the context for rendering the endpoint app */ export const AppRootProvider = memo<{ - store: ReturnType; + store: Store; history: History; coreStart: CoreStart; - depsStart: EndpointPluginStartDependencies; + depsStart: Pick; children: ReactNode | ReactNode[]; }>( ({ @@ -56,3 +56,5 @@ export const AppRootProvider = memo<{ ); } ); + +AppRootProvider.displayName = 'AppRootProvider'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/mocks/dependencies_start_mock.ts b/x-pack/plugins/siem/public/common/mock/endpoint/dependencies_start_mock.ts similarity index 100% rename from x-pack/plugins/endpoint/public/applications/endpoint/mocks/dependencies_start_mock.ts rename to x-pack/plugins/siem/public/common/mock/endpoint/dependencies_start_mock.ts diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/mocks/index.ts b/x-pack/plugins/siem/public/common/mock/endpoint/index.ts similarity index 100% rename from x-pack/plugins/endpoint/public/applications/endpoint/mocks/index.ts rename to x-pack/plugins/siem/public/common/mock/endpoint/index.ts diff --git a/x-pack/plugins/siem/public/common/mock/global_state.ts b/x-pack/plugins/siem/public/common/mock/global_state.ts index e215aa7403ec9..63dd6dddfa9c5 100644 --- a/x-pack/plugins/siem/public/common/mock/global_state.ts +++ b/x-pack/plugins/siem/public/common/mock/global_state.ts @@ -25,6 +25,15 @@ import { } from '../../../common/constants'; import { networkModel } from '../../network/store'; import { TimelineType } from '../../../common/types/timeline'; +import { initialPolicyListState } from '../../endpoint_policy/store/policy_list/reducer'; +import { initialAlertListState } from '../../endpoint_alerts/store/reducer'; +import { initialPolicyDetailsState } from '../../endpoint_policy/store/policy_details/reducer'; +import { initialHostListState } from '../../endpoint_hosts/store/reducer'; + +const policyList = initialPolicyListState(); +const alertList = initialAlertListState(); +const policyDetails = initialPolicyDetailsState(); +const hostList = initialHostListState(); export const mockGlobalState: State = { app: { @@ -225,4 +234,8 @@ export const mockGlobalState: State = { }, }, }, + alertList, + hostList, + policyList, + policyDetails, }; diff --git a/x-pack/plugins/siem/public/common/mock/utils.ts b/x-pack/plugins/siem/public/common/mock/utils.ts index 2b54bf83c0a9b..68c52e493898f 100644 --- a/x-pack/plugins/siem/public/common/mock/utils.ts +++ b/x-pack/plugins/siem/public/common/mock/utils.ts @@ -7,6 +7,10 @@ import { hostsReducer } from '../../hosts/store'; import { networkReducer } from '../../network/store'; import { timelineReducer } from '../../timelines/store/timeline/reducer'; +import { hostListReducer } from '../../endpoint_hosts/store'; +import { alertListReducer } from '../../endpoint_alerts/store'; +import { policyListReducer } from '../../endpoint_policy/store/policy_list'; +import { policyDetailsReducer } from '../../endpoint_policy/store/policy_details'; interface Global extends NodeJS.Global { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -19,4 +23,8 @@ export const SUB_PLUGINS_REDUCER = { hosts: hostsReducer, network: networkReducer, timeline: timelineReducer, + hostList: hostListReducer, + alertList: alertListReducer, + policyList: policyListReducer, + policyDetails: policyDetailsReducer, }; diff --git a/x-pack/plugins/siem/public/common/store/actions.ts b/x-pack/plugins/siem/public/common/store/actions.ts index 8a6c292c4893a..a51b075dc7514 100644 --- a/x-pack/plugins/siem/public/common/store/actions.ts +++ b/x-pack/plugins/siem/public/common/store/actions.ts @@ -4,6 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ +import { HostAction } from '../../endpoint_hosts/store/action'; +import { AlertAction } from '../../endpoint_alerts/store/action'; +import { PolicyListAction } from '../../endpoint_policy/store/policy_list'; +import { PolicyDetailsAction } from '../../endpoint_policy/store/policy_details'; + export { appActions } from './app'; export { dragAndDropActions } from './drag_and_drop'; export { inputsActions } from './inputs'; +import { RoutingAction } from './routing'; + +export type AppAction = + | HostAction + | AlertAction + | RoutingAction + | PolicyListAction + | PolicyDetailsAction; diff --git a/x-pack/plugins/siem/public/common/store/index.ts b/x-pack/plugins/siem/public/common/store/index.ts index 8f5c4449308e2..57162eaae842a 100644 --- a/x-pack/plugins/siem/public/common/store/index.ts +++ b/x-pack/plugins/siem/public/common/store/index.ts @@ -9,5 +9,19 @@ export * from './reducer'; export * from './selectors'; import { createStore, getStore } from './store'; +import { SubstateMiddlewareFactory } from './types'; export { createStore, getStore }; + +export const substateMiddlewareFactory: SubstateMiddlewareFactory = (selector, middleware) => { + return api => { + const substateAPI = { + ...api, + // Return just the substate instead of global state. + getState() { + return selector(api.getState()); + }, + }; + return middleware(substateAPI); + }; +}; diff --git a/x-pack/plugins/siem/public/common/store/reducer.ts b/x-pack/plugins/siem/public/common/store/reducer.ts index da1dcd3ea9e73..570e851a3aa5e 100644 --- a/x-pack/plugins/siem/public/common/store/reducer.ts +++ b/x-pack/plugins/siem/public/common/store/reducer.ts @@ -13,8 +13,28 @@ import { createInitialInputsState, initialInputsState, inputsReducer, InputsStat import { HostsPluginState, HostsPluginReducer } from '../../hosts/store'; import { NetworkPluginState, NetworkPluginReducer } from '../../network/store'; import { TimelinePluginState, TimelinePluginReducer } from '../../timelines/store/timeline'; +import { + EndpointAlertsPluginState, + EndpointAlertsPluginReducer, +} from '../../endpoint_alerts/store'; +import { EndpointHostsPluginState, EndpointHostsPluginReducer } from '../../endpoint_hosts/store'; +import { + EndpointPolicyDetailsStatePluginState, + EndpointPolicyDetailsStatePluginReducer, +} from '../../endpoint_policy/store/policy_details'; +import { + EndpointPolicyListStatePluginState, + EndpointPolicyListStatePluginReducer, +} from '../../endpoint_policy/store/policy_list'; -export interface State extends HostsPluginState, NetworkPluginState, TimelinePluginState { +export interface State + extends HostsPluginState, + NetworkPluginState, + TimelinePluginState, + EndpointAlertsPluginState, + EndpointHostsPluginState, + EndpointPolicyDetailsStatePluginState, + EndpointPolicyListStatePluginState { app: AppState; dragAndDrop: DragAndDropState; inputs: InputsState; @@ -26,10 +46,20 @@ export const initialState: Pick = { inputs: initialInputsState, }; -type SubPluginsInitState = HostsPluginState & NetworkPluginState & TimelinePluginState; +type SubPluginsInitState = HostsPluginState & + NetworkPluginState & + TimelinePluginState & + EndpointAlertsPluginState & + EndpointHostsPluginState & + EndpointPolicyDetailsStatePluginState & + EndpointPolicyListStatePluginState; export type SubPluginsInitReducer = HostsPluginReducer & NetworkPluginReducer & - TimelinePluginReducer; + TimelinePluginReducer & + EndpointAlertsPluginReducer & + EndpointHostsPluginReducer & + EndpointPolicyDetailsStatePluginReducer & + EndpointPolicyListStatePluginReducer; export const createInitialState = (pluginsInitState: SubPluginsInitState): State => ({ ...initialState, diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/routing/action.ts b/x-pack/plugins/siem/public/common/store/routing/action.ts similarity index 68% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/routing/action.ts rename to x-pack/plugins/siem/public/common/store/routing/action.ts index fd72a02b33588..ae5e4eb32d476 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/routing/action.ts +++ b/x-pack/plugins/siem/public/common/store/routing/action.ts @@ -4,12 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Immutable } from '../../../../../common/types'; -import { EndpointAppLocation } from '../../types'; +import { AppLocation, Immutable } from '../../../../common/endpoint/types'; interface UserChangedUrl { readonly type: 'userChangedUrl'; - readonly payload: Immutable; + readonly payload: Immutable; } export type RoutingAction = UserChangedUrl; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/routing/index.ts b/x-pack/plugins/siem/public/common/store/routing/index.ts similarity index 100% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/routing/index.ts rename to x-pack/plugins/siem/public/common/store/routing/index.ts diff --git a/x-pack/plugins/siem/public/common/store/store.ts b/x-pack/plugins/siem/public/common/store/store.ts index ea7cb417fb24b..10ea61828ed36 100644 --- a/x-pack/plugins/siem/public/common/store/store.ts +++ b/x-pack/plugins/siem/public/common/store/store.ts @@ -4,7 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Action, applyMiddleware, compose, createStore as createReduxStore, Store } from 'redux'; +import { + Action, + applyMiddleware, + compose, + createStore as createReduxStore, + Store, + Middleware, + Dispatch, +} from 'redux'; import { createEpicMiddleware } from 'redux-observable'; import { Observable } from 'rxjs'; @@ -16,6 +24,8 @@ import { inputsSelectors } from './inputs'; import { State, SubPluginsInitReducer, createReducer } from './reducer'; import { createRootEpic } from './epic'; import { AppApolloClient } from '../lib/lib'; +import { AppAction } from './actions'; +import { Immutable } from '../../../common/endpoint/types'; type ComposeType = typeof compose; declare global { @@ -28,7 +38,8 @@ export { SubPluginsInitReducer }; export const createStore = ( state: State, pluginsReducer: SubPluginsInitReducer, - apolloClient: Observable + apolloClient: Observable, + additionalMiddleware?: Array>>> ): Store => { const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; @@ -49,7 +60,9 @@ export const createStore = ( store = createReduxStore( createReducer(pluginsReducer), state, - composeEnhancers(applyMiddleware(epicMiddleware, telemetryMiddleware)) + composeEnhancers( + applyMiddleware(epicMiddleware, telemetryMiddleware, ...(additionalMiddleware ?? [])) + ) ); epicMiddleware.run(createRootEpic()); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/test_utils.ts b/x-pack/plugins/siem/public/common/store/test_utils.ts similarity index 95% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/test_utils.ts rename to x-pack/plugins/siem/public/common/store/test_utils.ts index df17cf8cf6638..74d65ee5b589b 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/test_utils.ts +++ b/x-pack/plugins/siem/public/common/store/test_utils.ts @@ -5,12 +5,14 @@ */ import { Dispatch } from 'redux'; -import { AppAction, GlobalState, ImmutableMiddlewareFactory } from '../types'; +import { State } from './reducer'; +import { AppAction } from './actions'; +import { ImmutableMiddlewareFactory } from './types'; /** * Utilities for testing Redux middleware */ -export interface MiddlewareActionSpyHelper { +export interface MiddlewareActionSpyHelper { /** * Returns a promise that is fulfilled when the given action is dispatched or a timeout occurs. * The `action` will given to the promise `resolve` thus allowing for checks to be done. @@ -67,7 +69,7 @@ export interface MiddlewareActionSpyHelper(): MiddlewareActionSpyHelper => { type ActionWatcher = (action: A) => void; diff --git a/x-pack/plugins/siem/public/common/store/types.ts b/x-pack/plugins/siem/public/common/store/types.ts index 2c679ba41116e..0a1010ea87fca 100644 --- a/x-pack/plugins/siem/public/common/store/types.ts +++ b/x-pack/plugins/siem/public/common/store/types.ts @@ -4,6 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ +import { + Dispatch, + Action as ReduxAction, + AnyAction as ReduxAnyAction, + Action, + Middleware, +} from 'redux'; + +import { CoreStart } from '../../../../../../src/core/public'; +import { Immutable } from '../../../common/endpoint_alerts/types'; +import { State } from './reducer'; +import { StartPlugins } from '../../types'; +import { AppAction } from './actions'; + export type KueryFilterQueryKind = 'kuery' | 'lucene'; export interface KueryFilterQuery { @@ -15,3 +29,94 @@ export interface SerializedFilterQuery { kuery: KueryFilterQuery | null; serializedQuery: string; } + +/** + * like redux's `MiddlewareAPI` but `getState` returns an `Immutable` version of + * state and `dispatch` accepts `Immutable` versions of actions. + */ +export interface ImmutableMiddlewareAPI { + dispatch: Dispatch>; + getState(): Immutable; +} + +/** + * Like redux's `Middleware` but without the ability to mutate actions or state. + * Differences: + * * `getState` returns an `Immutable` version of state + * * `dispatch` accepts `Immutable` versions of actions + * * `action`s received will be `Immutable` + */ +export type ImmutableMiddleware = ( + api: ImmutableMiddlewareAPI +) => (next: Dispatch>) => (action: Immutable) => unknown; + +/** + * Takes application-standard middleware dependencies + * and returns a redux middleware. + * Middleware will be of the `ImmutableMiddleware` variety. Not able to directly + * change actions or state. + */ +export type ImmutableMiddlewareFactory = ( + coreStart: CoreStart, + depsStart: Pick +) => ImmutableMiddleware; + +/** + * Simple type for a redux selector. + */ +type Selector = (state: S) => R; + +/** + * Takes a selector and an `ImmutableMiddleware`. The + * middleware's version of `getState` will receive + * the result of the selector instead of the global state. + * + * This allows middleware to have knowledge of only a subsection of state. + * + * `selector` returns an `Immutable` version of the substate. + * `middleware` must be an `ImmutableMiddleware`. + * + * Returns a regular middleware, meant to be used with `applyMiddleware`. + */ +export type SubstateMiddlewareFactory = ( + selector: Selector>, + middleware: ImmutableMiddleware +) => Middleware<{}, State, Dispatch>>; + +/** + * Like `Reducer` from `redux` but it accepts immutable versions of `state` and `action`. + * Use this type for all Reducers in order to help enforce our pattern of immutable state. + */ +export type ImmutableReducer = ( + state: Immutable | undefined, + action: Immutable +) => State | Immutable; + +/** + * A alternate interface for `redux`'s `combineReducers`. Will work with the same underlying implementation, + * but will enforce that `Immutable` versions of `state` and `action` are received. + */ +export type ImmutableCombineReducers = ( + reducers: ImmutableReducersMapObject +) => ImmutableReducer; + +/** + * Like `redux`'s `ReducersMapObject` (which is used by `combineReducers`) but enforces that + * the `state` and `action` received are `Immutable` versions. + */ +type ImmutableReducersMapObject = { + [K in keyof S]: ImmutableReducer; +}; + +/** + * A better type for createStructuredSelector. This doesn't support the options object. + */ +export type CreateStructuredSelector = < + SelectorMap extends { [key: string]: (...args: never[]) => unknown } +>( + selectorMap: SelectorMap +) => ( + state: SelectorMap[keyof SelectorMap] extends (state: infer State) => unknown ? State : never +) => { + [Key in keyof SelectorMap]: ReturnType; +}; diff --git a/x-pack/plugins/endpoint/server/routes/alerts/details/lib/index.ts b/x-pack/plugins/siem/public/common/types.ts similarity index 72% rename from x-pack/plugins/endpoint/server/routes/alerts/details/lib/index.ts rename to x-pack/plugins/siem/public/common/types.ts index 20ae25f7aa849..f83bb71790884 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/details/lib/index.ts +++ b/x-pack/plugins/siem/public/common/types.ts @@ -4,4 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -export { AlertDetailsPagination } from './pagination'; +export interface ServerApiError { + statusCode: number; + error: string; + message: string; +} diff --git a/x-pack/plugins/endpoint/public/common/clone_http_fetch_query.test.ts b/x-pack/plugins/siem/public/common/utils/clone_http_fetch_query.test.ts similarity index 85% rename from x-pack/plugins/endpoint/public/common/clone_http_fetch_query.test.ts rename to x-pack/plugins/siem/public/common/utils/clone_http_fetch_query.test.ts index 9ac6b8b29f462..f70c2e8b63885 100644 --- a/x-pack/plugins/endpoint/public/common/clone_http_fetch_query.test.ts +++ b/x-pack/plugins/siem/public/common/utils/clone_http_fetch_query.test.ts @@ -5,8 +5,8 @@ */ import { cloneHttpFetchQuery } from './clone_http_fetch_query'; -import { Immutable } from '../../common/types'; -import { HttpFetchQuery } from '../../../../../src/core/public'; +import { HttpFetchQuery } from '../../../../../../src/core/public'; +import { Immutable } from '../../../common/endpoint/types'; describe('cloneHttpFetchQuery', () => { it('can clone complex queries', () => { diff --git a/x-pack/plugins/endpoint/public/common/clone_http_fetch_query.ts b/x-pack/plugins/siem/public/common/utils/clone_http_fetch_query.ts similarity index 82% rename from x-pack/plugins/endpoint/public/common/clone_http_fetch_query.ts rename to x-pack/plugins/siem/public/common/utils/clone_http_fetch_query.ts index fdf1d6603830a..bfa433dc9f9ac 100644 --- a/x-pack/plugins/endpoint/public/common/clone_http_fetch_query.ts +++ b/x-pack/plugins/siem/public/common/utils/clone_http_fetch_query.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Immutable } from '../../common/types'; +import { Immutable } from '../../../common/endpoint_alerts/types'; -import { HttpFetchQuery } from '../../../../../src/core/public'; +import { HttpFetchQuery } from '../../../../../../src/core/public'; export function cloneHttpFetchQuery(query: Immutable): HttpFetchQuery { const clone: HttpFetchQuery = {}; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/formatted_date.tsx b/x-pack/plugins/siem/public/endpoint_alerts/components/formatted_date.tsx similarity index 93% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/formatted_date.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/components/formatted_date.tsx index 731bd31b26cef..4b9bce4d42eb5 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/formatted_date.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/components/formatted_date.tsx @@ -20,3 +20,5 @@ export const FormattedDate = memo(({ timestamp }: { timestamp: number }) => { /> ); }); + +FormattedDate.displayName = 'FormattedDate'; diff --git a/x-pack/plugins/siem/public/endpoint_alerts/index.ts b/x-pack/plugins/siem/public/endpoint_alerts/index.ts new file mode 100644 index 0000000000000..a1f730e209dc2 --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_alerts/index.ts @@ -0,0 +1,39 @@ +/* + * 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 { SecuritySubPluginWithStore } from '../app/types'; +import { getEndpointAlertsRoutes } from './routes'; +import { Immutable } from '../../common/endpoint/types'; +import { initialAlertListState, alertListReducer } from './store/reducer'; +import { AlertListState } from '../../common/endpoint_alerts/types'; +import { alertMiddlewareFactory } from './store/middleware'; +import { substateMiddlewareFactory } from '../common/store'; +import { CoreStart } from '../../../../../src/core/public'; +import { StartPlugins } from '../types'; + +export class EndpointAlerts { + public setup() {} + + public start( + core: CoreStart, + plugins: StartPlugins + ): SecuritySubPluginWithStore<'alertList', Immutable> { + const { data, ingestManager } = plugins; + const middleware = substateMiddlewareFactory( + globalState => globalState.alertList, + alertMiddlewareFactory(core, { data, ingestManager }) + ); + + return { + routes: getEndpointAlertsRoutes(), + store: { + initialState: { alertList: initialAlertListState() }, + reducer: { alertList: alertListReducer }, + middleware, + }, + }; + } +} diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/models/index_pattern.ts b/x-pack/plugins/siem/public/endpoint_alerts/models/index_pattern.ts similarity index 78% rename from x-pack/plugins/endpoint/public/applications/endpoint/models/index_pattern.ts rename to x-pack/plugins/siem/public/endpoint_alerts/models/index_pattern.ts index 0cae054432f96..8daaa3fef7a29 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/models/index_pattern.ts +++ b/x-pack/plugins/siem/public/endpoint_alerts/models/index_pattern.ts @@ -5,8 +5,8 @@ */ import { all } from 'deepmerge'; -import { Immutable } from '../../../../common/types'; -import { IIndexPattern } from '../../../../../../../src/plugins/data/common'; +import { IIndexPattern } from 'src/plugins/data/public'; +import { Immutable } from '../../../common/endpoint_alerts/types'; /** * Model for the `IIndexPattern` interface exported by the `data` plugin. diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/index.ts b/x-pack/plugins/siem/public/endpoint_alerts/routes.tsx similarity index 50% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/index.ts rename to x-pack/plugins/siem/public/endpoint_alerts/routes.tsx index 8086acc41d2bd..60df7f5d47129 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/index.ts +++ b/x-pack/plugins/siem/public/endpoint_alerts/routes.tsx @@ -4,6 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -export { policyListReducer } from './reducer'; -export { PolicyListAction } from './action'; -export { policyListMiddlewareFactory } from './middleware'; +import React from 'react'; +import { Route } from 'react-router-dom'; + +import { AlertIndex } from './view'; + +export const getEndpointAlertsRoutes = () => [ + + + , +]; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/action.ts b/x-pack/plugins/siem/public/endpoint_alerts/store/action.ts similarity index 84% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/action.ts rename to x-pack/plugins/siem/public/endpoint_alerts/store/action.ts index 80b7fd87e13be..ae103edaa5a2b 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/action.ts +++ b/x-pack/plugins/siem/public/endpoint_alerts/store/action.ts @@ -5,8 +5,8 @@ */ import { IIndexPattern } from 'src/plugins/data/public'; -import { Immutable, AlertDetails } from '../../../../../common/types'; -import { AlertListData } from '../../types'; +// import { Immutable } from '../../../common/types'; +import { AlertDetails, AlertListData, Immutable } from '../../../common/endpoint_alerts/types'; interface ServerReturnedAlertsData { readonly type: 'serverReturnedAlertsData'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_details.test.ts b/x-pack/plugins/siem/public/endpoint_alerts/store/alert_details.test.ts similarity index 83% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_details.test.ts rename to x-pack/plugins/siem/public/endpoint_alerts/store/alert_details.test.ts index feac8944f476b..c6f3de73aa2b3 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_details.test.ts +++ b/x-pack/plugins/siem/public/endpoint_alerts/store/alert_details.test.ts @@ -5,19 +5,20 @@ */ import { Store, createStore, applyMiddleware } from 'redux'; -import { History } from 'history'; +import { createBrowserHistory, History } from 'history'; + +import { coreMock } from '../../../../../../src/core/public/mocks'; +import { AlertListState, Immutable } from '../../../common/endpoint_alerts/types'; +import { depsStartMock, DepsStartMock } from '../../common/mock/endpoint'; + import { alertListReducer } from './reducer'; -import { AlertListState } from '../../types'; + import { alertMiddlewareFactory } from './middleware'; -import { AppAction } from '../action'; -import { coreMock } from 'src/core/public/mocks'; -import { DepsStartMock, depsStartMock } from '../../mocks'; -import { createBrowserHistory } from 'history'; + import { mockAlertResultList } from './mock_alert_result_list'; -import { Immutable } from '../../../../../common/types'; describe('alert details tests', () => { - let store: Store, Immutable>; + let store: Store; let coreStart: ReturnType; let depsStart: DepsStartMock; let history: History; @@ -56,7 +57,7 @@ describe('alert details tests', () => { type: 'userChangedUrl', payload: { ...history.location, - pathname: '/alerts', + pathname: '/endpoint-alerts', search: '?selected_alert=q9ncfh4q9ctrmc90umcq4', }, }); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list.test.ts b/x-pack/plugins/siem/public/endpoint_alerts/store/alert_list.test.ts similarity index 85% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list.test.ts rename to x-pack/plugins/siem/public/endpoint_alerts/store/alert_list.test.ts index 84281813312e0..9acf22d4cefe2 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list.test.ts +++ b/x-pack/plugins/siem/public/endpoint_alerts/store/alert_list.test.ts @@ -5,20 +5,17 @@ */ import { Store, createStore, applyMiddleware } from 'redux'; -import { History } from 'history'; +import { History, createBrowserHistory } from 'history'; import { alertListReducer } from './reducer'; -import { AlertListState } from '../../types'; +import { AlertListState, AlertResultList, Immutable } from '../../../common/endpoint_alerts/types'; import { alertMiddlewareFactory } from './middleware'; -import { AppAction } from '../action'; import { coreMock } from 'src/core/public/mocks'; -import { DepsStartMock, depsStartMock } from '../../mocks'; -import { AlertResultList, Immutable } from '../../../../../common/types'; +import { DepsStartMock, depsStartMock } from '../../common/mock/endpoint'; import { isOnAlertPage } from './selectors'; -import { createBrowserHistory } from 'history'; import { mockAlertResultList } from './mock_alert_result_list'; describe('alert list tests', () => { - let store: Store, Immutable>; + let store: Store; let coreStart: ReturnType; let depsStart: DepsStartMock; let history: History; @@ -59,7 +56,7 @@ describe('alert list tests', () => { type: 'userChangedUrl', payload: { ...history.location, - pathname: '/alerts', + pathname: '/endpoint-alerts', }, }); }); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list_pagination.test.ts b/x-pack/plugins/siem/public/endpoint_alerts/store/alert_list_pagination.test.ts similarity index 80% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list_pagination.test.ts rename to x-pack/plugins/siem/public/endpoint_alerts/store/alert_list_pagination.test.ts index 4cc86e9c0449c..3ba7d830ccf4a 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/alert_list_pagination.test.ts +++ b/x-pack/plugins/siem/public/endpoint_alerts/store/alert_list_pagination.test.ts @@ -4,21 +4,28 @@ * you may not use this file except in compliance with the Elastic License. */ +/* + * 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 { Store, createStore, applyMiddleware } from 'redux'; -import { History } from 'history'; -import { alertListReducer } from './reducer'; -import { AlertListState, AlertingIndexUIQueryParams } from '../../types'; +import { History, createBrowserHistory } from 'history'; + +import { coreMock } from '../../../../../../src/core/public/mocks'; + +import { AlertingIndexUIQueryParams } from '../../../common/endpoint_alerts/types'; +import { DepsStartMock, depsStartMock } from '../../common/mock/endpoint'; + import { alertMiddlewareFactory } from './middleware'; -import { AppAction } from '../action'; -import { coreMock } from 'src/core/public/mocks'; -import { DepsStartMock, depsStartMock } from '../../mocks'; -import { createBrowserHistory } from 'history'; + +import { alertListReducer } from './reducer'; import { uiQueryParams } from './selectors'; -import { urlFromQueryParams } from '../../view/alerts/url_from_query_params'; -import { Immutable } from '../../../../../common/types'; +import { urlFromQueryParams } from '../view/url_from_query_params'; describe('alert list pagination', () => { - let store: Store, Immutable>; + let store: Store; let coreStart: ReturnType; let depsStart: DepsStartMock; let history: History; diff --git a/x-pack/plugins/siem/public/endpoint_alerts/store/index.ts b/x-pack/plugins/siem/public/endpoint_alerts/store/index.ts new file mode 100644 index 0000000000000..dd97d60c532b0 --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_alerts/store/index.ts @@ -0,0 +1,20 @@ +/* + * 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 { AlertListState, Immutable } from '../../../common/endpoint_alerts/types'; +import { ImmutableReducer } from '../../common/store'; +import { AppAction } from '../../common/store/actions'; + +export { alertListReducer } from './reducer'; +export { AlertAction } from './action'; + +export interface EndpointAlertsPluginState { + alertList: Immutable; +} + +export interface EndpointAlertsPluginReducer { + alertList: ImmutableReducer; +} diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/middleware.ts b/x-pack/plugins/siem/public/endpoint_alerts/store/middleware.ts similarity index 79% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/middleware.ts rename to x-pack/plugins/siem/public/endpoint_alerts/store/middleware.ts index 6bc728db99819..f217cfcdfb5a7 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/middleware.ts +++ b/x-pack/plugins/siem/public/endpoint_alerts/store/middleware.ts @@ -4,14 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -import { IIndexPattern } from 'src/plugins/data/public'; -import { AlertResultList, AlertDetails } from '../../../../../common/types'; -import { ImmutableMiddlewareFactory, AlertListState } from '../../types'; +import { IIndexPattern } from '../../../../../../src/plugins/data/public'; +import { + AlertResultList, + AlertDetails, + AlertListState, +} from '../../../common/endpoint_alerts/types'; +import { AlertConstants } from '../../../common/endpoint_alerts/alert_constants'; +import { ImmutableMiddlewareFactory } from '../../common/store'; +import { cloneHttpFetchQuery } from '../../common/utils/clone_http_fetch_query'; import { isOnAlertPage, apiQueryParams, hasSelectedAlert, uiQueryParams } from './selectors'; -import { cloneHttpFetchQuery } from '../../../../common/clone_http_fetch_query'; -import { AlertConstants } from '../../../../../common/alert_constants'; +import { Immutable } from '../../../common/endpoint/types'; -export const alertMiddlewareFactory: ImmutableMiddlewareFactory = ( +export const alertMiddlewareFactory: ImmutableMiddlewareFactory> = ( coreStart, depsStart ) => { diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/mock_alert_result_list.ts b/x-pack/plugins/siem/public/endpoint_alerts/store/mock_alert_result_list.ts similarity index 89% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/mock_alert_result_list.ts rename to x-pack/plugins/siem/public/endpoint_alerts/store/mock_alert_result_list.ts index 6a13e0f92471b..88bba2b7a2474 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/mock_alert_result_list.ts +++ b/x-pack/plugins/siem/public/endpoint_alerts/store/mock_alert_result_list.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AlertResultList, AlertDetails } from '../../../../../common/types'; -import { EndpointDocGenerator } from '../../../../../common/generate_data'; +import { EndpointDocGenerator } from '../../../common/endpoint/generate_data'; +import { AlertResultList, AlertDetails } from '../../../common/endpoint_alerts/types'; export const mockAlertResultList: (options?: { total?: number; @@ -30,7 +30,7 @@ export const mockAlertResultList: (options?: { alerts.push({ ...generator.generateAlert(new Date().getTime() + index * 1000), ...{ - id: 'xDUYMHABAJk0XnHd8rrd' + index, + id: `xDUYMHABAJk0XnHd8rrd${index}`, prev: null, next: null, }, diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/reducer.ts b/x-pack/plugins/siem/public/endpoint_alerts/store/reducer.ts similarity index 82% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/reducer.ts rename to x-pack/plugins/siem/public/endpoint_alerts/store/reducer.ts index 52b91dcae7d70..3e79ad4d1c614 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/reducer.ts +++ b/x-pack/plugins/siem/public/endpoint_alerts/store/reducer.ts @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AlertListState, ImmutableReducer } from '../../types'; -import { AppAction } from '../action'; -import { Immutable } from '../../../../../common/types'; +import { Immutable, AlertListState } from '../../../common/endpoint_alerts/types'; +import { ImmutableReducer } from '../../common/store'; +import { AppAction } from '../../common/store/actions'; -const initialState = (): Immutable => { +export const initialAlertListState = (): Immutable => { return { alerts: [], alertDetails: undefined, @@ -23,7 +23,7 @@ const initialState = (): Immutable => { }; export const alertListReducer: ImmutableReducer = ( - state = initialState(), + state = initialAlertListState(), action ) => { if (action.type === 'serverReturnedAlertsData') { diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/selectors.ts b/x-pack/plugins/siem/public/endpoint_alerts/store/selectors.ts similarity index 92% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/selectors.ts rename to x-pack/plugins/siem/public/endpoint_alerts/store/selectors.ts index cc362c3701956..0e9de70f7b415 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/selectors.ts +++ b/x-pack/plugins/siem/public/endpoint_alerts/store/selectors.ts @@ -4,15 +4,23 @@ * you may not use this file except in compliance with the Elastic License. */ +// eslint-disable-next-line import/no-nodejs-modules import querystring from 'querystring'; import { createSelector, createStructuredSelector as createStructuredSelectorWithBadType, } from 'reselect'; import { encode, decode } from 'rison-node'; -import { Query, TimeRange, Filter } from 'src/plugins/data/public'; -import { AlertListState, AlertingIndexUIQueryParams, CreateStructuredSelector } from '../../types'; -import { Immutable, AlertingIndexGetQueryInput } from '../../../../../common/types'; + +import { Query, TimeRange, Filter } from '../../../../../../src/plugins/data/public'; + +import { + Immutable, + AlertingIndexGetQueryInput, + AlertListState, + AlertingIndexUIQueryParams, +} from '../../../common/endpoint_alerts/types'; +import { CreateStructuredSelector } from '../../common/store'; const createStructuredSelector: CreateStructuredSelector = createStructuredSelectorWithBadType; @@ -36,7 +44,7 @@ export const alertListPagination = createStructuredSelector({ * Returns a boolean based on whether or not the user is on the alerts page */ export const isOnAlertPage = (state: Immutable): boolean => { - return state.location ? state.location.pathname === '/alerts' : false; + return state.location ? state.location.pathname === '/endpoint-alerts' : false; }; /** diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/alert_details.test.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/alert_details.test.tsx similarity index 87% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/alert_details.test.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/view/alert_details.test.tsx index e3639bf1cacbc..cb44176d6b4c3 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/alert_details.test.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/alert_details.test.tsx @@ -5,21 +5,22 @@ */ import * as reactTestingLibrary from '@testing-library/react'; -import { appStoreFactory } from '../../store'; -import { fireEvent } from '@testing-library/react'; import { MemoryHistory } from 'history'; -import { AppAction } from '../../types'; -import { mockAlertDetailsResult } from '../../store/alerts/mock_alert_result_list'; +import { Store } from 'redux'; + +import { mockAlertDetailsResult } from '../store/mock_alert_result_list'; import { alertPageTestRender } from './test_helpers/render_alert_page'; +import { AppAction } from '../../common/store/actions'; +import { State } from '../../common/store/reducer'; describe('when the alert details flyout is open', () => { let render: () => reactTestingLibrary.RenderResult; let history: MemoryHistory; - let store: ReturnType; + let store: Store; beforeEach(async () => { // Creates the render elements for the tests to use - ({ render, history, store } = alertPageTestRender); + ({ render, history, store } = alertPageTestRender()); }); describe('when the alerts details flyout is open', () => { beforeEach(() => { @@ -50,7 +51,7 @@ describe('when the alert details flyout is open', () => { 'alertDetailTakeActionDropdownButton' ); if (takeActionButton) { - fireEvent.click(takeActionButton); + reactTestingLibrary.fireEvent.click(takeActionButton); } }); it('should display the correct fields in the dropdown', async () => { @@ -64,7 +65,7 @@ describe('when the alert details flyout is open', () => { renderResult = render(); const overviewTab = await renderResult.findByTestId('overviewMetadata'); if (overviewTab) { - fireEvent.click(overviewTab); + reactTestingLibrary.fireEvent.click(overviewTab); } }); it('should render all accordion panels', async () => { diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/index.ts b/x-pack/plugins/siem/public/endpoint_alerts/view/details/index.ts similarity index 100% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/index.ts rename to x-pack/plugins/siem/public/endpoint_alerts/view/details/index.ts diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/file_accordion.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/file_accordion.tsx similarity index 60% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/file_accordion.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/file_accordion.tsx index 26f1985368465..1009bec0cec0e 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/file_accordion.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/file_accordion.tsx @@ -6,56 +6,62 @@ import React, { memo, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiAccordion, EuiDescriptionList } from '@elastic/eui'; -import { Immutable, AlertData } from '../../../../../../../common/types'; +import { Immutable, AlertData } from '../../../../../common/endpoint_alerts/types'; import { FormattedDate } from '../../formatted_date'; export const FileAccordion = memo(({ alertData }: { alertData: Immutable }) => { const columns = useMemo(() => { return [ { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.fileName', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.fileName', { defaultMessage: 'File Name', }), description: alertData.file.name, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.filePath', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.filePath', { defaultMessage: 'File Path', }), description: alertData.file.path, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.fileSize', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.fileSize', { defaultMessage: 'File Size', }), description: alertData.file.size, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.fileCreated', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.fileCreated', { defaultMessage: 'File Created', }), description: , }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.fileModified', { - defaultMessage: 'File Modified', - }), + title: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.fileModified', + { + defaultMessage: 'File Modified', + } + ), description: , }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.fileAccessed', { - defaultMessage: 'File Accessed', - }), + title: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.fileAccessed', + { + defaultMessage: 'File Accessed', + } + ), description: , }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.signer', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.signer', { defaultMessage: 'Signer', }), description: alertData.file.code_signature.subject_name, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.owner', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.owner', { defaultMessage: 'Owner', }), description: alertData.file.owner, @@ -67,7 +73,7 @@ export const FileAccordion = memo(({ alertData }: { alertData: Immutable ); }); + +FileAccordion.displayName = 'FileAccordion'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/general_accordion.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/general_accordion.tsx similarity index 64% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/general_accordion.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/general_accordion.tsx index 79cb61693056c..fc0d38188fd27 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/general_accordion.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/general_accordion.tsx @@ -6,44 +6,47 @@ import React, { memo, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiAccordion, EuiDescriptionList } from '@elastic/eui'; -import { Immutable, AlertData } from '../../../../../../../common/types'; +import { Immutable, AlertData } from '../../../../../common/endpoint_alerts/types'; import { FormattedDate } from '../../formatted_date'; export const GeneralAccordion = memo(({ alertData }: { alertData: Immutable }) => { const columns = useMemo(() => { return [ { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.alertType', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.alertType', { defaultMessage: 'Alert Type', }), description: alertData.event.category, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.eventType', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.eventType', { defaultMessage: 'Event Type', }), description: alertData.event.kind, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.status', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.status', { defaultMessage: 'Status', }), description: 'TODO', }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.dateCreated', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.dateCreated', { defaultMessage: 'Date Created', }), description: , }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.malwareScore', { - defaultMessage: 'MalwareScore', - }), + title: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.malwareScore', + { + defaultMessage: 'MalwareScore', + } + ), description: alertData.file.malware_classification.score, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.fileName', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.fileName', { defaultMessage: 'File Name', }), description: alertData.file.name, @@ -54,7 +57,7 @@ export const GeneralAccordion = memo(({ alertData }: { alertData: Immutable ); }); + +GeneralAccordion.displayName = 'GeneralAccordion'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/hash_accordion.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/hash_accordion.tsx similarity index 70% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/hash_accordion.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/hash_accordion.tsx index 4a2f7378a36ed..ae62bd80b73bc 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/hash_accordion.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/hash_accordion.tsx @@ -6,25 +6,25 @@ import React, { memo, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiAccordion, EuiDescriptionList } from '@elastic/eui'; -import { Immutable, AlertData } from '../../../../../../../common/types'; +import { Immutable, AlertData } from '../../../../../common/endpoint_alerts/types'; export const HashAccordion = memo(({ alertData }: { alertData: Immutable }) => { const columns = useMemo(() => { return [ { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.md5', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.md5', { defaultMessage: 'MD5', }), description: alertData.file.hash.md5, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.sha1', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.sha1', { defaultMessage: 'SHA1', }), description: alertData.file.hash.sha1, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.sha256', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.sha256', { defaultMessage: 'SHA256', }), description: alertData.file.hash.sha256, @@ -36,7 +36,7 @@ export const HashAccordion = memo(({ alertData }: { alertData: Immutable ); }); + +HashAccordion.displayName = 'HashAccordion'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/host_accordion.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/host_accordion.tsx similarity index 50% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/host_accordion.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/host_accordion.tsx index e332c96192fab..70723efd97b8c 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/host_accordion.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/host_accordion.tsx @@ -5,60 +5,75 @@ */ import React, { memo, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiAccordion, EuiDescriptionList } from '@elastic/eui'; -import { EuiHealth } from '@elastic/eui'; +import { EuiAccordion, EuiDescriptionList, EuiHealth } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { Immutable, AlertDetails } from '../../../../../../../common/types'; + +import { Immutable, AlertDetails } from '../../../../../common/endpoint_alerts/types'; export const HostAccordion = memo(({ alertData }: { alertData: Immutable }) => { const columns = useMemo(() => { return [ { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.hostNameCurrent', { - defaultMessage: 'Host Name (Current)', - }), + title: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.hostNameCurrent', + { + defaultMessage: 'Host Name (Current)', + } + ), description: alertData.state.host_metadata.host.hostname, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.hostNameOriginal', { - defaultMessage: 'Host Name (At time of alert)', - }), + title: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.hostNameOriginal', + { + defaultMessage: 'Host Name (At time of alert)', + } + ), description: alertData.host.hostname, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.hostIPCurrent', { - defaultMessage: 'Host IP (Current)', - }), + title: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.hostIPCurrent', + { + defaultMessage: 'Host IP (Current)', + } + ), description: alertData.state.host_metadata.host.ip.join(', '), }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.hostIPOriginal', { - defaultMessage: 'Host IP (At time of alert)', - }), + title: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.hostIPOriginal', + { + defaultMessage: 'Host IP (At time of alert)', + } + ), description: alertData.host.ip.join(', '), }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.currentStatus', { - defaultMessage: 'Current Status', - }), + title: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.currentStatus', + { + defaultMessage: 'Current Status', + } + ), description: ( {' '} ), }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.osCurrent', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.osCurrent', { defaultMessage: 'OS (Current)', }), description: alertData.state.host_metadata.host.os.name, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.osOriginal', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.osOriginal', { defaultMessage: 'OS (At time of alert)', }), description: alertData.host.os.name, @@ -70,7 +85,7 @@ export const HostAccordion = memo(({ alertData }: { alertData: Immutable ); }); + +HostAccordion.displayName = 'HostAccordion'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/index.ts b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/index.ts similarity index 100% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/index.ts rename to x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/index.ts diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/source_process_accordion.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/source_process_accordion.tsx similarity index 58% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/source_process_accordion.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/source_process_accordion.tsx index 538562bfbbc06..607327a49de1c 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/source_process_accordion.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/source_process_accordion.tsx @@ -6,73 +6,79 @@ import React, { memo, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiAccordion, EuiDescriptionList } from '@elastic/eui'; -import { Immutable, AlertData } from '../../../../../../../common/types'; +import { Immutable, AlertData } from '../../../../../common/endpoint_alerts/types'; export const SourceProcessAccordion = memo(({ alertData }: { alertData: Immutable }) => { const columns = useMemo(() => { return [ { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.processID', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.processID', { defaultMessage: 'Process ID', }), description: alertData.process.pid, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.processName', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.processName', { defaultMessage: 'Process Name', }), description: alertData.process.name, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.processPath', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.processPath', { defaultMessage: 'Process Path', }), description: alertData.process.executable, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.md5', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.md5', { defaultMessage: 'MD5', }), description: alertData.process.hash.md5, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.sha1', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.sha1', { defaultMessage: 'SHA1', }), description: alertData.process.hash.sha1, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.sha256', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.sha256', { defaultMessage: 'SHA256', }), description: alertData.process.hash.sha256, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.malwareScore', { - defaultMessage: 'MalwareScore', - }), + title: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.malwareScore', + { + defaultMessage: 'MalwareScore', + } + ), description: alertData.process.malware_classification?.score || '-', }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.parentProcessID', { - defaultMessage: 'Parent Process ID', - }), + title: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.parentProcessID', + { + defaultMessage: 'Parent Process ID', + } + ), description: alertData.process.parent?.pid || '-', }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.signer', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.signer', { defaultMessage: 'Signer', }), description: alertData.process.code_signature.subject_name, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.username', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.username', { defaultMessage: 'Username', }), description: alertData.process.token.user, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.domain', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.domain', { defaultMessage: 'Domain', }), description: alertData.process.token.domain, @@ -84,7 +90,7 @@ export const SourceProcessAccordion = memo(({ alertData }: { alertData: Immutabl ); }); + +SourceProcessAccordion.displayName = 'SourceProcessAccordion'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/source_process_token_accordion.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/source_process_token_accordion.tsx similarity index 68% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/source_process_token_accordion.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/source_process_token_accordion.tsx index 00755673d3f82..9be494d92a88d 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/metadata/source_process_token_accordion.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/details/metadata/source_process_token_accordion.tsx @@ -6,22 +6,25 @@ import React, { memo, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiAccordion, EuiDescriptionList } from '@elastic/eui'; -import { Immutable, AlertData } from '../../../../../../../common/types'; +import { Immutable, AlertData } from '../../../../../common/endpoint_alerts/types'; export const SourceProcessTokenAccordion = memo( ({ alertData }: { alertData: Immutable }) => { const columns = useMemo(() => { return [ { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.sid', { + title: i18n.translate('xpack.siem.endpoint.application.endpoint.alertDetails.sid', { defaultMessage: 'SID', }), description: alertData.process.token.sid, }, { - title: i18n.translate('xpack.endpoint.application.endpoint.alertDetails.integrityLevel', { - defaultMessage: 'Integrity Level', - }), + title: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.integrityLevel', + { + defaultMessage: 'Integrity Level', + } + ), description: alertData.process.token.integrity_level, }, ]; @@ -31,7 +34,7 @@ export const SourceProcessTokenAccordion = memo( { + const alertDetailsData = useAlertListSelector(selectors.selectedAlertDetailsData); + if (alertDetailsData === undefined) { + return null; + } + + const tabs: EuiTabbedContentTab[] = useMemo(() => { + return [ + { + id: 'overviewMetadata', + 'data-test-subj': 'overviewMetadata', + name: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.overview.tabs.overview', + { + defaultMessage: 'Overview', + } + ), + content: ( + <> + + + + ), + }, + { + id: 'overviewResolver', + 'data-test-subj': 'overviewResolverTab', + name: i18n.translate( + 'xpack.siem.endpoint.application.endpoint.alertDetails.overview.tabs.resolver', + { + defaultMessage: 'Resolver', + } + ), + content: ( + <> + + + + ), + }, + ]; + }, [alertDetailsData]); + + return ( + <> +
    + +

    + +

    +
    + + +

    + , + }} + /> +

    +
    + + + {'Endpoint Status: '} + + + + + + + + + + +
    + + + ); +}); + +AlertDetailsOverviewComponent.displayName = 'AlertDetailsOverview'; + +export const AlertDetailsOverview = styled(AlertDetailsOverviewComponent)` + height: 100%; + width: 100%; +`; + +AlertDetailsOverview.displayName = 'AlertDetailsOverview'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/overview/metadata_panel.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/details/overview/metadata_panel.tsx similarity index 92% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/overview/metadata_panel.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/view/details/overview/metadata_panel.tsx index 556d7bea2e310..75ddc58c8cad2 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/overview/metadata_panel.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/details/overview/metadata_panel.tsx @@ -7,7 +7,7 @@ import React, { memo } from 'react'; import { EuiSpacer } from '@elastic/eui'; import { useAlertListSelector } from '../../hooks/use_alerts_selector'; -import * as selectors from '../../../../store/alerts/selectors'; +import * as selectors from '../../../store/selectors'; import { GeneralAccordion, HostAccordion, @@ -38,3 +38,5 @@ export const MetadataPanel = memo(() => { ); }); + +MetadataPanel.displayName = 'MetadataPanel'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/overview/take_action_dropdown.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/details/overview/take_action_dropdown.tsx similarity index 83% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/overview/take_action_dropdown.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/view/details/overview/take_action_dropdown.tsx index 8d8468b4df4a3..847249125a5fa 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/details/overview/take_action_dropdown.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/details/overview/take_action_dropdown.tsx @@ -16,12 +16,14 @@ const TakeActionButton = memo(({ onClick }: { onClick: () => void }) => ( onClick={onClick} > )); +TakeActionButton.displayName = 'TakeActionButton'; + export const TakeActionDropdown = memo(() => { const [isDropdownOpen, setIsDropdownOpen] = useState(false); @@ -48,7 +50,7 @@ export const TakeActionDropdown = memo(() => { iconType="folderCheck" > @@ -61,7 +63,7 @@ export const TakeActionDropdown = memo(() => { iconType="listAdd" > @@ -69,3 +71,5 @@ export const TakeActionDropdown = memo(() => { ); }); + +TakeActionDropdown.displayName = 'TakeActionDropdown'; diff --git a/x-pack/plugins/siem/public/endpoint_alerts/view/formatted_date.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/formatted_date.tsx new file mode 100644 index 0000000000000..4b9bce4d42eb5 --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/formatted_date.tsx @@ -0,0 +1,24 @@ +/* + * 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 { FormattedDate as ReactIntlFormattedDate } from '@kbn/i18n/react'; + +export const FormattedDate = memo(({ timestamp }: { timestamp: number }) => { + const date = new Date(timestamp); + return ( + + ); +}); + +FormattedDate.displayName = 'FormattedDate'; diff --git a/x-pack/plugins/siem/public/endpoint_alerts/view/hooks/use_alerts_selector.ts b/x-pack/plugins/siem/public/endpoint_alerts/view/hooks/use_alerts_selector.ts new file mode 100644 index 0000000000000..726f6a453cb5d --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/hooks/use_alerts_selector.ts @@ -0,0 +1,17 @@ +/* + * 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 { useSelector } from 'react-redux'; +import { Immutable, AlertListState } from '../../../../common/endpoint_alerts/types'; +import { State } from '../../../common/store/reducer'; + +export function useAlertListSelector( + selector: ( + state: Immutable + ) => TSelected extends Immutable ? TSelected : never +) { + return useSelector((state: Immutable) => selector(state.alertList)); +} diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/index.test.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/index.test.tsx similarity index 92% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/index.test.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/view/index.test.tsx index 77e31d015fc03..6d7350f20d21f 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/index.test.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/index.test.tsx @@ -6,23 +6,24 @@ import * as reactTestingLibrary from '@testing-library/react'; import { IIndexPattern } from 'src/plugins/data/public'; -import { appStoreFactory } from '../../store'; -import { fireEvent, act } from '@testing-library/react'; import { MemoryHistory } from 'history'; -import { AppAction } from '../../types'; -import { mockAlertResultList } from '../../store/alerts/mock_alert_result_list'; -import { DepsStartMock } from '../../mocks'; +import { Store } from 'redux'; + +import { mockAlertResultList } from '../store/mock_alert_result_list'; import { alertPageTestRender } from './test_helpers/render_alert_page'; +import { DepsStartMock } from '../../common/mock/endpoint'; +import { State } from '../../common/store/reducer'; +import { AppAction } from '../../common/store/actions'; describe('when on the alerting page', () => { let render: () => reactTestingLibrary.RenderResult; let history: MemoryHistory; - let store: ReturnType; + let store: Store; let depsStart: DepsStartMock; beforeEach(async () => { // Creates the render elements for the tests to use - ({ render, history, store, depsStart } = alertPageTestRender); + ({ render, history, store, depsStart } = alertPageTestRender()); }); it('should show a data grid', async () => { await render().findByTestId('alertListGrid'); @@ -63,7 +64,7 @@ describe('when on the alerting page', () => { /** * This is the cell with the alert type, it has a link. */ - fireEvent.click(alertLinks[0]); + reactTestingLibrary.fireEvent.click(alertLinks[0]); }); it('should show the flyout', async () => { await renderResult.findByTestId('alertDetailFlyout'); @@ -92,7 +93,7 @@ describe('when on the alerting page', () => { */ const closeButton = await renderResult.findByTestId('euiFlyoutCloseButton'); if (closeButton) { - fireEvent.click(closeButton); + reactTestingLibrary.fireEvent.click(closeButton); } }); it('should no longer show the flyout', () => { @@ -125,14 +126,14 @@ describe('when on the alerting page', () => { const renderResult = render(); const paginationButton = await renderResult.findByTestId('tablePaginationPopoverButton'); if (paginationButton) { - act(() => { - fireEvent.click(paginationButton); + reactTestingLibrary.act(() => { + reactTestingLibrary.fireEvent.click(paginationButton); }); } const show10RowsButton = await renderResult.findByTestId('tablePagination-10-rows'); if (show10RowsButton) { - act(() => { - fireEvent.click(show10RowsButton); + reactTestingLibrary.act(() => { + reactTestingLibrary.fireEvent.click(show10RowsButton); }); } }); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/index.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/index.tsx similarity index 81% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/index.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/view/index.tsx index 6a6936c59a00e..e991080c9dc35 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/index.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/index.tsx @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { memo, useState, useMemo, useCallback } from 'react'; -import React from 'react'; +import React, { memo, useState, useMemo, useCallback } from 'react'; import { EuiDataGrid, EuiDataGridColumn, @@ -26,9 +25,9 @@ import { import { i18n } from '@kbn/i18n'; import { useHistory } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; +import { AlertData } from '../../../common/endpoint_alerts/types'; import { urlFromQueryParams } from './url_from_query_params'; -import { AlertData } from '../../../../../common/types'; -import * as selectors from '../../store/alerts/selectors'; +import * as selectors from '../store/selectors'; import { useAlertListSelector } from './hooks/use_alerts_selector'; import { AlertDetailsOverview } from './details'; import { FormattedDate } from './formatted_date'; @@ -41,49 +40,49 @@ export const AlertIndex = memo(() => { return [ { id: 'alert_type', - display: i18n.translate('xpack.endpoint.application.endpoint.alerts.alertType', { + display: i18n.translate('xpack.siem.endpoint.application.endpoint.alerts.alertType', { defaultMessage: 'Alert Type', }), }, { id: 'event_type', - display: i18n.translate('xpack.endpoint.application.endpoint.alerts.eventType', { + display: i18n.translate('xpack.siem.endpoint.application.endpoint.alerts.eventType', { defaultMessage: 'Event Type', }), }, { id: 'os', - display: i18n.translate('xpack.endpoint.application.endpoint.alerts.os', { + display: i18n.translate('xpack.siem.endpoint.application.endpoint.alerts.os', { defaultMessage: 'OS', }), }, { id: 'ip_address', - display: i18n.translate('xpack.endpoint.application.endpoint.alerts.ipAddress', { + display: i18n.translate('xpack.siem.endpoint.application.endpoint.alerts.ipAddress', { defaultMessage: 'IP Address', }), }, { id: 'host_name', - display: i18n.translate('xpack.endpoint.application.endpoint.alerts.hostName', { + display: i18n.translate('xpack.siem.endpoint.application.endpoint.alerts.hostName', { defaultMessage: 'Host Name', }), }, { id: 'timestamp', - display: i18n.translate('xpack.endpoint.application.endpoint.alerts.timestamp', { + display: i18n.translate('xpack.siem.endpoint.application.endpoint.alerts.timestamp', { defaultMessage: 'Timestamp', }), }, { id: 'archived', - display: i18n.translate('xpack.endpoint.application.endpoint.alerts.archived', { + display: i18n.translate('xpack.siem.endpoint.application.endpoint.alerts.archived', { defaultMessage: 'Archived', }), }, { id: 'malware_score', - display: i18n.translate('xpack.endpoint.application.endpoint.alerts.malwareScore', { + display: i18n.translate('xpack.siem.endpoint.application.endpoint.alerts.malwareScore', { defaultMessage: 'Malware Score', }), }, @@ -133,8 +132,8 @@ export const AlertIndex = memo(() => { ); }, [alertListData]); - const renderCellValue = useMemo(() => { - return ({ rowIndex, columnId }: { rowIndex: number; columnId: string }) => { + const renderCellValue = useCallback( + ({ rowIndex, columnId }: { rowIndex: number; columnId: string }) => { if (rowIndex > total) { return null; } @@ -149,7 +148,7 @@ export const AlertIndex = memo(() => { } > {i18n.translate( - 'xpack.endpoint.application.endpoint.alerts.alertType.maliciousFileDescription', + 'xpack.siem.endpoint.application.endpoint.alerts.alertType.maliciousFileDescription', { defaultMessage: 'Malicious File', } @@ -172,7 +171,7 @@ export const AlertIndex = memo(() => { return ( {i18n.translate( - 'xpack.endpoint.application.endpoint.alerts.alertDate.timestampInvalidLabel', + 'xpack.siem.endpoint.application.endpoint.alerts.alertDate.timestampInvalidLabel', { defaultMessage: 'invalid', } @@ -186,8 +185,9 @@ export const AlertIndex = memo(() => { return row.file.malware_classification.score; } return null; - }; - }, [total, alertListData, pageSize, history, queryParams, timestampForRows]); + }, + [total, alertListData, pageSize, history, queryParams, timestampForRows] + ); const pagination = useMemo(() => { return { @@ -216,7 +216,7 @@ export const AlertIndex = memo(() => {

    - {i18n.translate('xpack.endpoint.application.endpoint.alerts.detailsTitle', { + {i18n.translate('xpack.siem.endpoint.application.endpoint.alerts.detailsTitle', { defaultMessage: 'Alert Details', })}

    @@ -235,7 +235,7 @@ export const AlertIndex = memo(() => {

    @@ -260,3 +260,5 @@ export const AlertIndex = memo(() => { ); }); + +AlertIndex.displayName = 'AlertIndex'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/index_search_bar.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/index_search_bar.tsx similarity index 87% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/index_search_bar.tsx rename to x-pack/plugins/siem/public/endpoint_alerts/view/index_search_bar.tsx index 1ede06c086517..8fe6eaa665765 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/index_search_bar.tsx +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/index_search_bar.tsx @@ -4,17 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useMemo } from 'react'; -import { memo, useEffect, useCallback } from 'react'; +import React, { useMemo, memo, useEffect, useCallback } from 'react'; import { useHistory } from 'react-router-dom'; -import { encode, RisonValue } from 'rison-node'; import { Query, TimeRange } from 'src/plugins/data/public'; -import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; +import { encode, RisonValue } from 'rison-node'; + +import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; import { urlFromQueryParams } from './url_from_query_params'; import { useAlertListSelector } from './hooks/use_alerts_selector'; -import * as selectors from '../../store/alerts/selectors'; -import { EndpointPluginServices } from '../../../../plugin'; -import { clone } from '../../models/index_pattern'; +import * as selectors from '../store/selectors'; +import { StartServices } from '../../types'; +import { clone } from '../models/index_pattern'; export const AlertIndexSearchBar = memo(() => { const history = useHistory(); @@ -30,7 +30,7 @@ export const AlertIndexSearchBar = memo(() => { const searchBarDateRange = useAlertListSelector(selectors.searchBarDateRange); const searchBarFilters = useAlertListSelector(selectors.searchBarFilters); - const kibanaContext = useKibana(); + const kibanaContext = useKibana(); const { ui: { SearchBar }, query: { filterManager }, diff --git a/x-pack/plugins/siem/public/endpoint_alerts/view/resolver.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/resolver.tsx new file mode 100644 index 0000000000000..92213a8bd3925 --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/resolver.tsx @@ -0,0 +1,39 @@ +/* + * 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 from 'react'; +import styled from 'styled-components'; +import { Provider } from 'react-redux'; +import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; +import { ResolverEvent } from '../../../common/endpoint/types'; +import { StartServices } from '../../types'; +import { storeFactory } from '../../resolver/store'; +import { Resolver } from '../../resolver/view'; + +const AlertDetailResolverComponents = React.memo( + ({ className, selectedEvent }: { className?: string; selectedEvent?: ResolverEvent }) => { + const context = useKibana(); + const { store } = storeFactory(context); + + return ( +
    + + + +
    + ); + } +); + +AlertDetailResolverComponents.displayName = 'AlertDetailResolver'; + +export const AlertDetailResolver = styled(AlertDetailResolverComponents)` + height: 100%; + width: 100%; + display: flex; + flex-grow: 1; + min-height: calc(100vh - 505px); +`; diff --git a/x-pack/plugins/siem/public/endpoint_alerts/view/test_helpers/render_alert_page.tsx b/x-pack/plugins/siem/public/endpoint_alerts/view/test_helpers/render_alert_page.tsx new file mode 100644 index 0000000000000..f52d854d986ff --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/test_helpers/render_alert_page.tsx @@ -0,0 +1,63 @@ +/* + * 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 from 'react'; +import * as reactTestingLibrary from '@testing-library/react'; +import { Provider } from 'react-redux'; +import { I18nProvider } from '@kbn/i18n/react'; +import { createMemoryHistory } from 'history'; +import { Router } from 'react-router-dom'; + +import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public'; +import { AlertIndex } from '../index'; +import { RouteCapture } from '../../../common/components/endpoint/route_capture'; +import { depsStartMock } from '../../../common/mock/endpoint'; +import { createStore } from '../../../common/store'; +import { SUB_PLUGINS_REDUCER, mockGlobalState, apolloClientObservable } from '../../../common/mock'; + +export const alertPageTestRender = () => { + /** + * Create a 'history' instance that is only in-memory and causes no side effects to the testing environment. + */ + const history = createMemoryHistory(); + /** + * Create a store, with the middleware disabled. We don't want side effects being created by our code in this test. + */ + const store = createStore(mockGlobalState, SUB_PLUGINS_REDUCER, apolloClientObservable); + + const depsStart = depsStartMock(); + depsStart.data.ui.SearchBar.mockImplementation(() =>
    ); + + return { + store, + history, + depsStart, + + /** + * Render the test component, use this after setting up anything in `beforeEach`. + */ + render: () => { + /** + * Provide the store via `Provider`, and i18n APIs via `I18nProvider`. + * Use react-router via `Router`, passing our in-memory `history` instance. + * Use `RouteCapture` to emit url-change actions when the URL is changed. + * Finally, render the `AlertIndex` component which we are testing. + */ + return reactTestingLibrary.render( + + + + + + + + + + + + ); + }, + }; +}; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/url_from_query_params.ts b/x-pack/plugins/siem/public/endpoint_alerts/view/url_from_query_params.ts similarity index 74% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/url_from_query_params.ts rename to x-pack/plugins/siem/public/endpoint_alerts/view/url_from_query_params.ts index e037d000e6e8f..a8a37547a43e2 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/alerts/url_from_query_params.ts +++ b/x-pack/plugins/siem/public/endpoint_alerts/view/url_from_query_params.ts @@ -4,8 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ +// eslint-disable-next-line import/no-nodejs-modules import querystring from 'querystring'; -import { AlertingIndexUIQueryParams, EndpointAppLocation } from '../../types'; + +import { AlertingIndexUIQueryParams } from '../../../common/endpoint_alerts/types'; +import { AppLocation } from '../../../common/endpoint/types'; /** * Return a relative URL for `AlertingIndexUIQueryParams`. @@ -21,9 +24,7 @@ import { AlertingIndexUIQueryParams, EndpointAppLocation } from '../../types'; * // now use relativeURL in the 'href' of a link, the 'to' of a react-router-dom 'Link' or history.push, history.replace * ``` */ -export function urlFromQueryParams( - queryParams: AlertingIndexUIQueryParams -): Partial { +export function urlFromQueryParams(queryParams: AlertingIndexUIQueryParams): Partial { const search = querystring.stringify(queryParams); return { search, diff --git a/x-pack/plugins/siem/public/endpoint_hosts/index.ts b/x-pack/plugins/siem/public/endpoint_hosts/index.ts new file mode 100644 index 0000000000000..49d5fff98c92a --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_hosts/index.ts @@ -0,0 +1,38 @@ +/* + * 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 { SecuritySubPluginWithStore } from '../app/types'; +import { getEndpointHostsRoutes } from './routes'; +import { initialHostListState, hostListReducer } from './store/reducer'; +import { Immutable } from '../../common/endpoint/types'; +import { HostState } from './types'; +import { hostMiddlewareFactory } from './store/middleware'; +import { CoreStart } from '../../../../../src/core/public'; +import { StartPlugins } from '../types'; +import { substateMiddlewareFactory } from '../common/store'; + +export class EndpointHosts { + public setup() {} + + public start( + core: CoreStart, + plugins: StartPlugins + ): SecuritySubPluginWithStore<'hostList', Immutable> { + const { data, ingestManager } = plugins; + const middleware = substateMiddlewareFactory( + globalState => globalState.hostList, + hostMiddlewareFactory(core, { data, ingestManager }) + ); + return { + routes: getEndpointHostsRoutes(), + store: { + initialState: { hostList: initialHostListState() }, + reducer: { hostList: hostListReducer }, + middleware, + }, + }; + } +} diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/index.ts b/x-pack/plugins/siem/public/endpoint_hosts/routes.tsx similarity index 51% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/index.ts rename to x-pack/plugins/siem/public/endpoint_hosts/routes.tsx index 39f0f13d2daa2..b7e549dc4e5e8 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/index.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/routes.tsx @@ -4,6 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -export { policyDetailsMiddlewareFactory } from './middleware'; -export { PolicyDetailsAction } from './action'; -export { policyDetailsReducer } from './reducer'; +import React from 'react'; +import { Route } from 'react-router-dom'; + +import { HostList } from './view'; + +export const getEndpointHostsRoutes = () => [ + + + , +]; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts b/x-pack/plugins/siem/public/endpoint_hosts/store/action.ts similarity index 93% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts rename to x-pack/plugins/siem/public/endpoint_hosts/store/action.ts index ac10adcda0306..9b38d7ce5a23a 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/store/action.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ServerApiError } from '../../types'; -import { HostResultList, HostInfo, GetHostPolicyResponse } from '../../../../../common/types'; +import { HostResultList, HostInfo, GetHostPolicyResponse } from '../../../common/endpoint/types'; +import { ServerApiError } from '../../common/types'; interface ServerReturnedHostList { type: 'serverReturnedHostList'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/host_pagination.test.ts b/x-pack/plugins/siem/public/endpoint_hosts/store/host_pagination.test.ts similarity index 91% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/host_pagination.test.ts rename to x-pack/plugins/siem/public/endpoint_hosts/store/host_pagination.test.ts index d2e1985d055c6..d67f5af866540 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/host_pagination.test.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/store/host_pagination.test.ts @@ -5,25 +5,30 @@ */ import { CoreStart, HttpSetup } from 'kibana/public'; -import { DepsStartMock, depsStartMock } from '../../mocks'; -import { AppAction, HostState, HostIndexUIQueryParams } from '../../types'; -import { Immutable, HostResultList } from '../../../../../common/types'; import { History, createBrowserHistory } from 'history'; -import { hostMiddlewareFactory } from './middleware'; import { applyMiddleware, Store, createStore } from 'redux'; + +import { coreMock } from '../../../../../../src/core/public/mocks'; + +import { HostResultList } from '../../../common/endpoint/types'; +import { DepsStartMock, depsStartMock } from '../../common/mock/endpoint'; + +import { hostMiddlewareFactory } from './middleware'; + import { hostListReducer } from './reducer'; -import { coreMock } from 'src/core/public/mocks'; -import { urlFromQueryParams } from '../../view/hosts/url_from_query_params'; + import { uiQueryParams } from './selectors'; import { mockHostResultList } from './mock_host_result_list'; -import { MiddlewareActionSpyHelper, createSpyMiddleware } from '../test_utils'; +import { HostState, HostIndexUIQueryParams } from '../types'; +import { MiddlewareActionSpyHelper, createSpyMiddleware } from '../../common/store/test_utils'; +import { urlFromQueryParams } from '../view/url_from_query_params'; describe('host list pagination: ', () => { let fakeCoreStart: jest.Mocked; let depsStart: DepsStartMock; let fakeHttpServices: jest.Mocked; let history: History; - let store: Store, Immutable>; + let store: Store; let queryParams: () => HostIndexUIQueryParams; let waitForAction: MiddlewareActionSpyHelper['waitForAction']; let actionSpyMiddleware; @@ -62,7 +67,7 @@ describe('host list pagination: ', () => { type: 'userChangedUrl', payload: { ...history.location, - pathname: '/hosts', + pathname: '/endpoint-hosts', }, }); await waitForAction('serverReturnedHostList'); @@ -123,7 +128,7 @@ describe('host list pagination: ', () => { type: 'userChangedUrl', payload: { ...history.location, - pathname: '/hosts', + pathname: '/endpoint-hosts', search: '?foo=bar', }, }); @@ -135,7 +140,7 @@ describe('host list pagination: ', () => { type: 'userChangedUrl', payload: { ...history.location, - pathname: '/hosts', + pathname: '/endpoint-hosts', search: '?page_index=2&page_index=3&page_size=20&page_size=50', }, }); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.test.ts b/x-pack/plugins/siem/public/endpoint_hosts/store/index.test.ts similarity index 98% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.test.ts rename to x-pack/plugins/siem/public/endpoint_hosts/store/index.test.ts index f60a69a471684..8518c37fe3f5d 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.test.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/store/index.test.ts @@ -6,7 +6,7 @@ import { createStore, Dispatch, Store } from 'redux'; import { HostAction, hostListReducer } from './index'; -import { HostState } from '../../types'; +import { HostState } from '../types'; import { listData } from './selectors'; import { mockHostResultList } from './mock_host_result_list'; diff --git a/x-pack/plugins/siem/public/endpoint_hosts/store/index.ts b/x-pack/plugins/siem/public/endpoint_hosts/store/index.ts new file mode 100644 index 0000000000000..eafea5b9c7404 --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_hosts/store/index.ts @@ -0,0 +1,22 @@ +/* + * 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 { HostState } from '../types'; +import { ImmutableReducer } from '../../common/store'; +import { AppAction } from '../../common/store/actions'; +import { Immutable } from '../../../common/endpoint/types'; + +export { hostListReducer } from './reducer'; +export { HostAction } from './action'; +export { hostMiddlewareFactory } from './middleware'; + +export interface EndpointHostsPluginState { + hostList: Immutable; +} + +export interface EndpointHostsPluginReducer { + hostList: ImmutableReducer; +} diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts b/x-pack/plugins/siem/public/endpoint_hosts/store/middleware.test.ts similarity index 86% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts rename to x-pack/plugins/siem/public/endpoint_hosts/store/middleware.test.ts index 2064c76f7dfb5..6c9e3dd41907f 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/store/middleware.test.ts @@ -5,16 +5,18 @@ */ import { CoreStart, HttpSetup } from 'kibana/public'; import { applyMiddleware, createStore, Store } from 'redux'; -import { coreMock } from '../../../../../../../../src/core/public/mocks'; +import { coreMock } from '../../../../../../src/core/public/mocks'; import { History, createBrowserHistory } from 'history'; import { hostListReducer, hostMiddlewareFactory } from './index'; -import { HostResultList, Immutable } from '../../../../../common/types'; -import { HostState } from '../../types'; -import { AppAction } from '../action'; -import { listData } from './selectors'; -import { DepsStartMock, depsStartMock } from '../../mocks'; + +import { DepsStartMock, depsStartMock } from '../../common/mock/endpoint'; + +import { createSpyMiddleware, MiddlewareActionSpyHelper } from '../../common/store/test_utils'; +import { Immutable, HostResultList } from '../../../common/endpoint/types'; +import { AppAction } from '../../common/store/actions'; import { mockHostResultList } from './mock_host_result_list'; -import { createSpyMiddleware, MiddlewareActionSpyHelper } from '../test_utils'; +import { listData } from './selectors'; +import { HostState } from '../types'; describe('host list middleware', () => { let fakeCoreStart: jest.Mocked; @@ -53,7 +55,7 @@ describe('host list middleware', () => { type: 'userChangedUrl', payload: { ...history.location, - pathname: '/hosts', + pathname: '/endpoint-hosts', }, }); await waitForAction('serverReturnedHostList'); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.ts b/x-pack/plugins/siem/public/endpoint_hosts/store/middleware.ts similarity index 91% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.ts rename to x-pack/plugins/siem/public/endpoint_hosts/store/middleware.ts index 9a28423d6adc4..ce518db0ffc93 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/store/middleware.ts @@ -4,12 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HostResultList } from '../../../../../common/types'; +import { HostResultList, Immutable } from '../../../common/endpoint/types'; +import { ImmutableMiddlewareFactory } from '../../common/store'; import { isOnHostPage, hasSelectedHost, uiQueryParams, listData } from './selectors'; -import { HostState } from '../../types'; -import { ImmutableMiddlewareFactory } from '../../types'; +import { HostState } from '../types'; -export const hostMiddlewareFactory: ImmutableMiddlewareFactory = coreStart => { +export const hostMiddlewareFactory: ImmutableMiddlewareFactory> = coreStart => { return ({ getState, dispatch }) => next => async action => { next(action); const state = getState(); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/mock_host_result_list.ts b/x-pack/plugins/siem/public/endpoint_hosts/store/mock_host_result_list.ts similarity index 90% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/mock_host_result_list.ts rename to x-pack/plugins/siem/public/endpoint_hosts/store/mock_host_result_list.ts index 20aa973ffc93d..a2c410b5dbd65 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/mock_host_result_list.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/store/mock_host_result_list.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HostInfo, HostResultList, HostStatus } from '../../../../../common/types'; -import { EndpointDocGenerator } from '../../../../../common/generate_data'; +import { HostInfo, HostResultList, HostStatus } from '../../../common/endpoint/types'; +import { EndpointDocGenerator } from '../../../common/endpoint/generate_data'; export const mockHostResultList: (options?: { total?: number; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/reducer.ts b/x-pack/plugins/siem/public/endpoint_hosts/store/reducer.ts similarity index 92% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/reducer.ts rename to x-pack/plugins/siem/public/endpoint_hosts/store/reducer.ts index 18bc6b0bea3da..98f4a457a4598 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/reducer.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/store/reducer.ts @@ -4,12 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Immutable } from '../../../../../common/types'; -import { HostState, ImmutableReducer } from '../../types'; -import { AppAction } from '../action'; import { isOnHostPage, hasSelectedHost } from './selectors'; +import { HostState } from '../types'; +import { AppAction } from '../../common/store/actions'; +import { ImmutableReducer } from '../../common/store'; +import { Immutable } from '../../../common/endpoint/types'; -const initialState = (): HostState => { +export const initialHostListState = (): HostState => { return { hosts: [], pageSize: 10, @@ -28,7 +29,7 @@ const initialState = (): HostState => { }; export const hostListReducer: ImmutableReducer = ( - state = initialState(), + state = initialHostListState(), action ) => { if (action.type === 'serverReturnedHostList') { diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/selectors.ts b/x-pack/plugins/siem/public/endpoint_hosts/store/selectors.ts similarity index 95% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/selectors.ts rename to x-pack/plugins/siem/public/endpoint_hosts/store/selectors.ts index 457b449b060c4..a915480b1aa2a 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/selectors.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/store/selectors.ts @@ -3,6 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + +// eslint-disable-next-line import/no-nodejs-modules import querystring from 'querystring'; import { createSelector } from 'reselect'; import { @@ -10,8 +12,8 @@ import { HostPolicyResponseAppliedAction, HostPolicyResponseConfiguration, HostPolicyResponseActionStatus, -} from '../../../../../common/types'; -import { HostState, HostIndexUIQueryParams } from '../../types'; +} from '../../../common/endpoint/types'; +import { HostState, HostIndexUIQueryParams } from '../types'; const PAGE_SIZES = Object.freeze([10, 20, 50]); @@ -95,7 +97,7 @@ export const policyResponseLoading = (state: Immutable): boolean => export const policyResponseError = (state: Immutable) => state.policyResponseError; export const isOnHostPage = (state: Immutable) => - state.location ? state.location.pathname === '/hosts' : false; + state.location ? state.location.pathname === '/endpoint-hosts' : false; export const uiQueryParams: ( state: Immutable diff --git a/x-pack/plugins/siem/public/endpoint_hosts/types.ts b/x-pack/plugins/siem/public/endpoint_hosts/types.ts new file mode 100644 index 0000000000000..421903cb6e1ab --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_hosts/types.ts @@ -0,0 +1,57 @@ +/* + * 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 { + HostInfo, + Immutable, + HostMetadata, + HostPolicyResponse, + AppLocation, +} from '../../common/endpoint/types'; +import { ServerApiError } from '../common/types'; + +export interface HostState { + /** list of host **/ + hosts: HostInfo[]; + /** number of items per page */ + pageSize: number; + /** which page to show */ + pageIndex: number; + /** total number of hosts returned */ + total: number; + /** list page is retrieving data */ + loading: boolean; + /** api error from retrieving host list */ + error?: ServerApiError; + /** details data for a specific host */ + details?: Immutable; + /** details page is retrieving data */ + detailsLoading: boolean; + /** api error from retrieving host details */ + detailsError?: ServerApiError; + /** Holds the Policy Response for the Host currently being displayed in the details */ + policyResponse?: HostPolicyResponse; + /** policyResponse is being retrieved */ + policyResponseLoading: boolean; + /** api error from retrieving the policy response */ + policyResponseError?: ServerApiError; + /** current location info */ + location?: Immutable; +} + +/** + * Query params on the host page parsed from the URL + */ +export interface HostIndexUIQueryParams { + /** Selected host id shows host details flyout */ + selected_host?: string; + /** How many items to show in list */ + page_size?: string; + /** Which page to show */ + page_index?: string; + /** show the policy response or host details */ + show?: string; +} diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/components/flyout_sub_header.tsx b/x-pack/plugins/siem/public/endpoint_hosts/view/details/components/flyout_sub_header.tsx similarity index 97% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/components/flyout_sub_header.tsx rename to x-pack/plugins/siem/public/endpoint_hosts/view/details/components/flyout_sub_header.tsx index 9abb54e8b1807..14bebfbdc88d9 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/components/flyout_sub_header.tsx +++ b/x-pack/plugins/siem/public/endpoint_hosts/view/details/components/flyout_sub_header.tsx @@ -74,3 +74,5 @@ export const FlyoutSubHeader = memo( ); } ); + +FlyoutSubHeader.displayName = 'FlyoutSubHeader'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/host_details.tsx b/x-pack/plugins/siem/public/endpoint_hosts/view/details/host_details.tsx similarity index 76% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/host_details.tsx rename to x-pack/plugins/siem/public/endpoint_hosts/view/details/host_details.tsx index 2ded0e4b3123d..eb265675d3a24 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/host_details.tsx +++ b/x-pack/plugins/siem/public/endpoint_hosts/view/details/host_details.tsx @@ -16,14 +16,14 @@ import { import React, { memo, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { HostMetadata } from '../../../../../../common/types'; -import { FormattedDateAndTime } from '../../formatted_date_time'; -import { LinkToApp } from '../../components/link_to_app'; +import { HostMetadata } from '../../../../common/endpoint/types'; import { useHostSelector, useHostLogsUrl } from '../hooks'; import { urlFromQueryParams } from '../url_from_query_params'; -import { policyResponseStatus, uiQueryParams } from '../../../store/hosts/selectors'; -import { useNavigateByRouterEventHandler } from '../../hooks/use_navigate_by_router_event_handler'; +import { policyResponseStatus, uiQueryParams } from '../../store/selectors'; import { POLICY_STATUS_TO_HEALTH_COLOR } from '../host_constants'; +import { FormattedDateAndTime } from '../../../common/components/endpoint/formatted_date_time'; +import { useNavigateByRouterEventHandler } from '../../../common/hooks/endpoint/use_navigate_by_router_event_handler'; +import { LinkToApp } from '../../../common/components/endpoint/link_to_app'; const HostIds = styled(EuiListGroupItem)` margin-top: 0; @@ -41,19 +41,19 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { const detailsResultsUpper = useMemo(() => { return [ { - title: i18n.translate('xpack.endpoint.host.details.os', { + title: i18n.translate('xpack.siem.endpoint.host.details.os', { defaultMessage: 'OS', }), description: details.host.os.full, }, { - title: i18n.translate('xpack.endpoint.host.details.lastSeen', { + title: i18n.translate('xpack.siem.endpoint.host.details.lastSeen', { defaultMessage: 'Last Seen', }), description: , }, { - title: i18n.translate('xpack.endpoint.host.details.alerts', { + title: i18n.translate('xpack.siem.endpoint.host.details.alerts', { defaultMessage: 'Alerts', }), description: '0', @@ -73,13 +73,13 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { const detailsResultsLower = useMemo(() => { return [ { - title: i18n.translate('xpack.endpoint.host.details.policy', { + title: i18n.translate('xpack.siem.endpoint.host.details.policy', { defaultMessage: 'Policy', }), description: details.endpoint.policy.id, }, { - title: i18n.translate('xpack.endpoint.host.details.policyStatus', { + title: i18n.translate('xpack.siem.endpoint.host.details.policyStatus', { defaultMessage: 'Policy Status', }), description: ( @@ -90,11 +90,11 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} @@ -103,7 +103,7 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { ), }, { - title: i18n.translate('xpack.endpoint.host.details.ipAddress', { + title: i18n.translate('xpack.siem.endpoint.host.details.ipAddress', { defaultMessage: 'IP Address', }), description: ( @@ -115,13 +115,13 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { ), }, { - title: i18n.translate('xpack.endpoint.host.details.hostname', { + title: i18n.translate('xpack.siem.endpoint.host.details.hostname', { defaultMessage: 'Hostname', }), description: details.host.hostname, }, { - title: i18n.translate('xpack.endpoint.host.details.sensorVersion', { + title: i18n.translate('xpack.siem.endpoint.host.details.sensorVersion', { defaultMessage: 'Sensor Version', }), description: details.agent.version, @@ -159,7 +159,7 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { data-test-subj="hostDetailsLinkToLogs" > @@ -167,3 +167,5 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { ); }); + +HostDetails.displayName = 'HostDetails'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/index.tsx b/x-pack/plugins/siem/public/endpoint_hosts/view/details/index.tsx similarity index 86% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/index.tsx rename to x-pack/plugins/siem/public/endpoint_hosts/view/details/index.tsx index e4121503b4a96..9904306a76e9c 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/index.tsx +++ b/x-pack/plugins/siem/public/endpoint_hosts/view/details/index.tsx @@ -18,7 +18,7 @@ import { import { useHistory } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { useKibana } from '../../../../../../../../../src/plugins/kibana_react/public'; +import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; import { useHostSelector } from '../hooks'; import { urlFromQueryParams } from '../url_from_query_params'; import { @@ -32,12 +32,12 @@ import { policyResponseFailedOrWarningActionCount, policyResponseError, policyResponseLoading, -} from '../../../store/hosts/selectors'; +} from '../../store/selectors'; import { HostDetails } from './host_details'; import { PolicyResponse } from './policy_response'; -import { HostMetadata } from '../../../../../../common/types'; +import { HostMetadata } from '../../../../common/endpoint/types'; import { FlyoutSubHeader, FlyoutSubHeaderProps } from './components/flyout_sub_header'; -import { useNavigateByRouterEventHandler } from '../../hooks/use_navigate_by_router_event_handler'; +import { useNavigateByRouterEventHandler } from '../../../common/hooks/endpoint/use_navigate_by_router_event_handler'; export const HostDetailsFlyout = memo(() => { const history = useHistory(); @@ -58,13 +58,13 @@ export const HostDetailsFlyout = memo(() => { notifications.toasts.danger({ title: ( ), body: ( ), @@ -104,6 +104,8 @@ export const HostDetailsFlyout = memo(() => { ); }); +HostDetailsFlyout.displayName = 'HostDetailsFlyout'; + const PolicyResponseFlyoutPanel = memo<{ hostMeta: HostMetadata; }>(({ hostMeta }) => { @@ -124,10 +126,10 @@ const PolicyResponseFlyoutPanel = memo<{ const backToDetailsClickHandler = useNavigateByRouterEventHandler(detailsUri); const backButtonProp = useMemo((): FlyoutSubHeaderProps['backButton'] => { return { - title: i18n.translate('xpack.endpoint.host.policyResponse.backLinkTitle', { + title: i18n.translate('xpack.siem.endpoint.host.policyResponse.backLinkTitle', { defaultMessage: 'Endpoint Details', }), - href: '?' + detailsUri.search, + href: `?${detailsUri.search}`, onClick: backToDetailsClickHandler, }; }, [backToDetailsClickHandler, detailsUri.search]); @@ -142,7 +144,7 @@ const PolicyResponseFlyoutPanel = memo<{

    @@ -151,7 +153,7 @@ const PolicyResponseFlyoutPanel = memo<{ } @@ -169,3 +171,5 @@ const PolicyResponseFlyoutPanel = memo<{ ); }); + +PolicyResponseFlyoutPanel.displayName = 'PolicyResponseFlyoutPanel'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/policy_response.tsx b/x-pack/plugins/siem/public/endpoint_hosts/view/details/policy_response.tsx similarity index 95% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/policy_response.tsx rename to x-pack/plugins/siem/public/endpoint_hosts/view/details/policy_response.tsx index 24ae3e2b0f037..58ff9a17643bc 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/policy_response.tsx +++ b/x-pack/plugins/siem/public/endpoint_hosts/view/details/policy_response.tsx @@ -5,16 +5,21 @@ */ import React, { memo, useMemo } from 'react'; import styled from 'styled-components'; -import { EuiAccordion, EuiNotificationBadge, EuiHealth } from '@elastic/eui'; -import { EuiText } from '@elastic/eui'; -import { htmlIdGenerator } from '@elastic/eui'; import { - HostPolicyResponseAppliedAction, - HostPolicyResponseConfiguration, - Immutable, -} from '../../../../../../common/types'; + EuiAccordion, + EuiNotificationBadge, + EuiHealth, + EuiText, + htmlIdGenerator, +} from '@elastic/eui'; + import { formatResponse } from './policy_response_friendly_names'; import { POLICY_STATUS_TO_HEALTH_COLOR } from '../host_constants'; +import { + Immutable, + HostPolicyResponseAppliedAction, + HostPolicyResponseConfiguration, +} from '../../../../common/endpoint/types'; /** * Nested accordion in the policy response detailing any concerned @@ -110,6 +115,8 @@ const ResponseActions = memo( } ); +ResponseActions.displayName = 'ResponseActions'; + /** * A policy response is returned by the endpoint and shown in the host details after a user modifies a policy */ @@ -158,3 +165,5 @@ export const PolicyResponse = memo( ); } ); + +PolicyResponse.displayName = 'PolicyResponse'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/policy_response_friendly_names.ts b/x-pack/plugins/siem/public/endpoint_hosts/view/details/policy_response_friendly_names.ts similarity index 54% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/policy_response_friendly_names.ts rename to x-pack/plugins/siem/public/endpoint_hosts/view/details/policy_response_friendly_names.ts index 8eaacb31b4f87..2f05840567a57 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/policy_response_friendly_names.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/view/details/policy_response_friendly_names.ts @@ -9,163 +9,166 @@ import { i18n } from '@kbn/i18n'; const responseMap = new Map(); responseMap.set( 'success', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.success', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.success', { defaultMessage: 'Success', }) ); responseMap.set( 'warning', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.warning', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.warning', { defaultMessage: 'Warning', }) ); responseMap.set( 'failure', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.failed', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.failed', { defaultMessage: 'Failed', }) ); responseMap.set( 'logging', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.logging', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.logging', { defaultMessage: 'Logging', }) ); responseMap.set( 'streaming', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.streaming', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.streaming', { defaultMessage: 'Streaming', }) ); responseMap.set( 'malware', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.malware', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.malware', { defaultMessage: 'Malware', }) ); responseMap.set( 'events', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.events', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.events', { defaultMessage: 'Events', }) ); responseMap.set( 'configure_elasticsearch_connection', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.configureElasticSearchConnection', { - defaultMessage: 'Configure Elastic Search Connection', - }) + i18n.translate( + 'xpack.siem.endpoint.hostDetails.policyResponse.configureElasticSearchConnection', + { + defaultMessage: 'Configure Elastic Search Connection', + } + ) ); responseMap.set( 'configure_logging', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.configureLogging', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.configureLogging', { defaultMessage: 'Configure Logging', }) ); responseMap.set( 'configure_kernel', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.configureKernel', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.configureKernel', { defaultMessage: 'Configure Kernel', }) ); responseMap.set( 'configure_malware', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.configureMalware', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.configureMalware', { defaultMessage: 'Configure Malware', }) ); responseMap.set( 'connect_kernel', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.connectKernel', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.connectKernel', { defaultMessage: 'Connect Kernel', }) ); responseMap.set( 'detect_file_open_events', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.detectFileOpenEvents', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.detectFileOpenEvents', { defaultMessage: 'Detect File Open Events', }) ); responseMap.set( 'detect_file_write_events', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.detectFileWriteEvents', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.detectFileWriteEvents', { defaultMessage: 'Detect File Write Events', }) ); responseMap.set( 'detect_image_load_events', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.detectImageLoadEvents', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.detectImageLoadEvents', { defaultMessage: 'Detect Image Load Events', }) ); responseMap.set( 'detect_process_events', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.detectProcessEvents', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.detectProcessEvents', { defaultMessage: 'Detect Process Events', }) ); responseMap.set( 'download_global_artifacts', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.downloadGlobalArtifacts', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.downloadGlobalArtifacts', { defaultMessage: 'Download Global Artifacts', }) ); responseMap.set( 'load_config', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.loadConfig', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.loadConfig', { defaultMessage: 'Load Config', }) ); responseMap.set( 'load_malware_model', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.loadMalwareModel', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.loadMalwareModel', { defaultMessage: 'Load Malware Model', }) ); responseMap.set( 'read_elasticsearch_config', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.readElasticSearchConfig', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.readElasticSearchConfig', { defaultMessage: 'Read ElasticSearch Config', }) ); responseMap.set( 'read_events_config', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.readEventsConfig', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.readEventsConfig', { defaultMessage: 'Read Events Config', }) ); responseMap.set( 'read_kernel_config', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.readKernelConfig', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.readKernelConfig', { defaultMessage: 'Read Kernel Config', }) ); responseMap.set( 'read_logging_config', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.readLoggingConfig', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.readLoggingConfig', { defaultMessage: 'Read Logging Config', }) ); responseMap.set( 'read_malware_config', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.readMalwareConfig', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.readMalwareConfig', { defaultMessage: 'Read Malware Config', }) ); responseMap.set( 'workflow', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.workflow', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.workflow', { defaultMessage: 'Workflow', }) ); responseMap.set( 'download_model', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.downloadModel', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.downloadModel', { defaultMessage: 'Download Model', }) ); responseMap.set( 'ingest_events_config', - i18n.translate('xpack.endpoint.hostDetails.policyResponse.injestEventsConfig', { + i18n.translate('xpack.siem.endpoint.hostDetails.policyResponse.injestEventsConfig', { defaultMessage: 'Injest Events Config', }) ); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/hooks.ts b/x-pack/plugins/siem/public/endpoint_hosts/view/hooks.ts similarity index 78% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/hooks.ts rename to x-pack/plugins/siem/public/endpoint_hosts/view/hooks.ts index eb242f5c535f4..727f601dd7670 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/hooks.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/view/hooks.ts @@ -6,12 +6,13 @@ import { useSelector } from 'react-redux'; import { useMemo } from 'react'; -import { GlobalState, HostState } from '../../types'; -import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; +import { HostState } from '../types'; +import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; +import { State } from '../../common/store/reducer'; export function useHostSelector(selector: (state: HostState) => TSelected) { - return useSelector(function(state: GlobalState) { - return selector(state.hostList); + return useSelector(function(state: State) { + return selector(state.hostList as HostState); }); } diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/host_constants.ts b/x-pack/plugins/siem/public/endpoint_hosts/view/host_constants.ts similarity index 87% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/host_constants.ts rename to x-pack/plugins/siem/public/endpoint_hosts/view/host_constants.ts index 08b2608698a66..efad4e3a468d8 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/host_constants.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/view/host_constants.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HostPolicyResponseActionStatus, HostStatus } from '../../../../../common/types'; +import { HostStatus, HostPolicyResponseActionStatus } from '../../../common/endpoint/types'; export const HOST_STATUS_TO_HEALTH_COLOR = Object.freeze< { diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/index.test.tsx b/x-pack/plugins/siem/public/endpoint_hosts/view/index.test.tsx similarity index 96% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/index.test.tsx rename to x-pack/plugins/siem/public/endpoint_hosts/view/index.test.tsx index c3066dc41fa24..bb09323f547c7 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/index.test.tsx +++ b/x-pack/plugins/siem/public/endpoint_hosts/view/index.test.tsx @@ -6,16 +6,17 @@ import React from 'react'; import * as reactTestingLibrary from '@testing-library/react'; -import { fireEvent } from '@testing-library/react'; -import { AppAction } from '../../types'; + import { HostList } from './index'; +import { mockHostDetailsApiResult, mockHostResultList } from '../store/mock_host_result_list'; +import { AppContextTestRender, createAppRootMockRenderer } from '../../common/mock/endpoint'; import { - mockHostDetailsApiResult, - mockHostResultList, -} from '../../store/hosts/mock_host_result_list'; -import { AppContextTestRender, createAppRootMockRenderer } from '../../mocks'; -import { HostInfo, HostStatus, HostPolicyResponseActionStatus } from '../../../../../common/types'; -import { EndpointDocGenerator } from '../../../../../common/generate_data'; + HostInfo, + HostStatus, + HostPolicyResponseActionStatus, +} from '../../../common/endpoint/types'; +import { EndpointDocGenerator } from '../../../common/endpoint/generate_data'; +import { AppAction } from '../../common/store/actions'; describe('when on the hosts page', () => { const docGenerator = new EndpointDocGenerator(); @@ -209,7 +210,7 @@ describe('when on the hosts page', () => { const policyStatusLink = await renderResult.findByTestId('policyStatusValue'); const userChangedUrlChecker = middlewareSpy.waitForAction('userChangedUrl'); reactTestingLibrary.act(() => { - fireEvent.click(policyStatusLink); + reactTestingLibrary.fireEvent.click(policyStatusLink); }); const changedUrlAction = await userChangedUrlChecker; expect(changedUrlAction.payload.search).toEqual( @@ -282,7 +283,7 @@ describe('when on the hosts page', () => { const renderResult = render(); const linkToLogs = await renderResult.findByTestId('hostDetailsLinkToLogs'); reactTestingLibrary.act(() => { - fireEvent.click(linkToLogs); + reactTestingLibrary.fireEvent.click(linkToLogs); }); }); @@ -297,7 +298,7 @@ describe('when on the hosts page', () => { const policyStatusLink = await renderResult.findByTestId('policyStatusValue'); const userChangedUrlChecker = middlewareSpy.waitForAction('userChangedUrl'); reactTestingLibrary.act(() => { - fireEvent.click(policyStatusLink); + reactTestingLibrary.fireEvent.click(policyStatusLink); }); await userChangedUrlChecker; reactTestingLibrary.act(() => { @@ -385,7 +386,7 @@ describe('when on the hosts page', () => { const subHeaderBackLink = await renderResult.findByTestId('flyoutSubHeaderBackButton'); const userChangedUrlChecker = middlewareSpy.waitForAction('userChangedUrl'); reactTestingLibrary.act(() => { - fireEvent.click(subHeaderBackLink); + reactTestingLibrary.fireEvent.click(subHeaderBackLink); }); const changedUrlAction = await userChangedUrlChecker; expect(changedUrlAction.payload.search).toEqual( diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/index.tsx b/x-pack/plugins/siem/public/endpoint_hosts/view/index.tsx similarity index 76% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/index.tsx rename to x-pack/plugins/siem/public/endpoint_hosts/view/index.tsx index 638dd190dcbce..10a7a7ea0d445 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/index.tsx +++ b/x-pack/plugins/siem/public/endpoint_hosts/view/index.tsx @@ -8,6 +8,7 @@ import React, { useMemo, useCallback, memo } from 'react'; import { EuiHorizontalRule, EuiBasicTable, + EuiBasicTableColumn, EuiText, EuiLink, EuiHealth, @@ -17,16 +18,16 @@ import { useHistory } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { createStructuredSelector } from 'reselect'; -import { EuiBasicTableColumn } from '@elastic/eui'; + import { HostDetailsFlyout } from './details'; -import * as selectors from '../../store/hosts/selectors'; +import * as selectors from '../store/selectors'; import { useHostSelector } from './hooks'; -import { CreateStructuredSelector } from '../../types'; import { urlFromQueryParams } from './url_from_query_params'; -import { HostInfo, Immutable } from '../../../../../common/types'; -import { PageView } from '../components/page_view'; -import { useNavigateByRouterEventHandler } from '../hooks/use_navigate_by_router_event_handler'; import { HOST_STATUS_TO_HEALTH_COLOR } from './host_constants'; +import { useNavigateByRouterEventHandler } from '../../common/hooks/endpoint/use_navigate_by_router_event_handler'; +import { CreateStructuredSelector } from '../../common/store'; +import { Immutable, HostInfo } from '../../../common/endpoint/types'; +import { PageView } from '../../common/components/endpoint/page_view'; const HostLink = memo<{ name: string; @@ -47,6 +48,7 @@ const HostLink = memo<{
    ); }); +HostLink.displayName = 'HostLink'; const selector = (createStructuredSelector as CreateStructuredSelector)(selectors); export const HostList = () => { @@ -90,21 +92,22 @@ export const HostList = () => { return [ { field: 'metadata.host', - name: i18n.translate('xpack.endpoint.host.list.hostname', { + name: i18n.translate('xpack.siem.endpoint.host.list.hostname', { defaultMessage: 'Hostname', }), render: ({ hostname, id }: HostInfo['metadata']['host']) => { const newQueryParams = urlFromQueryParams({ ...queryParams, selected_host: id }); return ( - + ); }, }, { field: 'host_status', - name: i18n.translate('xpack.endpoint.host.list.hostStatus', { + name: i18n.translate('xpack.siem.endpoint.host.list.hostStatus', { defaultMessage: 'Host Status', }), + // eslint-disable-next-line react/display-name render: (hostStatus: HostInfo['host_status']) => { return ( { className="eui-textTruncate" > @@ -123,24 +126,26 @@ export const HostList = () => { }, { field: '', - name: i18n.translate('xpack.endpoint.host.list.policy', { + name: i18n.translate('xpack.siem.endpoint.host.list.policy', { defaultMessage: 'Policy', }), truncateText: true, + // eslint-disable-next-line react/display-name render: () => { - return Policy Name; + return {'Policy Name'}; }, }, { field: '', - name: i18n.translate('xpack.endpoint.host.list.policyStatus', { + name: i18n.translate('xpack.siem.endpoint.host.list.policyStatus', { defaultMessage: 'Policy Status', }), + // eslint-disable-next-line react/display-name render: () => { return ( @@ -149,7 +154,7 @@ export const HostList = () => { }, { field: '', - name: i18n.translate('xpack.endpoint.host.list.alerts', { + name: i18n.translate('xpack.siem.endpoint.host.list.alerts', { defaultMessage: 'Alerts', }), dataType: 'number', @@ -159,16 +164,17 @@ export const HostList = () => { }, { field: 'metadata.host.os.name', - name: i18n.translate('xpack.endpoint.host.list.os', { + name: i18n.translate('xpack.siem.endpoint.host.list.os', { defaultMessage: 'Operating System', }), truncateText: true, }, { field: 'metadata.host.ip', - name: i18n.translate('xpack.endpoint.host.list.ip', { + name: i18n.translate('xpack.siem.endpoint.host.list.ip', { defaultMessage: 'IP Address', }), + // eslint-disable-next-line react/display-name render: (ip: string[]) => { return ( @@ -183,13 +189,13 @@ export const HostList = () => { }, { field: 'metadata.agent.version', - name: i18n.translate('xpack.endpoint.host.list.endpointVersion', { + name: i18n.translate('xpack.siem.endpoint.host.list.endpointVersion', { defaultMessage: 'Version', }), }, { field: '', - name: i18n.translate('xpack.endpoint.host.list.lastActive', { + name: i18n.translate('xpack.siem.endpoint.host.list.lastActive', { defaultMessage: 'Last Active', }), dataType: 'date', @@ -204,12 +210,12 @@ export const HostList = () => { {hasSelectedHost && } diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/url_from_query_params.ts b/x-pack/plugins/siem/public/endpoint_hosts/view/url_from_query_params.ts similarity index 58% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/url_from_query_params.ts rename to x-pack/plugins/siem/public/endpoint_hosts/view/url_from_query_params.ts index 225aad8cab020..e3728d63aea7c 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/url_from_query_params.ts +++ b/x-pack/plugins/siem/public/endpoint_hosts/view/url_from_query_params.ts @@ -4,12 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +// eslint-disable-next-line import/no-nodejs-modules import querystring from 'querystring'; -import { EndpointAppLocation, HostIndexUIQueryParams } from '../../types'; -export function urlFromQueryParams( - queryParams: HostIndexUIQueryParams -): Partial { +import { HostIndexUIQueryParams } from '../types'; +import { AppLocation } from '../../../common/endpoint/types'; + +export function urlFromQueryParams(queryParams: HostIndexUIQueryParams): Partial { const search = querystring.stringify(queryParams); return { search, diff --git a/x-pack/plugins/siem/public/endpoint_policy/details.ts b/x-pack/plugins/siem/public/endpoint_policy/details.ts new file mode 100644 index 0000000000000..1128bcfac6ab2 --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_policy/details.ts @@ -0,0 +1,41 @@ +/* + * 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 { SecuritySubPluginWithStore } from '../app/types'; +import { getPolicyDetailsRoutes } from './routes'; +import { PolicyDetailsState } from './types'; +import { Immutable } from '../../common/endpoint/types'; +import { initialPolicyDetailsState, policyDetailsReducer } from './store/policy_details/reducer'; +import { policyDetailsMiddlewareFactory } from './store/policy_details/middleware'; +import { CoreStart } from '../../../../../src/core/public'; +import { StartPlugins } from '../types'; +import { substateMiddlewareFactory } from '../common/store'; + +export class EndpointPolicyDetails { + public setup() {} + + public start( + core: CoreStart, + plugins: StartPlugins + ): SecuritySubPluginWithStore<'policyDetails', Immutable> { + const { data, ingestManager } = plugins; + const middleware = substateMiddlewareFactory( + globalState => globalState.policyDetails, + policyDetailsMiddlewareFactory(core, { data, ingestManager }) + ); + + return { + routes: getPolicyDetailsRoutes(), + store: { + initialState: { + policyDetails: initialPolicyDetailsState(), + }, + reducer: { policyDetails: policyDetailsReducer }, + middleware, + }, + }; + } +} diff --git a/x-pack/plugins/siem/public/endpoint_policy/list.ts b/x-pack/plugins/siem/public/endpoint_policy/list.ts new file mode 100644 index 0000000000000..417931e64f44e --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_policy/list.ts @@ -0,0 +1,41 @@ +/* + * 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 { SecuritySubPluginWithStore } from '../app/types'; +import { getPolicyListRoutes } from './routes'; +import { PolicyListState } from './types'; +import { Immutable } from '../../common/endpoint/types'; +import { initialPolicyListState, policyListReducer } from './store/policy_list/reducer'; +import { policyListMiddlewareFactory } from './store/policy_list/middleware'; +import { CoreStart } from '../../../../../src/core/public'; +import { StartPlugins } from '../types'; +import { substateMiddlewareFactory } from '../common/store'; + +export class EndpointPolicyList { + public setup() {} + + public start( + core: CoreStart, + plugins: StartPlugins + ): SecuritySubPluginWithStore<'policyList', Immutable> { + const { data, ingestManager } = plugins; + const middleware = substateMiddlewareFactory( + globalState => globalState.policyList, + policyListMiddlewareFactory(core, { data, ingestManager }) + ); + + return { + routes: getPolicyListRoutes(), + store: { + initialState: { + policyList: initialPolicyListState(), + }, + reducer: { policyList: policyListReducer }, + middleware, + }, + }; + } +} diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/models/policy_details_config.ts b/x-pack/plugins/siem/public/endpoint_policy/models/policy_details_config.ts similarity index 97% rename from x-pack/plugins/endpoint/public/applications/endpoint/models/policy_details_config.ts rename to x-pack/plugins/siem/public/endpoint_policy/models/policy_details_config.ts index 3e56b1ff14d65..44be5ddcc003f 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/models/policy_details_config.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/models/policy_details_config.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UIPolicyConfig } from '../../../../common/types'; +import { UIPolicyConfig } from '../../../common/endpoint/types'; /** * A typed Object.entries() function where the keys and values are typed based on the given object diff --git a/x-pack/plugins/siem/public/endpoint_policy/routes.tsx b/x-pack/plugins/siem/public/endpoint_policy/routes.tsx new file mode 100644 index 0000000000000..be820f3f2c5dc --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_policy/routes.tsx @@ -0,0 +1,18 @@ +/* + * 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 from 'react'; +import { Route } from 'react-router-dom'; + +import { PolicyList, PolicyDetails } from './view'; + +export const getPolicyListRoutes = () => [ + , +]; + +export const getPolicyDetailsRoutes = () => [ + , +]; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/action.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/action.ts similarity index 86% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/action.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_details/action.ts index 4de3dac02a8ec..ceb62a9f9ace9 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/action.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/action.ts @@ -4,9 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { PolicyDetailsState, ServerApiError } from '../../types'; -import { GetAgentStatusResponse } from '../../../../../../ingest_manager/common/types/rest_spec'; -import { PolicyData, UIPolicyConfig } from '../../../../../common/types'; +import { GetAgentStatusResponse } from '../../../../../ingest_manager/common/types/rest_spec'; +import { PolicyData, UIPolicyConfig } from '../../../../common/endpoint/types'; +import { ServerApiError } from '../../../common/types'; +import { PolicyDetailsState } from '../../types'; interface ServerReturnedPolicyDetailsData { type: 'serverReturnedPolicyDetailsData'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/index.test.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/index.test.ts similarity index 97% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/index.test.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_details/index.test.ts index dd4e63c95ee8f..01a824ecc7b8e 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/index.test.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/index.test.ts @@ -9,7 +9,7 @@ import { createStore, Dispatch, Store } from 'redux'; import { policyDetailsReducer, PolicyDetailsAction } from './index'; import { policyConfig } from './selectors'; import { clone } from '../../models/policy_details_config'; -import { factory as policyConfigFactory } from '../../../../../common/models/policy_config'; +import { factory as policyConfigFactory } from '../../../../common/endpoint/models/policy_config'; describe('policy details: ', () => { let store: Store; diff --git a/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/index.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/index.ts new file mode 100644 index 0000000000000..88f090301cfa3 --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/index.ts @@ -0,0 +1,22 @@ +/* + * 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 { PolicyDetailsState } from '../../types'; +import { ImmutableReducer } from '../../../common/store'; +import { AppAction } from '../../../common/store/actions'; +import { Immutable } from '../../../../common/endpoint/types'; + +export { policyDetailsMiddlewareFactory } from './middleware'; +export { PolicyDetailsAction } from './action'; +export { policyDetailsReducer } from './reducer'; + +export interface EndpointPolicyDetailsStatePluginState { + policyDetails: Immutable; +} + +export interface EndpointPolicyDetailsStatePluginReducer { + policyDetails: ImmutableReducer; +} diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/middleware.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/middleware.ts similarity index 88% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/middleware.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_details/middleware.ts index d82273bfdb221..f908befe05aa3 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/middleware.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/middleware.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ImmutableMiddlewareFactory, PolicyDetailsState, UpdatePolicyResponse } from '../../types'; +import { PolicyDetailsState, UpdatePolicyResponse } from '../../types'; import { policyIdFromParams, isOnPolicyDetailsPage, @@ -16,10 +16,13 @@ import { sendGetFleetAgentStatusForConfig, sendPutDatasource, } from '../policy_list/services/ingest'; -import { NewPolicyData, PolicyData } from '../../../../../common/types'; -import { factory as policyConfigFactory } from '../../../../../common/models/policy_config'; +import { NewPolicyData, PolicyData, Immutable } from '../../../../common/endpoint/types'; +import { factory as policyConfigFactory } from '../../../../common/endpoint/models/policy_config'; +import { ImmutableMiddlewareFactory } from '../../../common/store'; -export const policyDetailsMiddlewareFactory: ImmutableMiddlewareFactory = coreStart => { +export const policyDetailsMiddlewareFactory: ImmutableMiddlewareFactory> = coreStart => { const http = coreStart.http; return ({ getState, dispatch }) => next => async action => { diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/reducer.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/reducer.ts similarity index 91% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/reducer.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_details/reducer.ts index 9778f23d083a2..ff441ba663cf7 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/reducer.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/reducer.ts @@ -3,13 +3,13 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - -import { AppAction } from '../action'; import { fullPolicy, isOnPolicyDetailsPage } from './selectors'; -import { PolicyDetailsState, ImmutableReducer } from '../../types'; -import { Immutable, PolicyConfig, UIPolicyConfig } from '../../../../../common/types'; +import { PolicyDetailsState } from '../../types'; +import { Immutable, PolicyConfig, UIPolicyConfig } from '../../../../common/endpoint/types'; +import { ImmutableReducer } from '../../../common/store'; +import { AppAction } from '../../../common/store/actions'; -const initialPolicyDetailsState = (): PolicyDetailsState => { +export const initialPolicyDetailsState = (): PolicyDetailsState => { return { policyItem: undefined, isLoading: false, diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/selectors.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/selectors.ts similarity index 97% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/selectors.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_details/selectors.ts index 8ab6f77dc7276..dfbbbf65ada20 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/selectors.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_details/selectors.ts @@ -11,8 +11,8 @@ import { NewPolicyData, PolicyConfig, UIPolicyConfig, -} from '../../../../../common/types'; -import { factory as policyConfigFactory } from '../../../../../common/models/policy_config'; +} from '../../../../common/endpoint/types'; +import { factory as policyConfigFactory } from '../../../../common/endpoint/models/policy_config'; /** Returns the policy details */ export const policyDetails = (state: Immutable) => state.policyItem; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/action.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/action.ts similarity index 84% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/action.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_list/action.ts index 4c379b7426461..bedbcdae3306f 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/action.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/action.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ServerApiError } from '../../types'; -import { PolicyData } from '../../../../../common/types'; +import { PolicyData } from '../../../../common/endpoint/types'; +import { ServerApiError } from '../../../common/types'; interface ServerReturnedPolicyListData { type: 'serverReturnedPolicyListData'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/index.test.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/index.test.ts similarity index 80% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/index.test.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_list/index.test.ts index 9912c9a81e6e1..9b56062879583 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/index.test.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/index.test.ts @@ -4,27 +4,25 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EndpointAppLocation, PolicyListState } from '../../types'; -import { applyMiddleware, createStore, Store } from 'redux'; -import { AppAction } from '../action'; -import { policyListReducer } from './reducer'; +import { PolicyListState } from '../../types'; +import { Store, applyMiddleware, createStore } from 'redux'; + +import { coreMock } from '../../../../../../../src/core/public/mocks'; +import { DATASOURCE_SAVED_OBJECT_TYPE } from '../../../../../ingest_manager/common'; + +import { policyListReducer, initialPolicyListState } from './reducer'; import { policyListMiddlewareFactory } from './middleware'; -import { coreMock } from '../../../../../../../../src/core/public/mocks'; + import { isOnPolicyListPage, selectIsLoading, urlSearchParams } from './selectors'; -import { DepsStartMock, depsStartMock } from '../../mocks'; +import { DepsStartMock, depsStartMock } from '../../../common/mock/endpoint'; import { setPolicyListApiMockImplementation } from './test_mock_utils'; import { INGEST_API_DATASOURCES } from './services/ingest'; -import { Immutable } from '../../../../../common/types'; -import { createSpyMiddleware, MiddlewareActionSpyHelper } from '../test_utils'; -import { DATASOURCE_SAVED_OBJECT_TYPE } from '../../../../../../ingest_manager/common'; +import { createSpyMiddleware, MiddlewareActionSpyHelper } from '../../../common/store/test_utils'; describe('policy list store concerns', () => { let fakeCoreStart: ReturnType; let depsStart: DepsStartMock; - type PolicyListStore = Store, Immutable>; - let store: PolicyListStore; - let getState: PolicyListStore['getState']; - let dispatch: PolicyListStore['dispatch']; + let store: Store; let waitForAction: MiddlewareActionSpyHelper['waitForAction']; beforeEach(() => { @@ -36,28 +34,27 @@ describe('policy list store concerns', () => { store = createStore( policyListReducer, + initialPolicyListState(), applyMiddleware(policyListMiddlewareFactory(fakeCoreStart, depsStart), actionSpyMiddleware) ); - getState = store.getState; - dispatch = store.dispatch; }); it('it does nothing on `userChangedUrl` if pathname is NOT `/policy`', async () => { - const state = getState(); + const state = store.getState(); expect(isOnPolicyListPage(state)).toBe(false); - dispatch({ + store.dispatch({ type: 'userChangedUrl', payload: { pathname: '/foo', search: '', hash: '', - } as EndpointAppLocation, + }, }); - expect(getState()).toEqual(state); + expect(store.getState()).toEqual(state); }); it('it reports `isOnPolicyListPage` correctly when router pathname is `/policy`', async () => { - dispatch({ + store.dispatch({ type: 'userChangedUrl', payload: { pathname: '/policy', @@ -65,12 +62,12 @@ describe('policy list store concerns', () => { hash: '', }, }); - expect(isOnPolicyListPage(getState())).toBe(true); + expect(isOnPolicyListPage(store.getState())).toBe(true); }); it('it sets `isLoading` when `userChangedUrl`', async () => { - expect(selectIsLoading(getState())).toBe(false); - dispatch({ + expect(selectIsLoading(store.getState())).toBe(false); + store.dispatch({ type: 'userChangedUrl', payload: { pathname: '/policy', @@ -78,13 +75,13 @@ describe('policy list store concerns', () => { hash: '', }, }); - expect(selectIsLoading(getState())).toBe(true); + expect(selectIsLoading(store.getState())).toBe(true); await waitForAction('serverReturnedPolicyListData'); - expect(selectIsLoading(getState())).toBe(false); + expect(selectIsLoading(store.getState())).toBe(false); }); it('it resets state on `userChangedUrl` and pathname is NOT `/policy`', async () => { - dispatch({ + store.dispatch({ type: 'userChangedUrl', payload: { pathname: '/policy', @@ -93,7 +90,7 @@ describe('policy list store concerns', () => { }, }); await waitForAction('serverReturnedPolicyListData'); - dispatch({ + store.dispatch({ type: 'userChangedUrl', payload: { pathname: '/foo', @@ -101,7 +98,7 @@ describe('policy list store concerns', () => { hash: '', }, }); - expect(getState()).toEqual({ + expect(store.getState()).toEqual({ apiError: undefined, location: undefined, policyItems: [], @@ -112,7 +109,7 @@ describe('policy list store concerns', () => { }); }); it('uses default pagination params when not included in url', async () => { - dispatch({ + store.dispatch({ type: 'userChangedUrl', payload: { pathname: '/policy', @@ -132,7 +129,7 @@ describe('policy list store concerns', () => { describe('when url contains search params', () => { const dispatchUserChangedUrl = (searchParams: string = '') => - dispatch({ + store.dispatch({ type: 'userChangedUrl', payload: { pathname: '/policy', @@ -154,12 +151,12 @@ describe('policy list store concerns', () => { }); it('uses defaults for params not in url', async () => { dispatchUserChangedUrl('?page_index=99'); - expect(urlSearchParams(getState())).toEqual({ + expect(urlSearchParams(store.getState())).toEqual({ page_index: 99, page_size: 10, }); dispatchUserChangedUrl('?page_size=50'); - expect(urlSearchParams(getState())).toEqual({ + expect(urlSearchParams(store.getState())).toEqual({ page_index: 0, page_size: 50, }); @@ -199,14 +196,14 @@ describe('policy list store concerns', () => { }); it(`ignores unknown url search params`, async () => { dispatchUserChangedUrl('?page_size=20&page_index=10&foo=bar'); - expect(urlSearchParams(getState())).toEqual({ + expect(urlSearchParams(store.getState())).toEqual({ page_index: 10, page_size: 20, }); }); it(`uses last param value if param is defined multiple times`, async () => { dispatchUserChangedUrl('?page_size=20&page_size=50&page_index=20&page_index=40'); - expect(urlSearchParams(getState())).toEqual({ + expect(urlSearchParams(store.getState())).toEqual({ page_index: 40, page_size: 50, }); diff --git a/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/index.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/index.ts new file mode 100644 index 0000000000000..a4f51fcf0ec66 --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/index.ts @@ -0,0 +1,21 @@ +/* + * 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 { PolicyListState } from '../../types'; +import { ImmutableReducer } from '../../../common/store'; +import { AppAction } from '../../../common/store/actions'; +import { Immutable } from '../../../../common/endpoint/types'; +export { policyListReducer } from './reducer'; +export { PolicyListAction } from './action'; +export { policyListMiddlewareFactory } from './middleware'; + +export interface EndpointPolicyListStatePluginState { + policyList: Immutable; +} + +export interface EndpointPolicyListStatePluginReducer { + policyList: ImmutableReducer; +} diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/middleware.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/middleware.ts similarity index 84% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/middleware.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_list/middleware.ts index 78ebacd971840..b74ffec6ed897 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/middleware.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/middleware.ts @@ -4,18 +4,21 @@ * you may not use this file except in compliance with the Elastic License. */ -import { GetPolicyListResponse, ImmutableMiddlewareFactory, PolicyListState } from '../../types'; +import { GetPolicyListResponse, PolicyListState } from '../../types'; import { sendGetEndpointSpecificDatasources } from './services/ingest'; import { isOnPolicyListPage, urlSearchParams } from './selectors'; +import { ImmutableMiddlewareFactory } from '../../../common/store'; +import { Immutable } from '../../../../common/endpoint/types'; -export const policyListMiddlewareFactory: ImmutableMiddlewareFactory = coreStart => { +export const policyListMiddlewareFactory: ImmutableMiddlewareFactory> = coreStart => { const http = coreStart.http; return ({ getState, dispatch }) => next => async action => { next(action); const state = getState(); - if (action.type === 'userChangedUrl' && isOnPolicyListPage(state)) { const { page_index: pageIndex, page_size: pageSize } = urlSearchParams(state); let response: GetPolicyListResponse; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/reducer.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/reducer.ts similarity index 84% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/reducer.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_list/reducer.ts index ccd3f84dd060c..80e890602c921 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/reducer.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/reducer.ts @@ -4,12 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { PolicyListState, ImmutableReducer } from '../../types'; -import { AppAction } from '../action'; +import { PolicyListState } from '../../types'; import { isOnPolicyListPage } from './selectors'; -import { Immutable } from '../../../../../common/types'; +import { ImmutableReducer } from '../../../common/store'; +import { AppAction } from '../../../common/store/actions'; +import { Immutable } from '../../../../common/endpoint/types'; -const initialPolicyListState = (): PolicyListState => { +export const initialPolicyListState = (): PolicyListState => { return { policyItems: [], isLoading: false, diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/selectors.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/selectors.ts similarity index 97% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/selectors.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_list/selectors.ts index 4986a342cca19..15516a026ff6b 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/selectors.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/selectors.ts @@ -7,7 +7,7 @@ import { createSelector } from 'reselect'; import { parse } from 'query-string'; import { PolicyListState, PolicyListUrlSearchParams } from '../../types'; -import { Immutable } from '../../../../../common/types'; +import { Immutable } from '../../../../common/endpoint/types'; const PAGE_SIZES = Object.freeze([10, 20, 50]); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/services/ingest.test.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/services/ingest.test.ts similarity index 94% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/services/ingest.test.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_list/services/ingest.test.ts index 46f4c09e05a74..df61bbe893c58 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/services/ingest.test.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/services/ingest.test.ts @@ -5,8 +5,8 @@ */ import { sendGetDatasource, sendGetEndpointSpecificDatasources } from './ingest'; -import { httpServiceMock } from '../../../../../../../../../src/core/public/mocks'; -import { DATASOURCE_SAVED_OBJECT_TYPE } from '../../../../../../../ingest_manager/common'; +import { httpServiceMock } from '../../../../../../../../src/core/public/mocks'; +import { DATASOURCE_SAVED_OBJECT_TYPE } from '../../../../../../ingest_manager/common'; describe('ingest service', () => { let http: ReturnType; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/services/ingest.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/services/ingest.ts similarity index 93% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/services/ingest.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_list/services/ingest.ts index 5c27680d6a35c..312a3f7491ab2 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/services/ingest.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/services/ingest.ts @@ -9,9 +9,9 @@ import { GetDatasourcesRequest, GetAgentStatusResponse, DATASOURCE_SAVED_OBJECT_TYPE, -} from '../../../../../../../ingest_manager/common'; +} from '../../../../../../ingest_manager/common'; import { GetPolicyListResponse, GetPolicyResponse, UpdatePolicyResponse } from '../../../types'; -import { NewPolicyData } from '../../../../../../common/types'; +import { NewPolicyData } from '../../../../../common/endpoint/types'; const INGEST_API_ROOT = `/api/ingest_manager`; export const INGEST_API_DATASOURCES = `${INGEST_API_ROOT}/datasources`; @@ -33,7 +33,7 @@ export const sendGetEndpointSpecificDatasources = ( query: { ...options.query, kuery: `${ - options?.query?.kuery ? options.query.kuery + ' and ' : '' + options?.query?.kuery ? `${options.query.kuery} and ` : '' }${DATASOURCE_SAVED_OBJECT_TYPE}.package.name: endpoint`, }, }); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/test_mock_utils.ts b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/test_mock_utils.ts similarity index 93% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/test_mock_utils.ts rename to x-pack/plugins/siem/public/endpoint_policy/store/policy_list/test_mock_utils.ts index a1788b8f8021d..b8fac21b76a26 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/test_mock_utils.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/store/policy_list/test_mock_utils.ts @@ -6,7 +6,7 @@ import { HttpStart } from 'kibana/public'; import { INGEST_API_DATASOURCES } from './services/ingest'; -import { EndpointDocGenerator } from '../../../../../common/generate_data'; +import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data'; import { GetPolicyListResponse } from '../../types'; const generator = new EndpointDocGenerator('policy-list'); diff --git a/x-pack/plugins/siem/public/endpoint_policy/types.ts b/x-pack/plugins/siem/public/endpoint_policy/types.ts new file mode 100644 index 0000000000000..ba42140589789 --- /dev/null +++ b/x-pack/plugins/siem/public/endpoint_policy/types.ts @@ -0,0 +1,173 @@ +/* + * 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 { + PolicyData, + Immutable, + MalwareFields, + UIPolicyConfig, + AppLocation, +} from '../../common/endpoint/types'; +import { ServerApiError } from '../common/types'; +import { + GetAgentStatusResponse, + GetDatasourcesResponse, + GetOneDatasourceResponse, + UpdateDatasourceResponse, +} from '../../../ingest_manager/common'; + +/** + * Policy list store state + */ +export interface PolicyListState { + /** Array of policy items */ + policyItems: PolicyData[]; + /** API error if loading data failed */ + apiError?: ServerApiError; + /** total number of policies */ + total: number; + /** Number of policies per page */ + pageSize: number; + /** page number (zero based) */ + pageIndex: number; + /** data is being retrieved from server */ + isLoading: boolean; + /** current location information */ + location?: Immutable; +} + +/** + * Policy details store state + */ +export interface PolicyDetailsState { + /** A single policy item */ + policyItem?: PolicyData; + /** API error if loading data failed */ + apiError?: ServerApiError; + isLoading: boolean; + /** current location of the application */ + location?: Immutable; + /** A summary of stats for the agents associated with a given Fleet Agent Configuration */ + agentStatusSummary?: GetAgentStatusResponse['results']; + /** Status of an update to the policy */ + updateStatus?: { + success: boolean; + error?: ServerApiError; + }; +} + +/** + * The URL search params that are supported by the Policy List page view + */ +export interface PolicyListUrlSearchParams { + page_index: number; + page_size: number; +} + +/** + * Endpoint Policy configuration + */ +export interface PolicyConfig { + windows: { + events: { + dll_and_driver_load: boolean; + dns: boolean; + file: boolean; + network: boolean; + process: boolean; + registry: boolean; + security: boolean; + }; + malware: MalwareFields; + logging: { + stdout: string; + file: string; + }; + advanced: PolicyConfigAdvancedOptions; + }; + mac: { + events: { + file: boolean; + process: boolean; + network: boolean; + }; + malware: MalwareFields; + logging: { + stdout: string; + file: string; + }; + advanced: PolicyConfigAdvancedOptions; + }; + linux: { + events: { + file: boolean; + process: boolean; + network: boolean; + }; + logging: { + stdout: string; + file: string; + }; + advanced: PolicyConfigAdvancedOptions; + }; +} + +interface PolicyConfigAdvancedOptions { + elasticsearch: { + indices: { + control: string; + event: string; + logging: string; + }; + kernel: { + connect: boolean; + process: boolean; + }; + }; +} + +export enum OS { + windows = 'windows', + mac = 'mac', + linux = 'linux', +} + +/** + * Returns the keys of an object whose values meet a criteria. + * Ex) interface largeNestedObject = { + * a: { + * food: Foods; + * toiletPaper: true; + * }; + * b: { + * food: Foods; + * streamingServices: Streams; + * }; + * c: {}; + * } + * + * type hasFoods = KeysByValueCriteria; + * The above type will be: [a, b] only, and will not include c. + * + */ +export type KeysByValueCriteria = { + [K in keyof O]: O[K] extends Criteria ? K : never; +}[keyof O]; + +/** Returns an array of the policy OSes that have a malware protection field */ +export type MalwareProtectionOSes = KeysByValueCriteria; + +export interface GetPolicyListResponse extends GetDatasourcesResponse { + items: PolicyData[]; +} + +export interface GetPolicyResponse extends GetOneDatasourceResponse { + item: PolicyData; +} + +export interface UpdatePolicyResponse extends UpdateDatasourceResponse { + item: PolicyData; +} diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/agents_summary.tsx b/x-pack/plugins/siem/public/endpoint_policy/view/agents_summary.tsx similarity index 82% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/policy/agents_summary.tsx rename to x-pack/plugins/siem/public/endpoint_policy/view/agents_summary.tsx index a3e30eb891db4..215e52dedf5d1 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/agents_summary.tsx +++ b/x-pack/plugins/siem/public/endpoint_policy/view/agents_summary.tsx @@ -31,28 +31,28 @@ export const AgentsSummary = memo(props => { return [ { key: 'total', - title: i18n.translate('xpack.endpoint.policyDetails.agentsSummary.totalTitle', { + title: i18n.translate('xpack.siem.endpoint.policyDetails.agentsSummary.totalTitle', { defaultMessage: 'Hosts', }), health: '', }, { key: 'online', - title: i18n.translate('xpack.endpoint.policyDetails.agentsSummary.onlineTitle', { + title: i18n.translate('xpack.siem.endpoint.policyDetails.agentsSummary.onlineTitle', { defaultMessage: 'Online', }), health: 'success', }, { key: 'offline', - title: i18n.translate('xpack.endpoint.policyDetails.agentsSummary.offlineTitle', { + title: i18n.translate('xpack.siem.endpoint.policyDetails.agentsSummary.offlineTitle', { defaultMessage: 'Offline', }), health: 'warning', }, { key: 'error', - title: i18n.translate('xpack.endpoint.policyDetails.agentsSummary.errorTitle', { + title: i18n.translate('xpack.siem.endpoint.policyDetails.agentsSummary.errorTitle', { defaultMessage: 'Error', }), health: 'danger', @@ -86,3 +86,5 @@ export const AgentsSummary = memo(props => { ); }); + +AgentsSummary.displayName = 'AgentsSummary'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/index.ts b/x-pack/plugins/siem/public/endpoint_policy/view/index.ts similarity index 100% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/policy/index.ts rename to x-pack/plugins/siem/public/endpoint_policy/view/index.ts diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_details.test.tsx b/x-pack/plugins/siem/public/endpoint_policy/view/policy_details.test.tsx similarity index 96% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_details.test.tsx rename to x-pack/plugins/siem/public/endpoint_policy/view/policy_details.test.tsx index d780b7bde8af3..35786b568ce11 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_details.test.tsx +++ b/x-pack/plugins/siem/public/endpoint_policy/view/policy_details.test.tsx @@ -6,9 +6,10 @@ import React from 'react'; import { mount } from 'enzyme'; -import { createAppRootMockRenderer } from '../../mocks'; + import { PolicyDetails } from './policy_details'; -import { EndpointDocGenerator } from '../../../../../common/generate_data'; +import { EndpointDocGenerator } from '../../../common/endpoint/generate_data'; +import { createAppRootMockRenderer } from '../../common/mock/endpoint'; describe('Policy Details', () => { type FindReactWrapperResponse = ReturnType['find']>; @@ -57,7 +58,7 @@ describe('Policy Details', () => { if (typeof path === 'string') { // GET datasouce if (path === '/api/ingest_manager/datasources/1') { - asyncActions = asyncActions.then(async (): Promise => await sleep()); + asyncActions = asyncActions.then(async (): Promise => sleep()); return Promise.resolve({ item: policyDatasource, success: true, @@ -66,7 +67,7 @@ describe('Policy Details', () => { // GET Agent status for agent config if (path === '/api/ingest_manager/fleet/agent-status') { - asyncActions = asyncActions.then(async () => await sleep()); + asyncActions = asyncActions.then(async () => sleep()); return Promise.resolve({ results: { events: 0, total: 5, online: 3, error: 1, offline: 1 }, success: true, @@ -160,7 +161,7 @@ describe('Policy Details', () => { 'button[data-test-subj="confirmModalConfirmButton"]' ); http.put.mockImplementation((...args) => { - asyncActions = asyncActions.then(async () => await sleep()); + asyncActions = asyncActions.then(async () => sleep()); const [path] = args; if (typeof path === 'string') { if (path === '/api/ingest_manager/datasources/1') { diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_details.tsx b/x-pack/plugins/siem/public/endpoint_policy/view/policy_details.tsx similarity index 74% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_details.tsx rename to x-pack/plugins/siem/public/endpoint_policy/view/policy_details.tsx index d9bb7eabcf7b0..c928a374502a5 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_details.tsx +++ b/x-pack/plugins/siem/public/endpoint_policy/view/policy_details.tsx @@ -27,15 +27,15 @@ import { updateStatus, isLoading, apiError, -} from '../../store/policy_details/selectors'; -import { PageView, PageViewHeaderTitle } from '../components/page_view'; -import { AppAction } from '../../types'; -import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; +} from '../store/policy_details/selectors'; +import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; import { AgentsSummary } from './agents_summary'; import { VerticalDivider } from './vertical_divider'; import { WindowsEvents, MacEvents, LinuxEvents } from './policy_forms/events'; import { MalwareProtections } from './policy_forms/protections/malware'; -import { useNavigateByRouterEventHandler } from '../hooks/use_navigate_by_router_event_handler'; +import { AppAction } from '../../common/store/actions'; +import { useNavigateByRouterEventHandler } from '../../common/hooks/endpoint/use_navigate_by_router_event_handler'; +import { PageView, PageViewHeaderTitle } from '../../common/components/endpoint/page_view'; export const PolicyDetails = React.memo(() => { const dispatch = useDispatch<(action: AppAction) => void>(); @@ -58,12 +58,12 @@ export const PolicyDetails = React.memo(() => { if (policyUpdateStatus.success) { notifications.toasts.success({ toastLifeTimeMs: 10000, - title: i18n.translate('xpack.endpoint.policy.details.updateSuccessTitle', { + title: i18n.translate('xpack.siem.endpoint.policy.details.updateSuccessTitle', { defaultMessage: 'Success!', }), body: ( @@ -72,7 +72,7 @@ export const PolicyDetails = React.memo(() => { } else { notifications.toasts.danger({ toastLifeTimeMs: 10000, - title: i18n.translate('xpack.endpoint.policy.details.updateErrorTitle', { + title: i18n.translate('xpack.siem.endpoint.policy.details.updateErrorTitle', { defaultMessage: 'Failed!', }), body: <>{policyUpdateStatus.error!.message}, @@ -122,10 +122,10 @@ export const PolicyDetails = React.memo(() => { iconType="arrowLeft" contentProps={{ style: { paddingLeft: '0' } }} onClick={handleBackToListOnClick} - href={services.http.basePath.get() + '/app/endpoint/policy'} + href={`${services.http.basePath.get()}/app/endpoint/policy`} > @@ -136,7 +136,12 @@ export const PolicyDetails = React.memo(() => { const headerRightContent = ( - + @@ -146,7 +151,10 @@ export const PolicyDetails = React.memo(() => { onClick={handleBackToListOnClick} data-test-subj="policyDetailsCancelButton" > - + @@ -157,7 +165,7 @@ export const PolicyDetails = React.memo(() => { onClick={handleSaveOnClick} isLoading={isPolicyLoading} > - + @@ -167,7 +175,7 @@ export const PolicyDetails = React.memo(() => { <> {showConfirm && ( @@ -181,7 +189,7 @@ export const PolicyDetails = React.memo(() => {

    @@ -192,7 +200,7 @@ export const PolicyDetails = React.memo(() => {

    @@ -208,6 +216,8 @@ export const PolicyDetails = React.memo(() => { ); }); +PolicyDetails.displayName = 'PolicyDetails'; + const ConfirmUpdate = React.memo<{ hostCount: number; onConfirm: () => void; @@ -217,19 +227,19 @@ const ConfirmUpdate = React.memo<{ @@ -255,7 +268,7 @@ const ConfirmUpdate = React.memo<{ )}

    @@ -263,3 +276,5 @@ const ConfirmUpdate = React.memo<{
    ); }); + +ConfirmUpdate.displayName = 'ConfirmUpdate'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/config_form.tsx b/x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/config_form.tsx similarity index 93% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/config_form.tsx rename to x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/config_form.tsx index 341086c7cf75c..a888aa6b4cd6e 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/config_form.tsx +++ b/x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/config_form.tsx @@ -52,7 +52,7 @@ export const ConfigForm: React.FC<{
    - +
    @@ -65,7 +65,7 @@ export const ConfigForm: React.FC<{
    @@ -94,3 +94,5 @@ export const ConfigForm: React.FC<{ ); }); + +ConfigForm.displayName = 'ConfigForm'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/events/checkbox.tsx b/x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/events/checkbox.tsx similarity index 80% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/events/checkbox.tsx rename to x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/events/checkbox.tsx index 74322ac8b993b..9c2e19d0b96c8 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/events/checkbox.tsx +++ b/x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/events/checkbox.tsx @@ -5,13 +5,13 @@ */ import React, { useCallback, useMemo } from 'react'; -import { EuiCheckbox } from '@elastic/eui'; +import { EuiCheckbox, htmlIdGenerator } from '@elastic/eui'; import { useDispatch } from 'react-redux'; -import { htmlIdGenerator } from '@elastic/eui'; + import { usePolicyDetailsSelector } from '../../policy_hooks'; -import { policyConfig } from '../../../../store/policy_details/selectors'; -import { PolicyDetailsAction } from '../../../../store/policy_details'; -import { UIPolicyConfig } from '../../../../../../../common/types'; +import { policyConfig } from '../../../store/policy_details/selectors'; +import { PolicyDetailsAction } from '../../../store/policy_details'; +import { UIPolicyConfig } from '../../../../../common/endpoint/types'; export const EventsCheckbox = React.memo(function({ name, @@ -47,3 +47,5 @@ export const EventsCheckbox = React.memo(function({ /> ); }); + +EventsCheckbox.displayName = 'EventsCheckbox'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/events/index.tsx b/x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/events/index.tsx similarity index 100% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/events/index.tsx rename to x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/events/index.tsx diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/events/linux.tsx b/x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/events/linux.tsx similarity index 74% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/events/linux.tsx rename to x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/events/linux.tsx index c3d6bdba7c852..2b7b247e4276c 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/events/linux.tsx +++ b/x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/events/linux.tsx @@ -9,12 +9,12 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiTitle, EuiText, EuiSpacer } from '@elastic/eui'; import { EventsCheckbox } from './checkbox'; -import { OS } from '../../../../types'; +import { OS } from '../../../types'; import { usePolicyDetailsSelector } from '../../policy_hooks'; -import { selectedLinuxEvents, totalLinuxEvents } from '../../../../store/policy_details/selectors'; +import { selectedLinuxEvents, totalLinuxEvents } from '../../../store/policy_details/selectors'; import { ConfigForm } from '../config_form'; -import { getIn, setIn } from '../../../../models/policy_details_config'; -import { UIPolicyConfig } from '../../../../../../../common/types'; +import { getIn, setIn } from '../../../models/policy_details_config'; +import { UIPolicyConfig } from '../../../../../common/endpoint/types'; export const LinuxEvents = React.memo(() => { const selected = usePolicyDetailsSelector(selectedLinuxEvents); @@ -27,21 +27,21 @@ export const LinuxEvents = React.memo(() => { protectionField: keyof UIPolicyConfig['linux']['events']; }> = [ { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.linux.events.file', { + name: i18n.translate('xpack.siem.endpoint.policyDetailsConfig.linux.events.file', { defaultMessage: 'File', }), os: OS.linux, protectionField: 'file', }, { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.linux.events.process', { + name: i18n.translate('xpack.siem.endpoint.policyDetailsConfig.linux.events.process', { defaultMessage: 'Process', }), os: OS.linux, protectionField: 'process', }, { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.linux.events.network', { + name: i18n.translate('xpack.siem.endpoint.policyDetailsConfig.linux.events.network', { defaultMessage: 'Network', }), os: OS.linux, @@ -53,7 +53,7 @@ export const LinuxEvents = React.memo(() => {
    @@ -79,7 +79,7 @@ export const LinuxEvents = React.memo(() => { return ( @@ -89,13 +89,13 @@ export const LinuxEvents = React.memo(() => { return ( { const selected = usePolicyDetailsSelector(selectedMacEvents); @@ -27,21 +27,21 @@ export const MacEvents = React.memo(() => { protectionField: keyof UIPolicyConfig['mac']['events']; }> = [ { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.mac.events.file', { + name: i18n.translate('xpack.siem.endpoint.policyDetailsConfig.mac.events.file', { defaultMessage: 'File', }), os: OS.mac, protectionField: 'file', }, { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.mac.events.process', { + name: i18n.translate('xpack.siem.endpoint.policyDetailsConfig.mac.events.process', { defaultMessage: 'Process', }), os: OS.mac, protectionField: 'process', }, { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.mac.events.network', { + name: i18n.translate('xpack.siem.endpoint.policyDetailsConfig.mac.events.network', { defaultMessage: 'Network', }), os: OS.mac, @@ -53,7 +53,7 @@ export const MacEvents = React.memo(() => {
    @@ -79,7 +79,7 @@ export const MacEvents = React.memo(() => { return ( @@ -89,13 +89,15 @@ export const MacEvents = React.memo(() => { return ( diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/events/windows.tsx b/x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/events/windows.tsx similarity index 67% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/events/windows.tsx rename to x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/events/windows.tsx index 9d73f12869058..f95b097d85df3 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/events/windows.tsx +++ b/x-pack/plugins/siem/public/endpoint_policy/view/policy_forms/events/windows.tsx @@ -9,15 +9,12 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiTitle, EuiText, EuiSpacer } from '@elastic/eui'; import { EventsCheckbox } from './checkbox'; -import { OS } from '../../../../types'; +import { OS } from '../../../types'; import { usePolicyDetailsSelector } from '../../policy_hooks'; -import { - selectedWindowsEvents, - totalWindowsEvents, -} from '../../../../store/policy_details/selectors'; +import { selectedWindowsEvents, totalWindowsEvents } from '../../../store/policy_details/selectors'; import { ConfigForm } from '../config_form'; -import { setIn, getIn } from '../../../../models/policy_details_config'; -import { UIPolicyConfig, Immutable } from '../../../../../../../common/types'; +import { setIn, getIn } from '../../../models/policy_details_config'; +import { UIPolicyConfig, Immutable } from '../../../../../common/endpoint/types'; export const WindowsEvents = React.memo(() => { const selected = usePolicyDetailsSelector(selectedWindowsEvents); @@ -30,49 +27,52 @@ export const WindowsEvents = React.memo(() => { protectionField: keyof UIPolicyConfig['windows']['events']; }>> = [ { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.windows.events.dllDriverLoad', { - defaultMessage: 'DLL and Driver Load', - }), + name: i18n.translate( + 'xpack.siem.endpoint.policyDetailsConfig.windows.events.dllDriverLoad', + { + defaultMessage: 'DLL and Driver Load', + } + ), os: OS.windows, protectionField: 'dll_and_driver_load', }, { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.windows.events.dns', { + name: i18n.translate('xpack.siem.endpoint.policyDetailsConfig.windows.events.dns', { defaultMessage: 'DNS', }), os: OS.windows, protectionField: 'dns', }, { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.windows.events.file', { + name: i18n.translate('xpack.siem.endpoint.policyDetailsConfig.windows.events.file', { defaultMessage: 'File', }), os: OS.windows, protectionField: 'file', }, { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.windows.events.network', { + name: i18n.translate('xpack.siem.endpoint.policyDetailsConfig.windows.events.network', { defaultMessage: 'Network', }), os: OS.windows, protectionField: 'network', }, { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.windows.events.process', { + name: i18n.translate('xpack.siem.endpoint.policyDetailsConfig.windows.events.process', { defaultMessage: 'Process', }), os: OS.windows, protectionField: 'process', }, { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.windows.events.registry', { + name: i18n.translate('xpack.siem.endpoint.policyDetailsConfig.windows.events.registry', { defaultMessage: 'Registry', }), os: OS.windows, protectionField: 'registry', }, { - name: i18n.translate('xpack.endpoint.policyDetailsConfig.windows.events.security', { + name: i18n.translate('xpack.siem.endpoint.policyDetailsConfig.windows.events.security', { defaultMessage: 'Security', }), os: OS.windows, @@ -84,7 +84,7 @@ export const WindowsEvents = React.memo(() => {
    @@ -110,7 +110,7 @@ export const WindowsEvents = React.memo(() => { return ( @@ -120,13 +120,13 @@ export const WindowsEvents = React.memo(() => { return ( { return [ { id: ProtectionModes.detect, - label: i18n.translate('xpack.endpoint.policy.details.detect', { defaultMessage: 'Detect' }), + label: i18n.translate('xpack.siem.endpoint.policy.details.detect', { + defaultMessage: 'Detect', + }), protection: 'malware', }, { id: ProtectionModes.prevent, - label: i18n.translate('xpack.endpoint.policy.details.prevent', { + label: i18n.translate('xpack.siem.endpoint.policy.details.prevent', { defaultMessage: 'Prevent', }), protection: 'malware', }, { id: ProtectionModes.preventNotify, - label: i18n.translate('xpack.endpoint.policy.details.preventAndNotify', { + label: i18n.translate('xpack.siem.endpoint.policy.details.preventAndNotify', { defaultMessage: 'Prevent and notify user', }), protection: 'malware', @@ -129,7 +133,7 @@ export const MalwareProtections = React.memo(() => {
    @@ -153,7 +157,7 @@ export const MalwareProtections = React.memo(() => { const protectionSwitch = useMemo(() => { return ( { return ( { ); }); + +MalwareProtections.displayName = 'MalwareProtections'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_hooks.ts b/x-pack/plugins/siem/public/endpoint_policy/view/policy_hooks.ts similarity index 63% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_hooks.ts rename to x-pack/plugins/siem/public/endpoint_policy/view/policy_hooks.ts index 5bfce15d680bf..9fadba85c5245 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_hooks.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/view/policy_hooks.ts @@ -5,14 +5,15 @@ */ import { useSelector } from 'react-redux'; -import { GlobalState, PolicyListState, PolicyDetailsState } from '../../types'; +import { PolicyListState, PolicyDetailsState } from '../types'; +import { State } from '../../common/store'; export function usePolicyListSelector(selector: (state: PolicyListState) => TSelected) { - return useSelector((state: GlobalState) => selector(state.policyList)); + return useSelector((state: State) => selector(state.policyList as PolicyListState)); } export function usePolicyDetailsSelector( selector: (state: PolicyDetailsState) => TSelected ) { - return useSelector((state: GlobalState) => selector(state.policyDetails)); + return useSelector((state: State) => selector(state.policyDetails as PolicyDetailsState)); } diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_list.tsx b/x-pack/plugins/siem/public/endpoint_policy/view/policy_list.tsx similarity index 79% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_list.tsx rename to x-pack/plugins/siem/public/endpoint_policy/view/policy_list.tsx index 39529e7c11ab1..a9aea57239ed1 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_list.tsx +++ b/x-pack/plugins/siem/public/endpoint_policy/view/policy_list.tsx @@ -9,7 +9,7 @@ import { EuiBasicTable, EuiText, EuiTableFieldDataColumnType, EuiLink } from '@e import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { useDispatch } from 'react-redux'; -import { useHistory, useLocation } from 'react-router-dom'; +import { useLocation, useHistory } from 'react-router-dom'; import { selectApiError, selectIsLoading, @@ -17,14 +17,14 @@ import { selectPageSize, selectPolicyItems, selectTotal, -} from '../../store/policy_list/selectors'; +} from '../store/policy_list/selectors'; import { usePolicyListSelector } from './policy_hooks'; -import { PolicyListAction } from '../../store/policy_list'; -import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; -import { PageView } from '../components/page_view'; -import { LinkToApp } from '../components/link_to_app'; -import { Immutable, PolicyData } from '../../../../../common/types'; -import { useNavigateByRouterEventHandler } from '../hooks/use_navigate_by_router_event_handler'; +import { PolicyListAction } from '../store/policy_list'; +import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; +import { Immutable, PolicyData } from '../../../common/endpoint/types'; +import { useNavigateByRouterEventHandler } from '../../common/hooks/endpoint/use_navigate_by_router_event_handler'; +import { PageView } from '../../common/components/endpoint/page_view'; +import { LinkToApp } from '../../common/components/endpoint/link_to_app'; interface TableChangeCallbackArguments { page: { index: number; size: number }; @@ -88,9 +88,10 @@ export const PolicyList = React.memo(() => { () => [ { field: 'name', - name: i18n.translate('xpack.endpoint.policyList.nameField', { + name: i18n.translate('xpack.siem.endpoint.policyList.nameField', { defaultMessage: 'Policy Name', }), + // eslint-disable-next-line react/display-name render: (value: string, item: Immutable) => { const routeUri = `/policy/${item.id}`; return ( @@ -105,14 +106,14 @@ export const PolicyList = React.memo(() => { }, { field: 'revision', - name: i18n.translate('xpack.endpoint.policyList.revisionField', { + name: i18n.translate('xpack.siem.endpoint.policyList.revisionField', { defaultMessage: 'Revision', }), dataType: 'number', }, { field: 'package', - name: i18n.translate('xpack.endpoint.policyList.versionField', { + name: i18n.translate('xpack.siem.endpoint.policyList.versionField', { defaultMessage: 'Version', }), render(pkg) { @@ -121,14 +122,14 @@ export const PolicyList = React.memo(() => { }, { field: 'description', - name: i18n.translate('xpack.endpoint.policyList.descriptionField', { + name: i18n.translate('xpack.siem.endpoint.policyList.descriptionField', { defaultMessage: 'Description', }), truncateText: true, }, { field: 'config_id', - name: i18n.translate('xpack.endpoint.policyList.agentConfigField', { + name: i18n.translate('xpack.siem.endpoint.policyList.agentConfigField', { defaultMessage: 'Agent Configuration', }), render(version: string) { @@ -152,13 +153,13 @@ export const PolicyList = React.memo(() => { @@ -176,3 +177,5 @@ export const PolicyList = React.memo(() => { ); }); + +PolicyList.displayName = 'PolicyList'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/vertical_divider.ts b/x-pack/plugins/siem/public/endpoint_policy/view/vertical_divider.ts similarity index 91% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/policy/vertical_divider.ts rename to x-pack/plugins/siem/public/endpoint_policy/view/vertical_divider.ts index c73f6f12bec82..918e94cb5b412 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/vertical_divider.ts +++ b/x-pack/plugins/siem/public/endpoint_policy/view/vertical_divider.ts @@ -5,7 +5,7 @@ */ import styled from 'styled-components'; -import { EuiTheme } from '../../../../../../../legacy/common/eui_styled_components'; +import { EuiTheme } from '../../../../../legacy/common/eui_styled_components'; type SpacingOptions = keyof EuiTheme['eui']['spacerSizes']; diff --git a/x-pack/plugins/siem/public/index.ts b/x-pack/plugins/siem/public/index.ts index 46f72c1fa17c8..36344a25e1568 100644 --- a/x-pack/plugins/siem/public/index.ts +++ b/x-pack/plugins/siem/public/index.ts @@ -5,7 +5,8 @@ */ import { PluginInitializerContext } from '../../../../src/core/public'; -import { Plugin, PluginSetup, PluginStart } from './plugin'; +import { Plugin } from './plugin'; +import { PluginSetup, PluginStart } from './types'; export const plugin = (context: PluginInitializerContext): Plugin => new Plugin(context); diff --git a/x-pack/plugins/siem/public/plugin.tsx b/x-pack/plugins/siem/public/plugin.tsx index cc46025ddc4a6..9bea776220720 100644 --- a/x-pack/plugins/siem/public/plugin.tsx +++ b/x-pack/plugins/siem/public/plugin.tsx @@ -14,51 +14,12 @@ import { Plugin as IPlugin, DEFAULT_APP_CATEGORIES, } from '../../../../src/core/public'; -import { - HomePublicPluginSetup, - FeatureCatalogueCategory, -} from '../../../../src/plugins/home/public'; -import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; -import { EmbeddableStart } from '../../../../src/plugins/embeddable/public'; -import { Start as NewsfeedStart } from '../../../../src/plugins/newsfeed/public'; -import { Start as InspectorStart } from '../../../../src/plugins/inspector/public'; -import { UiActionsStart } from '../../../../src/plugins/ui_actions/public'; -import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public'; -import { - TriggersAndActionsUIPublicPluginSetup as TriggersActionsSetup, - TriggersAndActionsUIPublicPluginStart as TriggersActionsStart, -} from '../../triggers_actions_ui/public'; -import { SecurityPluginSetup } from '../../security/public'; -import { APP_ID, APP_NAME, APP_PATH, APP_ICON } from '../common/constants'; +import { FeatureCatalogueCategory } from '../../../../src/plugins/home/public'; import { initTelemetry } from './common/lib/telemetry'; import { KibanaServices } from './common/lib/kibana/services'; import { serviceNowActionType, jiraActionType } from './common/lib/connectors'; - -export interface SetupPlugins { - home: HomePublicPluginSetup; - security: SecurityPluginSetup; - triggers_actions_ui: TriggersActionsSetup; - usageCollection?: UsageCollectionSetup; -} - -export interface StartPlugins { - data: DataPublicPluginStart; - embeddable: EmbeddableStart; - inspector: InspectorStart; - newsfeed?: NewsfeedStart; - triggers_actions_ui: TriggersActionsStart; - uiActions: UiActionsStart; -} - -export type StartServices = CoreStart & - StartPlugins & { - security: SecurityPluginSetup; - }; - -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface PluginSetup {} -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface PluginStart {} +import { PluginSetup, PluginStart, SetupPlugins, StartPlugins, StartServices } from './types'; +import { APP_ID, APP_NAME, APP_ICON, APP_PATH } from '../common/constants'; export class Plugin implements IPlugin { private kibanaVersion: string; @@ -102,6 +63,14 @@ export class Plugin implements IPlugin { describe('eventType', () => { diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/models/process_event.ts b/x-pack/plugins/siem/public/resolver/models/process_event.ts similarity index 95% rename from x-pack/plugins/endpoint/public/embeddables/resolver/models/process_event.ts rename to x-pack/plugins/siem/public/resolver/models/process_event.ts index a709d6caf46cb..038e5b90b2170 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/models/process_event.ts +++ b/x-pack/plugins/siem/public/resolver/models/process_event.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ResolverEvent } from '../../../../common/types'; -import * as event from '../../../../common/models/event'; +import * as event from '../../../common/endpoint/models/event'; +import { ResolverEvent } from '../../../common/endpoint/types'; import { ResolverProcessType } from '../types'; /** diff --git a/x-pack/plugins/siem/public/resolver/models/process_event_test_helpers.ts b/x-pack/plugins/siem/public/resolver/models/process_event_test_helpers.ts new file mode 100644 index 0000000000000..be0895dbec4fe --- /dev/null +++ b/x-pack/plugins/siem/public/resolver/models/process_event_test_helpers.ts @@ -0,0 +1,42 @@ +/* + * 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 { defaults } from 'lodash/fp'; +import { LegacyEndpointEvent } from '../../../common/endpoint/types'; + +type DeepPartial = { [K in keyof T]?: DeepPartial }; +/** + * Creates a mock process event given the 'parts' argument, which can + * include all or some process event fields as determined by the ProcessEvent type. + * The only field that must be provided is the event's 'node_id' field. + * The other fields are populated by the function unless provided in 'parts' + */ +export function mockProcessEvent(parts: DeepPartial): LegacyEndpointEvent { + return defaults( + { + endgame: { + event_timestamp: 1, + event_type: 1, + unique_ppid: 0, + unique_pid: 1, + machine_id: '', + event_subtype_full: 'creation_event', + event_type_full: 'process_event', + process_name: '', + process_path: '', + timestamp_utc: '', + serial_event_id: 1, + }, + '@timestamp': 1582233383000, + agent: { + type: '', + id: '', + version: '', + }, + }, + parts + ); +} diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/actions.ts b/x-pack/plugins/siem/public/resolver/store/actions.ts similarity index 98% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/actions.ts rename to x-pack/plugins/siem/public/resolver/store/actions.ts index 462f6e251d5d0..0963118ce14b8 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/actions.ts +++ b/x-pack/plugins/siem/public/resolver/store/actions.ts @@ -5,7 +5,7 @@ */ import { CameraAction } from './camera'; import { DataAction } from './data'; -import { ResolverEvent } from '../../../../common/types'; +import { ResolverEvent } from '../../../common/endpoint/types'; /** * When the user wants to bring a process node front-and-center on the map. diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/action.ts b/x-pack/plugins/siem/public/resolver/store/camera/action.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/action.ts rename to x-pack/plugins/siem/public/resolver/store/camera/action.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/animation.test.ts b/x-pack/plugins/siem/public/resolver/store/camera/animation.test.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/animation.test.ts rename to x-pack/plugins/siem/public/resolver/store/camera/animation.test.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/index.ts b/x-pack/plugins/siem/public/resolver/store/camera/index.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/index.ts rename to x-pack/plugins/siem/public/resolver/store/camera/index.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/inverse_projection_matrix.test.ts b/x-pack/plugins/siem/public/resolver/store/camera/inverse_projection_matrix.test.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/inverse_projection_matrix.test.ts rename to x-pack/plugins/siem/public/resolver/store/camera/inverse_projection_matrix.test.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/methods.ts b/x-pack/plugins/siem/public/resolver/store/camera/methods.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/methods.ts rename to x-pack/plugins/siem/public/resolver/store/camera/methods.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/panning.test.ts b/x-pack/plugins/siem/public/resolver/store/camera/panning.test.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/panning.test.ts rename to x-pack/plugins/siem/public/resolver/store/camera/panning.test.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/projection_matrix.test.ts b/x-pack/plugins/siem/public/resolver/store/camera/projection_matrix.test.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/projection_matrix.test.ts rename to x-pack/plugins/siem/public/resolver/store/camera/projection_matrix.test.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/reducer.ts b/x-pack/plugins/siem/public/resolver/store/camera/reducer.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/reducer.ts rename to x-pack/plugins/siem/public/resolver/store/camera/reducer.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/scale_to_zoom.ts b/x-pack/plugins/siem/public/resolver/store/camera/scale_to_zoom.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/scale_to_zoom.ts rename to x-pack/plugins/siem/public/resolver/store/camera/scale_to_zoom.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/scaling_constants.ts b/x-pack/plugins/siem/public/resolver/store/camera/scaling_constants.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/scaling_constants.ts rename to x-pack/plugins/siem/public/resolver/store/camera/scaling_constants.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/selectors.ts b/x-pack/plugins/siem/public/resolver/store/camera/selectors.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/selectors.ts rename to x-pack/plugins/siem/public/resolver/store/camera/selectors.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/test_helpers.ts b/x-pack/plugins/siem/public/resolver/store/camera/test_helpers.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/test_helpers.ts rename to x-pack/plugins/siem/public/resolver/store/camera/test_helpers.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/zooming.test.ts b/x-pack/plugins/siem/public/resolver/store/camera/zooming.test.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/zooming.test.ts rename to x-pack/plugins/siem/public/resolver/store/camera/zooming.test.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/__snapshots__/graphing.test.ts.snap b/x-pack/plugins/siem/public/resolver/store/data/__snapshots__/graphing.test.ts.snap similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/data/__snapshots__/graphing.test.ts.snap rename to x-pack/plugins/siem/public/resolver/store/data/__snapshots__/graphing.test.ts.snap diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/action.ts b/x-pack/plugins/siem/public/resolver/store/data/action.ts similarity index 94% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/data/action.ts rename to x-pack/plugins/siem/public/resolver/store/data/action.ts index 8c84d8f82b874..f6ef7b16ae682 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/action.ts +++ b/x-pack/plugins/siem/public/resolver/store/data/action.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ResolverEvent } from '../../../../../common/types'; +import { ResolverEvent } from '../../../../common/endpoint/types'; import { RelatedEventDataEntry } from '../../types'; interface ServerReturnedResolverData { diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/graphing.test.ts b/x-pack/plugins/siem/public/resolver/store/data/graphing.test.ts similarity index 99% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/data/graphing.test.ts rename to x-pack/plugins/siem/public/resolver/store/data/graphing.test.ts index f95ecc63d2a66..69edf3b4c134d 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/graphing.test.ts +++ b/x-pack/plugins/siem/public/resolver/store/data/graphing.test.ts @@ -8,7 +8,7 @@ import { Store, createStore } from 'redux'; import { DataAction } from './action'; import { dataReducer } from './reducer'; import { DataState } from '../../types'; -import { LegacyEndpointEvent, ResolverEvent } from '../../../../../common/types'; +import { LegacyEndpointEvent, ResolverEvent } from '../../../../common/endpoint/types'; import { graphableProcesses, processNodePositionsAndEdgeLineSegments } from './selectors'; import { mockProcessEvent } from '../../models/process_event_test_helpers'; diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/index.ts b/x-pack/plugins/siem/public/resolver/store/data/index.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/data/index.ts rename to x-pack/plugins/siem/public/resolver/store/data/index.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/reducer.ts b/x-pack/plugins/siem/public/resolver/store/data/reducer.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/data/reducer.ts rename to x-pack/plugins/siem/public/resolver/store/data/reducer.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/sample.ts b/x-pack/plugins/siem/public/resolver/store/data/sample.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/data/sample.ts rename to x-pack/plugins/siem/public/resolver/store/data/sample.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.test.ts b/x-pack/plugins/siem/public/resolver/store/data/selectors.test.ts similarity index 95% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.test.ts rename to x-pack/plugins/siem/public/resolver/store/data/selectors.test.ts index 561b0da12bcb1..f6d2b978d6b4d 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.test.ts +++ b/x-pack/plugins/siem/public/resolver/store/data/selectors.test.ts @@ -1,59 +1,59 @@ -/* - * 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 { Store, createStore } from 'redux'; -import { DataAction } from './action'; -import { dataReducer } from './reducer'; -import { - DataState, - RelatedEventDataEntry, - RelatedEventDataEntryWithStats, - RelatedEventData, -} from '../../types'; -import { ResolverEvent } from '../../../../../common/types'; -import { relatedEventStats, relatedEvents } from './selectors'; - -describe('resolver data selectors', () => { - const store: Store = createStore(dataReducer, undefined); - describe('when related event data is reduced into state with no results', () => { - let relatedEventInfoBeforeAction: RelatedEventData; - beforeEach(() => { - relatedEventInfoBeforeAction = new Map(relatedEvents(store.getState()) || []); - const payload: Map = new Map(); - const action: DataAction = { type: 'serverReturnedRelatedEventData', payload }; - store.dispatch(action); - }); - it('should have the same related info as before the action', () => { - const relatedInfoAfterAction = relatedEvents(store.getState()); - expect(relatedInfoAfterAction).toEqual(relatedEventInfoBeforeAction); - }); - }); - describe('when related event data is reduced into state with 2 dns results', () => { - let mockBaseEvent: ResolverEvent; - beforeEach(() => { - mockBaseEvent = {} as ResolverEvent; - function dnsRelatedEventEntry() { - const fakeEvent = {} as ResolverEvent; - return { relatedEvent: fakeEvent, relatedEventType: 'dns' }; - } - const payload: Map = new Map([ - [ - mockBaseEvent, - { - relatedEvents: [dnsRelatedEventEntry(), dnsRelatedEventEntry()], - }, - ], - ]); - const action: DataAction = { type: 'serverReturnedRelatedEventData', payload }; - store.dispatch(action); - }); - it('should compile stats reflecting a count of 2 for dns', () => { - const actualStats = relatedEventStats(store.getState()); - const statsForFakeEvent = actualStats.get(mockBaseEvent)! as RelatedEventDataEntryWithStats; - expect(statsForFakeEvent.stats).toEqual({ dns: 2 }); - }); - }); -}); +/* + * 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 { Store, createStore } from 'redux'; +import { DataAction } from './action'; +import { dataReducer } from './reducer'; +import { + DataState, + RelatedEventDataEntry, + RelatedEventDataEntryWithStats, + RelatedEventData, +} from '../../types'; +import { ResolverEvent } from '../../../../common/endpoint/types'; +import { relatedEventStats, relatedEvents } from './selectors'; + +describe('resolver data selectors', () => { + const store: Store = createStore(dataReducer, undefined); + describe('when related event data is reduced into state with no results', () => { + let relatedEventInfoBeforeAction: RelatedEventData; + beforeEach(() => { + relatedEventInfoBeforeAction = new Map(relatedEvents(store.getState()) || []); + const payload: Map = new Map(); + const action: DataAction = { type: 'serverReturnedRelatedEventData', payload }; + store.dispatch(action); + }); + it('should have the same related info as before the action', () => { + const relatedInfoAfterAction = relatedEvents(store.getState()); + expect(relatedInfoAfterAction).toEqual(relatedEventInfoBeforeAction); + }); + }); + describe('when related event data is reduced into state with 2 dns results', () => { + let mockBaseEvent: ResolverEvent; + beforeEach(() => { + mockBaseEvent = {} as ResolverEvent; + function dnsRelatedEventEntry() { + const fakeEvent = {} as ResolverEvent; + return { relatedEvent: fakeEvent, relatedEventType: 'dns' }; + } + const payload: Map = new Map([ + [ + mockBaseEvent, + { + relatedEvents: [dnsRelatedEventEntry(), dnsRelatedEventEntry()], + }, + ], + ]); + const action: DataAction = { type: 'serverReturnedRelatedEventData', payload }; + store.dispatch(action); + }); + it('should compile stats reflecting a count of 2 for dns', () => { + const actualStats = relatedEventStats(store.getState()); + const statsForFakeEvent = actualStats.get(mockBaseEvent)! as RelatedEventDataEntryWithStats; + expect(statsForFakeEvent.stats).toEqual({ dns: 2 }); + }); + }); +}); diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.ts b/x-pack/plugins/siem/public/resolver/store/data/selectors.ts similarity index 99% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.ts rename to x-pack/plugins/siem/public/resolver/store/data/selectors.ts index 413f4db1cc99e..ec6e937e03d9a 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/data/selectors.ts +++ b/x-pack/plugins/siem/public/resolver/store/data/selectors.ts @@ -14,11 +14,12 @@ import { ProcessWithWidthMetadata, Matrix3, AdjacentProcessMap, + Vector2, RelatedEventData, RelatedEventDataEntryWithStats, } from '../../types'; -import { ResolverEvent } from '../../../../../common/types'; -import { Vector2 } from '../../types'; +import { ResolverEvent } from '../../../../common/endpoint/types'; + import { add as vector2Add, applyMatrix3 } from '../../lib/vector2'; import { isGraphableProcess, uniquePidForProcess } from '../../models/process_event'; import { @@ -160,6 +161,7 @@ function processEdgeLineSegments( * We only handle children, drawing lines back to their parents. The root has no parent, so we skip it */ if (metadata.parent === null) { + // eslint-disable-next-line no-continue continue; } const { process, parent, parentWidth } = metadata; @@ -435,6 +437,7 @@ export const relatedEventStats = createSelector(relatedEventResults, function ge if (newStatsEntry === 'error') { // If the entry is an error, return it as is relatedEventStats.set(updatedEvent, newStatsEntry); + // eslint-disable-next-line no-continue continue; } if (typeof newStatsEntry === 'object') { diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/index.ts b/x-pack/plugins/siem/public/resolver/store/index.ts similarity index 82% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/index.ts rename to x-pack/plugins/siem/public/resolver/store/index.ts index 2a20c73347348..203ecccb1d369 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/index.ts +++ b/x-pack/plugins/siem/public/resolver/store/index.ts @@ -6,14 +6,14 @@ import { createStore, applyMiddleware, Store } from 'redux'; import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly'; -import { KibanaReactContextValue } from '../../../../../../../src/plugins/kibana_react/public'; +import { KibanaReactContextValue } from '../../../../../../src/plugins/kibana_react/public'; import { ResolverAction, ResolverState } from '../types'; -import { EndpointPluginServices } from '../../../plugin'; +import { StartServices } from '../../types'; import { resolverReducer } from './reducer'; import { resolverMiddlewareFactory } from './middleware'; export const storeFactory = ( - context?: KibanaReactContextValue + context?: KibanaReactContextValue ): { store: Store } => { const actionsBlacklist: Array = ['userMovedPointer']; const composeEnhancers = composeWithDevTools({ diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/methods.ts b/x-pack/plugins/siem/public/resolver/store/methods.ts similarity index 93% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/methods.ts rename to x-pack/plugins/siem/public/resolver/store/methods.ts index f15307a662388..3890770259156 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/methods.ts +++ b/x-pack/plugins/siem/public/resolver/store/methods.ts @@ -7,7 +7,7 @@ import { animatePanning } from './camera/methods'; import { processNodePositionsAndEdgeLineSegments } from './selectors'; import { ResolverState } from '../types'; -import { ResolverEvent } from '../../../../common/types'; +import { ResolverEvent } from '../../../common/endpoint/types'; const animationDuration = 1000; diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/middleware.ts b/x-pack/plugins/siem/public/resolver/store/middleware.ts similarity index 93% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/middleware.ts rename to x-pack/plugins/siem/public/resolver/store/middleware.ts index 06758022b05c5..f0d89e7bb5d5c 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/middleware.ts +++ b/x-pack/plugins/siem/public/resolver/store/middleware.ts @@ -6,14 +6,14 @@ import { Dispatch, MiddlewareAPI } from 'redux'; import { HttpHandler } from 'kibana/public'; -import { KibanaReactContextValue } from '../../../../../../../src/plugins/kibana_react/public'; -import { EndpointPluginServices } from '../../../plugin'; +import { KibanaReactContextValue } from '../../../../../../src/plugins/kibana_react/public'; +import { StartServices } from '../../types'; import { ResolverState, ResolverAction, RelatedEventDataEntry } from '../types'; -import { ResolverEvent, ResolverNode } from '../../../../common/types'; -import * as event from '../../../../common/models/event'; +import { ResolverEvent, ResolverNode } from '../../../common/endpoint/types'; +import * as event from '../../../common/endpoint/models/event'; type MiddlewareFactory = ( - context?: KibanaReactContextValue + context?: KibanaReactContextValue ) => ( api: MiddlewareAPI, S> ) => (next: Dispatch) => (action: ResolverAction) => unknown; @@ -124,6 +124,7 @@ export const resolverMiddlewareFactory: MiddlewareFactory = context => { type: 'serverFailedToReturnRelatedEventData', payload: results[0], }); + // eslint-disable-next-line no-continue continue; } diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/reducer.ts b/x-pack/plugins/siem/public/resolver/store/reducer.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/reducer.ts rename to x-pack/plugins/siem/public/resolver/store/reducer.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/selectors.ts b/x-pack/plugins/siem/public/resolver/store/selectors.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/selectors.ts rename to x-pack/plugins/siem/public/resolver/store/selectors.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/ui/selectors.ts b/x-pack/plugins/siem/public/resolver/store/ui/selectors.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/store/ui/selectors.ts rename to x-pack/plugins/siem/public/resolver/store/ui/selectors.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/types.ts b/x-pack/plugins/siem/public/resolver/types.ts similarity index 98% rename from x-pack/plugins/endpoint/public/embeddables/resolver/types.ts rename to x-pack/plugins/siem/public/resolver/types.ts index 32fefba8f0f20..e93a7856557cc 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/types.ts +++ b/x-pack/plugins/siem/public/resolver/types.ts @@ -8,8 +8,8 @@ import { Store } from 'redux'; import { ResolverAction } from './store/actions'; export { ResolverAction } from './store/actions'; -import { ResolverEvent } from '../../../common/types'; -import { eventType } from '../../../common/models/event'; +import { ResolverEvent } from '../../common/endpoint/types'; +import { eventType } from '../../common/endpoint/models/event'; /** * Redux state for the Resolver feature. Properties on this interface are populated via multiple reducers using redux's `combineReducers`. diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/defs.tsx b/x-pack/plugins/siem/public/resolver/view/defs.tsx similarity index 95% rename from x-pack/plugins/endpoint/public/embeddables/resolver/view/defs.tsx rename to x-pack/plugins/siem/public/resolver/view/defs.tsx index 064645019ca34..d70ee7bc23587 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/view/defs.tsx +++ b/x-pack/plugins/siem/public/resolver/view/defs.tsx @@ -150,6 +150,8 @@ const PaintServers = memo(() => ( )); +PaintServers.displayName = 'PaintServers'; + /** * Ids of symbols to be linked by elements */ @@ -183,7 +185,7 @@ const SymbolsAndShapes = memo(() => ( /> - Running Process + {'Running Process'} ( /> - resolver_dark process running + {'resolver_dark process running'} ( /> - Terminated Process + {'Terminated Process'} ( - Terminated Trigger Process + {'Terminated Trigger Process'} ( - resolver active backing + {'resolver active backing'} ( )); +SymbolsAndShapes.displayName = 'SymbolsAndShapes'; + /** * This `` element is used to define the reusable assets for the Resolver * It confers several advantages, including but not limited to: @@ -379,16 +383,18 @@ const SymbolsAndShapes = memo(() => ( * 2. Separation of concerns between creative assets and more functional areas of the app * 3. `` elements can be handled by compositor (faster) */ -export const SymbolDefinitions = styled( - memo(({ className }: { className?: string }) => ( - - - - - - - )) -)` +const SymbolDefinitionsComponent = memo(({ className }: { className?: string }) => ( + + + + + + +)); + +SymbolDefinitionsComponent.displayName = 'SymbolDefinitions'; + +export const SymbolDefinitions = styled(SymbolDefinitionsComponent)` position: absolute; left: 100%; top: 100%; diff --git a/x-pack/plugins/siem/public/resolver/view/edge_line.tsx b/x-pack/plugins/siem/public/resolver/view/edge_line.tsx new file mode 100644 index 0000000000000..2192422b7d31d --- /dev/null +++ b/x-pack/plugins/siem/public/resolver/view/edge_line.tsx @@ -0,0 +1,80 @@ +/* + * 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 from 'react'; +import styled from 'styled-components'; +import { applyMatrix3, distance, angle } from '../lib/vector2'; +import { Vector2, Matrix3 } from '../types'; + +/** + * A placeholder line segment view that connects process nodes. + */ +const EdgeLineComponent = React.memo( + ({ + className, + startPosition, + endPosition, + projectionMatrix, + }: { + /** + * A className string provided by `styled` + */ + className?: string; + /** + * The postion of first point in the line segment. In 'world' coordinates. + */ + startPosition: Vector2; + /** + * The postion of second point in the line segment. In 'world' coordinates. + */ + endPosition: Vector2; + /** + * projectionMatrix which can be used to convert `startPosition` and `endPosition` to screen coordinates. + */ + projectionMatrix: Matrix3; + }) => { + /** + * Convert the start and end positions, which are in 'world' coordinates, + * to `left` and `top` css values. + */ + const screenStart = applyMatrix3(startPosition, projectionMatrix); + const screenEnd = applyMatrix3(endPosition, projectionMatrix); + + /** + * We render the line using a short, long, `div` element. The length of this `div` + * should be the same as the distance between the start and end points. + */ + const length = distance(screenStart, screenEnd); + + const style = { + left: `${screenStart[0]}px`, + top: `${screenStart[1]}px`, + width: `${length}px`, + /** + * Transform from the left of the div, as the left side of the `div` is positioned + * at the start point of the line segment. + */ + transformOrigin: 'top left', + /** + * Translate the `div` in the y axis to accomodate for the height of the `div`. + * Also rotate the `div` in the z axis so that it's angle matches the angle + * between the start and end points. + */ + transform: `translateY(-50%) rotateZ(${angle(screenStart, screenEnd)}rad)`, + }; + return
    ; + } +); + +EdgeLineComponent.displayName = 'EdgeLine'; + +export const EdgeLine = styled(EdgeLineComponent)` + position: absolute; + height: 3px; + background-color: #d4d4d4; + color: #333333; + contain: strict; +`; diff --git a/x-pack/plugins/siem/public/resolver/view/graph_controls.tsx b/x-pack/plugins/siem/public/resolver/view/graph_controls.tsx new file mode 100644 index 0000000000000..f5bc571434d66 --- /dev/null +++ b/x-pack/plugins/siem/public/resolver/view/graph_controls.tsx @@ -0,0 +1,188 @@ +/* + * 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. + */ + +/* eslint-disable react/button-has-type */ + +import React, { useCallback, useMemo, useContext } from 'react'; +import styled from 'styled-components'; +import { EuiRange, EuiPanel, EuiIcon } from '@elastic/eui'; +import { useSelector, useDispatch } from 'react-redux'; +import { SideEffectContext } from './side_effect_context'; +import { ResolverAction, Vector2 } from '../types'; +import * as selectors from '../store/selectors'; + +/** + * Controls for zooming, panning, and centering in Resolver + */ +const GraphControlsComponent = React.memo( + ({ + className, + }: { + /** + * A className string provided by `styled` + */ + className?: string; + }) => { + const dispatch: (action: ResolverAction) => unknown = useDispatch(); + const scalingFactor = useSelector(selectors.scalingFactor); + const { timestamp } = useContext(SideEffectContext); + + const handleZoomAmountChange = useCallback( + (event: React.ChangeEvent | React.MouseEvent) => { + const valueAsNumber = parseFloat( + (event as React.ChangeEvent).target.value + ); + if (isNaN(valueAsNumber) === false) { + dispatch({ + type: 'userSetZoomLevel', + payload: valueAsNumber, + }); + } + }, + [dispatch] + ); + + const handleCenterClick = useCallback(() => { + dispatch({ + type: 'userSetPositionOfCamera', + payload: [0, 0], + }); + }, [dispatch]); + + const handleZoomOutClick = useCallback(() => { + dispatch({ + type: 'userClickedZoomOut', + }); + }, [dispatch]); + + const handleZoomInClick = useCallback(() => { + dispatch({ + type: 'userClickedZoomIn', + }); + }, [dispatch]); + + const [handleNorth, handleEast, handleSouth, handleWest] = useMemo(() => { + const directionVectors: readonly Vector2[] = [ + [0, 1], + [1, 0], + [0, -1], + [-1, 0], + ]; + return directionVectors.map(direction => { + return () => { + const action: ResolverAction = { + type: 'userNudgedCamera', + payload: { direction, time: timestamp() }, + }; + dispatch(action); + }; + }); + }, [dispatch, timestamp]); + + return ( +
    + +
    + +
    +
    + + + +
    +
    + +
    +
    + + + + + +
    + ); + } +); + +GraphControlsComponent.displayName = 'GraphControlsComponent'; + +export const GraphControls = styled(GraphControlsComponent)` + position: absolute; + top: 5px; + right: 5px; + background-color: #d4d4d4; + color: #333333; + + .zoom-controls { + display: flex; + flex-direction: column; + align-items: center; + padding: 5px 0px; + + .zoom-slider { + width: 20px; + height: 150px; + margin: 5px 0px 2px 0px; + + input[type='range'] { + width: 150px; + height: 20px; + transform-origin: 75px 75px; + transform: rotate(-90deg); + } + } + } + .panning-controls { + text-align: center; + } +`; diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/index.tsx b/x-pack/plugins/siem/public/resolver/view/index.tsx similarity index 94% rename from x-pack/plugins/endpoint/public/embeddables/resolver/view/index.tsx rename to x-pack/plugins/siem/public/resolver/view/index.tsx index 5275ba3ec5b4c..26d7842bbbeeb 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/view/index.tsx +++ b/x-pack/plugins/siem/public/resolver/view/index.tsx @@ -17,7 +17,7 @@ import { ProcessEventDot } from './process_event_dot'; import { useCamera } from './use_camera'; import { SymbolDefinitions, NamedColors } from './defs'; import { ResolverAction } from '../types'; -import { ResolverEvent } from '../../../../common/types'; +import { ResolverEvent } from '../../../common/endpoint/types'; const StyledPanel = styled(Panel)` position: absolute; @@ -29,12 +29,6 @@ const StyledPanel = styled(Panel)` max-width: 50%; `; -const StyledGraphControls = styled(GraphControls)` - position: absolute; - top: 5px; - right: 5px; -`; - const StyledResolverContainer = styled.div` display: flex; flex-grow: 1; @@ -81,7 +75,7 @@ export const Resolver = styled(
    {' '}
    @@ -123,7 +117,7 @@ export const Resolver = styled( )} - +
    ); diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/panel.tsx b/x-pack/plugins/siem/public/resolver/view/panel.tsx similarity index 77% rename from x-pack/plugins/endpoint/public/embeddables/resolver/view/panel.tsx rename to x-pack/plugins/siem/public/resolver/view/panel.tsx index 1250c1106b355..8039d2f53d802 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/view/panel.tsx +++ b/x-pack/plugins/siem/public/resolver/view/panel.tsx @@ -4,15 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { memo, useCallback, useMemo, useContext } from 'react'; -import { EuiPanel, EuiBadge, EuiBasicTableColumn } from '@elastic/eui'; -import { EuiTitle } from '@elastic/eui'; -import { EuiHorizontalRule, EuiInMemoryTable } from '@elastic/eui'; +import { + EuiPanel, + EuiBadge, + EuiBasicTableColumn, + EuiTitle, + EuiHorizontalRule, + EuiInMemoryTable, +} from '@elastic/eui'; import euiVars from '@elastic/eui/dist/eui_theme_light.json'; import { useSelector } from 'react-redux'; import { i18n } from '@kbn/i18n'; import { SideEffectContext } from './side_effect_context'; -import { ResolverEvent } from '../../../../common/types'; -import * as event from '../../../../common/models/event'; +import { ResolverEvent } from '../../../common/endpoint/types'; +import * as event from '../../../common/endpoint/models/event'; import { useResolverDispatch } from './use_resolver_dispatch'; import * as selectors from '../store/selectors'; @@ -94,7 +99,7 @@ export const Panel = memo(function Event({ className }: { className?: string }) () => [ { field: 'name', - name: i18n.translate('xpack.endpoint.resolver.panel.tabel.row.processNameTitle', { + name: i18n.translate('xpack.siem.endpoint.resolver.panel.tabel.row.processNameTitle', { defaultMessage: 'Process Name', }), sortable: true, @@ -102,9 +107,12 @@ export const Panel = memo(function Event({ className }: { className?: string }) render(name: string) { return name === '' ? ( - {i18n.translate('xpack.endpoint.resolver.panel.table.row.valueMissingDescription', { - defaultMessage: 'Value is missing', - })} + {i18n.translate( + 'xpack.siem.endpoint.resolver.panel.table.row.valueMissingDescription', + { + defaultMessage: 'Value is missing', + } + )} ) : ( name @@ -113,7 +121,7 @@ export const Panel = memo(function Event({ className }: { className?: string }) }, { field: 'timestamp', - name: i18n.translate('xpack.endpoint.resolver.panel.tabel.row.timestampTitle', { + name: i18n.translate('xpack.siem.endpoint.resolver.panel.tabel.row.timestampTitle', { defaultMessage: 'Timestamp', }), dataType: 'date', @@ -123,27 +131,30 @@ export const Panel = memo(function Event({ className }: { className?: string }) formatter.format(eventDate) ) : ( - {i18n.translate('xpack.endpoint.resolver.panel.tabel.row.timestampInvalidLabel', { - defaultMessage: 'invalid', - })} + {i18n.translate( + 'xpack.siem.endpoint.resolver.panel.tabel.row.timestampInvalidLabel', + { + defaultMessage: 'invalid', + } + )} ); }, }, { - name: i18n.translate('xpack.endpoint.resolver.panel.tabel.row.actionsTitle', { + name: i18n.translate('xpack.siem.endpoint.resolver.panel.tabel.row.actionsTitle', { defaultMessage: 'Actions', }), actions: [ { name: i18n.translate( - 'xpack.endpoint.resolver.panel.tabel.row.actions.bringIntoViewButtonLabel', + 'xpack.siem.endpoint.resolver.panel.tabel.row.actions.bringIntoViewButtonLabel', { defaultMessage: 'Bring into view', } ), description: i18n.translate( - 'xpack.endpoint.resolver.panel.tabel.row.bringIntoViewLabel', + 'xpack.siem.endpoint.resolver.panel.tabel.row.bringIntoViewLabel', { defaultMessage: 'Bring the process into view on the map.', } @@ -161,7 +172,7 @@ export const Panel = memo(function Event({ className }: { className?: string })

    - {i18n.translate('xpack.endpoint.resolver.panel.title', { + {i18n.translate('xpack.siem.endpoint.resolver.panel.title', { defaultMessage: 'Processes', })}

    diff --git a/x-pack/plugins/siem/public/resolver/view/process_event_dot.tsx b/x-pack/plugins/siem/public/resolver/view/process_event_dot.tsx new file mode 100644 index 0000000000000..18a7ba404c270 --- /dev/null +++ b/x-pack/plugins/siem/public/resolver/view/process_event_dot.tsx @@ -0,0 +1,614 @@ +/* + * 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, useMemo } from 'react'; +import styled from 'styled-components'; +import { i18n } from '@kbn/i18n'; +import { + htmlIdGenerator, + EuiI18nNumber, + EuiKeyboardAccessible, + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; +import { useSelector } from 'react-redux'; +import { NodeSubMenu, subMenuAssets } from './submenu'; +import { applyMatrix3 } from '../lib/vector2'; +import { + Vector2, + Matrix3, + AdjacentProcessMap, + ResolverProcessType, + RelatedEventEntryWithStatsOrWaiting, +} from '../types'; +import { SymbolIds, NamedColors } from './defs'; +import { ResolverEvent } from '../../../common/endpoint/types'; +import { useResolverDispatch } from './use_resolver_dispatch'; +import * as eventModel from '../../../common/endpoint/models/event'; +import * as processModel from '../models/process_event'; +import * as selectors from '../store/selectors'; + +const nodeAssets = { + runningProcessCube: { + cubeSymbol: `#${SymbolIds.runningProcessCube}`, + labelBackground: NamedColors.labelBackgroundRunningProcess, + descriptionFill: NamedColors.empty, + descriptionText: i18n.translate('xpack.siem.endpoint.resolver.runningProcess', { + defaultMessage: 'Running Process', + }), + }, + runningTriggerCube: { + cubeSymbol: `#${SymbolIds.runningTriggerCube}`, + labelBackground: NamedColors.labelBackgroundRunningTrigger, + descriptionFill: NamedColors.empty, + descriptionText: i18n.translate('xpack.siem.endpoint.resolver.runningTrigger', { + defaultMessage: 'Running Trigger', + }), + }, + terminatedProcessCube: { + cubeSymbol: `#${SymbolIds.terminatedProcessCube}`, + labelBackground: NamedColors.labelBackgroundTerminatedProcess, + descriptionFill: NamedColors.empty, + descriptionText: i18n.translate('xpack.siem.endpoint.resolver.terminatedProcess', { + defaultMessage: 'Terminated Process', + }), + }, + terminatedTriggerCube: { + cubeSymbol: `#${SymbolIds.terminatedTriggerCube}`, + labelBackground: NamedColors.labelBackgroundTerminatedTrigger, + descriptionFill: NamedColors.empty, + descriptionText: i18n.translate('xpack.siem.endpoint.resolver.terminatedTrigger', { + defaultMessage: 'Terminated Trigger', + }), + }, +}; + +/** + * Take a gross `schemaName` and return a beautiful translated one. + */ +const getDisplayName: (schemaName: string) => string = function nameInSchemaToDisplayName( + schemaName: string +) { + const displayNameRecord: Record = { + application: i18n.translate('xpack.siem.endpoint.resolver.applicationEventTypeDisplayName', { + defaultMessage: 'Application', + }), + apm: i18n.translate('xpack.siem.endpoint.resolver.apmEventTypeDisplayName', { + defaultMessage: 'APM', + }), + audit: i18n.translate('xpack.siem.endpoint.resolver.auditEventTypeDisplayName', { + defaultMessage: 'Audit', + }), + authentication: i18n.translate( + 'xpack.siem.endpoint.resolver.authenticationEventTypeDisplayName', + { + defaultMessage: 'Authentication', + } + ), + certificate: i18n.translate('xpack.siem.endpoint.resolver.certificateEventTypeDisplayName', { + defaultMessage: 'Certificate', + }), + cloud: i18n.translate('xpack.siem.endpoint.resolver.cloudEventTypeDisplayName', { + defaultMessage: 'Cloud', + }), + database: i18n.translate('xpack.siem.endpoint.resolver.databaseEventTypeDisplayName', { + defaultMessage: 'Database', + }), + driver: i18n.translate('xpack.siem.endpoint.resolver.driverEventTypeDisplayName', { + defaultMessage: 'Driver', + }), + email: i18n.translate('xpack.siem.endpoint.resolver.emailEventTypeDisplayName', { + defaultMessage: 'Email', + }), + file: i18n.translate('xpack.siem.endpoint.resolver.fileEventTypeDisplayName', { + defaultMessage: 'File', + }), + host: i18n.translate('xpack.siem.endpoint.resolver.hostEventTypeDisplayName', { + defaultMessage: 'Host', + }), + iam: i18n.translate('xpack.siem.endpoint.resolver.iamEventTypeDisplayName', { + defaultMessage: 'IAM', + }), + iam_group: i18n.translate('xpack.siem.endpoint.resolver.iam_groupEventTypeDisplayName', { + defaultMessage: 'IAM Group', + }), + intrusion_detection: i18n.translate( + 'xpack.siem.endpoint.resolver.intrusion_detectionEventTypeDisplayName', + { + defaultMessage: 'Intrusion Detection', + } + ), + malware: i18n.translate('xpack.siem.endpoint.resolver.malwareEventTypeDisplayName', { + defaultMessage: 'Malware', + }), + network_flow: i18n.translate('xpack.siem.endpoint.resolver.network_flowEventTypeDisplayName', { + defaultMessage: 'Network Flow', + }), + network: i18n.translate('xpack.siem.endpoint.resolver.networkEventTypeDisplayName', { + defaultMessage: 'Network', + }), + package: i18n.translate('xpack.siem.endpoint.resolver.packageEventTypeDisplayName', { + defaultMessage: 'Package', + }), + process: i18n.translate('xpack.siem.endpoint.resolver.processEventTypeDisplayName', { + defaultMessage: 'Process', + }), + registry: i18n.translate('xpack.siem.endpoint.resolver.registryEventTypeDisplayName', { + defaultMessage: 'Registry', + }), + session: i18n.translate('xpack.siem.endpoint.resolver.sessionEventTypeDisplayName', { + defaultMessage: 'Session', + }), + service: i18n.translate('xpack.siem.endpoint.resolver.serviceEventTypeDisplayName', { + defaultMessage: 'Service', + }), + socket: i18n.translate('xpack.siem.endpoint.resolver.socketEventTypeDisplayName', { + defaultMessage: 'Socket', + }), + vulnerability: i18n.translate( + 'xpack.siem.endpoint.resolver.vulnerabilityEventTypeDisplayName', + { + defaultMessage: 'Vulnerability', + } + ), + web: i18n.translate('xpack.siem.endpoint.resolver.webEventTypeDisplayName', { + defaultMessage: 'Web', + }), + alert: i18n.translate('xpack.siem.endpoint.resolver.alertEventTypeDisplayName', { + defaultMessage: 'Alert', + }), + security: i18n.translate('xpack.siem.endpoint.resolver.securityEventTypeDisplayName', { + defaultMessage: 'Security', + }), + dns: i18n.translate('xpack.siem.endpoint.resolver.dnsEventTypeDisplayName', { + defaultMessage: 'DNS', + }), + clr: i18n.translate('xpack.siem.endpoint.resolver.clrEventTypeDisplayName', { + defaultMessage: 'CLR', + }), + image_load: i18n.translate('xpack.siem.endpoint.resolver.image_loadEventTypeDisplayName', { + defaultMessage: 'Image Load', + }), + powershell: i18n.translate('xpack.siem.endpoint.resolver.powershellEventTypeDisplayName', { + defaultMessage: 'Powershell', + }), + wmi: i18n.translate('xpack.siem.endpoint.resolver.wmiEventTypeDisplayName', { + defaultMessage: 'WMI', + }), + api: i18n.translate('xpack.siem.endpoint.resolver.apiEventTypeDisplayName', { + defaultMessage: 'API', + }), + user: i18n.translate('xpack.siem.endpoint.resolver.userEventTypeDisplayName', { + defaultMessage: 'User', + }), + }; + return ( + displayNameRecord[schemaName] || + i18n.translate('xpack.siem.endpoint.resolver.userEventTypeDisplayUnknown', { + defaultMessage: 'Unknown', + }) + ); +}; + +/** + * An artifact that represents a process node and the things associated with it in the Resolver + */ +const ProcessEventDotComponents = React.memo( + ({ + className, + position, + event, + projectionMatrix, + adjacentNodeMap, + relatedEvents, + }: { + /** + * A `className` string provided by `styled` + */ + className?: string; + /** + * The positon of the process node, in 'world' coordinates. + */ + position: Vector2; + /** + * An event which contains details about the process node. + */ + event: ResolverEvent; + /** + * projectionMatrix which can be used to convert `position` to screen coordinates. + */ + projectionMatrix: Matrix3; + /** + * map of what nodes are "adjacent" to this one in "up, down, previous, next" directions + */ + adjacentNodeMap: AdjacentProcessMap; + /** + * A collection of events related to the current node and statistics (e.g. counts indexed by event type) + * to provide the user some visibility regarding the contents thereof. + */ + relatedEvents?: RelatedEventEntryWithStatsOrWaiting; + }) => { + /** + * Convert the position, which is in 'world' coordinates, to screen coordinates. + */ + const [left, top] = applyMatrix3(position, projectionMatrix); + + const [magFactorX] = projectionMatrix; + + const selfId = adjacentNodeMap.self; + + const activeDescendantId = useSelector(selectors.uiActiveDescendantId); + const selectedDescendantId = useSelector(selectors.uiSelectedDescendantId); + + const logicalProcessNodeViewWidth = 360; + const logicalProcessNodeViewHeight = 120; + /** + * The `left` and `top` values represent the 'center' point of the process node. + * Since the view has content to the left and above the 'center' point, offset the + * position to accomodate for that. This aligns the logical center of the process node + * with the correct position on the map. + */ + const processNodeViewXOffset = -0.172413 * logicalProcessNodeViewWidth * magFactorX; + const processNodeViewYOffset = -0.73684 * logicalProcessNodeViewHeight * magFactorX; + + const nodeViewportStyle = useMemo( + () => ({ + left: `${left + processNodeViewXOffset}px`, + top: `${top + processNodeViewYOffset}px`, + // Width of symbol viewport scaled to fit + width: `${logicalProcessNodeViewWidth * magFactorX}px`, + // Height according to symbol viewbox AR + height: `${logicalProcessNodeViewHeight * magFactorX}px`, + }), + [left, magFactorX, processNodeViewXOffset, processNodeViewYOffset, top] + ); + + /** + * Type in non-SVG components scales as follows: + * (These values were adjusted to match the proportions in the comps provided by UX/Design) + * 18.75 : The smallest readable font size at which labels/descriptions can be read. Font size will not scale below this. + * 12.5 : A 'slope' at which the font size will scale w.r.t. to zoom level otherwise + */ + const minimumFontSize = 18.75; + const slopeOfFontScale = 12.5; + const fontSizeAdjustmentForScale = magFactorX > 1 ? slopeOfFontScale * (magFactorX - 1) : 0; + const scaledTypeSize = minimumFontSize + fontSizeAdjustmentForScale; + + const markerBaseSize = 15; + const markerSize = markerBaseSize; + const markerPositionOffset = -markerBaseSize / 2; + + /** + * An element that should be animated when the node is clicked. + */ + const animationTarget: { + current: + | (SVGAnimationElement & { + /** + * `beginElement` is by [w3](https://www.w3.org/TR/SVG11/animate.html#__smil__ElementTimeControl__beginElement) + * but missing in [TSJS-lib-generator](https://github.com/microsoft/TSJS-lib-generator/blob/15a4678e0ef6de308e79451503e444e9949ee849/inputfiles/addedTypes.json#L1819) + */ + beginElement: () => void; + }) + | null; + } = React.createRef(); + const { cubeSymbol, labelBackground, descriptionText } = nodeAssets[nodeType(event)]; + const resolverNodeIdGenerator = useMemo(() => htmlIdGenerator('resolverNode'), []); + + const nodeId = useMemo(() => resolverNodeIdGenerator(selfId), [ + resolverNodeIdGenerator, + selfId, + ]); + const labelId = useMemo(() => resolverNodeIdGenerator(), [resolverNodeIdGenerator]); + const descriptionId = useMemo(() => resolverNodeIdGenerator(), [resolverNodeIdGenerator]); + const isActiveDescendant = nodeId === activeDescendantId; + const isSelectedDescendant = nodeId === selectedDescendantId; + + const dispatch = useResolverDispatch(); + + const handleFocus = useCallback(() => { + dispatch({ + type: 'userFocusedOnResolverNode', + payload: { + nodeId, + }, + }); + }, [dispatch, nodeId]); + + const handleClick = useCallback(() => { + if (animationTarget.current !== null) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (animationTarget.current as any).beginElement(); + } + dispatch({ + type: 'userSelectedResolverNode', + payload: { + nodeId, + }, + }); + }, [animationTarget, dispatch, nodeId]); + + const handleRelatedEventRequest = useCallback(() => { + dispatch({ + type: 'userRequestedRelatedEventData', + payload: event, + }); + }, [dispatch, event]); + + const handleRelatedAlertsRequest = useCallback(() => { + dispatch({ + type: 'userSelectedRelatedAlerts', + payload: event, + }); + }, [dispatch, event]); + /** + * Enumerates the stats for related events to display with the node as options, + * generally in the form `number of related events in category` `category title` + * e.g. "10 DNS", "230 File" + */ + const relatedEventOptions = useMemo(() => { + if (relatedEvents === 'error') { + // Return an empty set of options if there was an error requesting them + return []; + } + const relatedStats = typeof relatedEvents === 'object' && relatedEvents.stats; + if (!relatedStats) { + // Return an empty set of options if there are no stats to report + return []; + } + // If we have entries to show, map them into options to display in the selectable list + return Object.entries(relatedStats).map(statsEntry => { + const displayName = getDisplayName(statsEntry[0]); + return { + prefix: , + optionTitle: `${displayName}`, + action: () => { + dispatch({ + type: 'userSelectedRelatedEventCategory', + payload: { + subject: event, + category: statsEntry[0], + }, + }); + }, + }; + }); + }, [relatedEvents, dispatch, event]); + + const relatedEventStatusOrOptions = (() => { + if (!relatedEvents) { + // If related events have not yet been requested + return subMenuAssets.initialMenuStatus; + } + if (relatedEvents === 'error') { + // If there was an error when we tried to request the events + return subMenuAssets.menuError; + } + if (relatedEvents === 'waitingForRelatedEventData') { + // If we're waiting for events to be returned + // Pass on the waiting symbol + return relatedEvents; + } + return relatedEventOptions; + })(); + + /* eslint-disable jsx-a11y/click-events-have-key-events */ + /** + * Key event handling (e.g. 'Enter'/'Space') is provisioned by the `EuiKeyboardAccessible` component + */ + return ( + +
    + + + + + + + + +
    +
    + {descriptionText} +
    +
    = 2 ? 'euiButton' : 'euiButton euiButton--small'} + data-test-subject="nodeLabel" + id={labelId} + style={{ + backgroundColor: labelBackground, + padding: '.15rem 0', + textAlign: 'center', + maxWidth: '20rem', + minWidth: '12rem', + width: '60%', + overflow: 'hidden', + whiteSpace: 'nowrap', + textOverflow: 'ellipsis', + contain: 'content', + margin: '.25rem 0 .35rem 0', + }} + > + + + {eventModel.eventName(event)} + + +
    + {magFactorX >= 2 && ( + + + + + + + + + )} +
    +
    +
    + ); + /* eslint-enable jsx-a11y/click-events-have-key-events */ + } +); + +ProcessEventDotComponents.displayName = 'ProcessEventDot'; + +export const ProcessEventDot = styled(ProcessEventDotComponents)` + position: absolute; + text-align: left; + font-size: 10px; + user-select: none; + box-sizing: border-box; + border-radius: 10%; + white-space: nowrap; + will-change: left, top, width, height; + contain: layout; + min-width: 280px; + min-height: 90px; + overflow-y: visible; + + //dasharray & dashoffset should be equal to "pull" the stroke back + //when it is transitioned. + //The value is tuned to look good when animated, but to preserve + //the effect, it should always be _at least_ the length of the stroke + & .backing { + stroke-dasharray: 500; + stroke-dashoffset: 500; + } + &[aria-current] .backing { + transition-property: stroke-dashoffset; + transition-duration: 1s; + stroke-dashoffset: 0; + } + + & .related-dropdown { + width: 4.5em; + } + & .euiSelectableList-bordered { + border-top-right-radius: 0px; + border-top-left-radius: 0px; + } + & .euiSelectableListItem { + background-color: black; + } + & .euiSelectableListItem path { + fill: white; + } + & .euiSelectableListItem__text { + color: white; + } +`; + +const processTypeToCube: Record = { + processCreated: 'runningProcessCube', + processRan: 'runningProcessCube', + processTerminated: 'terminatedProcessCube', + unknownProcessEvent: 'runningProcessCube', + processCausedAlert: 'runningTriggerCube', + unknownEvent: 'runningProcessCube', +}; + +function nodeType(processEvent: ResolverEvent): keyof typeof nodeAssets { + const processType = processModel.eventType(processEvent); + + if (processType in processTypeToCube) { + return processTypeToCube[processType]; + } + return 'runningProcessCube'; +} diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/side_effect_context.ts b/x-pack/plugins/siem/public/resolver/view/side_effect_context.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/view/side_effect_context.ts rename to x-pack/plugins/siem/public/resolver/view/side_effect_context.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/side_effect_simulator.ts b/x-pack/plugins/siem/public/resolver/view/side_effect_simulator.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/view/side_effect_simulator.ts rename to x-pack/plugins/siem/public/resolver/view/side_effect_simulator.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/submenu.tsx b/x-pack/plugins/siem/public/resolver/view/submenu.tsx similarity index 51% rename from x-pack/plugins/endpoint/public/embeddables/resolver/view/submenu.tsx rename to x-pack/plugins/siem/public/resolver/view/submenu.tsx index 9f6427d801ce4..cdcce5d23c0c3 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/view/submenu.tsx +++ b/x-pack/plugins/siem/public/resolver/view/submenu.tsx @@ -1,178 +1,182 @@ -/* - * 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'; -import React, { ReactNode, useState, useMemo, useCallback } from 'react'; -import { EuiSelectable, EuiButton } from '@elastic/eui'; -import styled from 'styled-components'; - -/** - * i18n-translated titles for submenus and identifiers for display of states: - * initialMenuStatus: submenu before it has been opened / requested data - * menuError: if the submenu requested data, but received an error - */ -export const subMenuAssets = { - initialMenuStatus: i18n.translate('xpack.endpoint.resolver.relatedNotRetrieved', { - defaultMessage: 'Related Events have not yet been retrieved.', - }), - menuError: i18n.translate('xpack.endpoint.resolver.relatedRetrievalError', { - defaultMessage: 'There was an error retrieving related events.', - }), - relatedAlerts: { - title: i18n.translate('xpack.endpoint.resolver.relatedAlerts', { - defaultMessage: 'Related Alerts', - }), - }, - relatedEvents: { - title: i18n.translate('xpack.endpoint.resolver.relatedEvents', { - defaultMessage: 'Events', - }), - }, -}; - -interface ResolverSubmenuOption { - optionTitle: string; - action: () => unknown; - prefix?: number | JSX.Element; -} - -export type ResolverSubmenuOptionList = ResolverSubmenuOption[] | string; - -const OptionList = React.memo( - ({ - subMenuOptions, - isLoading, - }: { - subMenuOptions: ResolverSubmenuOptionList; - isLoading: boolean; - }) => { - const [options, setOptions] = useState(() => - typeof subMenuOptions !== 'object' - ? [] - : subMenuOptions.map((opt: ResolverSubmenuOption): { - label: string; - prepend?: ReactNode; - } => { - return opt.prefix - ? { - label: opt.optionTitle, - prepend: {opt.prefix} , - } - : { - label: opt.optionTitle, - prepend: , - }; - }) - ); - return useMemo( - () => ( - { - setOptions(newOptions); - }} - listProps={{ showIcons: true, bordered: true }} - isLoading={isLoading} - > - {list => list} - - ), - [isLoading, options] - ); - } -); - -/** - * A Submenu to be displayed in one of two forms: - * 1) Provided a collection of `optionsWithActions`: it will call `menuAction` then - if and when menuData becomes available - display each item with an optional prefix and call the supplied action for the options when that option is clicked. - * 2) Provided `optionsWithActions` is undefined, it will call the supplied `menuAction` when its host button is clicked. - */ -export const NodeSubMenu = styled( - React.memo( - ({ - menuTitle, - menuAction, - optionsWithActions, - className, - }: { menuTitle: string; className?: string; menuAction: () => unknown } & { - optionsWithActions?: ResolverSubmenuOptionList | string | undefined; - }) => { - const [menuIsOpen, setMenuOpen] = useState(false); - const handleMenuOpenClick = useCallback( - (clickEvent: React.MouseEvent) => { - // stopping propagation/default to prevent other node animations from triggering - clickEvent.preventDefault(); - clickEvent.stopPropagation(); - setMenuOpen(!menuIsOpen); - }, - [menuIsOpen] - ); - const handleMenuActionClick = useCallback( - (clickEvent: React.MouseEvent) => { - // stopping propagation/default to prevent other node animations from triggering - clickEvent.preventDefault(); - clickEvent.stopPropagation(); - if (typeof menuAction === 'function') menuAction(); - setMenuOpen(true); - }, - [menuAction] - ); - - const isMenuLoading = optionsWithActions === 'waitingForRelatedEventData'; - - if (!optionsWithActions) { - /** - * When called with a `menuAction` - * Render without dropdown and call the supplied action when host button is clicked - */ - return ( -
    - - {menuTitle} - -
    - ); - } - /** - * When called with a set of `optionsWithActions`: - * Render with a panel of options that appear when the menu host button is clicked - */ - return ( -
    - - {menuTitle} - - {menuIsOpen && typeof optionsWithActions === 'object' && ( - - )} -
    - ); - } - ) -)` - margin: 0; - padding: 0; - border: none; - display: flex; - flex-flow: column; - &.is-open .euiButton { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - } - &.is-open .euiSelectableListItem__prepend { - color: white; - } -`; +/* + * 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'; +import React, { ReactNode, useState, useMemo, useCallback } from 'react'; +import { EuiSelectable, EuiButton } from '@elastic/eui'; +import styled from 'styled-components'; + +/** + * i18n-translated titles for submenus and identifiers for display of states: + * initialMenuStatus: submenu before it has been opened / requested data + * menuError: if the submenu requested data, but received an error + */ +export const subMenuAssets = { + initialMenuStatus: i18n.translate('xpack.siem.endpoint.resolver.relatedNotRetrieved', { + defaultMessage: 'Related Events have not yet been retrieved.', + }), + menuError: i18n.translate('xpack.siem.endpoint.resolver.relatedRetrievalError', { + defaultMessage: 'There was an error retrieving related events.', + }), + relatedAlerts: { + title: i18n.translate('xpack.siem.endpoint.resolver.relatedAlerts', { + defaultMessage: 'Related Alerts', + }), + }, + relatedEvents: { + title: i18n.translate('xpack.siem.endpoint.resolver.relatedEvents', { + defaultMessage: 'Events', + }), + }, +}; + +interface ResolverSubmenuOption { + optionTitle: string; + action: () => unknown; + prefix?: number | JSX.Element; +} + +export type ResolverSubmenuOptionList = ResolverSubmenuOption[] | string; + +const OptionList = React.memo( + ({ + subMenuOptions, + isLoading, + }: { + subMenuOptions: ResolverSubmenuOptionList; + isLoading: boolean; + }) => { + const [options, setOptions] = useState(() => + typeof subMenuOptions !== 'object' + ? [] + : subMenuOptions.map((opt: ResolverSubmenuOption): { + label: string; + prepend?: ReactNode; + } => { + return opt.prefix + ? { + label: opt.optionTitle, + prepend: {opt.prefix} , + } + : { + label: opt.optionTitle, + prepend: , + }; + }) + ); + return useMemo( + () => ( + { + setOptions(newOptions); + }} + listProps={{ showIcons: true, bordered: true }} + isLoading={isLoading} + > + {list => list} + + ), + [isLoading, options] + ); + } +); + +OptionList.displayName = 'OptionList'; + +/** + * A Submenu to be displayed in one of two forms: + * 1) Provided a collection of `optionsWithActions`: it will call `menuAction` then - if and when menuData becomes available - display each item with an optional prefix and call the supplied action for the options when that option is clicked. + * 2) Provided `optionsWithActions` is undefined, it will call the supplied `menuAction` when its host button is clicked. + */ +const NodeSubMenuComponents = React.memo( + ({ + menuTitle, + menuAction, + optionsWithActions, + className, + }: { menuTitle: string; className?: string; menuAction: () => unknown } & { + optionsWithActions?: ResolverSubmenuOptionList | string | undefined; + }) => { + const [menuIsOpen, setMenuOpen] = useState(false); + const handleMenuOpenClick = useCallback( + (clickEvent: React.MouseEvent) => { + // stopping propagation/default to prevent other node animations from triggering + clickEvent.preventDefault(); + clickEvent.stopPropagation(); + setMenuOpen(!menuIsOpen); + }, + [menuIsOpen] + ); + const handleMenuActionClick = useCallback( + (clickEvent: React.MouseEvent) => { + // stopping propagation/default to prevent other node animations from triggering + clickEvent.preventDefault(); + clickEvent.stopPropagation(); + if (typeof menuAction === 'function') menuAction(); + setMenuOpen(true); + }, + [menuAction] + ); + + const isMenuLoading = optionsWithActions === 'waitingForRelatedEventData'; + + if (!optionsWithActions) { + /** + * When called with a `menuAction` + * Render without dropdown and call the supplied action when host button is clicked + */ + return ( +
    + + {menuTitle} + +
    + ); + } + /** + * When called with a set of `optionsWithActions`: + * Render with a panel of options that appear when the menu host button is clicked + */ + return ( +
    + + {menuTitle} + + {menuIsOpen && typeof optionsWithActions === 'object' && ( + + )} +
    + ); + } +); + +NodeSubMenuComponents.displayName = 'NodeSubMenu'; + +export const NodeSubMenu = styled(NodeSubMenuComponents)` + margin: 0; + padding: 0; + border: none; + display: flex; + flex-flow: column; + &.is-open .euiButton { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + &.is-open .euiSelectableListItem__prepend { + color: white; + } +`; diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/use_camera.test.tsx b/x-pack/plugins/siem/public/resolver/view/use_camera.test.tsx similarity index 99% rename from x-pack/plugins/endpoint/public/embeddables/resolver/view/use_camera.test.tsx rename to x-pack/plugins/siem/public/resolver/view/use_camera.test.tsx index 63f47396d4479..f8aa4fbca3291 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/view/use_camera.test.tsx +++ b/x-pack/plugins/siem/public/resolver/view/use_camera.test.tsx @@ -12,7 +12,7 @@ import { Provider } from 'react-redux'; import * as selectors from '../store/selectors'; import { storeFactory } from '../store'; import { Matrix3, ResolverAction, ResolverStore, SideEffectSimulator } from '../types'; -import { ResolverEvent } from '../../../../common/types'; +import { ResolverEvent } from '../../../common/endpoint/types'; import { SideEffectContext } from './side_effect_context'; import { applyMatrix3 } from '../lib/vector2'; import { sideEffectSimulator } from './side_effect_simulator'; diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/use_camera.ts b/x-pack/plugins/siem/public/resolver/view/use_camera.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/view/use_camera.ts rename to x-pack/plugins/siem/public/resolver/view/use_camera.ts diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/use_resolver_dispatch.ts b/x-pack/plugins/siem/public/resolver/view/use_resolver_dispatch.ts similarity index 100% rename from x-pack/plugins/endpoint/public/embeddables/resolver/view/use_resolver_dispatch.ts rename to x-pack/plugins/siem/public/resolver/view/use_resolver_dispatch.ts diff --git a/x-pack/plugins/siem/public/types.ts b/x-pack/plugins/siem/public/types.ts new file mode 100644 index 0000000000000..6c338d47cf63c --- /dev/null +++ b/x-pack/plugins/siem/public/types.ts @@ -0,0 +1,47 @@ +/* + * 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 { CoreStart } from '../../../../src/core/public'; + +import { HomePublicPluginSetup } from '../../../../src/plugins/home/public'; +import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; +import { EmbeddableStart } from '../../../../src/plugins/embeddable/public'; +import { Start as NewsfeedStart } from '../../../../src/plugins/newsfeed/public'; +import { Start as InspectorStart } from '../../../../src/plugins/inspector/public'; +import { UiActionsStart } from '../../../../src/plugins/ui_actions/public'; +import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public'; +import { IngestManagerStart } from '../../ingest_manager/public'; +import { + TriggersAndActionsUIPublicPluginSetup as TriggersActionsSetup, + TriggersAndActionsUIPublicPluginStart as TriggersActionsStart, +} from '../../triggers_actions_ui/public'; +import { SecurityPluginSetup } from '../../security/public'; + +export interface SetupPlugins { + home: HomePublicPluginSetup; + security: SecurityPluginSetup; + triggers_actions_ui: TriggersActionsSetup; + usageCollection?: UsageCollectionSetup; +} + +export interface StartPlugins { + data: DataPublicPluginStart; + embeddable: EmbeddableStart; + inspector: InspectorStart; + ingestManager: IngestManagerStart; + newsfeed?: NewsfeedStart; + triggers_actions_ui: TriggersActionsStart; + uiActions: UiActionsStart; +} + +export type StartServices = CoreStart & + StartPlugins & { + security: SecurityPluginSetup; + }; + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface PluginSetup {} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface PluginStart {} diff --git a/x-pack/plugins/endpoint/scripts/README.md b/x-pack/plugins/siem/scripts/endpoint/README.md similarity index 97% rename from x-pack/plugins/endpoint/scripts/README.md rename to x-pack/plugins/siem/scripts/endpoint/README.md index f0c8c5a9b0b66..84e92d8c397e1 100644 --- a/x-pack/plugins/endpoint/scripts/README.md +++ b/x-pack/plugins/siem/scripts/endpoint/README.md @@ -11,7 +11,7 @@ Example command sequence to get ES and kibana running with sample data after ins ```yarn es snapshot``` -> starts ES -```npx yarn start --xpack.endpoint.enabled=true --no-base-path``` -> starts kibana +```npx yarn start --xpack.siem.endpoint.enabled=true --no-base-path``` -> starts kibana ```cd ~/path/to/kibana/x-pack/plugins/endpoint``` diff --git a/x-pack/plugins/endpoint/scripts/alert_mapping.json b/x-pack/plugins/siem/scripts/endpoint/alert_mapping.json similarity index 100% rename from x-pack/plugins/endpoint/scripts/alert_mapping.json rename to x-pack/plugins/siem/scripts/endpoint/alert_mapping.json diff --git a/x-pack/plugins/endpoint/scripts/cli_tsconfig.json b/x-pack/plugins/siem/scripts/endpoint/cli_tsconfig.json similarity index 68% rename from x-pack/plugins/endpoint/scripts/cli_tsconfig.json rename to x-pack/plugins/siem/scripts/endpoint/cli_tsconfig.json index 25afe109a42ea..5c68f8ee0abf2 100644 --- a/x-pack/plugins/endpoint/scripts/cli_tsconfig.json +++ b/x-pack/plugins/siem/scripts/endpoint/cli_tsconfig.json @@ -1,8 +1,7 @@ { - "extends": "../../../tsconfig.json", + "extends": "../../../../tsconfig.json", "compilerOptions": { "target": "es2019", "resolveJsonModule": true } } - \ No newline at end of file diff --git a/x-pack/plugins/endpoint/scripts/event_mapping.json b/x-pack/plugins/siem/scripts/endpoint/event_mapping.json similarity index 100% rename from x-pack/plugins/endpoint/scripts/event_mapping.json rename to x-pack/plugins/siem/scripts/endpoint/event_mapping.json diff --git a/x-pack/plugins/endpoint/scripts/policy_mapping.json b/x-pack/plugins/siem/scripts/endpoint/policy_mapping.json similarity index 100% rename from x-pack/plugins/endpoint/scripts/policy_mapping.json rename to x-pack/plugins/siem/scripts/endpoint/policy_mapping.json diff --git a/x-pack/plugins/endpoint/scripts/resolver_generator.ts b/x-pack/plugins/siem/scripts/endpoint/resolver_generator.ts similarity index 93% rename from x-pack/plugins/endpoint/scripts/resolver_generator.ts rename to x-pack/plugins/siem/scripts/endpoint/resolver_generator.ts index 30752877db824..68d578173719c 100644 --- a/x-pack/plugins/endpoint/scripts/resolver_generator.ts +++ b/x-pack/plugins/siem/scripts/endpoint/resolver_generator.ts @@ -7,7 +7,7 @@ import * as yargs from 'yargs'; import seedrandom from 'seedrandom'; import { Client, ClientOptions } from '@elastic/elasticsearch'; import { ResponseError } from '@elastic/elasticsearch/lib/errors'; -import { EndpointDocGenerator, Event } from '../common/generate_data'; +import { EndpointDocGenerator, Event } from '../../common/endpoint/generate_data'; import { default as eventMapping } from './event_mapping.json'; import { default as alertMapping } from './alert_mapping.json'; import { default as policyMapping } from './policy_mapping.json'; @@ -142,6 +142,7 @@ async function main() { if (err instanceof ResponseError && err.statusCode !== 404) { // eslint-disable-next-line no-console console.log(err); + // eslint-disable-next-line no-process-exit process.exit(1); } } @@ -173,6 +174,7 @@ async function main() { } catch (err) { // eslint-disable-next-line no-console console.log(err); + // eslint-disable-next-line no-process-exit process.exit(1); } @@ -180,6 +182,7 @@ async function main() { await createIndex(client, argv.eventIndex, eventMapping); await createIndex(client, argv.policyIndex, policyMapping); if (argv.setupOnly) { + // eslint-disable-next-line no-process-exit process.exit(0); } @@ -187,7 +190,7 @@ async function main() { if (!seed) { seed = Math.random().toString(); // eslint-disable-next-line no-console - console.log('No seed supplied, using random seed: ' + seed); + console.log(`No seed supplied, using random seed: ${seed}`); } const random = seedrandom(seed); for (let i = 0; i < argv.numHosts; i++) { @@ -229,6 +232,7 @@ async function main() { k++; } const body = resolverDocs.reduce( + // eslint-disable-next-line @typescript-eslint/no-explicit-any (array: Array>, doc) => ( array.push({ index: { _index: argv.eventIndex } }, doc), array ), @@ -240,6 +244,7 @@ async function main() { } } +// eslint-disable-next-line @typescript-eslint/no-explicit-any async function createIndex(client: Client, index: string, mapping: any) { try { await client.indices.create({ @@ -253,6 +258,7 @@ async function createIndex(client: Client, index: string, mapping: any) { ) { // eslint-disable-next-line no-console console.log(err.body); + // eslint-disable-next-line no-process-exit process.exit(1); } } diff --git a/x-pack/plugins/siem/server/config.ts b/x-pack/plugins/siem/server/config.ts index 4b0e8d34ef1a0..f7d961ae3ec5c 100644 --- a/x-pack/plugins/siem/server/config.ts +++ b/x-pack/plugins/siem/server/config.ts @@ -16,6 +16,19 @@ export const configSchema = schema.object({ maxTimelineImportExportSize: schema.number({ defaultValue: 10000 }), maxTimelineImportPayloadBytes: schema.number({ defaultValue: 10485760 }), [SIGNALS_INDEX_KEY]: schema.string({ defaultValue: DEFAULT_SIGNALS_INDEX }), + /** + * Host Endpoint Configuration + */ + endpointResultListDefaultFirstPageIndex: schema.number({ defaultValue: 0 }), + endpointResultListDefaultPageSize: schema.number({ defaultValue: 10 }), + + /** + * Alert Endpoint Configuration + */ + alertResultListDefaultDateRange: schema.object({ + from: schema.string({ defaultValue: 'now-15m' }), + to: schema.string({ defaultValue: 'now' }), + }), }); export const createConfig$ = (context: PluginInitializerContext) => diff --git a/x-pack/plugins/endpoint/server/routes/alerts/alerts.test.ts b/x-pack/plugins/siem/server/endpoint/alerts/handlers/alerts.test.ts similarity index 89% rename from x-pack/plugins/endpoint/server/routes/alerts/alerts.test.ts rename to x-pack/plugins/siem/server/endpoint/alerts/handlers/alerts.test.ts index 1124c977ff924..37bf4bbfcbbb2 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/alerts.test.ts +++ b/x-pack/plugins/siem/server/endpoint/alerts/handlers/alerts.test.ts @@ -8,12 +8,12 @@ import { elasticsearchServiceMock, httpServiceMock, loggingServiceMock, -} from '../../../../../../src/core/server/mocks'; -import { registerAlertRoutes } from './index'; -import { EndpointConfigSchema } from '../../config'; -import { alertingIndexGetQuerySchema } from '../../../common/schema/alert_index'; +} from '../../../../../../../src/core/server/mocks'; +import { registerAlertRoutes } from '../routes'; +import { alertingIndexGetQuerySchema } from '../../../../common/endpoint_alerts/schema/alert_index'; import { createMockAgentService, createMockIndexPatternRetriever } from '../../mocks'; import { EndpointAppContextService } from '../../endpoint_app_context_services'; +import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__'; describe('test alerts route', () => { let routerMock: jest.Mocked; @@ -36,7 +36,7 @@ describe('test alerts route', () => { registerAlertRoutes(routerMock, { logFactory: loggingServiceMock.create(), service: endpointAppContextService, - config: () => Promise.resolve(EndpointConfigSchema.validate({})), + config: () => Promise.resolve(createMockConfig()), }); }); diff --git a/x-pack/plugins/endpoint/server/routes/alerts/details/handlers.ts b/x-pack/plugins/siem/server/endpoint/alerts/handlers/details/index.ts similarity index 89% rename from x-pack/plugins/endpoint/server/routes/alerts/details/handlers.ts rename to x-pack/plugins/siem/server/endpoint/alerts/handlers/details/index.ts index ab6d1850e425d..a829cdd14027c 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/details/handlers.ts +++ b/x-pack/plugins/siem/server/endpoint/alerts/handlers/details/index.ts @@ -5,11 +5,11 @@ */ import { GetResponse } from 'elasticsearch'; import { KibanaRequest, RequestHandler } from 'kibana/server'; -import { AlertEvent } from '../../../../common/types'; +import { AlertEvent } from '../../../../../common/endpoint/types'; import { EndpointAppContext } from '../../../types'; -import { AlertDetailsRequestParams } from '../types'; -import { AlertDetailsPagination } from './lib'; -import { getHostData } from '../../metadata'; +import { AlertDetailsRequestParams } from '../../../../../common/endpoint_alerts/types'; +import { AlertDetailsPagination } from './lib/pagination'; +import { getHostData } from '../../../routes/metadata'; import { AlertId, AlertIdError } from '../lib'; export const alertDetailsHandlerWrapper = function( diff --git a/x-pack/plugins/endpoint/server/routes/alerts/details/lib/pagination.ts b/x-pack/plugins/siem/server/endpoint/alerts/handlers/details/lib/pagination.ts similarity index 81% rename from x-pack/plugins/endpoint/server/routes/alerts/details/lib/pagination.ts rename to x-pack/plugins/siem/server/endpoint/alerts/handlers/details/lib/pagination.ts index 5c95b1217d829..e12bd9e4c8de9 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/details/lib/pagination.ts +++ b/x-pack/plugins/siem/server/endpoint/alerts/handlers/details/lib/pagination.ts @@ -5,14 +5,20 @@ */ import { GetResponse, SearchResponse } from 'elasticsearch'; -import { AlertEvent, AlertHits, AlertAPIOrdering } from '../../../../../common/types'; -import { AlertConstants } from '../../../../../common/alert_constants'; +import { AlertEvent } from '../../../../../../common/endpoint/types'; +import { + AlertHits, + AlertAPIOrdering, + AlertSearchQuery, + SearchCursor, + AlertDetailsRequestParams, +} from '../../../../../../common/endpoint_alerts/types'; +import { AlertConstants } from '../../../../../../common/endpoint_alerts/alert_constants'; import { EndpointConfigType } from '../../../../config'; import { searchESForAlerts, Pagination, AlertId } from '../../lib'; -import { AlertSearchQuery, SearchCursor, AlertDetailsRequestParams } from '../../types'; -import { BASE_ALERTS_ROUTE } from '../..'; -import { RequestHandlerContext } from '../../../../../../../../src/core/server'; -import { Filter } from '../../../../../../../../src/plugins/data/server'; +import { BASE_ALERTS_ROUTE } from '../../../routes'; +import { RequestHandlerContext } from '../../../../../../../../../src/core/server'; +import { Filter } from '../../../../../../../../../src/plugins/data/server'; /** * Pagination class for alert details. diff --git a/x-pack/plugins/endpoint/server/routes/alerts/details/schemas.ts b/x-pack/plugins/siem/server/endpoint/alerts/handlers/details/schemas.ts similarity index 100% rename from x-pack/plugins/endpoint/server/routes/alerts/details/schemas.ts rename to x-pack/plugins/siem/server/endpoint/alerts/handlers/details/schemas.ts diff --git a/x-pack/plugins/siem/server/endpoint/alerts/handlers/index_pattern.ts b/x-pack/plugins/siem/server/endpoint/alerts/handlers/index_pattern.ts new file mode 100644 index 0000000000000..cb40be586560f --- /dev/null +++ b/x-pack/plugins/siem/server/endpoint/alerts/handlers/index_pattern.ts @@ -0,0 +1,28 @@ +/* + * 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 { Logger, RequestHandler } from 'kibana/server'; +import { EndpointAppContext } from '../../types'; +import { IndexPatternGetParamsResult } from '../../../../common/endpoint_alerts/types'; + +export function handleIndexPattern( + log: Logger, + endpointAppContext: EndpointAppContext +): RequestHandler { + return async (context, req, res) => { + try { + const indexRetriever = endpointAppContext.service.getIndexPatternRetriever(); + return res.ok({ + body: { + indexPattern: await indexRetriever.getIndexPattern(context, req.params.datasetPath), + }, + }); + } catch (error) { + log.warn(error); + return res.notFound({ body: error }); + } + }; +} diff --git a/x-pack/plugins/endpoint/server/routes/alerts/lib/alert_id.ts b/x-pack/plugins/siem/server/endpoint/alerts/handlers/lib/alert_id.ts similarity index 100% rename from x-pack/plugins/endpoint/server/routes/alerts/lib/alert_id.ts rename to x-pack/plugins/siem/server/endpoint/alerts/handlers/lib/alert_id.ts diff --git a/x-pack/plugins/endpoint/server/routes/alerts/lib/error.ts b/x-pack/plugins/siem/server/endpoint/alerts/handlers/lib/error.ts similarity index 82% rename from x-pack/plugins/endpoint/server/routes/alerts/lib/error.ts rename to x-pack/plugins/siem/server/endpoint/alerts/handlers/lib/error.ts index 7b00634b25c9c..1ba92c64d3cde 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/lib/error.ts +++ b/x-pack/plugins/siem/server/endpoint/alerts/handlers/lib/error.ts @@ -5,6 +5,7 @@ */ export class AlertIdError extends Error { + // eslint-disable-next-line @typescript-eslint/no-useless-constructor constructor(message: string) { super(message); } diff --git a/x-pack/plugins/endpoint/server/routes/alerts/lib/index.ts b/x-pack/plugins/siem/server/endpoint/alerts/handlers/lib/index.ts similarity index 90% rename from x-pack/plugins/endpoint/server/routes/alerts/lib/index.ts rename to x-pack/plugins/siem/server/endpoint/alerts/handlers/lib/index.ts index 1c98e3c615669..4f0a7ba2450dc 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/lib/index.ts +++ b/x-pack/plugins/siem/server/endpoint/alerts/handlers/lib/index.ts @@ -5,17 +5,18 @@ */ import { SearchResponse } from 'elasticsearch'; import { IScopedClusterClient } from 'kibana/server'; -import { JsonObject } from '../../../../../../../src/plugins/kibana_utils/public'; -import { esQuery } from '../../../../../../../src/plugins/data/server'; -import { AlertEvent, AlertAPIOrdering } from '../../../../common/types'; -import { AlertConstants } from '../../../../common/alert_constants'; +import { AlertEvent } from '../../../../../common/endpoint/types'; +import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/public'; +import { esQuery } from '../../../../../../../../src/plugins/data/server'; import { + AlertAPIOrdering, AlertSearchQuery, AlertSearchRequest, AlertSearchRequestWrapper, AlertSort, UndefinedResultPosition, -} from '../types'; +} from '../../../../../common/endpoint_alerts/types'; +import { AlertConstants } from '../../../../../common/endpoint_alerts/alert_constants'; export { AlertIdError } from './error'; export { Pagination } from './pagination'; @@ -40,7 +41,7 @@ function buildQuery(query: AlertSearchQuery): JsonObject { ? [ { range: { - ['@timestamp']: { + '@timestamp': { gte: query.dateRange.from, lte: query.dateRange.to, }, diff --git a/x-pack/plugins/endpoint/server/routes/alerts/lib/pagination.ts b/x-pack/plugins/siem/server/endpoint/alerts/handlers/lib/pagination.ts similarity index 89% rename from x-pack/plugins/endpoint/server/routes/alerts/lib/pagination.ts rename to x-pack/plugins/siem/server/endpoint/alerts/handlers/lib/pagination.ts index fc408878f8956..d0ca493bf7183 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/lib/pagination.ts +++ b/x-pack/plugins/siem/server/endpoint/alerts/handlers/lib/pagination.ts @@ -5,7 +5,7 @@ */ import { EndpointConfigType } from '../../../config'; -import { RequestHandlerContext } from '../../../../../../../src/core/server'; +import { RequestHandlerContext } from '../../../../../../../../src/core/server'; /** * Abstract Pagination class for determining next/prev urls, diff --git a/x-pack/plugins/endpoint/server/routes/alerts/list/handlers.ts b/x-pack/plugins/siem/server/endpoint/alerts/handlers/list/index.ts similarity index 93% rename from x-pack/plugins/endpoint/server/routes/alerts/list/handlers.ts rename to x-pack/plugins/siem/server/endpoint/alerts/handlers/list/index.ts index 44a0cf8744a9e..ebea12191ef10 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/list/handlers.ts +++ b/x-pack/plugins/siem/server/endpoint/alerts/handlers/list/index.ts @@ -7,7 +7,7 @@ import { RequestHandler } from 'kibana/server'; import { EndpointAppContext } from '../../../types'; import { searchESForAlerts } from '../lib'; import { getRequestData, mapToAlertResultList } from './lib'; -import { AlertingIndexGetQueryResult } from '../../../../common/types'; +import { AlertingIndexGetQueryResult } from '../../../../../common/endpoint_alerts/types'; export const alertListHandlerWrapper = function( endpointAppContext: EndpointAppContext diff --git a/x-pack/plugins/endpoint/server/routes/alerts/list/lib/index.ts b/x-pack/plugins/siem/server/endpoint/alerts/handlers/list/lib/index.ts similarity index 93% rename from x-pack/plugins/endpoint/server/routes/alerts/list/lib/index.ts rename to x-pack/plugins/siem/server/endpoint/alerts/handlers/list/lib/index.ts index 0af8f6cf792dd..18e38280c7a0d 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/list/lib/index.ts +++ b/x-pack/plugins/siem/server/endpoint/alerts/handlers/list/lib/index.ts @@ -7,18 +7,18 @@ import { decode } from 'rison-node'; import { SearchResponse } from 'elasticsearch'; import { KibanaRequest } from 'kibana/server'; import { RequestHandlerContext } from 'src/core/server'; -import { Query, Filter, TimeRange } from '../../../../../../../../src/plugins/data/server'; +import { AlertEvent } from '../../../../../../common/endpoint/types'; +import { Query, Filter, TimeRange } from '../../../../../../../../../src/plugins/data/server'; import { - AlertEvent, AlertData, AlertResultList, AlertHits, ESTotal, AlertingIndexGetQueryResult, -} from '../../../../../common/types'; -import { AlertConstants } from '../../../../../common/alert_constants'; + AlertSearchQuery, +} from '../../../../../../common/endpoint_alerts/types'; +import { AlertConstants } from '../../../../../../common/endpoint_alerts/alert_constants'; import { EndpointAppContext } from '../../../../types'; -import { AlertSearchQuery } from '../../types'; import { AlertListPagination } from './pagination'; import { AlertId } from '../../lib'; diff --git a/x-pack/plugins/endpoint/server/routes/alerts/list/lib/pagination.ts b/x-pack/plugins/siem/server/endpoint/alerts/handlers/list/lib/pagination.ts similarity index 93% rename from x-pack/plugins/endpoint/server/routes/alerts/list/lib/pagination.ts rename to x-pack/plugins/siem/server/endpoint/alerts/handlers/list/lib/pagination.ts index 7bebe3d9288c3..0a831714275ee 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/list/lib/pagination.ts +++ b/x-pack/plugins/siem/server/endpoint/alerts/handlers/list/lib/pagination.ts @@ -7,11 +7,10 @@ import { get } from 'lodash'; import { RisonValue, encode } from 'rison-node'; import { RequestHandlerContext } from 'src/core/server'; -import { AlertHits } from '../../../../../common/types'; +import { AlertHits, AlertSearchQuery } from '../../../../../../common/endpoint_alerts/types'; import { EndpointConfigType } from '../../../../config'; -import { AlertSearchQuery } from '../../types'; -import { Pagination } from '../../lib'; -import { BASE_ALERTS_ROUTE } from '../..'; +import { Pagination } from '../../lib/pagination'; +import { BASE_ALERTS_ROUTE } from '../../../routes'; /** * Pagination class for alert list. diff --git a/x-pack/plugins/endpoint/server/index_pattern.ts b/x-pack/plugins/siem/server/endpoint/alerts/index_pattern.ts similarity index 91% rename from x-pack/plugins/endpoint/server/index_pattern.ts rename to x-pack/plugins/siem/server/endpoint/alerts/index_pattern.ts index f4bb1460aee4b..1cbdf96c5bcee 100644 --- a/x-pack/plugins/endpoint/server/index_pattern.ts +++ b/x-pack/plugins/siem/server/endpoint/alerts/index_pattern.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ import { Logger, LoggerFactory, RequestHandlerContext } from 'kibana/server'; -import { AlertConstants } from '../common/alert_constants'; -import { ESIndexPatternService } from '../../ingest_manager/server'; +import { AlertConstants } from '../../../common/endpoint_alerts/alert_constants'; +import { ESIndexPatternService } from '../../../../ingest_manager/server'; export interface IndexPatternRetriever { getIndexPattern(ctx: RequestHandlerContext, datasetPath: string): Promise; @@ -34,7 +34,7 @@ export class IngestIndexPatternRetriever implements IndexPatternRetriever { * @returns a string representing the index pattern (e.g. `events-endpoint-*`) */ async getEventIndexPattern(ctx: RequestHandlerContext) { - return await this.getIndexPattern(ctx, AlertConstants.EVENT_DATASET); + return this.getIndexPattern(ctx, AlertConstants.EVENT_DATASET); } /** @@ -44,7 +44,7 @@ export class IngestIndexPatternRetriever implements IndexPatternRetriever { * @returns a string representing the index pattern (e.g. `metrics-endpoint-*`) */ async getMetadataIndexPattern(ctx: RequestHandlerContext) { - return await this.getIndexPattern(ctx, IngestIndexPatternRetriever.metadataDataset); + return this.getIndexPattern(ctx, IngestIndexPatternRetriever.metadataDataset); } /** diff --git a/x-pack/plugins/endpoint/server/routes/alerts/index.ts b/x-pack/plugins/siem/server/endpoint/alerts/routes.ts similarity index 50% rename from x-pack/plugins/endpoint/server/routes/alerts/index.ts rename to x-pack/plugins/siem/server/endpoint/alerts/routes.ts index b61f90b5b17f5..07cca9e80d88b 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/index.ts +++ b/x-pack/plugins/siem/server/endpoint/alerts/routes.ts @@ -4,11 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ import { IRouter } from 'kibana/server'; -import { EndpointAppContext } from '../../types'; -import { AlertConstants } from '../../../common/alert_constants'; -import { alertListHandlerWrapper } from './list'; -import { alertDetailsHandlerWrapper, alertDetailsReqSchema } from './details'; -import { alertingIndexGetQuerySchema } from '../../../common/schema/alert_index'; +import { EndpointAppContext } from '../types'; +import { AlertConstants } from '../../../common/endpoint_alerts/alert_constants'; +import { alertListHandlerWrapper } from './handlers/list'; +import { alertDetailsHandlerWrapper } from './handlers/details'; +import { alertDetailsReqSchema } from './handlers/details/schemas'; +import { alertingIndexGetQuerySchema } from '../../../common/endpoint_alerts/schema/alert_index'; +import { indexPatternGetParamsSchema } from '../../../common/endpoint_alerts/schema/index_pattern'; +import { handleIndexPattern } from './handlers/index_pattern'; export const BASE_ALERTS_ROUTE = `${AlertConstants.BASE_API_URL}/alerts`; @@ -34,4 +37,15 @@ export function registerAlertRoutes(router: IRouter, endpointAppContext: Endpoin }, alertDetailsHandlerWrapper(endpointAppContext) ); + + const log = endpointAppContext.logFactory.get('index_pattern'); + + router.get( + { + path: `${AlertConstants.INDEX_PATTERN_ROUTE}/{datasetPath}`, + validate: { params: indexPatternGetParamsSchema }, + options: { authRequired: true }, + }, + handleIndexPattern(log, endpointAppContext) + ); } diff --git a/x-pack/plugins/endpoint/server/config.test.ts b/x-pack/plugins/siem/server/endpoint/config.test.ts similarity index 100% rename from x-pack/plugins/endpoint/server/config.test.ts rename to x-pack/plugins/siem/server/endpoint/config.test.ts diff --git a/x-pack/plugins/endpoint/server/config.ts b/x-pack/plugins/siem/server/endpoint/config.ts similarity index 100% rename from x-pack/plugins/endpoint/server/config.ts rename to x-pack/plugins/siem/server/endpoint/config.ts diff --git a/x-pack/plugins/endpoint/server/endpoint_app_context_services.test.ts b/x-pack/plugins/siem/server/endpoint/endpoint_app_context_services.test.ts similarity index 100% rename from x-pack/plugins/endpoint/server/endpoint_app_context_services.test.ts rename to x-pack/plugins/siem/server/endpoint/endpoint_app_context_services.test.ts diff --git a/x-pack/plugins/endpoint/server/endpoint_app_context_services.ts b/x-pack/plugins/siem/server/endpoint/endpoint_app_context_services.ts similarity index 91% rename from x-pack/plugins/endpoint/server/endpoint_app_context_services.ts rename to x-pack/plugins/siem/server/endpoint/endpoint_app_context_services.ts index b087405c7bc5b..5d74c75ebca5c 100644 --- a/x-pack/plugins/endpoint/server/endpoint_app_context_services.ts +++ b/x-pack/plugins/siem/server/endpoint/endpoint_app_context_services.ts @@ -3,8 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { IndexPatternRetriever } from './index_pattern'; -import { AgentService } from '../../ingest_manager/server'; +import { IndexPatternRetriever } from './alerts/index_pattern'; +import { AgentService } from '../../../ingest_manager/server'; /** * A singleton that holds shared services that are initialized during the start up phase diff --git a/x-pack/plugins/endpoint/server/mocks.ts b/x-pack/plugins/siem/server/endpoint/mocks.ts similarity index 96% rename from x-pack/plugins/endpoint/server/mocks.ts rename to x-pack/plugins/siem/server/endpoint/mocks.ts index 76a3628562a82..6260a6c630643 100644 --- a/x-pack/plugins/endpoint/server/mocks.ts +++ b/x-pack/plugins/siem/server/endpoint/mocks.ts @@ -9,8 +9,8 @@ import { RequestHandlerContext, SavedObjectsClientContract, } from 'kibana/server'; -import { AgentService, IngestManagerStartContract } from '../../ingest_manager/server'; -import { IndexPatternRetriever } from './index_pattern'; +import { AgentService, IngestManagerStartContract } from '../../../ingest_manager/server'; +import { IndexPatternRetriever } from './alerts/index_pattern'; /** * Creates a mock IndexPatternRetriever for use in tests. diff --git a/x-pack/plugins/endpoint/server/routes/metadata/index.ts b/x-pack/plugins/siem/server/endpoint/routes/metadata/index.ts similarity index 94% rename from x-pack/plugins/endpoint/server/routes/metadata/index.ts rename to x-pack/plugins/siem/server/endpoint/routes/metadata/index.ts index 08950930441df..983739b249596 100644 --- a/x-pack/plugins/endpoint/server/routes/metadata/index.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/metadata/index.ts @@ -9,9 +9,14 @@ import { SearchResponse } from 'elasticsearch'; import { schema } from '@kbn/config-schema'; import { getESQueryHostMetadataByID, kibanaRequestToMetadataListESQuery } from './query_builders'; -import { HostInfo, HostMetadata, HostResultList, HostStatus } from '../../../common/types'; +import { + HostInfo, + HostMetadata, + HostResultList, + HostStatus, +} from '../../../../common/endpoint/types'; import { EndpointAppContext } from '../../types'; -import { AgentStatus } from '../../../../ingest_manager/common/types/models'; +import { AgentStatus } from '../../../../../ingest_manager/common/types/models'; interface HitSource { _source: HostMetadata; @@ -130,10 +135,11 @@ export async function getHostData( return undefined; } - return await enrichHostMetadata(response.hits.hits[0]._source, metadataRequestContext); + return enrichHostMetadata(response.hits.hits[0]._source, metadataRequestContext); } async function mapToHostResultList( + // eslint-disable-next-line @typescript-eslint/no-explicit-any queryParams: Record, searchResponse: SearchResponse, metadataRequestContext: MetadataRequestContext diff --git a/x-pack/plugins/endpoint/server/routes/metadata/metadata.test.ts b/x-pack/plugins/siem/server/endpoint/routes/metadata/metadata.test.ts similarity index 95% rename from x-pack/plugins/endpoint/server/routes/metadata/metadata.test.ts rename to x-pack/plugins/siem/server/endpoint/routes/metadata/metadata.test.ts index 5415ebcae31c4..b2f5866a3ae7d 100644 --- a/x-pack/plugins/endpoint/server/routes/metadata/metadata.test.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/metadata/metadata.test.ts @@ -18,20 +18,25 @@ import { httpServiceMock, loggingServiceMock, savedObjectsClientMock, -} from '../../../../../../src/core/server/mocks'; -import { HostInfo, HostMetadata, HostResultList, HostStatus } from '../../../common/types'; +} from '../../../../../../../src/core/server/mocks'; +import { + HostInfo, + HostMetadata, + HostResultList, + HostStatus, +} from '../../../../common/endpoint/types'; import { SearchResponse } from 'elasticsearch'; import { registerEndpointRoutes } from './index'; -import { EndpointConfigSchema } from '../../config'; import * as data from '../../test_data/all_metadata_data.json'; import { createMockAgentService, createMockMetadataIndexPatternRetriever, createRouteHandlerContext, } from '../../mocks'; -import { AgentService } from '../../../../ingest_manager/server'; +import { AgentService } from '../../../../../ingest_manager/server'; import Boom from 'boom'; import { EndpointAppContextService } from '../../endpoint_app_context_services'; +import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__'; describe('test endpoint route', () => { let routerMock: jest.Mocked; @@ -39,7 +44,9 @@ describe('test endpoint route', () => { let mockClusterClient: jest.Mocked; let mockScopedClient: jest.Mocked; let mockSavedObjectClient: jest.Mocked; + // eslint-disable-next-line @typescript-eslint/no-explicit-any let routeHandler: RequestHandler; + // eslint-disable-next-line @typescript-eslint/no-explicit-any let routeConfig: RouteConfig; let mockAgentService: jest.Mocked; let endpointAppContextService: EndpointAppContextService; @@ -63,7 +70,7 @@ describe('test endpoint route', () => { registerEndpointRoutes(routerMock, { logFactory: loggingServiceMock.create(), service: endpointAppContextService, - config: () => Promise.resolve(EndpointConfigSchema.validate({})), + config: () => Promise.resolve(createMockConfig()), }); }); @@ -235,6 +242,7 @@ describe('test endpoint route', () => { it('should return a single endpoint with status online', async () => { const mockRequest = httpServerMock.createKibanaRequest({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any params: { id: (data as any).hits.hits[0]._id }, }); const response: SearchResponse = (data as unknown) as SearchResponse< diff --git a/x-pack/plugins/endpoint/server/routes/metadata/query_builders.test.ts b/x-pack/plugins/siem/server/endpoint/routes/metadata/query_builders.test.ts similarity index 91% rename from x-pack/plugins/endpoint/server/routes/metadata/query_builders.test.ts rename to x-pack/plugins/siem/server/endpoint/routes/metadata/query_builders.test.ts index 28bac2fa10e0c..7fa5a8b13db3d 100644 --- a/x-pack/plugins/endpoint/server/routes/metadata/query_builders.test.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/metadata/query_builders.test.ts @@ -3,11 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { httpServerMock, loggingServiceMock } from '../../../../../../src/core/server/mocks'; -import { EndpointConfigSchema } from '../../config'; +import { httpServerMock, loggingServiceMock } from '../../../../../../../src/core/server/mocks'; import { kibanaRequestToMetadataListESQuery, getESQueryHostMetadataByID } from './query_builders'; import { MetadataIndexPattern } from '../../mocks'; import { EndpointAppContextService } from '../../endpoint_app_context_services'; +import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__'; describe('query builder', () => { describe('MetadataListESQuery', () => { @@ -20,7 +20,7 @@ describe('query builder', () => { { logFactory: loggingServiceMock.create(), service: new EndpointAppContextService(), - config: () => Promise.resolve(EndpointConfigSchema.validate({})), + config: () => Promise.resolve(createMockConfig()), }, MetadataIndexPattern ); @@ -55,6 +55,7 @@ describe('query builder', () => { from: 0, size: 10, index: MetadataIndexPattern, + // eslint-disable-next-line @typescript-eslint/no-explicit-any } as Record); }); }); @@ -71,7 +72,7 @@ describe('query builder', () => { { logFactory: loggingServiceMock.create(), service: new EndpointAppContextService(), - config: () => Promise.resolve(EndpointConfigSchema.validate({})), + config: () => Promise.resolve(createMockConfig()), }, MetadataIndexPattern ); @@ -119,6 +120,7 @@ describe('query builder', () => { from: 0, size: 10, index: MetadataIndexPattern, + // eslint-disable-next-line @typescript-eslint/no-explicit-any } as Record); }); }); diff --git a/x-pack/plugins/endpoint/server/routes/metadata/query_builders.ts b/x-pack/plugins/siem/server/endpoint/routes/metadata/query_builders.ts similarity index 88% rename from x-pack/plugins/endpoint/server/routes/metadata/query_builders.ts rename to x-pack/plugins/siem/server/endpoint/routes/metadata/query_builders.ts index abcc293985f9f..a34113e8d6f62 100644 --- a/x-pack/plugins/endpoint/server/routes/metadata/query_builders.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/metadata/query_builders.ts @@ -4,13 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ import { KibanaRequest } from 'kibana/server'; -import { esKuery } from '../../../../../../src/plugins/data/server'; +import { esKuery } from '../../../../../../../src/plugins/data/server'; import { EndpointAppContext } from '../../types'; export const kibanaRequestToMetadataListESQuery = async ( + // eslint-disable-next-line @typescript-eslint/no-explicit-any request: KibanaRequest, endpointAppContext: EndpointAppContext, index: string + // eslint-disable-next-line @typescript-eslint/no-explicit-any ): Promise> => { const pagingProperties = await getPagingProperties(request, endpointAppContext); return { @@ -46,6 +48,7 @@ export const kibanaRequestToMetadataListESQuery = async ( }; async function getPagingProperties( + // eslint-disable-next-line @typescript-eslint/no-explicit-any request: KibanaRequest, endpointAppContext: EndpointAppContext ) { @@ -65,6 +68,7 @@ async function getPagingProperties( }; } +// eslint-disable-next-line @typescript-eslint/no-explicit-any function buildQueryBody(request: KibanaRequest): Record { if (typeof request?.body?.filter === 'string') { return esKuery.toElasticsearchQuery(esKuery.fromKueryExpression(request.body.filter)); diff --git a/x-pack/plugins/endpoint/server/routes/policy/handlers.test.ts b/x-pack/plugins/siem/server/endpoint/routes/policy/handlers.test.ts similarity index 90% rename from x-pack/plugins/endpoint/server/routes/policy/handlers.test.ts rename to x-pack/plugins/siem/server/endpoint/routes/policy/handlers.test.ts index 9348353425370..25bf2c45aa421 100644 --- a/x-pack/plugins/endpoint/server/routes/policy/handlers.test.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/policy/handlers.test.ts @@ -10,7 +10,6 @@ import { createRouteHandlerContext, } from '../../mocks'; import { getHostPolicyResponseHandler } from './handlers'; -import { EndpointConfigSchema } from '../../config'; import { IScopedClusterClient, KibanaResponseFactory, @@ -21,11 +20,12 @@ import { httpServerMock, loggingServiceMock, savedObjectsClientMock, -} from '../../../../../../src/core/server/mocks'; -import { AgentService } from '../../../../ingest_manager/server/services'; +} from '../../../../../../../src/core/server/mocks'; +import { AgentService } from '../../../../../ingest_manager/server/services'; import { SearchResponse } from 'elasticsearch'; -import { GetHostPolicyResponse, HostPolicyResponse } from '../../../common/types'; -import { EndpointDocGenerator } from '../../../common/generate_data'; +import { GetHostPolicyResponse, HostPolicyResponse } from '../../../../common/endpoint/types'; +import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data'; +import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__'; describe('test policy response handler', () => { let endpointAppContextService: EndpointAppContextService; @@ -53,7 +53,7 @@ describe('test policy response handler', () => { const hostPolicyResponseHandler = getHostPolicyResponseHandler({ logFactory: loggingServiceMock.create(), service: endpointAppContextService, - config: () => Promise.resolve(EndpointConfigSchema.validate({})), + config: () => Promise.resolve(createMockConfig()), }); mockScopedClient.callAsCurrentUser.mockImplementationOnce(() => Promise.resolve(response)); @@ -76,7 +76,7 @@ describe('test policy response handler', () => { const hostPolicyResponseHandler = getHostPolicyResponseHandler({ logFactory: loggingServiceMock.create(), service: endpointAppContextService, - config: () => Promise.resolve(EndpointConfigSchema.validate({})), + config: () => Promise.resolve(createMockConfig()), }); mockScopedClient.callAsCurrentUser.mockImplementationOnce(() => diff --git a/x-pack/plugins/endpoint/server/routes/policy/handlers.ts b/x-pack/plugins/siem/server/endpoint/routes/policy/handlers.ts similarity index 93% rename from x-pack/plugins/endpoint/server/routes/policy/handlers.ts rename to x-pack/plugins/siem/server/endpoint/routes/policy/handlers.ts index 5a34164c0bb37..000d353ab90f8 100644 --- a/x-pack/plugins/endpoint/server/routes/policy/handlers.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/policy/handlers.ts @@ -5,7 +5,7 @@ */ import { RequestHandler } from 'kibana/server'; import { TypeOf } from '@kbn/config-schema'; -import { GetPolicyResponseSchema } from '../../../common/schema/policy'; +import { GetPolicyResponseSchema } from '../../../../common/endpoint/schema/policy'; import { EndpointAppContext } from '../../types'; import { getPolicyResponseByHostId } from './service'; diff --git a/x-pack/plugins/endpoint/server/routes/policy/index.ts b/x-pack/plugins/siem/server/endpoint/routes/policy/index.ts similarity index 90% rename from x-pack/plugins/endpoint/server/routes/policy/index.ts rename to x-pack/plugins/siem/server/endpoint/routes/policy/index.ts index 4c3bd8e21315c..b233ff1af30fc 100644 --- a/x-pack/plugins/endpoint/server/routes/policy/index.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/policy/index.ts @@ -6,7 +6,7 @@ import { IRouter } from 'kibana/server'; import { EndpointAppContext } from '../../types'; -import { GetPolicyResponseSchema } from '../../../common/schema/policy'; +import { GetPolicyResponseSchema } from '../../../../common/endpoint/schema/policy'; import { getHostPolicyResponseHandler } from './handlers'; export const BASE_POLICY_RESPONSE_ROUTE = `/api/endpoint/policy_response`; diff --git a/x-pack/plugins/endpoint/server/routes/policy/service.test.ts b/x-pack/plugins/siem/server/endpoint/routes/policy/service.test.ts similarity index 86% rename from x-pack/plugins/endpoint/server/routes/policy/service.test.ts rename to x-pack/plugins/siem/server/endpoint/routes/policy/service.test.ts index c7bf65627769e..7c8d006687a6b 100644 --- a/x-pack/plugins/endpoint/server/routes/policy/service.test.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/policy/service.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { GetPolicyResponseSchema } from '../../../common/schema/policy'; +import { GetPolicyResponseSchema } from '../../../../common/endpoint/schema/policy'; describe('test policy handlers schema', () => { it('validate that get policy response query schema', async () => { diff --git a/x-pack/plugins/endpoint/server/routes/policy/service.ts b/x-pack/plugins/siem/server/endpoint/routes/policy/service.ts similarity index 97% rename from x-pack/plugins/endpoint/server/routes/policy/service.ts rename to x-pack/plugins/siem/server/endpoint/routes/policy/service.ts index 7ec2c65634110..5e3c3537ec591 100644 --- a/x-pack/plugins/endpoint/server/routes/policy/service.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/policy/service.ts @@ -6,7 +6,7 @@ import { SearchResponse } from 'elasticsearch'; import { IScopedClusterClient } from 'kibana/server'; -import { GetHostPolicyResponse, HostPolicyResponse } from '../../../common/types'; +import { GetHostPolicyResponse, HostPolicyResponse } from '../../../../common/endpoint/types'; export function getESQueryPolicyResponseByHostID(hostID: string, index: string) { return { diff --git a/x-pack/plugins/endpoint/server/routes/resolver.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver.ts similarity index 96% rename from x-pack/plugins/endpoint/server/routes/resolver.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver.ts index 3599acacb4f59..9a4f55770f934 100644 --- a/x-pack/plugins/endpoint/server/routes/resolver.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/resolver.ts @@ -11,7 +11,7 @@ import { validateEvents, validateChildren, validateAncestry, -} from '../../common/schema/resolver'; +} from '../../../common/endpoint/schema/resolver'; import { handleEvents } from './resolver/events'; import { handleChildren } from './resolver/children'; import { handleAncestry } from './resolver/ancestry'; diff --git a/x-pack/plugins/endpoint/server/routes/resolver/ancestry.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/ancestry.ts similarity index 94% rename from x-pack/plugins/endpoint/server/routes/resolver/ancestry.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/ancestry.ts index 6648dc5b9e493..233f23bd314c1 100644 --- a/x-pack/plugins/endpoint/server/routes/resolver/ancestry.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/resolver/ancestry.ts @@ -6,7 +6,7 @@ import { RequestHandler, Logger } from 'kibana/server'; import { TypeOf } from '@kbn/config-schema'; -import { validateAncestry } from '../../../common/schema/resolver'; +import { validateAncestry } from '../../../../common/endpoint/schema/resolver'; import { Fetcher } from './utils/fetch'; import { EndpointAppContext } from '../../types'; diff --git a/x-pack/plugins/endpoint/server/routes/resolver/children.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/children.ts similarity index 94% rename from x-pack/plugins/endpoint/server/routes/resolver/children.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/children.ts index bb18b29a4b947..13af514c4c55f 100644 --- a/x-pack/plugins/endpoint/server/routes/resolver/children.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/resolver/children.ts @@ -6,7 +6,7 @@ import { RequestHandler, Logger } from 'kibana/server'; import { TypeOf } from '@kbn/config-schema'; -import { validateChildren } from '../../../common/schema/resolver'; +import { validateChildren } from '../../../../common/endpoint/schema/resolver'; import { Fetcher } from './utils/fetch'; import { EndpointAppContext } from '../../types'; diff --git a/x-pack/plugins/endpoint/server/routes/resolver/events.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/events.ts similarity index 94% rename from x-pack/plugins/endpoint/server/routes/resolver/events.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/events.ts index a70a6e8d097d0..97f718b66a437 100644 --- a/x-pack/plugins/endpoint/server/routes/resolver/events.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/resolver/events.ts @@ -6,7 +6,7 @@ import { TypeOf } from '@kbn/config-schema'; import { RequestHandler, Logger } from 'kibana/server'; -import { validateEvents } from '../../../common/schema/resolver'; +import { validateEvents } from '../../../../common/endpoint/schema/resolver'; import { Fetcher } from './utils/fetch'; import { EndpointAppContext } from '../../types'; diff --git a/x-pack/plugins/endpoint/server/routes/resolver/queries/base.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/base.ts similarity index 91% rename from x-pack/plugins/endpoint/server/routes/resolver/queries/base.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/queries/base.ts index eba4e5581c136..4f6003492fd3a 100644 --- a/x-pack/plugins/endpoint/server/routes/resolver/queries/base.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/base.ts @@ -6,14 +6,14 @@ import { SearchResponse } from 'elasticsearch'; import { IScopedClusterClient } from 'kibana/server'; -import { ResolverEvent } from '../../../../common/types'; +import { ResolverEvent } from '../../../../../common/endpoint/types'; import { paginate, paginatedResults, PaginationParams, PaginatedResults, } from '../utils/pagination'; -import { JsonObject } from '../../../../../../../src/plugins/kibana_utils/public'; +import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/public'; import { legacyEventIndexPattern } from './legacy_event_index_pattern'; export abstract class ResolverQuery { diff --git a/x-pack/plugins/endpoint/server/routes/resolver/queries/children.test.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/children.test.ts similarity index 100% rename from x-pack/plugins/endpoint/server/routes/resolver/queries/children.test.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/queries/children.test.ts diff --git a/x-pack/plugins/endpoint/server/routes/resolver/queries/children.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/children.ts similarity index 100% rename from x-pack/plugins/endpoint/server/routes/resolver/queries/children.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/queries/children.ts diff --git a/x-pack/plugins/endpoint/server/routes/resolver/queries/events.test.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/events.test.ts similarity index 100% rename from x-pack/plugins/endpoint/server/routes/resolver/queries/events.test.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/queries/events.test.ts diff --git a/x-pack/plugins/endpoint/server/routes/resolver/queries/events.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/events.ts similarity index 95% rename from x-pack/plugins/endpoint/server/routes/resolver/queries/events.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/queries/events.ts index b622cb8a21111..80c3a0e9acccc 100644 --- a/x-pack/plugins/endpoint/server/routes/resolver/queries/events.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/events.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { ResolverQuery } from './base'; -import { JsonObject } from '../../../../../../../src/plugins/kibana_utils/public'; +import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/public'; export class EventsQuery extends ResolverQuery { protected legacyQuery(endpointID: string, uniquePIDs: string[], index: string): JsonObject { diff --git a/x-pack/plugins/endpoint/server/routes/resolver/queries/legacy_event_index_pattern.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/legacy_event_index_pattern.ts similarity index 100% rename from x-pack/plugins/endpoint/server/routes/resolver/queries/legacy_event_index_pattern.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/queries/legacy_event_index_pattern.ts diff --git a/x-pack/plugins/endpoint/server/routes/resolver/queries/lifecycle.test.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/lifecycle.test.ts similarity index 100% rename from x-pack/plugins/endpoint/server/routes/resolver/queries/lifecycle.test.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/queries/lifecycle.test.ts diff --git a/x-pack/plugins/endpoint/server/routes/resolver/queries/lifecycle.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/lifecycle.ts similarity index 94% rename from x-pack/plugins/endpoint/server/routes/resolver/queries/lifecycle.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/queries/lifecycle.ts index e775b0cf9b6d2..7dbbdec2fdfcd 100644 --- a/x-pack/plugins/endpoint/server/routes/resolver/queries/lifecycle.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/lifecycle.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { ResolverQuery } from './base'; -import { JsonObject } from '../../../../../../../src/plugins/kibana_utils/public'; +import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/public'; export class LifecycleQuery extends ResolverQuery { protected legacyQuery(endpointID: string, uniquePIDs: string[], index: string): JsonObject { diff --git a/x-pack/plugins/endpoint/server/routes/resolver/queries/stats.test.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/stats.test.ts similarity index 100% rename from x-pack/plugins/endpoint/server/routes/resolver/queries/stats.test.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/queries/stats.test.ts diff --git a/x-pack/plugins/endpoint/server/routes/resolver/queries/stats.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/stats.ts similarity index 93% rename from x-pack/plugins/endpoint/server/routes/resolver/queries/stats.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/queries/stats.ts index 7db3ab2b0cb1f..5fddf86ea4a7c 100644 --- a/x-pack/plugins/endpoint/server/routes/resolver/queries/stats.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/resolver/queries/stats.ts @@ -5,17 +5,19 @@ */ import { SearchResponse } from 'elasticsearch'; import { ResolverQuery } from './base'; -import { ResolverEvent } from '../../../../common/types'; -import { JsonObject } from '../../../../../../../src/plugins/kibana_utils/public'; +import { ResolverEvent } from '../../../../../common/endpoint/types'; +import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/public'; import { PaginatedResults } from '../utils/pagination'; export class StatsQuery extends ResolverQuery { protected postSearch(response: SearchResponse): PaginatedResults { const alerts = response.aggregations.alerts.ids.buckets.reduce( + // eslint-disable-next-line @typescript-eslint/no-explicit-any (cummulative: any, bucket: any) => ({ ...cummulative, [bucket.key]: bucket.doc_count }), {} ); const events = response.aggregations.events.ids.buckets.reduce( + // eslint-disable-next-line @typescript-eslint/no-explicit-any (cummulative: any, bucket: any) => ({ ...cummulative, [bucket.key]: bucket.doc_count }), {} ); diff --git a/x-pack/plugins/endpoint/server/routes/resolver/tree.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/tree.ts similarity index 95% rename from x-pack/plugins/endpoint/server/routes/resolver/tree.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/tree.ts index 25f15586341d5..3551123393960 100644 --- a/x-pack/plugins/endpoint/server/routes/resolver/tree.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/resolver/tree.ts @@ -6,7 +6,7 @@ import { RequestHandler, Logger } from 'kibana/server'; import { TypeOf } from '@kbn/config-schema'; -import { validateTree } from '../../../common/schema/resolver'; +import { validateTree } from '../../../../common/endpoint/schema/resolver'; import { Fetcher } from './utils/fetch'; import { Tree } from './utils/tree'; import { EndpointAppContext } from '../../types'; diff --git a/x-pack/plugins/endpoint/server/routes/resolver/utils/fetch.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/utils/fetch.ts similarity index 97% rename from x-pack/plugins/endpoint/server/routes/resolver/utils/fetch.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/utils/fetch.ts index 7315b4ee6c618..f0e1a8a9bfc6e 100644 --- a/x-pack/plugins/endpoint/server/routes/resolver/utils/fetch.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/resolver/utils/fetch.ts @@ -5,7 +5,7 @@ */ import { IScopedClusterClient } from 'kibana/server'; -import { entityId, parentEntityId } from '../../../../common/models/event'; +import { entityId, parentEntityId } from '../../../../../common/endpoint/models/event'; import { getPaginationParams } from './pagination'; import { Tree } from './tree'; import { LifecycleQuery } from '../queries/lifecycle'; diff --git a/x-pack/plugins/endpoint/server/routes/resolver/utils/pagination.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/utils/pagination.ts similarity index 83% rename from x-pack/plugins/endpoint/server/routes/resolver/utils/pagination.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/utils/pagination.ts index 20249b81660bb..a47c4442b6cf4 100644 --- a/x-pack/plugins/endpoint/server/routes/resolver/utils/pagination.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/resolver/utils/pagination.ts @@ -5,9 +5,9 @@ */ import { SearchResponse } from 'elasticsearch'; -import { ResolverEvent } from '../../../../common/types'; -import { entityId } from '../../../../common/models/event'; -import { JsonObject } from '../../../../../../../src/plugins/kibana_utils/public'; +import { ResolverEvent } from '../../../../../common/endpoint/types'; +import { entityId } from '../../../../../common/endpoint/models/event'; +import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/public'; export interface PaginationParams { size: number; @@ -37,8 +37,8 @@ function urlEncodeCursor(data: PaginationCursor): string { } function urlDecodeCursor(value: string): PaginationCursor { - value = value.replace(/\-/g, '+').replace(/_/g, '/'); - const data = Buffer.from(value, 'base64').toString('utf8'); + const localValue = value.replace(/\-/g, '+').replace(/_/g, '/'); + const data = Buffer.from(localValue, 'base64').toString('utf8'); const { timestamp, eventID } = JSON.parse(data); // take some extra care to only grab the things we want // convert the timestamp string to date object @@ -72,7 +72,10 @@ export function paginate( const { size, timestamp, eventID } = pagination; query.sort = [{ '@timestamp': 'asc' }, { [tiebreaker]: 'asc' }]; query.aggs = query.aggs || {}; - query.aggs = Object.assign({}, query.aggs, { totals: { terms: { field: aggregator, size } } }); + query.aggs = { + ...(typeof query.aggs === 'object' ? query.aggs : {}), + totals: { terms: { field: aggregator, size } }, + }; query.size = size; if (timestamp && eventID) { query.search_after = [timestamp, eventID] as Array; @@ -98,6 +101,7 @@ export function paginatedResults(response: SearchResponse): Pagin } const totals = response.aggregations?.totals?.buckets?.reduce( + // eslint-disable-next-line @typescript-eslint/no-explicit-any (cummulative: any, bucket: any) => ({ ...cummulative, [bucket.key]: bucket.doc_count }), {} ); diff --git a/x-pack/plugins/endpoint/server/routes/resolver/utils/tree.ts b/x-pack/plugins/siem/server/endpoint/routes/resolver/utils/tree.ts similarity index 98% rename from x-pack/plugins/endpoint/server/routes/resolver/utils/tree.ts rename to x-pack/plugins/siem/server/endpoint/routes/resolver/utils/tree.ts index 5a55c23b90873..28615117cf7ba 100644 --- a/x-pack/plugins/endpoint/server/routes/resolver/utils/tree.ts +++ b/x-pack/plugins/siem/server/endpoint/routes/resolver/utils/tree.ts @@ -10,8 +10,8 @@ import { ResolverNode, ResolverNodeStats, ResolverNodePagination, -} from '../../../../common/types'; -import { entityId, parentEntityId } from '../../../../common/models/event'; +} from '../../../../../common/endpoint/types'; +import { entityId, parentEntityId } from '../../../../../common/endpoint/models/event'; import { buildPaginationCursor } from './pagination'; type ExtractFunction = (event: ResolverEvent) => string | undefined; diff --git a/x-pack/plugins/endpoint/server/test_data/all_metadata_data.json b/x-pack/plugins/siem/server/endpoint/test_data/all_metadata_data.json similarity index 100% rename from x-pack/plugins/endpoint/server/test_data/all_metadata_data.json rename to x-pack/plugins/siem/server/endpoint/test_data/all_metadata_data.json diff --git a/x-pack/plugins/endpoint/server/types.ts b/x-pack/plugins/siem/server/endpoint/types.ts similarity index 86% rename from x-pack/plugins/endpoint/server/types.ts rename to x-pack/plugins/siem/server/endpoint/types.ts index dfa5950adba5c..fbcc5bc833d73 100644 --- a/x-pack/plugins/endpoint/server/types.ts +++ b/x-pack/plugins/siem/server/endpoint/types.ts @@ -4,15 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ import { LoggerFactory } from 'kibana/server'; -import { EndpointConfigType } from './config'; import { EndpointAppContextService } from './endpoint_app_context_services'; +import { ConfigType } from '../config'; /** * The context for Endpoint apps. */ export interface EndpointAppContext { logFactory: LoggerFactory; - config(): Promise; + config(): Promise; /** * Object readiness is tied to plugin start method diff --git a/x-pack/plugins/siem/server/lib/detection_engine/routes/__mocks__/index.ts b/x-pack/plugins/siem/server/lib/detection_engine/routes/__mocks__/index.ts index a28eb6ba3ccaa..0cec1832dab83 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/routes/__mocks__/index.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/routes/__mocks__/index.ts @@ -19,4 +19,10 @@ export const createMockConfig = () => ({ maxRuleImportPayloadBytes: 10485760, maxTimelineImportExportSize: 10000, maxTimelineImportPayloadBytes: 10485760, + endpointResultListDefaultFirstPageIndex: 0, + endpointResultListDefaultPageSize: 10, + alertResultListDefaultDateRange: { + from: 'now-15m', + to: 'now', + }, }); diff --git a/x-pack/plugins/siem/server/plugin.ts b/x-pack/plugins/siem/server/plugin.ts index d296ee94e8958..3c336991f3d9d 100644 --- a/x-pack/plugins/siem/server/plugin.ts +++ b/x-pack/plugins/siem/server/plugin.ts @@ -22,6 +22,7 @@ import { MlPluginSetup as MlSetup } from '../../ml/server'; import { EncryptedSavedObjectsPluginSetup as EncryptedSavedObjectsSetup } from '../../encrypted_saved_objects/server'; import { SpacesPluginSetup as SpacesSetup } from '../../spaces/server'; import { LicensingPluginSetup } from '../../licensing/server'; +import { IngestManagerStartContract } from '../../ingest_manager/server'; import { initServer } from './init_server'; import { compose } from './lib/compose/kibana'; import { initRoutes } from './routes'; @@ -35,6 +36,13 @@ import { SiemClientFactory } from './client'; import { createConfig$, ConfigType } from './config'; import { initUiSettings } from './ui_settings'; import { APP_ID, APP_ICON } from '../common/constants'; +import { registerEndpointRoutes } from './endpoint/routes/metadata'; +import { registerResolverRoutes } from './endpoint/routes/resolver'; +import { registerAlertRoutes } from './endpoint/alerts/routes'; +import { registerPolicyRoutes } from './endpoint/routes/policy'; +import { EndpointAppContextService } from './endpoint/endpoint_app_context_services'; +import { EndpointAppContext } from './endpoint/types'; +import { IngestIndexPatternRetriever } from './endpoint/alerts/index_pattern'; export interface SetupPlugins { alerting: AlertingSetup; @@ -46,8 +54,9 @@ export interface SetupPlugins { ml?: MlSetup; } -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface StartPlugins {} +export interface StartPlugins { + ingestManager: IngestManagerStartContract; +} // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface PluginSetup {} @@ -59,6 +68,7 @@ export class Plugin implements IPlugin; private context: PluginInitializerContext; private siemClientFactory: SiemClientFactory; + private readonly endpointAppContextService = new EndpointAppContextService(); constructor(context: PluginInitializerContext) { this.context = context; @@ -79,21 +89,27 @@ export class Plugin implements IPlugin => Promise.resolve(config), + }; const router = core.http.createRouter(); core.http.registerRouteHandlerContext(APP_ID, (context, request, response) => ({ getSiemClient: () => this.siemClientFactory.create(request), })); - const config = await this.config$.pipe(first()).toPromise(); - this.siemClientFactory.setup({ getSpaceId: plugins.spaces?.spacesService?.getSpaceId, config, }); + // TO DO We need to get the endpoint routes inside of initRoutes initRoutes( router, config, @@ -101,6 +117,10 @@ export class Plugin implements IPlugin { await ingestManager.setup(); }); - loadTestFile(require.resolve('./index_pattern')); + loadTestFile(require.resolve('./alerts/index_pattern')); loadTestFile(require.resolve('./resolver')); loadTestFile(require.resolve('./metadata')); loadTestFile(require.resolve('./alerts')); diff --git a/x-pack/test/api_integration/apis/features/features/features.ts b/x-pack/test/api_integration/apis/features/features/features.ts index 7a0196adbfffd..197e551c71888 100644 --- a/x-pack/test/api_integration/apis/features/features/features.ts +++ b/x-pack/test/api_integration/apis/features/features/features.ts @@ -114,7 +114,6 @@ export default function({ getService }: FtrProviderContext) { 'maps', 'uptime', 'siem', - 'endpoint', 'ingestManager', ].sort() ); diff --git a/x-pack/test/api_integration/apis/security/privileges.ts b/x-pack/test/api_integration/apis/security/privileges.ts index 9bec3fd076e86..a6537644551a1 100644 --- a/x-pack/test/api_integration/apis/security/privileges.ts +++ b/x-pack/test/api_integration/apis/security/privileges.ts @@ -36,7 +36,6 @@ export default function({ getService }: FtrProviderContext) { uptime: ['all', 'read'], apm: ['all', 'read'], siem: ['all', 'read'], - endpoint: ['all', 'read'], ingestManager: ['all', 'read'], }, global: ['all', 'read'], diff --git a/x-pack/test/api_integration/apis/security/privileges_basic.ts b/x-pack/test/api_integration/apis/security/privileges_basic.ts index 1f9eac148b302..dc352c2833594 100644 --- a/x-pack/test/api_integration/apis/security/privileges_basic.ts +++ b/x-pack/test/api_integration/apis/security/privileges_basic.ts @@ -34,7 +34,6 @@ export default function({ getService }: FtrProviderContext) { uptime: ['all', 'read'], apm: ['all', 'read'], siem: ['all', 'read'], - endpoint: ['all', 'read'], ingestManager: ['all', 'read'], }, global: ['all', 'read'], diff --git a/x-pack/test/api_integration/config.js b/x-pack/test/api_integration/config.js index dda8c2d888d30..41ae65062b113 100644 --- a/x-pack/test/api_integration/config.js +++ b/x-pack/test/api_integration/config.js @@ -26,11 +26,9 @@ export async function getApiIntegrationConfig({ readConfigFile }) { ...xPackFunctionalTestsConfig.get('kbnTestServer.serverArgs'), '--xpack.security.session.idleTimeout=3600000', // 1 hour '--optimize.enabled=false', - '--xpack.endpoint.enabled=true', '--telemetry.optIn=true', - '--xpack.endpoint.enabled=true', '--xpack.ingestManager.enabled=true', - '--xpack.endpoint.alertResultListDefaultDateRange.from=2018-01-10T00:00:00.000Z', + '--xpack.siem.alertResultListDefaultDateRange.from=2018-01-10T00:00:00.000Z', ], }, esTestCluster: { diff --git a/x-pack/test/endpoint_api_integration_no_ingest/apis/alerts.ts b/x-pack/test/endpoint_api_integration_no_ingest/apis/alerts/index.ts similarity index 93% rename from x-pack/test/endpoint_api_integration_no_ingest/apis/alerts.ts rename to x-pack/test/endpoint_api_integration_no_ingest/apis/alerts/index.ts index b75d69238d653..badb05cbe7a74 100644 --- a/x-pack/test/endpoint_api_integration_no_ingest/apis/alerts.ts +++ b/x-pack/test/endpoint_api_integration_no_ingest/apis/alerts/index.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { FtrProviderContext } from '../ftr_provider_context'; +import { FtrProviderContext } from '../../ftr_provider_context'; export default function({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); diff --git a/x-pack/test/endpoint_api_integration_no_ingest/apis/index_pattern.ts b/x-pack/test/endpoint_api_integration_no_ingest/apis/alerts/index_pattern.ts similarity index 90% rename from x-pack/test/endpoint_api_integration_no_ingest/apis/index_pattern.ts rename to x-pack/test/endpoint_api_integration_no_ingest/apis/alerts/index_pattern.ts index 664ef7d96847c..13a0d61de3139 100644 --- a/x-pack/test/endpoint_api_integration_no_ingest/apis/index_pattern.ts +++ b/x-pack/test/endpoint_api_integration_no_ingest/apis/alerts/index_pattern.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { FtrProviderContext } from '../ftr_provider_context'; +import { FtrProviderContext } from '../../ftr_provider_context'; export default function({ getService }: FtrProviderContext) { const supertest = getService('supertest'); diff --git a/x-pack/test/endpoint_api_integration_no_ingest/apis/index.ts b/x-pack/test/endpoint_api_integration_no_ingest/apis/index.ts index 6110f398df5a0..321ef35180ca8 100644 --- a/x-pack/test/endpoint_api_integration_no_ingest/apis/index.ts +++ b/x-pack/test/endpoint_api_integration_no_ingest/apis/index.ts @@ -9,7 +9,7 @@ import { FtrProviderContext } from '../ftr_provider_context'; export default function endpointAPIIntegrationTests({ loadTestFile }: FtrProviderContext) { describe('Endpoint plugin', function() { this.tags('ciGroup7'); - loadTestFile(require.resolve('./index_pattern')); + loadTestFile(require.resolve('./alerts/index_pattern')); loadTestFile(require.resolve('./metadata')); loadTestFile(require.resolve('./alerts')); }); diff --git a/x-pack/test/functional_endpoint/config.ts b/x-pack/test/functional_endpoint/config.ts index a371c548f3022..8b87993e4b985 100644 --- a/x-pack/test/functional_endpoint/config.ts +++ b/x-pack/test/functional_endpoint/config.ts @@ -30,7 +30,6 @@ export default async function({ readConfigFile }: FtrConfigProviderContext) { ...xpackFunctionalConfig.get('kbnTestServer'), serverArgs: [ ...xpackFunctionalConfig.get('kbnTestServer.serverArgs'), - '--xpack.endpoint.enabled=true', '--xpack.ingestManager.enabled=true', ], }, diff --git a/x-pack/test/functional_endpoint/services/endpoint_policy.ts b/x-pack/test/functional_endpoint/services/endpoint_policy.ts index e8e2d9957aa38..5142c083a0891 100644 --- a/x-pack/test/functional_endpoint/services/endpoint_policy.ts +++ b/x-pack/test/functional_endpoint/services/endpoint_policy.ts @@ -9,8 +9,8 @@ import { CreateAgentConfigResponse, CreateDatasourceResponse, } from '../../../plugins/ingest_manager/common'; -import { Immutable } from '../../../plugins/endpoint/common/types'; -import { factory as policyConfigFactory } from '../../../plugins/endpoint/common/models/policy_config'; +import { Immutable } from '../../../plugins/siem/common/endpoint/types'; +import { factory as policyConfigFactory } from '../../../plugins/siem/common/endpoint/models/policy_config'; const INGEST_API_ROOT = '/api/ingest_manager'; const INGEST_API_AGENT_CONFIGS = `${INGEST_API_ROOT}/agent_configs`; diff --git a/x-pack/test/plugin_functional/config.ts b/x-pack/test/plugin_functional/config.ts index aa3c9bd24842a..496be59ec3427 100644 --- a/x-pack/test/plugin_functional/config.ts +++ b/x-pack/test/plugin_functional/config.ts @@ -42,7 +42,6 @@ export default async function({ readConfigFile }: FtrConfigProviderContext) { ...plugins.map(pluginDir => `--plugin-path=${resolve(__dirname, 'plugins', pluginDir)}`), // Required to load new platform plugins via `--plugin-path` flag. '--env.name=development', - '--xpack.endpoint.enabled=true', ], }, uiSettings: xpackFunctionalConfig.get('uiSettings'), diff --git a/x-pack/test/reporting/configs/chromium_api.js b/x-pack/test/reporting/configs/chromium_api.js index 95649dfb5d7a3..98235f433681e 100644 --- a/x-pack/test/reporting/configs/chromium_api.js +++ b/x-pack/test/reporting/configs/chromium_api.js @@ -26,7 +26,6 @@ export default async function({ readConfigFile }) { ...functionalConfig.get('kbnTestServer.serverArgs'), '--logging.events.log', '["info","warning","error","fatal","optimize","reporting"]', - '--xpack.endpoint.enabled=true', '--xpack.reporting.csv.enablePanelActionDownload=true', '--xpack.reporting.capture.maxAttempts=1', '--xpack.security.session.idleTimeout=3600000', diff --git a/x-pack/test/siem_cypress/config.ts b/x-pack/test/siem_cypress/config.ts index bd5052cf38381..b4c0eaaa77324 100644 --- a/x-pack/test/siem_cypress/config.ts +++ b/x-pack/test/siem_cypress/config.ts @@ -46,6 +46,9 @@ export default async function({ readConfigFile }: FtrConfigProviderContext) { '--csp.strict=false', // define custom kibana server args here `--elasticsearch.ssl.certificateAuthorities=${CA_CERT_PATH}`, + '--xpack.ingestManager.enabled=true', + '--xpack.ingestManager.epm.enabled=true', + '--xpack.ingestManager.fleet.enabled=true', ], }, }; diff --git a/yarn.lock b/yarn.lock index a18f89cd480f8..a6dc525547be9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4696,16 +4696,6 @@ "@types/prop-types" "*" "@types/react" "*" -"@types/react-redux@^7.1.0": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.5.tgz#c7a528d538969250347aa53c52241051cf886bd3" - integrity sha512-ZoNGQMDxh5ENY7PzU7MVonxDzS1l/EWiy8nUhDqxFqUZn4ovboCyvk4Djf68x6COb7vhGTKjyjxHxtFdAA5sUA== - dependencies: - "@types/hoist-non-react-statics" "^3.3.0" - "@types/react" "*" - hoist-non-react-statics "^3.3.0" - redux "^4.0.0" - "@types/react-redux@^7.1.7": version "7.1.7" resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.7.tgz#12a0c529aba660696947384a059c5c6e08185c7a" From dfc3ccffc92477695d51c98369b32a7a0bc08af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Tue, 19 May 2020 17:29:33 +0200 Subject: [PATCH 043/129] Automate the labels for any PRs affecting files for the Ingest Management team (#67022) * chore: add Ingest Management paths and labels to the path-labeller bot * chore: remove duplicated entry in bot descriptor --- .github/paths-labeller.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/paths-labeller.yml b/.github/paths-labeller.yml index d9d99fc1416e4..039b520561d65 100644 --- a/.github/paths-labeller.yml +++ b/.github/paths-labeller.yml @@ -10,6 +10,9 @@ - "src/plugins/bfetch/**/*.*" - "Team:apm": - "x-pack/plugins/apm/**/*.*" - - "x-pack/plugins/apm/**/*.*" + - "Team:Ingest Management": + - "x-pack/plugins/ingest_manager/**/*.*" + - "x-pack/test/api_integration/apis/fleet/**/*.*" + - "x-pack/test/epm_api_integration/**/*.*" - "Team:uptime": - "x-pack/plugins/uptime/**/*.*" From 1b89dddde5f93571633c55976076bb1760ca8eaa Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Tue, 19 May 2020 17:51:33 +0200 Subject: [PATCH 044/129] move role reset into the top level after clause (#66971) --- test/functional/apps/visualize/_area_chart.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/visualize/_area_chart.js b/test/functional/apps/visualize/_area_chart.js index 88a1fa3f7fa7f..48d36e4d51349 100644 --- a/test/functional/apps/visualize/_area_chart.js +++ b/test/functional/apps/visualize/_area_chart.js @@ -70,6 +70,10 @@ export default function({ getService, getPageObjects }) { await initAreaChart(); }); + after(async function() { + await security.testUser.restoreDefaults(); + }); + it('should save and load with special characters', async function() { const vizNamewithSpecialChars = vizName1 + '/?&=%'; await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb( @@ -296,7 +300,6 @@ export default function({ getService, getPageObjects }) { .pop() .replace('embed=true', ''); await PageObjects.common.navigateToUrl('visualize', embedUrl, { useActualUrl: true }); - await security.testUser.restoreDefaults(); }); }); From c579b6718115fdfac7ad426545efb53c4d0ec9d9 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Tue, 19 May 2020 18:20:51 +0200 Subject: [PATCH 045/129] Fix saved object share link (#66771) --- .../url_panel_content.test.tsx.snap | 6 +- .../components/url_panel_content.test.tsx | 185 ++++++++++++++++-- .../public/components/url_panel_content.tsx | 4 +- 3 files changed, 175 insertions(+), 20 deletions(-) diff --git a/src/plugins/share/public/components/__snapshots__/url_panel_content.test.tsx.snap b/src/plugins/share/public/components/__snapshots__/url_panel_content.test.tsx.snap index c10ca55130880..8787e0c027375 100644 --- a/src/plugins/share/public/components/__snapshots__/url_panel_content.test.tsx.snap +++ b/src/plugins/share/public/components/__snapshots__/url_panel_content.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`render 1`] = ` +exports[`share url panel content render 1`] = ` `; -exports[`should enable saved object export option when objectId is provided 1`] = ` +exports[`share url panel content should enable saved object export option when objectId is provided 1`] = ` `; -exports[`should hide short url section when allowShortUrl is false 1`] = ` +exports[`share url panel content should hide short url section when allowShortUrl is false 1`] = ` ({})); +import { EuiCopy, EuiRadioGroup, EuiSwitch, EuiSwitchEvent } from '@elastic/eui'; + +jest.mock('../lib/url_shortener', () => ({ shortenUrl: jest.fn() })); import React from 'react'; import { shallow } from 'enzyme'; -import { UrlPanelContent } from './url_panel_content'; +import { ExportUrlAsType, UrlPanelContent } from './url_panel_content'; +import { act } from 'react-dom/test-utils'; +import { shortenUrl } from '../lib/url_shortener'; const defaultProps = { allowShortUrl: true, @@ -31,19 +35,170 @@ const defaultProps = { post: () => Promise.resolve({} as any), }; -test('render', () => { - const component = shallow(); - expect(component).toMatchSnapshot(); -}); +describe('share url panel content', () => { + test('render', () => { + const component = shallow(); + expect(component).toMatchSnapshot(); + }); -test('should enable saved object export option when objectId is provided', () => { - const component = shallow(); - expect(component).toMatchSnapshot(); -}); + test('should enable saved object export option when objectId is provided', () => { + const component = shallow(); + expect(component).toMatchSnapshot(); + }); + + test('should hide short url section when allowShortUrl is false', () => { + const component = shallow( + + ); + expect(component).toMatchSnapshot(); + }); + + test('should remove _a query parameter in saved object mode', () => { + const component = shallow( + + ); + act(() => { + component.find(EuiRadioGroup).prop('onChange')!(ExportUrlAsType.EXPORT_URL_AS_SAVED_OBJECT); + }); + expect(component.find(EuiCopy).prop('textToCopy')).toEqual( + 'http://localhost:5601/app/myapp#/?_g=()' + ); + }); + + describe('short url', () => { + test('should generate short url and put it in copy button', async () => { + const shortenUrlMock = shortenUrl as jest.Mock; + shortenUrlMock.mockReset(); + shortenUrlMock.mockResolvedValue('http://localhost/short/url'); + + const component = shallow( + + ); + await act(async () => { + component.find(EuiSwitch).prop('onChange')!(({ + target: { checked: true }, + } as unknown) as EuiSwitchEvent); + }); + expect(shortenUrlMock).toHaveBeenCalledWith( + 'http://localhost:5601/app/myapp#/?_g=()&_a=()', + expect.anything() + ); + expect(component.find(EuiCopy).prop('textToCopy')).toContain('http://localhost/short/url'); + }); + + test('should hide short url for saved object mode', async () => { + const component = shallow( + + ); + act(() => { + component.find(EuiRadioGroup).prop('onChange')!(ExportUrlAsType.EXPORT_URL_AS_SAVED_OBJECT); + }); + expect(component.exists(EuiSwitch)).toEqual(false); + }); + }); + + describe('embedded', () => { + const asIframe = (url: string) => ``; + + test('should add embedded flag to target code in snapshot mode', () => { + const component = shallow( + + ); + expect(component.find(EuiCopy).prop('textToCopy')).toEqual( + asIframe('http://localhost:5601/app/myapp#/?embed=true') + ); + }); + + test('should add embedded flag to target code in snapshot mode with existing query parameters', () => { + const component = shallow( + + ); + expect(component.find(EuiCopy).prop('textToCopy')).toEqual( + asIframe('http://localhost:5601/app/myapp#/?embed=true&_g=()&_a=()') + ); + }); + + test('should remove _a query parameter and add embedded flag in saved object mode', () => { + const component = shallow( + + ); + act(() => { + component.find(EuiRadioGroup).prop('onChange')!(ExportUrlAsType.EXPORT_URL_AS_SAVED_OBJECT); + }); + expect(component.find(EuiCopy).prop('textToCopy')).toEqual( + asIframe('http://localhost:5601/app/myapp#/?embed=true&_g=()') + ); + }); + + test('should generate short url with embed flag and put it in copy button', async () => { + const shortenUrlMock = shortenUrl as jest.Mock; + shortenUrlMock.mockReset(); + shortenUrlMock.mockResolvedValue('http://localhost/short/url'); + + const component = shallow( + + ); + await act(async () => { + component.find(EuiSwitch).prop('onChange')!(({ + target: { checked: true }, + } as unknown) as EuiSwitchEvent); + }); + expect(shortenUrlMock).toHaveBeenCalledWith( + 'http://localhost:5601/app/myapp#/?embed=true&_g=()&_a=()', + expect.anything() + ); + expect(component.find(EuiCopy).prop('textToCopy')).toContain('http://localhost/short/url'); + }); -test('should hide short url section when allowShortUrl is false', () => { - const component = shallow( - - ); - expect(component).toMatchSnapshot(); + test('should hide short url for saved object mode', async () => { + const component = shallow( + + ); + act(() => { + component.find(EuiRadioGroup).prop('onChange')!(ExportUrlAsType.EXPORT_URL_AS_SAVED_OBJECT); + }); + expect(component.exists(EuiSwitch)).toEqual(false); + }); + }); }); diff --git a/src/plugins/share/public/components/url_panel_content.tsx b/src/plugins/share/public/components/url_panel_content.tsx index 2b1159be89003..804b606696a83 100644 --- a/src/plugins/share/public/components/url_panel_content.tsx +++ b/src/plugins/share/public/components/url_panel_content.tsx @@ -52,7 +52,7 @@ interface Props { post: HttpStart['post']; } -enum ExportUrlAsType { +export enum ExportUrlAsType { EXPORT_URL_AS_SAVED_OBJECT = 'savedObject', EXPORT_URL_AS_SNAPSHOT = 'snapshot', } @@ -181,7 +181,7 @@ export class UrlPanelContent extends Component { }), }); if (this.props.isEmbedded) { - formattedUrl = this.makeUrlEmbeddable(url); + formattedUrl = this.makeUrlEmbeddable(formattedUrl); } return formattedUrl; From 3350bffe4939f27667c31aaf3b9c18a031ea14f9 Mon Sep 17 00:00:00 2001 From: Tim Roes Date: Tue, 19 May 2020 18:47:22 +0200 Subject: [PATCH 046/129] Allow histogram fields in average and sum aggregations (#66891) * Allow histogram fields in average and sum aggs * Fix PR review --- .../data/public/search/aggs/metrics/avg.ts | 2 +- .../data/public/search/aggs/metrics/sum.ts | 2 +- .../page_objects/visualize_chart_page.ts | 1 + .../apps/visualize/precalculated_histogram.ts | 73 +++++++++++++------ 4 files changed, 52 insertions(+), 26 deletions(-) diff --git a/src/plugins/data/public/search/aggs/metrics/avg.ts b/src/plugins/data/public/search/aggs/metrics/avg.ts index 96be3e849a3e8..dba18d562ec19 100644 --- a/src/plugins/data/public/search/aggs/metrics/avg.ts +++ b/src/plugins/data/public/search/aggs/metrics/avg.ts @@ -51,7 +51,7 @@ export const getAvgMetricAgg = ({ getInternalStartServices }: AvgMetricAggDepend { name: 'field', type: 'field', - filterFieldTypes: KBN_FIELD_TYPES.NUMBER, + filterFieldTypes: [KBN_FIELD_TYPES.NUMBER, KBN_FIELD_TYPES.HISTOGRAM], }, ], }, diff --git a/src/plugins/data/public/search/aggs/metrics/sum.ts b/src/plugins/data/public/search/aggs/metrics/sum.ts index 70fc379f2d5f1..66fad89316613 100644 --- a/src/plugins/data/public/search/aggs/metrics/sum.ts +++ b/src/plugins/data/public/search/aggs/metrics/sum.ts @@ -54,7 +54,7 @@ export const getSumMetricAgg = ({ getInternalStartServices }: SumMetricAggDepend { name: 'field', type: 'field', - filterFieldTypes: KBN_FIELD_TYPES.NUMBER, + filterFieldTypes: [KBN_FIELD_TYPES.NUMBER, KBN_FIELD_TYPES.HISTOGRAM], }, ], }, diff --git a/test/functional/page_objects/visualize_chart_page.ts b/test/functional/page_objects/visualize_chart_page.ts index 80fb33bb49d49..31e18adad7589 100644 --- a/test/functional/page_objects/visualize_chart_page.ts +++ b/test/functional/page_objects/visualize_chart_page.ts @@ -312,6 +312,7 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr /** * If you are writing new tests, you should rather look into getTableVisContent method instead. + * @deprecated Use getTableVisContent instead. */ public async getTableVisData() { return await testSubjects.getVisibleText('paginated-table-body'); diff --git a/x-pack/test/functional/apps/visualize/precalculated_histogram.ts b/x-pack/test/functional/apps/visualize/precalculated_histogram.ts index 5d362d29b640c..d20af67508b57 100644 --- a/x-pack/test/functional/apps/visualize/precalculated_histogram.ts +++ b/x-pack/test/functional/apps/visualize/precalculated_histogram.ts @@ -24,37 +24,62 @@ export default function({ getService, getPageObjects }: FtrProviderContext) { return esArchiver.unload('pre_calculated_histogram'); }); - const initHistogramBarChart = async () => { - await PageObjects.visualize.navigateToNewVisualization(); - await PageObjects.visualize.clickVerticalBarChart(); - await PageObjects.visualize.clickNewSearch('histogram-test'); - await PageObjects.visChart.waitForVisualization(); - }; - - const getFieldOptionsForAggregation = async (aggregation: string): Promise => { - await PageObjects.visEditor.clickBucket('Y-axis', 'metrics'); - await PageObjects.visEditor.selectAggregation(aggregation, 'metrics'); - const fieldValues = await PageObjects.visEditor.getField(); - return fieldValues; - }; - it('appears correctly in discover', async function() { await PageObjects.common.navigateToApp('discover'); const rowData = await PageObjects.discover.getDocTableIndex(1); expect(rowData.includes('"values": [ 0.3, 1, 3, 4.2, 4.8 ]')).to.be.ok(); }); - it('appears in the field options of a Percentiles aggregation', async function() { - await initHistogramBarChart(); - const fieldValues: string[] = await getFieldOptionsForAggregation('Percentiles'); - log.debug('Percentiles Fields = ' + fieldValues); - expect(fieldValues[0]).to.be('histogram-content'); - }); + describe('works in visualizations', () => { + before(async () => { + await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.clickDataTable(); + await PageObjects.visualize.clickNewSearch('histogram-test'); + await PageObjects.visChart.waitForVisualization(); + await PageObjects.visEditor.clickMetricEditor(); + }); + + const renderTableForAggregation = async (aggregation: string) => { + await PageObjects.visEditor.selectAggregation(aggregation, 'metrics'); + await PageObjects.visEditor.selectField('histogram-content', 'metrics'); + await PageObjects.visEditor.clickGo(); + + return await PageObjects.visChart.getTableVisContent(); + }; + + it('with percentiles aggregation', async () => { + const data = (await renderTableForAggregation('Percentiles')) as string[][]; + expect(data[0]).to.have.property('length', 7); + // Percentile values are not deterministic, so we can't check for the exact values here, + // but just check they are all within the given range + // see https://github.com/elastic/elasticsearch/issues/49225 + expect(data[0].every((p: string) => Number(p) >= 0.3 && Number(p) <= 5)).to.be(true); + }); + + it('with percentile ranks aggregation', async () => { + const data = await renderTableForAggregation('Percentile Ranks'); + expect(data).to.eql([['0%']]); + }); + + it('with average aggregation', async () => { + const data = await renderTableForAggregation('Average'); + expect(data).to.eql([['2.8510720308359434']]); + }); + + it('with median aggregation', async () => { + // Percentile values (which are used by median behind the scenes) are not deterministic, + // so we can't check for the exact values here, but just check they are all within the given range + // see https://github.com/elastic/elasticsearch/issues/49225 + const data = await renderTableForAggregation('Median'); + const value = Number(data[0][0]); + expect(value).to.be.above(3.0); + expect(value).to.be.below(3.3); + }); - it('appears in the field options of a Percentile Ranks aggregation', async function() { - const fieldValues: string[] = await getFieldOptionsForAggregation('Percentile Ranks'); - log.debug('Percentile Ranks Fields = ' + fieldValues); - expect(fieldValues[0]).to.be('histogram-content'); + it('with sum aggregation', async () => { + const data = await renderTableForAggregation('Sum'); + expect(data).to.eql([['11834.800000000001']]); + }); }); }); } From a8b1a6b924f9e14d11d1798212734d91d09fe2b6 Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Tue, 19 May 2020 11:37:09 -0700 Subject: [PATCH 047/129] [Reporting] Consolidate API Integration Test configs (#66637) * [Reporting] Consolidate API Integration Test configs * fix test isolation * tweak * import order * fix ts refactor ish * fix a test bug * fix test * --wip-- [skip ci] * revision * undo bad cherrypick * fix delete reports * log tweak * fix default index pattern * fix the test * revert * --wip-- [skip ci] * unrevert * harden the deleteAllReportingIndexes function * fix tests * move the log.debug line * fix config path Co-authored-by: Elastic Machine --- x-pack/scripts/functional_tests.js | 3 +- x-pack/test/reporting/.gitignore | 1 - x-pack/test/reporting/api/chromium_tests.ts | 34 --------------- x-pack/test/reporting/configs/chromium_api.js | 38 ----------------- x-pack/test/reporting/services/index.ts | 15 ------- .../config.js} | 17 ++++---- .../fixtures.ts | 0 .../ftr_provider_context.d.ts | 0 .../generation_urls.ts | 0 .../reporting}/constants.ts | 10 +++-- .../reporting}/csv_job_params.ts | 13 ++++-- .../reporting}/csv_saved_search.ts | 15 +++++-- .../reporting}/index.ts | 7 ++-- .../reporting}/usage.ts | 32 ++++++++++---- .../services.ts} | 42 ++++++++++++++++--- 15 files changed, 101 insertions(+), 126 deletions(-) delete mode 100644 x-pack/test/reporting/.gitignore delete mode 100644 x-pack/test/reporting/api/chromium_tests.ts delete mode 100644 x-pack/test/reporting/configs/chromium_api.js delete mode 100644 x-pack/test/reporting/services/index.ts rename x-pack/test/{reporting/configs/generate_api.js => reporting_api_integration/config.js} (69%) rename x-pack/test/{reporting/api/generate => reporting_api_integration}/fixtures.ts (100%) rename x-pack/test/{reporting => reporting_api_integration}/ftr_provider_context.d.ts (100%) rename x-pack/test/{reporting/api => reporting_api_integration}/generation_urls.ts (100%) rename x-pack/test/{reporting/api => reporting_api_integration/reporting}/constants.ts (65%) rename x-pack/test/{reporting/api/generate => reporting_api_integration/reporting}/csv_job_params.ts (89%) rename x-pack/test/{reporting/api/generate => reporting_api_integration/reporting}/csv_saved_search.ts (98%) rename x-pack/test/{reporting/api/generate => reporting_api_integration/reporting}/index.ts (77%) rename x-pack/test/{reporting/api => reporting_api_integration/reporting}/usage.ts (88%) rename x-pack/test/{reporting/services/reporting_api.ts => reporting_api_integration/services.ts} (76%) diff --git a/x-pack/scripts/functional_tests.js b/x-pack/scripts/functional_tests.js index 0bd7618ba973f..fc78e1b80bc68 100644 --- a/x-pack/scripts/functional_tests.js +++ b/x-pack/scripts/functional_tests.js @@ -11,8 +11,6 @@ const alwaysImportedTests = [ require.resolve('../test/functional/config_security_trial.ts'), ]; const onlyNotInCoverageTests = [ - require.resolve('../test/reporting/configs/chromium_api.js'), - require.resolve('../test/reporting/configs/generate_api.js'), require.resolve('../test/api_integration/config_security_basic.js'), require.resolve('../test/api_integration/config.js'), require.resolve('../test/alerting_api_integration/basic/config.ts'), @@ -50,6 +48,7 @@ const onlyNotInCoverageTests = [ require.resolve('../test/licensing_plugin/config.public.ts'), require.resolve('../test/licensing_plugin/config.legacy.ts'), require.resolve('../test/endpoint_api_integration_no_ingest/config.ts'), + require.resolve('../test/reporting_api_integration/config.js'), ]; require('@kbn/plugin-helpers').babelRegister(); diff --git a/x-pack/test/reporting/.gitignore b/x-pack/test/reporting/.gitignore deleted file mode 100644 index 99ee4c44686a0..0000000000000 --- a/x-pack/test/reporting/.gitignore +++ /dev/null @@ -1 +0,0 @@ -functional/reports/session/ diff --git a/x-pack/test/reporting/api/chromium_tests.ts b/x-pack/test/reporting/api/chromium_tests.ts deleted file mode 100644 index 75e8e3e70b5a5..0000000000000 --- a/x-pack/test/reporting/api/chromium_tests.ts +++ /dev/null @@ -1,34 +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 { OSS_DATA_ARCHIVE_PATH, OSS_KIBANA_ARCHIVE_PATH } from './constants'; -import { FtrProviderContext } from '../ftr_provider_context'; - -// eslint-disable-next-line import/no-default-export -export default function({ loadTestFile, getService }: FtrProviderContext) { - const esArchiver = getService('esArchiver'); - const kibanaServer = getService('kibanaServer'); - - describe('chromium', function() { - this.tags('ciGroup2'); - - before(async () => { - await esArchiver.load(OSS_KIBANA_ARCHIVE_PATH); - await esArchiver.load(OSS_DATA_ARCHIVE_PATH); - - await kibanaServer.uiSettings.update({ - defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c', - }); - }); - - after(async () => { - await esArchiver.unload(OSS_KIBANA_ARCHIVE_PATH); - await esArchiver.unload(OSS_DATA_ARCHIVE_PATH); - }); - - loadTestFile(require.resolve('./usage')); - }); -} diff --git a/x-pack/test/reporting/configs/chromium_api.js b/x-pack/test/reporting/configs/chromium_api.js deleted file mode 100644 index 98235f433681e..0000000000000 --- a/x-pack/test/reporting/configs/chromium_api.js +++ /dev/null @@ -1,38 +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 { ReportingAPIProvider } from '../services'; - -export default async function({ readConfigFile }) { - const apiConfig = await readConfigFile(require.resolve('../../api_integration/config.js')); - const functionalConfig = await readConfigFile(require.resolve('../../functional/config.js')); - - return { - servers: apiConfig.get('servers'), - junit: { reportName: 'X-Pack Chromium API Reporting Tests' }, - testFiles: [require.resolve('../api/chromium_tests')], - services: { - ...apiConfig.get('services'), - reportingAPI: ReportingAPIProvider, - }, - kbnTestServer: { - ...apiConfig.get('kbnTestServer'), - serverArgs: [ - // Reporting API tests use functionalConfig instead of apiConfig because they needs a fully working UI. By default, the API config - // does not have optimize setting enabled, and Kibana would not have a working UI. - ...functionalConfig.get('kbnTestServer.serverArgs'), - '--logging.events.log', - '["info","warning","error","fatal","optimize","reporting"]', - '--xpack.reporting.csv.enablePanelActionDownload=true', - '--xpack.reporting.capture.maxAttempts=1', - '--xpack.security.session.idleTimeout=3600000', - '--xpack.spaces.enabled=false', - ], - }, - esArchiver: apiConfig.get('esArchiver'), - esTestCluster: apiConfig.get('esTestCluster'), - }; -} diff --git a/x-pack/test/reporting/services/index.ts b/x-pack/test/reporting/services/index.ts deleted file mode 100644 index 9684f2a8abc6c..0000000000000 --- a/x-pack/test/reporting/services/index.ts +++ /dev/null @@ -1,15 +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 { ReportingAPIProvider } from './reporting_api'; -import { services as xpackServices } from '../../functional/services'; - -export const services = { - ...xpackServices, - reportingAPI: ReportingAPIProvider, -}; - -export { ReportingAPIProvider }; diff --git a/x-pack/test/reporting/configs/generate_api.js b/x-pack/test/reporting_api_integration/config.js similarity index 69% rename from x-pack/test/reporting/configs/generate_api.js rename to x-pack/test/reporting_api_integration/config.js index c2b5e6c84f05f..2b1cd637a831d 100644 --- a/x-pack/test/reporting/configs/generate_api.js +++ b/x-pack/test/reporting_api_integration/config.js @@ -6,15 +6,16 @@ import { esTestConfig, kbnTestConfig, kibanaServerTestUser } from '@kbn/test'; import { format as formatUrl } from 'url'; -import { ReportingAPIProvider } from '../services'; +import { ReportingAPIProvider } from './services'; export default async function({ readConfigFile }) { - const apiConfig = await readConfigFile(require.resolve('../../api_integration/config.js')); + const apiConfig = await readConfigFile(require.resolve('../api_integration/config')); + const functionalConfig = await readConfigFile(require.resolve('../functional/config')); // Reporting API tests need a fully working UI return { servers: apiConfig.get('servers'), - junit: { reportName: 'X-Pack Reporting Generate API Integration Tests' }, - testFiles: [require.resolve('../api/generate')], + junit: { reportName: 'X-Pack Reporting API Integration Tests' }, + testFiles: [require.resolve('./reporting')], services: { ...apiConfig.get('services'), reportingAPI: ReportingAPIProvider, @@ -22,18 +23,18 @@ export default async function({ readConfigFile }) { kbnTestServer: { ...apiConfig.get('kbnTestServer'), serverArgs: [ - '--logging.events.log', - '["info","warning","error","fatal","optimize","reporting"]', + ...functionalConfig.get('kbnTestServer.serverArgs'), + `--elasticsearch.hosts=${formatUrl(esTestConfig.getUrlParts())}`, `--elasticsearch.password=${kibanaServerTestUser.password}`, `--elasticsearch.username=${kibanaServerTestUser.username}`, `--logging.json=false`, - `--optimize.enabled=false`, `--server.maxPayloadBytes=1679958`, `--server.port=${kbnTestConfig.getPort()}`, - `--xpack.reporting.csv.enablePanelActionDownload=true`, + `--xpack.reporting.capture.maxAttempts=1`, `--xpack.reporting.csv.maxSizeBytes=2850`, `--xpack.reporting.queue.pollInterval=3000`, + `--xpack.security.session.idleTimeout=3600000`, `--xpack.spaces.enabled=false`, ], }, diff --git a/x-pack/test/reporting/api/generate/fixtures.ts b/x-pack/test/reporting_api_integration/fixtures.ts similarity index 100% rename from x-pack/test/reporting/api/generate/fixtures.ts rename to x-pack/test/reporting_api_integration/fixtures.ts diff --git a/x-pack/test/reporting/ftr_provider_context.d.ts b/x-pack/test/reporting_api_integration/ftr_provider_context.d.ts similarity index 100% rename from x-pack/test/reporting/ftr_provider_context.d.ts rename to x-pack/test/reporting_api_integration/ftr_provider_context.d.ts diff --git a/x-pack/test/reporting/api/generation_urls.ts b/x-pack/test/reporting_api_integration/generation_urls.ts similarity index 100% rename from x-pack/test/reporting/api/generation_urls.ts rename to x-pack/test/reporting_api_integration/generation_urls.ts diff --git a/x-pack/test/reporting/api/constants.ts b/x-pack/test/reporting_api_integration/reporting/constants.ts similarity index 65% rename from x-pack/test/reporting/api/constants.ts rename to x-pack/test/reporting_api_integration/reporting/constants.ts index 0b4cb4f44a4bc..590ef6325dd51 100644 --- a/x-pack/test/reporting/api/constants.ts +++ b/x-pack/test/reporting_api_integration/reporting/constants.ts @@ -3,13 +3,15 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + +import { REPO_ROOT } from '@kbn/dev-utils'; import path from 'path'; export const OSS_KIBANA_ARCHIVE_PATH = path.resolve( - __dirname, - '../../../../test/functional/fixtures/es_archiver/dashboard/current/kibana' + REPO_ROOT, + 'test/functional/fixtures/es_archiver/dashboard/current/kibana' ); export const OSS_DATA_ARCHIVE_PATH = path.resolve( - __dirname, - '../../../../test/functional/fixtures/es_archiver/dashboard/current/data' + REPO_ROOT, + 'test/functional/fixtures/es_archiver/dashboard/current/data' ); diff --git a/x-pack/test/reporting/api/generate/csv_job_params.ts b/x-pack/test/reporting_api_integration/reporting/csv_job_params.ts similarity index 89% rename from x-pack/test/reporting/api/generate/csv_job_params.ts rename to x-pack/test/reporting_api_integration/reporting/csv_job_params.ts index c8d6f11b74f9d..0cee0308e7489 100644 --- a/x-pack/test/reporting/api/generate/csv_job_params.ts +++ b/x-pack/test/reporting_api_integration/reporting/csv_job_params.ts @@ -6,12 +6,15 @@ import expect from '@kbn/expect'; import supertest from 'supertest'; -import { JOB_PARAMS_RISON } from './fixtures'; +import { JOB_PARAMS_RISON } from '../fixtures'; +import { FtrProviderContext } from '../ftr_provider_context'; // eslint-disable-next-line import/no-default-export -export default function({ getService }: { getService: any }) { +export default function({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const supertestSvc = getService('supertest'); + const reportingAPI = getService('reportingAPI'); + const generateAPI = { getCsvFromParamsInPayload: async (jobParams: object = {}) => { return await supertestSvc @@ -30,11 +33,13 @@ export default function({ getService }: { getService: any }) { before(async () => { await esArchiver.load('reporting/logs'); await esArchiver.load('logstash_functional'); - }); // prettier-ignore + }); + after(async () => { await esArchiver.unload('reporting/logs'); await esArchiver.unload('logstash_functional'); - }); // prettier-ignore + await reportingAPI.deleteAllReports(); + }); it('Rejects bogus jobParams', async () => { const { status: resStatus, text: resText } = (await generateAPI.getCsvFromParamsInPayload({ diff --git a/x-pack/test/reporting/api/generate/csv_saved_search.ts b/x-pack/test/reporting_api_integration/reporting/csv_saved_search.ts similarity index 98% rename from x-pack/test/reporting/api/generate/csv_saved_search.ts rename to x-pack/test/reporting_api_integration/reporting/csv_saved_search.ts index ed44ba8ea4a76..96d3f0f28c22b 100644 --- a/x-pack/test/reporting/api/generate/csv_saved_search.ts +++ b/x-pack/test/reporting_api_integration/reporting/csv_saved_search.ts @@ -7,15 +7,16 @@ import expect from '@kbn/expect'; import supertest from 'supertest'; import { + CSV_RESULT_DOCVALUE, CSV_RESULT_HUGE, + CSV_RESULT_NANOS, CSV_RESULT_SCRIPTED, CSV_RESULT_SCRIPTED_REQUERY, CSV_RESULT_SCRIPTED_RESORTED, CSV_RESULT_TIMEBASED, CSV_RESULT_TIMELESS, - CSV_RESULT_NANOS, - CSV_RESULT_DOCVALUE, -} from './fixtures'; +} from '../fixtures'; +import { FtrProviderContext } from '../ftr_provider_context'; interface GenerateOpts { timerange?: { @@ -27,9 +28,11 @@ interface GenerateOpts { } // eslint-disable-next-line import/no-default-export -export default function({ getService }: { getService: any }) { +export default function({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const supertestSvc = getService('supertest'); + const reportingAPI = getService('reportingAPI'); + const generateAPI = { getCsvFromSavedSearch: async ( id: string, @@ -45,6 +48,10 @@ export default function({ getService }: { getService: any }) { describe('Generation from Saved Search ID', () => { describe('Saved Search Features', () => { + after(async () => { + await reportingAPI.deleteAllReports(); + }); + it('With filters and timebased data', async () => { // load test data that contains a saved search and documents await esArchiver.load('reporting/logs'); diff --git a/x-pack/test/reporting/api/generate/index.ts b/x-pack/test/reporting_api_integration/reporting/index.ts similarity index 77% rename from x-pack/test/reporting/api/generate/index.ts rename to x-pack/test/reporting_api_integration/reporting/index.ts index b9db0d465d005..abfdb735d1dc7 100644 --- a/x-pack/test/reporting/api/generate/index.ts +++ b/x-pack/test/reporting_api_integration/reporting/index.ts @@ -4,13 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { FtrProviderContext } from '../../ftr_provider_context'; +import { FtrProviderContext } from '../ftr_provider_context'; // eslint-disable-next-line import/no-default-export export default function({ loadTestFile }: FtrProviderContext) { - describe('CSV', function() { + describe('Reporting APIs', function() { this.tags('ciGroup2'); - loadTestFile(require.resolve('./csv_saved_search')); loadTestFile(require.resolve('./csv_job_params')); + loadTestFile(require.resolve('./csv_saved_search')); + loadTestFile(require.resolve('./usage')); }); } diff --git a/x-pack/test/reporting/api/usage.ts b/x-pack/test/reporting_api_integration/reporting/usage.ts similarity index 88% rename from x-pack/test/reporting/api/usage.ts rename to x-pack/test/reporting_api_integration/reporting/usage.ts index e3ebcf9d3bab0..dc0144f74912c 100644 --- a/x-pack/test/reporting/api/usage.ts +++ b/x-pack/test/reporting_api_integration/reporting/usage.ts @@ -6,8 +6,9 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../ftr_provider_context'; -import { ReportingUsageStats } from '../services/reporting_api'; -import * as GenerationUrls from './generation_urls'; +import * as GenerationUrls from '../generation_urls'; +import { ReportingUsageStats } from '../services'; +import { OSS_DATA_ARCHIVE_PATH, OSS_KIBANA_ARCHIVE_PATH } from './constants'; interface UsageStats { reporting: ReportingUsageStats; @@ -16,12 +17,29 @@ interface UsageStats { // eslint-disable-next-line import/no-default-export export default function({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); const reportingAPI = getService('reportingAPI'); const usageAPI = getService('usageAPI' as any); // NOTE Usage API service is not Typescript describe('reporting usage', () => { - before(() => reportingAPI.deleteAllReportingIndexes()); - afterEach(() => reportingAPI.deleteAllReportingIndexes()); + before(async () => { + await esArchiver.load(OSS_KIBANA_ARCHIVE_PATH); + await esArchiver.load(OSS_DATA_ARCHIVE_PATH); + + await kibanaServer.uiSettings.update({ + defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c', + }); + await reportingAPI.deleteAllReports(); + }); + + after(async () => { + await esArchiver.unload(OSS_KIBANA_ARCHIVE_PATH); + await esArchiver.unload(OSS_DATA_ARCHIVE_PATH); + }); + + afterEach(async () => { + await reportingAPI.deleteAllReports(); + }); describe('initial state', () => { let usage: UsageStats; @@ -98,7 +116,7 @@ export default function({ getService }: FtrProviderContext) { }); describe('from new jobs posted', () => { - it('csv', async () => { + it('should handle csv', async () => { await reportingAPI.expectAllJobsToFinishSuccessfully( await Promise.all([ reportingAPI.postJob(GenerationUrls.CSV_DISCOVER_KUERY_AND_FILTER_6_3), @@ -114,7 +132,7 @@ export default function({ getService }: FtrProviderContext) { reportingAPI.expectRecentJobTypeTotalStats(usage, 'printable_pdf', 0); }); - it('preserve_layout pdf', async () => { + it('should handle preserve_layout pdf', async () => { await reportingAPI.expectAllJobsToFinishSuccessfully( await Promise.all([ reportingAPI.postJob(GenerationUrls.PDF_PRESERVE_DASHBOARD_FILTER_6_3), @@ -131,7 +149,7 @@ export default function({ getService }: FtrProviderContext) { reportingAPI.expectRecentJobTypeTotalStats(usage, 'printable_pdf', 2); }); - it('print_layout pdf', async () => { + it('should handle print_layout pdf', async () => { await reportingAPI.expectAllJobsToFinishSuccessfully( await Promise.all([ reportingAPI.postJob(GenerationUrls.PDF_PRINT_DASHBOARD_6_3), diff --git a/x-pack/test/reporting/services/reporting_api.ts b/x-pack/test/reporting_api_integration/services.ts similarity index 76% rename from x-pack/test/reporting/services/reporting_api.ts rename to x-pack/test/reporting_api_integration/services.ts index 1fa5fd7135708..ae7b83e2ac81b 100644 --- a/x-pack/test/reporting/services/reporting_api.ts +++ b/x-pack/test/reporting_api_integration/services.ts @@ -5,9 +5,12 @@ */ import expect from '@kbn/expect'; +import * as Rx from 'rxjs'; +import { filter, first, mapTo, switchMap, timeout } from 'rxjs/operators'; // @ts-ignore no module definition -import { indexTimestamp } from '../../../legacy/plugins/reporting/server/lib/esqueue/helpers/index_timestamp'; -import { FtrProviderContext } from '../ftr_provider_context'; +import { indexTimestamp } from '../../legacy/plugins/reporting/server/lib/esqueue/helpers/index_timestamp'; +import { services as xpackServices } from '../functional/services'; +import { FtrProviderContext } from './ftr_provider_context'; interface PDFAppCounts { app: { @@ -56,7 +59,13 @@ export function ReportingAPIProvider({ getService }: FtrProviderContext) { .get(downloadReportPath) .responseType('blob') .set('kbn-xsrf', 'xxx')) as any; - log.debug(`Report at path ${downloadReportPath} returned code ${response.statusCode}`); + if (response.statusCode === 503) { + log.debug(`Report at path ${downloadReportPath} is pending`); + } else if (response.statusCode === 200) { + log.debug(`Report at path ${downloadReportPath} is complete`); + } else { + log.debug(`Report at path ${downloadReportPath} returned code ${response.statusCode}`); + } if (response.statusCode !== JOB_IS_PENDING_CODE) { clearInterval(intervalId); resolve(response.statusCode); @@ -120,9 +129,25 @@ export function ReportingAPIProvider({ getService }: FtrProviderContext) { }; }, - async deleteAllReportingIndexes() { - log.debug('ReportingAPI.deleteAllReportingIndexes'); - await esSupertest.delete('/.reporting*').expect(200); + async deleteAllReports() { + log.debug('ReportingAPI.deleteAllReports'); + + // ignores 409 errs and keeps retrying + const deleted$ = Rx.interval(100).pipe( + switchMap(() => + esSupertest + .post('/.reporting*/_delete_by_query') + .send({ query: { match_all: {} } }) + .then(({ status }) => status) + ), + filter(status => status === 200), + mapTo(true), + first(), + timeout(5000) + ); + + const reportsDeleted = await deleted$.toPromise(); + expect(reportsDeleted).to.be(true); }, expectRecentPdfAppStats(stats: UsageStats, app: string, count: number) { @@ -158,3 +183,8 @@ export function ReportingAPIProvider({ getService }: FtrProviderContext) { }, }; } + +export const services = { + ...xpackServices, + reportingAPI: ReportingAPIProvider, +}; From b15578cbdfd4a613d72bd50a5aee4cb09fb5c0fc Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 19 May 2020 14:58:01 -0400 Subject: [PATCH 048/129] [Uptime] Use React.lazy for alert type registration (#66829) * Use React.lazy for alert type registration. * Add typing to TLS alert component. Co-authored-by: Elastic Machine --- .../alerts/alerts_containers/alert_monitor_status.tsx | 7 +++++-- .../overview/alerts/alerts_containers/alert_tls.tsx | 5 ++++- .../uptime/public/lib/alert_types/monitor_status.tsx | 5 ++++- x-pack/plugins/uptime/public/lib/alert_types/tls.tsx | 5 +++-- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx index 9dd27db0be607..77e0c98c0260d 100644 --- a/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx +++ b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx @@ -21,13 +21,13 @@ interface Props { }; } -export const AlertMonitorStatus = ({ +export const AlertMonitorStatus: React.FC = ({ autocomplete, enabled, numTimes, setAlertParams, timerange, -}: Props) => { +}) => { const { filters, locations } = useSelector(selectMonitorStatusAlert); return ( ); }; + +// eslint-disable-next-line import/no-default-export +export { AlertMonitorStatus as default }; diff --git a/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_tls.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_tls.tsx index a2e1c1d43526c..c7657c34220fc 100644 --- a/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_tls.tsx +++ b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_tls.tsx @@ -10,7 +10,7 @@ import { AlertTlsComponent } from '../alert_tls'; import { setAlertFlyoutVisible } from '../../../../state/actions'; import { selectDynamicSettings } from '../../../../state/selectors'; -export const AlertTls = () => { +export const AlertTls: React.FC<{}> = () => { const dispatch = useDispatch(); const setFlyoutVisible = useCallback((value: boolean) => dispatch(setAlertFlyoutVisible(value)), [ dispatch, @@ -24,3 +24,6 @@ export const AlertTls = () => { /> ); }; + +// eslint-disable-next-line import/no-default-export +export { AlertTls as default }; diff --git a/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx b/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx index bba7907d79c5d..08fc044bee201 100644 --- a/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx +++ b/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx @@ -11,7 +11,6 @@ import { isRight } from 'fp-ts/lib/Either'; import { AlertTypeModel } from '../../../../triggers_actions_ui/public'; import { AlertTypeInitializer } from '.'; import { StatusCheckExecutorParamsType } from '../../../common/runtime_types'; -import { AlertMonitorStatus } from '../../components/overview/alerts/alerts_containers'; import { MonitorStatusTitle } from './monitor_status_title'; import { CLIENT_ALERT_TYPES } from '../../../common/constants'; import { MonitorStatusTranslations } from './translations'; @@ -57,6 +56,10 @@ export const validate = (alertParams: any) => { const { defaultActionMessage } = MonitorStatusTranslations; +const AlertMonitorStatus = React.lazy(() => + import('../../components/overview/alerts/alerts_containers/alert_monitor_status') +); + export const initMonitorStatusAlertType: AlertTypeInitializer = ({ autocomplete, }): AlertTypeModel => ({ diff --git a/x-pack/plugins/uptime/public/lib/alert_types/tls.tsx b/x-pack/plugins/uptime/public/lib/alert_types/tls.tsx index 5e1b8cf233d70..15ac849fe871d 100644 --- a/x-pack/plugins/uptime/public/lib/alert_types/tls.tsx +++ b/x-pack/plugins/uptime/public/lib/alert_types/tls.tsx @@ -9,14 +9,15 @@ import { AlertTypeModel } from '../../../../triggers_actions_ui/public'; import { CLIENT_ALERT_TYPES } from '../../../common/constants'; import { TlsTranslations } from './translations'; import { AlertTypeInitializer } from '.'; -import { AlertTls } from '../../components/overview/alerts/alerts_containers/alert_tls'; const { name, defaultActionMessage } = TlsTranslations; export const initTlsAlertType: AlertTypeInitializer = (): AlertTypeModel => ({ id: CLIENT_ALERT_TYPES.TLS, iconClass: 'uptimeApp', - alertParamsExpression: () => , + alertParamsExpression: React.lazy(() => + import('../../components/overview/alerts/alerts_containers/alert_tls') + ), name, validate: () => ({ errors: {} }), defaultActionMessage, From 89402acfae1e1c61e1ce2b9896538f0bdba4f2b7 Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Tue, 19 May 2020 12:05:39 -0700 Subject: [PATCH 049/129] [Metrics UI] Change Metric Threshold Alert charts to use bar charts (#66672) Co-authored-by: Elastic Machine --- .../components/expression_chart.tsx | 87 ++++++++++++------- 1 file changed, 57 insertions(+), 30 deletions(-) diff --git a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_chart.tsx b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_chart.tsx index 7665c4d84e1e9..99f5aa972758d 100644 --- a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_chart.tsx +++ b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_chart.tsx @@ -12,6 +12,8 @@ import { Settings, TooltipValue, RectAnnotation, + AnnotationDomainTypes, + LineAnnotation, } from '@elastic/charts'; import { first, last } from 'lodash'; import moment from 'moment'; @@ -140,6 +142,7 @@ export const ExpressionChart: React.FC = ({ } const isAbove = [Comparator.GT, Comparator.GT_OR_EQ].includes(expression.comparator); + const isBelow = [Comparator.LT, Comparator.LT_OR_EQ].includes(expression.comparator); const opacity = 0.3; const { timeSize, timeUnit } = expression; const timeLabel = TIME_LABELS[timeUnit]; @@ -149,44 +152,49 @@ export const ExpressionChart: React.FC = ({ - {thresholds.length ? ( - `threshold_${i}`)} - series={series} - stack={false} - opacity={opacity} - /> - ) : null} - {thresholds.length && expression.comparator === Comparator.OUTSIDE_RANGE ? ( + ({ + dataValue: threshold, + }))} + style={{ + line: { + strokeWidth: 2, + stroke: colorTransformer(MetricsExplorerColor.color1), + opacity: 1, + }, + }} + /> + {thresholds.length === 2 && expression.comparator === Comparator.BETWEEN ? ( <> - `threshold_${i}`)} - series={series} - stack={false} - opacity={opacity} + dataValues={[ + { + coordinates: { + x0: firstTimestamp, + x1: lastTimestamp, + y0: first(expression.threshold), + y1: last(expression.threshold), + }, + }, + ]} /> + + ) : null} + {thresholds.length === 2 && expression.comparator === Comparator.OUTSIDE_RANGE ? ( + <> = ({ /> ) : null} + {isBelow && first(expression.threshold) != null ? ( + + ) : null} {isAbove && first(expression.threshold) != null ? ( Date: Tue, 19 May 2020 12:06:07 -0700 Subject: [PATCH 050/129] [Metrics UI] Add sorting for name and value to Inventory View (#66644) * [Metrics UI] Add sorting for name and value to Inventory View * Fixing saved views * Fixing overlooked i18n translations * Fixing type issue * Fixing i18n paths Co-authored-by: Elastic Machine --- .../metrics_and_groupby_toolbar_items.tsx | 6 + .../common/saved_objects/inventory_view.ts | 10 ++ x-pack/plugins/infra/public/lib/lib.ts | 2 + .../inventory_view/components/layout.tsx | 2 + .../components/toolbars/toolbar.tsx | 6 +- .../components/toolbars/toolbar_wrapper.tsx | 6 + .../inventory_view/components/waffle/map.tsx | 4 +- .../waffle/metric_control/index.tsx | 5 +- .../waffle/waffle_accounts_controls.tsx | 5 +- .../waffle/waffle_group_by_controls.tsx | 5 +- .../waffle/waffle_inventory_switcher.tsx | 6 +- .../waffle/waffle_region_controls.tsx | 5 +- .../waffle/waffle_sort_controls.tsx | 125 ++++++++++++++++++ .../hooks/use_waffle_options.ts | 17 +++ .../hooks/use_waffle_view_state.ts | 3 + .../lib/create_uptime_link.test.ts | 1 + .../metrics/inventory_view/lib/sort_nodes.ts | 23 ++++ 17 files changed, 222 insertions(+), 9 deletions(-) create mode 100644 x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_sort_controls.tsx create mode 100644 x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/sort_nodes.ts diff --git a/x-pack/plugins/infra/common/inventory_models/shared/components/metrics_and_groupby_toolbar_items.tsx b/x-pack/plugins/infra/common/inventory_models/shared/components/metrics_and_groupby_toolbar_items.tsx index bf37828ed0856..4a4accc6edfed 100644 --- a/x-pack/plugins/infra/common/inventory_models/shared/components/metrics_and_groupby_toolbar_items.tsx +++ b/x-pack/plugins/infra/common/inventory_models/shared/components/metrics_and_groupby_toolbar_items.tsx @@ -7,6 +7,7 @@ import React, { useMemo } from 'react'; import { EuiFlexItem } from '@elastic/eui'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { WaffleSortControls } from '../../../../public/pages/metrics/inventory_view/components/waffle/waffle_sort_controls'; import { ToolbarProps } from '../../../../public/pages/metrics/inventory_view/components/toolbars/toolbar'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { WaffleMetricControls } from '../../../../public/pages/metrics/inventory_view/components/waffle/metric_control'; @@ -58,6 +59,11 @@ export const MetricsAndGroupByToolbarItems = (props: Props) => { customOptions={props.customOptions} /> + {props.view === 'map' && ( + + + + )} ); }; diff --git a/x-pack/plugins/infra/common/saved_objects/inventory_view.ts b/x-pack/plugins/infra/common/saved_objects/inventory_view.ts index c14b75efc6887..15874f2eee348 100644 --- a/x-pack/plugins/infra/common/saved_objects/inventory_view.ts +++ b/x-pack/plugins/infra/common/saved_objects/inventory_view.ts @@ -21,6 +21,16 @@ export const inventoryViewSavedObjectType: SavedObjectsType = { name: { type: 'keyword', }, + sort: { + properties: { + by: { + type: 'keyword', + }, + direction: { + type: 'keyword', + }, + }, + }, metric: { properties: { type: { diff --git a/x-pack/plugins/infra/public/lib/lib.ts b/x-pack/plugins/infra/public/lib/lib.ts index 9043b4d9f6979..6bd4c10c881e3 100644 --- a/x-pack/plugins/infra/public/lib/lib.ts +++ b/x-pack/plugins/infra/public/lib/lib.ts @@ -18,6 +18,7 @@ import { SnapshotNodeMetric, SnapshotNodePath, } from '../../common/http_api/snapshot_api'; +import { WaffleSortOption } from '../pages/metrics/inventory_view/hooks/use_waffle_options'; export interface InfraFrontendLibs { apolloClient: InfraApolloClient; @@ -163,6 +164,7 @@ export interface InfraWaffleMapOptions { metric: SnapshotMetricInput; groupBy: SnapshotGroupBy; legend: InfraWaffleMapLegend; + sort: WaffleSortOption; } export interface InfraOptions { diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx index a71e43874b480..32f8e47fe9b7d 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx @@ -32,6 +32,7 @@ export const Layout = () => { const { metric, groupBy, + sort, nodeType, accountId, region, @@ -64,6 +65,7 @@ export const Layout = () => { ], } as InfraWaffleMapGradientLegend, metric, + sort, fields: source?.configuration?.fields, groupBy, }; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx index e8485fb812586..6a68599aee38c 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar.tsx @@ -19,17 +19,17 @@ import { ToolbarWrapper } from './toolbar_wrapper'; import { InfraGroupByOptions } from '../../../../../lib/lib'; import { IIndexPattern } from '../../../../../../../../../src/plugins/data/public'; import { InventoryItemType } from '../../../../../../common/inventory_models/types'; -import { WaffleOptionsState } from '../../hooks/use_waffle_options'; +import { WaffleOptionsState, WaffleSortOption } from '../../hooks/use_waffle_options'; import { useInventoryMeta } from '../../hooks/use_inventory_meta'; -export interface ToolbarProps - extends Omit { +export interface ToolbarProps extends Omit { createDerivedIndexPattern: (type: 'logs' | 'metrics' | 'both') => IIndexPattern; changeMetric: (payload: SnapshotMetricInput) => void; changeGroupBy: (payload: SnapshotGroupBy) => void; changeCustomOptions: (payload: InfraGroupByOptions[]) => void; changeAccount: (id: string) => void; changeRegion: (name: string) => void; + changeSort: (sort: WaffleSortOption) => void; accounts: InventoryCloudAccount[]; regions: string[]; changeCustomMetrics: (payload: SnapshotCustomMetricInput[]) => void; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar_wrapper.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar_wrapper.tsx index ea53122984161..3606bcc6944d1 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar_wrapper.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/toolbars/toolbar_wrapper.tsx @@ -25,12 +25,15 @@ export const ToolbarWrapper = (props: Props) => { changeCustomOptions, changeAccount, changeRegion, + changeSort, customOptions, groupBy, metric, nodeType, accountId, + view, region, + sort, customMetrics, changeCustomMetrics, } = useWaffleOptionsContext(); @@ -47,8 +50,11 @@ export const ToolbarWrapper = (props: Props) => { changeAccount, changeRegion, changeCustomOptions, + changeSort, customOptions, groupBy, + sort, + view, metric, nodeType, region, diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/map.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/map.tsx index b1f816fb46d2e..eee8c69091ef0 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/map.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/map.tsx @@ -15,6 +15,7 @@ import { GroupOfNodes } from './group_of_nodes'; import { applyWaffleMapLayout } from '../../lib/apply_wafflemap_layout'; import { SnapshotNode } from '../../../../../../common/http_api/snapshot_api'; import { InventoryItemType } from '../../../../../../common/inventory_models/types'; +import { sortNodes } from '../../lib/sort_nodes'; interface Props { nodes: SnapshotNode[]; @@ -37,7 +38,8 @@ export const Map: React.FC = ({ nodeType, dataBounds, }) => { - const map = nodesToWaffleMap(nodes); + const sortedNodes = sortNodes(options.sort, nodes); + const map = nodesToWaffleMap(sortedNodes); return ( {({ measureRef, content: { width = 0, height = 0 } }) => { diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx index f91e9a4034bc2..0cf1faec06c11 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/index.tsx @@ -132,7 +132,10 @@ export const WaffleMetricControls = ({ } const button = ( - + {currentLabel} ); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_accounts_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_accounts_controls.tsx index 3e4ff1de8291d..5ac6320510257 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_accounts_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_accounts_controls.tsx @@ -58,7 +58,10 @@ export const WaffleAccountsControls = (props: Props) => { ); const button = ( - + {currentLabel ? currentLabel.name : i18n.translate('xpack.infra.waffle.accountAllTitle', { diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx index c1f406f31e85e..cc09ce226b2fe 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_group_by_controls.tsx @@ -130,7 +130,10 @@ export const WaffleGroupByControls = class extends React.PureComponent + {buttonBody} ); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_inventory_switcher.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_inventory_switcher.tsx index e534c97eda090..c31b7e0a3e6ff 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_inventory_switcher.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_inventory_switcher.tsx @@ -7,6 +7,7 @@ import { EuiPopover, EuiContextMenu, EuiContextMenuPanelDescriptor } from '@elastic/eui'; import React, { useCallback, useState, useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; import { findInventoryModel } from '../../../../../../common/inventory_models'; import { InventoryItemType } from '../../../../../../common/inventory_models/types'; import { useWaffleOptionsContext } from '../../hooks/use_waffle_options'; @@ -115,7 +116,10 @@ export const WaffleInventorySwitcher: React.FC = () => { }, [nodeType]); const button = ( - + {selectedText} ); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_region_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_region_controls.tsx index 9d759424cdc93..9c28f0798b519 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_region_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_region_controls.tsx @@ -57,7 +57,10 @@ export const WaffleRegionControls = (props: Props) => { ); const button = ( - + {currentLabel || i18n.translate('xpack.infra.waffle.region', { defaultMessage: 'All', diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_sort_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_sort_controls.tsx new file mode 100644 index 0000000000000..b5e6aacd0e6f4 --- /dev/null +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/waffle_sort_controls.tsx @@ -0,0 +1,125 @@ +/* + * 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, useMemo, useState, ReactNode } from 'react'; +import { EuiSwitch, EuiContextMenuPanelDescriptor, EuiPopover, EuiContextMenu } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { EuiTheme, withTheme } from '../../../../../../../observability/public'; +import { WaffleSortOption } from '../../hooks/use_waffle_options'; +import { DropdownButton } from '../dropdown_button'; + +interface Props { + sort: WaffleSortOption; + onChange: (sort: WaffleSortOption) => void; +} + +const LABELS = { + name: i18n.translate('xpack.infra.waffle.sortNameLabel', { defaultMessage: 'Name' }), + value: i18n.translate('xpack.infra.waffle.sort.valueLabel', { defaultMessage: 'Metric value' }), +}; + +export const WaffleSortControls = ({ sort, onChange }: Props) => { + const [isOpen, setIsOpen] = useState(false); + + const showPopover = useCallback(() => { + setIsOpen(true); + }, [setIsOpen]); + + const closePopover = useCallback(() => { + setIsOpen(false); + }, [setIsOpen]); + + const label = LABELS[sort.by]; + + const button = ( + + {label} + + ); + + const selectName = useCallback(() => { + onChange({ ...sort, by: 'name' }); + closePopover(); + }, [closePopover, onChange, sort]); + + const selectValue = useCallback(() => { + onChange({ ...sort, by: 'value' }); + closePopover(); + }, [closePopover, onChange, sort]); + + const toggleSort = useCallback(() => { + onChange({ + ...sort, + direction: sort.direction === 'asc' ? 'desc' : 'asc', + }); + }, [sort, onChange]); + + const panels = useMemo( + () => [ + { + id: 0, + title: '', + items: [ + { + name: LABELS.name, + icon: sort.by === 'name' ? 'check' : 'empty', + onClick: selectName, + }, + { + name: LABELS.value, + icon: sort.by === 'value' ? 'check' : 'empty', + onClick: selectValue, + }, + ], + }, + ], + [sort.by, selectName, selectValue] + ); + + return ( + + + + + + + ); +}; + +interface SwitchContainerProps { + theme: EuiTheme; + children: ReactNode; +} + +const SwitchContainer = withTheme(({ children, theme }: SwitchContainerProps) => { + return ( +
    + {children} +
    + ); +}); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts index 32bfe6e085b4e..92f9ee4897f2d 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts @@ -32,6 +32,7 @@ export const DEFAULT_WAFFLE_OPTIONS_STATE: WaffleOptionsState = { accountId: '', region: '', customMetrics: [], + sort: { by: 'name', direction: 'desc' }, }; export const useWaffleOptions = () => { @@ -99,7 +100,15 @@ export const useWaffleOptions = () => { [setState] ); + const changeSort = useCallback( + (sort: WaffleSortOption) => { + setState(previous => ({ ...previous, sort })); + }, + [setState] + ); + return { + ...DEFAULT_WAFFLE_OPTIONS_STATE, ...state, changeMetric, changeGroupBy, @@ -111,10 +120,16 @@ export const useWaffleOptions = () => { changeAccount, changeRegion, changeCustomMetrics, + changeSort, setWaffleOptionsState: setState, }; }; +export const WaffleSortOptionRT = rt.type({ + by: rt.keyof({ name: null, value: null }), + direction: rt.keyof({ asc: null, desc: null }), +}); + export const WaffleOptionsStateRT = rt.type({ metric: SnapshotMetricInputRT, groupBy: SnapshotGroupByRT, @@ -134,8 +149,10 @@ export const WaffleOptionsStateRT = rt.type({ accountId: rt.string, region: rt.string, customMetrics: rt.array(SnapshotCustomMetricInputRT), + sort: WaffleSortOptionRT, }); +export type WaffleSortOption = rt.TypeOf; export type WaffleOptionsState = rt.TypeOf; const encodeUrlState = (state: WaffleOptionsState) => { return WaffleOptionsStateRT.encode(state); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts index 869560b2b8709..306c30228596f 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts @@ -28,6 +28,7 @@ export const useWaffleViewState = () => { autoBounds, accountId, region, + sort, setWaffleOptionsState, } = useWaffleOptionsContext(); const { currentTime, isAutoReloading, setWaffleTimeState } = useWaffleTimeContext(); @@ -35,6 +36,7 @@ export const useWaffleViewState = () => { const viewState: WaffleViewState = { metric, + sort, groupBy, nodeType, view, @@ -59,6 +61,7 @@ export const useWaffleViewState = () => { const onViewChange = useCallback( (newState: WaffleViewState) => { setWaffleOptionsState({ + sort: newState.sort, metric: newState.metric, groupBy: newState.groupBy, nodeType: newState.nodeType, diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_uptime_link.test.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_uptime_link.test.ts index 5f760cf2f591e..fe9b2aebe27f7 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_uptime_link.test.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_uptime_link.test.ts @@ -21,6 +21,7 @@ const options: InfraWaffleMapOptions = { formatTemplate: '{{value}}', metric: { type: 'cpu' }, groupBy: [], + sort: { by: 'name', direction: 'asc' }, legend: { type: 'gradient', rules: [], diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/sort_nodes.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/sort_nodes.ts new file mode 100644 index 0000000000000..e676fb3e09c2b --- /dev/null +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/sort_nodes.ts @@ -0,0 +1,23 @@ +/* + * 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 { sortBy, last } from 'lodash'; +import { SnapshotNode } from '../../../../../common/http_api/snapshot_api'; +import { WaffleSortOption } from '../hooks/use_waffle_options'; + +const SORT_PATHS = { + name: (node: SnapshotNode) => last(node.path), + value: 'metric.value', +}; + +export const sortNodes = (sort: WaffleSortOption, nodes: SnapshotNode[]) => { + const sortPath = SORT_PATHS[sort.by]; + const sortedNodes = sortBy(nodes, sortPath); + if (sort.direction === 'desc') { + return sortedNodes.reverse(); + } + return sortedNodes; +}; From 59ae5293223c68345d070835cbdd3f0c7b6282bc Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Tue, 19 May 2020 14:42:49 -0700 Subject: [PATCH 051/129] [Metrics UI] Add support for multiple groupings to Metrics Explorer (and Alerts) (#66503) * [Metrics UI] Adding support for multiple groupings to Metrics Explorer * Adding keys to title parts * removing commented line Co-authored-by: Elastic Machine --- .../infra/common/http_api/metrics_explorer.ts | 24 +++++--- .../components/expression.tsx | 7 ++- .../public/alerting/metric_threshold/types.ts | 2 +- .../metrics_explorer/components/chart.tsx | 10 ++-- .../components/chart_context_menu.tsx | 19 ++++-- .../components/chart_title.tsx | 40 +++++++++++++ .../metrics_explorer/components/charts.tsx | 10 +++- .../metrics_explorer/components/group_by.tsx | 16 +++-- .../components/helpers/create_tsvb_link.ts | 16 ++++- .../metrics_explorer/components/toolbar.tsx | 2 +- .../hooks/use_metric_explorer_state.ts | 4 +- .../hooks/use_metrics_explorer_data.test.tsx | 2 +- .../hooks/use_metrics_explorer_data.ts | 2 +- .../hooks/use_metrics_explorer_options.ts | 2 +- .../metric_threshold_executor.ts | 34 +++++++---- .../register_metric_threshold_alert_type.ts | 2 +- .../alerting/metric_threshold/test_mocks.ts | 12 ++-- .../metrics_explorer/lib/get_groupings.ts | 60 +++++++++++++------ .../lib/populate_series_with_tsvb_data.ts | 18 +++++- .../apis/infra/metrics_explorer.ts | 59 ++++++++++++++---- 20 files changed, 256 insertions(+), 85 deletions(-) create mode 100644 x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_title.tsx diff --git a/x-pack/plugins/infra/common/http_api/metrics_explorer.ts b/x-pack/plugins/infra/common/http_api/metrics_explorer.ts index d3a978c9963cf..0f63b8d275e65 100644 --- a/x-pack/plugins/infra/common/http_api/metrics_explorer.ts +++ b/x-pack/plugins/infra/common/http_api/metrics_explorer.ts @@ -52,9 +52,12 @@ export const metricsExplorerRequestBodyRequiredFieldsRT = rt.type({ metrics: rt.array(metricsExplorerMetricRT), }); +const groupByRT = rt.union([rt.string, rt.null, rt.undefined]); +export const afterKeyObjectRT = rt.record(rt.string, rt.union([rt.string, rt.null])); + export const metricsExplorerRequestBodyOptionalFieldsRT = rt.partial({ - groupBy: rt.union([rt.string, rt.null, rt.undefined]), - afterKey: rt.union([rt.string, rt.null, rt.undefined]), + groupBy: rt.union([groupByRT, rt.array(groupByRT)]), + afterKey: rt.union([rt.string, rt.null, rt.undefined, afterKeyObjectRT]), limit: rt.union([rt.number, rt.null, rt.undefined]), filterQuery: rt.union([rt.string, rt.null, rt.undefined]), forceInterval: rt.boolean, @@ -68,7 +71,7 @@ export const metricsExplorerRequestBodyRT = rt.intersection([ export const metricsExplorerPageInfoRT = rt.type({ total: rt.number, - afterKey: rt.union([rt.string, rt.null]), + afterKey: rt.union([rt.string, rt.null, afterKeyObjectRT]), }); export const metricsExplorerColumnTypeRT = rt.keyof({ @@ -89,11 +92,16 @@ export const metricsExplorerRowRT = rt.intersection([ rt.record(rt.string, rt.union([rt.string, rt.number, rt.null, rt.undefined])), ]); -export const metricsExplorerSeriesRT = rt.type({ - id: rt.string, - columns: rt.array(metricsExplorerColumnRT), - rows: rt.array(metricsExplorerRowRT), -}); +export const metricsExplorerSeriesRT = rt.intersection([ + rt.type({ + id: rt.string, + columns: rt.array(metricsExplorerColumnRT), + rows: rt.array(metricsExplorerRowRT), + }), + rt.partial({ + keys: rt.array(rt.string), + }), +]); export const metricsExplorerResponseRT = rt.type({ series: rt.array(metricsExplorerSeriesRT), diff --git a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx index a176ba756652a..4151fd8d6cf49 100644 --- a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx +++ b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx @@ -138,7 +138,7 @@ export const Expressions: React.FC = props => { ]); const onGroupByChange = useCallback( - (group: string | null) => { + (group: string | null | string[]) => { setAlertParams('groupBy', group || ''); }, [setAlertParams] @@ -206,7 +206,10 @@ export const Expressions: React.FC = props => { convertKueryToElasticSearchQuery(md.currentOptions.filterQuery, derivedIndexPattern) || '' ); } else if (md && md.currentOptions?.groupBy && md.series) { - const filter = `${md.currentOptions?.groupBy}: "${md.series.id}"`; + const { groupBy } = md.currentOptions; + const filter = Array.isArray(groupBy) + ? groupBy.map((field, index) => `${field}: "${md.series?.keys?.[index]}"`).join(' and ') + : `${groupBy}: "${md.series.id}"`; setAlertParams('filterQueryText', filter); setAlertParams( 'filterQuery', diff --git a/x-pack/plugins/infra/public/alerting/metric_threshold/types.ts b/x-pack/plugins/infra/public/alerting/metric_threshold/types.ts index e421455cf6efd..feeec4b0ce8bf 100644 --- a/x-pack/plugins/infra/public/alerting/metric_threshold/types.ts +++ b/x-pack/plugins/infra/public/alerting/metric_threshold/types.ts @@ -35,7 +35,7 @@ export enum AGGREGATION_TYPES { export interface MetricThresholdAlertParams { criteria?: MetricExpression[]; - groupBy?: string; + groupBy?: string | string[]; filterQuery?: string; sourceId?: string; } diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx index 9bd53118cf0ec..d079b7bb93d73 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx @@ -36,6 +36,7 @@ import { getChartTheme } from './helpers/get_chart_theme'; import { useKibanaUiSetting } from '../../../../utils/use_kibana_ui_setting'; import { calculateDomain } from './helpers/calculate_domain'; import { useKibana, useUiSetting } from '../../../../../../../../src/plugins/kibana_react/public'; +import { ChartTitle } from './chart_title'; interface Props { title?: string | null; @@ -92,16 +93,17 @@ export const MetricsExplorerChart = ({ chartOptions.yAxisMode === MetricsExplorerYAxisMode.fromZero ? { ...dataDomain, min: 0 } : dataDomain; + return (
    {options.groupBy ? ( - + - {title} + - + { - if (source.fields.host === field) { + const fields = Array.isArray(groupBy) ? groupBy : [groupBy]; + if (fields.includes(source.fields.host)) { return 'host'; } - if (source.fields.pod === field) { + if (fields.includes(source.fields.pod)) { return 'pod'; } - if (source.fields.container === field) { + if (fields.includes(source.fields.container)) { return 'container'; } }; @@ -88,10 +89,16 @@ export const MetricsExplorerChartContextMenu: React.FC = ({ // onFilter needs check for Typescript even though it's // covered by supportFiltering variable if (supportFiltering && onFilter) { - onFilter(`${options.groupBy}: "${series.id}"`); + if (Array.isArray(options.groupBy)) { + onFilter( + options.groupBy.map((field, index) => `${field}: "${series.keys?.[index]}"`).join(' and ') + ); + } else { + onFilter(`${options.groupBy}: "${series.id}"`); + } } setPopoverState(false); - }, [supportFiltering, options.groupBy, series.id, onFilter]); + }, [supportFiltering, onFilter, options, series.keys, series.id]); // Only display the "Add Filter" option if it's supported const filterByItem = supportFiltering diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_title.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_title.tsx new file mode 100644 index 0000000000000..e756c3bc393ce --- /dev/null +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart_title.tsx @@ -0,0 +1,40 @@ +/* + * 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, { Fragment } from 'react'; +import { EuiText, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { MetricsExplorerSeries } from '../../../../../common/http_api'; + +interface Props { + series: MetricsExplorerSeries; +} + +export const ChartTitle = ({ series }: Props) => { + if (series.keys != null) { + const { keys } = series; + return ( + + {keys.map((name, i) => ( + + + i ? 'subdued' : 'default'}> + {name} + + + {keys.length - 1 > i && ( + + + / + + + )} + + ))} + + ); + } + return {series.id}; +}; diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/charts.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/charts.tsx index ecec116310875..2929a7316bd79 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/charts.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/charts.tsx @@ -19,11 +19,13 @@ import { NoData } from '../../../../components/empty_states/no_data'; import { MetricsExplorerChart } from './chart'; import { SourceQuery } from '../../../../graphql/types'; +type stringOrNull = string | null; + interface Props { loading: boolean; options: MetricsExplorerOptions; chartOptions: MetricsExplorerChartOptions; - onLoadMore: (afterKey: string | null) => void; + onLoadMore: (afterKey: stringOrNull | Record) => void; onRefetch: () => void; onFilter: (filter: string) => void; onTimeChange: (start: string, end: string) => void; @@ -74,6 +76,8 @@ export const MetricsExplorerCharts = ({ ); } + const and = i18n.translate('xpack.infra.metricsExplorer.andLabel', { defaultMessage: '" and "' }); + return (
    @@ -105,7 +109,9 @@ export const MetricsExplorerCharts = ({ values={{ length: data.series.length, total: data.pageInfo.total, - groupBy: options.groupBy, + groupBy: Array.isArray(options.groupBy) + ? options.groupBy.join(and) + : options.groupBy, }} />

    diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/group_by.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/group_by.tsx index bfe8ddb2e0829..793ddd3ce5691 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/group_by.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/group_by.tsx @@ -13,19 +13,25 @@ import { MetricsExplorerOptions } from '../hooks/use_metrics_explorer_options'; interface Props { options: MetricsExplorerOptions; - onChange: (groupBy: string | null) => void; + onChange: (groupBy: string | null | string[]) => void; fields: IFieldType[]; } export const MetricsExplorerGroupBy = ({ options, onChange, fields }: Props) => { const handleChange = useCallback( - selectedOptions => { - const groupBy = (selectedOptions.length === 1 && selectedOptions[0].label) || null; + (selectedOptions: Array<{ label: string }>) => { + const groupBy = selectedOptions.map(option => option.label); onChange(groupBy); }, [onChange] ); + const selectedOptions = Array.isArray(options.groupBy) + ? options.groupBy.map(field => ({ label: field })) + : options.groupBy + ? [{ label: options.groupBy }] + : []; + return ( defaultMessage: 'Graph per', })} fullWidth - singleSelection={true} - selectedOptions={(options.groupBy && [{ label: options.groupBy }]) || []} + singleSelection={false} + selectedOptions={selectedOptions} options={fields .filter(f => f.aggregatable && f.type === 'string') .map(f => ({ label: f.name }))} diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.ts index 19ea4cc7f7dec..a81e11418cd6a 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/helpers/create_tsvb_link.ts @@ -109,7 +109,21 @@ export const createFilterFromOptions = ( } if (options.groupBy) { const id = series.id.replace('"', '\\"'); - filters.push(`${options.groupBy} : "${id}"`); + const groupByFilters = Array.isArray(options.groupBy) + ? options.groupBy + .map((field, index) => { + if (!series.keys) { + return null; + } + const value = series.keys[index]; + if (!value) { + return null; + } + return `${field}: "${value.replace('"', '\\"')}"`; + }) + .join(' and ') + : `${options.groupBy} : "${id}"`; + filters.push(groupByFilters); } return { language: 'kuery', query: filters.join(' and ') }; }; diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx index 76945eb528345..7ad1d943a9896 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx @@ -37,7 +37,7 @@ interface Props { defaultViewState: MetricExplorerViewState; onRefresh: () => void; onTimeChange: (start: string, end: string) => void; - onGroupByChange: (groupBy: string | null) => void; + onGroupByChange: (groupBy: string | null | string[]) => void; onFilterQuerySubmit: (query: string) => void; onMetricsChange: (metrics: MetricsExplorerMetric[]) => void; onAggregationChange: (aggregation: MetricsExplorerAggregation) => void; diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts index 8a9ed901de0b0..936c6e456beb7 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metric_explorer_state.ts @@ -30,7 +30,7 @@ export const useMetricsExplorerState = ( derivedIndexPattern: IIndexPattern ) => { const [refreshSignal, setRefreshSignal] = useState(0); - const [afterKey, setAfterKey] = useState(null); + const [afterKey, setAfterKey] = useState>(null); const { defaultViewState, options, @@ -63,7 +63,7 @@ export const useMetricsExplorerState = ( ); const handleGroupByChange = useCallback( - (groupBy: string | null) => { + (groupBy: string | null | string[]) => { setAfterKey(null); setOptions({ ...options, diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx index 94edab54fb71e..f0b2627288d45 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.test.tsx @@ -46,7 +46,7 @@ const renderUseMetricsExplorerDataHook = () => { source, derivedIndexPattern, timeRange, - afterKey: null as string | null, + afterKey: null as string | null | Record, signal: 1, }, wrapper, diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts index 6b4ac8b1ba060..3a767b94d00c7 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data.ts @@ -28,7 +28,7 @@ export function useMetricsExplorerData( source: SourceQuery.Query['source']['configuration'] | undefined, derivedIndexPattern: IIndexPattern, timerange: MetricsExplorerTimeOptions, - afterKey: string | null, + afterKey: string | null | Record, signal: any, fetch?: HttpHandler ) { diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts index f79c7aa0d4d67..56595c09aadde 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts @@ -37,7 +37,7 @@ export interface MetricsExplorerChartOptions { export interface MetricsExplorerOptions { metrics: MetricsExplorerOptionsMetric[]; limit?: number; - groupBy?: string; + groupBy?: string | string[]; filterQuery?: string; aggregation: MetricsExplorerAggregation; forceInterval?: boolean; diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts index 71bee3209bf53..9738acd13eb6e 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts @@ -74,7 +74,7 @@ const getParsedFilterQuery: ( export const getElasticsearchMetricQuery = ( { metric, aggType, timeUnit, timeSize }: MetricExpressionParams, timefield: string, - groupBy?: string, + groupBy?: string | string[], filterQuery?: string ) => { if (aggType === Aggregators.COUNT && metric) { @@ -126,15 +126,21 @@ export const getElasticsearchMetricQuery = ( groupings: { composite: { size: 10, - sources: [ - { - groupBy: { - terms: { - field: groupBy, + sources: Array.isArray(groupBy) + ? groupBy.map((field, index) => ({ + [`groupBy${index}`]: { + terms: { field }, }, - }, - }, - ], + })) + : [ + { + groupBy0: { + terms: { + field: groupBy, + }, + }, + }, + ], }, aggs: baseAggs, }, @@ -186,7 +192,7 @@ const getMetric: ( params: MetricExpressionParams, index: string, timefield: string, - groupBy: string | undefined, + groupBy: string | undefined | string[], filterQuery: string | undefined ) => Promise> = async function( { callCluster }, @@ -213,11 +219,13 @@ const getMetric: ( searchBody, bucketSelector, afterKeyHandler - )) as Array; + )) as Array }>; return compositeBuckets.reduce( (result, bucket) => ({ ...result, - [bucket.key.groupBy]: getCurrentValueFromAggregations(bucket, aggType), + [Object.values(bucket.key) + .map(value => value) + .join(', ')]: getCurrentValueFromAggregations(bucket, aggType), }), {} ); @@ -249,7 +257,7 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs, alertId: s async function({ services, params }: AlertExecutorOptions) { const { criteria, groupBy, filterQuery, sourceId, alertOnNoData } = params as { criteria: MetricExpressionParams[]; - groupBy: string | undefined; + groupBy: string | undefined | string[]; filterQuery: string | undefined; sourceId?: string; alertOnNoData: boolean; diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts index c1c530131f3a0..8b3903f2ee3be 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts @@ -62,7 +62,7 @@ export function registerMetricThresholdAlertType(libs: InfraBackendLibs) { params: schema.object( { criteria: schema.arrayOf(schema.oneOf([countCriterion, nonCountCriterion])), - groupBy: schema.maybe(schema.string()), + groupBy: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])), filterQuery: schema.maybe( schema.string({ validate: validateIsStringElasticsearchJSONFilter, diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts index 25b709d6afc51..ee2cf94a2fd62 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts @@ -64,11 +64,11 @@ export const emptyMetricResponse = { export const basicCompositeResponse = { aggregations: { groupings: { - after_key: 'foo', + after_key: { groupBy0: 'foo' }, buckets: [ { key: { - groupBy: 'a', + groupBy0: 'a', }, aggregatedIntervals: { buckets: bucketsA, @@ -76,7 +76,7 @@ export const basicCompositeResponse = { }, { key: { - groupBy: 'b', + groupBy0: 'b', }, aggregatedIntervals: { buckets: bucketsB, @@ -95,11 +95,11 @@ export const basicCompositeResponse = { export const alternateCompositeResponse = { aggregations: { groupings: { - after_key: 'foo', + after_key: { groupBy0: 'foo' }, buckets: [ { key: { - groupBy: 'a', + groupBy0: 'a', }, aggregatedIntervals: { buckets: bucketsB, @@ -107,7 +107,7 @@ export const alternateCompositeResponse = { }, { key: { - groupBy: 'b', + groupBy0: 'b', }, aggregatedIntervals: { buckets: bucketsA, diff --git a/x-pack/plugins/infra/server/routes/metrics_explorer/lib/get_groupings.ts b/x-pack/plugins/infra/server/routes/metrics_explorer/lib/get_groupings.ts index 47dc58997a469..a6510b2ba1478 100644 --- a/x-pack/plugins/infra/server/routes/metrics_explorer/lib/get_groupings.ts +++ b/x-pack/plugins/infra/server/routes/metrics_explorer/lib/get_groupings.ts @@ -5,10 +5,12 @@ */ import { isObject, set } from 'lodash'; +import { i18n } from '@kbn/i18n'; import { InfraDatabaseSearchResponse } from '../../../lib/adapters/framework'; import { MetricsExplorerRequestBody, MetricsExplorerResponse, + afterKeyObjectRT, } from '../../../../common/http_api/metrics_explorer'; interface GroupingAggregation { @@ -24,7 +26,13 @@ interface GroupingAggregation { } const EMPTY_RESPONSE = { - series: [{ id: 'ALL', columns: [], rows: [] }], + series: [ + { + id: i18n.translate('xpack.infra.metricsExploer.everything', { defaultMessage: 'Everything' }), + columns: [], + rows: [], + }, + ], pageInfo: { total: 0, afterKey: null }, }; @@ -35,7 +43,25 @@ export const getGroupings = async ( if (!options.groupBy) { return EMPTY_RESPONSE; } + + if (Array.isArray(options.groupBy) && options.groupBy.length === 0) { + return EMPTY_RESPONSE; + } + const limit = options.limit || 9; + const groupBy = Array.isArray(options.groupBy) ? options.groupBy : [options.groupBy]; + const filter: Array> = [ + { + range: { + [options.timerange.field]: { + gte: options.timerange.from, + lte: options.timerange.to, + format: 'epoch_millis', + }, + }, + }, + ...groupBy.map(field => ({ exists: { field } })), + ]; const params = { allowNoIndices: true, ignoreUnavailable: true, @@ -51,27 +77,21 @@ export const getGroupings = async ( exists: { field: m.field }, })), ], - filter: [ - { - range: { - [options.timerange.field]: { - gte: options.timerange.from, - lte: options.timerange.to, - format: 'epoch_millis', - }, - }, - }, - ] as object[], + filter, }, }, aggs: { groupingsCount: { - cardinality: { field: options.groupBy }, + cardinality: { + script: { source: groupBy.map(field => `doc['${field}'].value`).join('+') }, + }, }, groupings: { composite: { size: limit, - sources: [{ groupBy: { terms: { field: options.groupBy, order: 'asc' } } }], + sources: groupBy.map((field, index) => ({ + [`groupBy${index}`]: { terms: { field, order: 'asc' } }, + })), }, }, }, @@ -83,7 +103,11 @@ export const getGroupings = async ( } if (options.afterKey) { - set(params, 'body.aggs.groupings.composite.after', { groupBy: options.afterKey }); + if (afterKeyObjectRT.is(options.afterKey)) { + set(params, 'body.aggs.groupings.composite.after', options.afterKey); + } else { + set(params, 'body.aggs.groupings.composite.after', { groupBy0: options.afterKey }); + } } if (options.filterQuery) { @@ -113,11 +137,13 @@ export const getGroupings = async ( const { after_key: afterKey } = groupings; return { series: groupings.buckets.map(bucket => { - return { id: bucket.key.groupBy, rows: [], columns: [] }; + const keys = Object.values(bucket.key); + const id = keys.join(' / '); + return { id, keys, rows: [], columns: [] }; }), pageInfo: { total: groupingsCount.value, - afterKey: afterKey && groupings.buckets.length === limit ? afterKey.groupBy : null, + afterKey: afterKey && groupings.buckets.length === limit ? afterKey : null, }, }; }; diff --git a/x-pack/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts b/x-pack/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts index a709cbdeeb680..ea77050112e19 100644 --- a/x-pack/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts +++ b/x-pack/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { union, uniq } from 'lodash'; +import { union, uniq, isArray, isString } from 'lodash'; import { KibanaRequest, RequestHandlerContext } from 'src/core/server'; import { KibanaFramework } from '../../../lib/adapters/framework/kibana_framework_adapter'; import { @@ -38,9 +38,21 @@ export const populateSeriesWithTSVBData = ( } // Set the filter for the group by or match everything - const filters: JsonObject[] = options.groupBy - ? [{ match: { [options.groupBy]: series.id } }] + const isGroupBySet = + Array.isArray(options.groupBy) && options.groupBy.length + ? true + : isString(options.groupBy) + ? true + : false; + + const filters: JsonObject[] = isGroupBySet + ? isArray(options.groupBy) + ? options.groupBy + .filter(f => f) + .map((field, index) => ({ match: { [field as string]: series.keys?.[index] || '' } })) + : [{ match: { [options.groupBy as string]: series.id } }] : []; + if (options.filterQuery) { try { const filterQuery = JSON.parse(options.filterQuery); diff --git a/x-pack/test/api_integration/apis/infra/metrics_explorer.ts b/x-pack/test/api_integration/apis/infra/metrics_explorer.ts index 1563ae208867c..4491944699b21 100644 --- a/x-pack/test/api_integration/apis/infra/metrics_explorer.ts +++ b/x-pack/test/api_integration/apis/infra/metrics_explorer.ts @@ -36,11 +36,9 @@ export default function({ getService }: FtrProviderContext) { { aggregation: 'avg', field: 'system.cpu.user.pct', - rate: false, }, { aggregation: 'count', - rate: false, }, ], }; @@ -52,7 +50,7 @@ export default function({ getService }: FtrProviderContext) { const body = decodeOrThrow(metricsExplorerResponseRT)(response.body); expect(body.series).length(1); const firstSeries = first(body.series); - expect(firstSeries).to.have.property('id', 'ALL'); + expect(firstSeries).to.have.property('id', 'Everything'); expect(firstSeries.columns).to.eql([ { name: 'timestamp', type: 'date' }, { name: 'metric_0', type: 'number' }, @@ -81,7 +79,6 @@ export default function({ getService }: FtrProviderContext) { { aggregation: 'avg', field: 'system.cpu.user.pct', - rate: false, }, ], }; @@ -93,7 +90,7 @@ export default function({ getService }: FtrProviderContext) { const body = decodeOrThrow(metricsExplorerResponseRT)(response.body); expect(body.series).length(1); const firstSeries = first(body.series); - expect(firstSeries).to.have.property('id', 'ALL'); + expect(firstSeries).to.have.property('id', 'Everything'); expect(firstSeries.columns).to.eql([ { name: 'timestamp', type: 'date' }, { name: 'metric_0', type: 'number' }, @@ -124,7 +121,7 @@ export default function({ getService }: FtrProviderContext) { const body = decodeOrThrow(metricsExplorerResponseRT)(response.body); expect(body.series).length(1); const firstSeries = first(body.series); - expect(firstSeries).to.have.property('id', 'ALL'); + expect(firstSeries).to.have.property('id', 'Everything'); expect(firstSeries.columns).to.eql([]); expect(firstSeries.rows).to.have.length(0); }); @@ -144,7 +141,6 @@ export default function({ getService }: FtrProviderContext) { metrics: [ { aggregation: 'count', - rate: false, }, ], }; @@ -169,10 +165,55 @@ export default function({ getService }: FtrProviderContext) { timestamp: 1547571300000, }); expect(body.pageInfo).to.eql({ - afterKey: 'system.fsstat', + afterKey: { groupBy0: 'system.fsstat' }, total: 12, }); }); + + it('should work with multiple groupBy', async () => { + const postBody = { + timerange: { + field: '@timestamp', + to: max, + from: min, + interval: '>=1m', + }, + indexPattern: 'metricbeat-*', + groupBy: ['host.name', 'system.network.name'], + limit: 3, + afterKey: null, + metrics: [ + { + aggregation: 'rate', + field: 'system.network.out.bytes', + }, + ], + }; + const response = await supertest + .post('/api/infra/metrics_explorer') + .set('kbn-xsrf', 'xxx') + .send(postBody) + .expect(200); + const body = decodeOrThrow(metricsExplorerResponseRT)(response.body); + expect(body.series).length(3); + const firstSeries = first(body.series); + expect(firstSeries).to.have.property('id', 'demo-stack-mysql-01 / eth0'); + expect(firstSeries.columns).to.eql([ + { name: 'timestamp', type: 'date' }, + { name: 'metric_0', type: 'number' }, + { name: 'groupBy', type: 'string' }, + ]); + expect(firstSeries.rows).to.have.length(9); + expect(firstSeries.rows![1]).to.eql({ + groupBy: 'demo-stack-mysql-01 / eth0', + metric_0: 53577.683333333334, + timestamp: 1547571300000, + }); + expect(body.pageInfo).to.eql({ + afterKey: { groupBy0: 'demo-stack-mysql-01', groupBy1: 'eth2' }, + total: 4, + }); + }); }); describe('without data', () => { @@ -191,7 +232,6 @@ export default function({ getService }: FtrProviderContext) { { aggregation: 'avg', field: 'system.cpu.user.pct', - rate: false, }, ], }; @@ -225,7 +265,6 @@ export default function({ getService }: FtrProviderContext) { { aggregation: 'avg', field: 'system.cpu.user.pct', - rate: false, }, ], }; From b6f9796a979b68c6fbbbbfbfedda6d94bbcdeb63 Mon Sep 17 00:00:00 2001 From: Tre Date: Tue, 19 May 2020 19:12:07 -0600 Subject: [PATCH 052/129] [QA] fixup coverage ingestion tests. (#66905) --- .../__tests__/transforms.test.js | 30 +- .../ingest_coverage/constants.js | 1 - .../code_coverage/ingest_coverage/ingest.js | 5 +- .../integration_tests/ingest_coverage.test.js | 128 +- .../coverage-summary-NO-total.json | 13340 --------------- .../coverage-summary-manual-mix.json | 130 - .../mocks/jest-combined/coverage-summary.json | 13366 ---------------- .../ingest_coverage/transforms.js | 5 +- 8 files changed, 60 insertions(+), 26945 deletions(-) diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/transforms.test.js b/src/dev/code_coverage/ingest_coverage/__tests__/transforms.test.js index 23b4f83d4b8e7..c62a28a2956e1 100644 --- a/src/dev/code_coverage/ingest_coverage/__tests__/transforms.test.js +++ b/src/dev/code_coverage/ingest_coverage/__tests__/transforms.test.js @@ -18,7 +18,7 @@ */ import expect from '@kbn/expect'; -import { ciRunUrl } from '../transforms'; +import { ciRunUrl, coveredFilePath, itemizeVcs } from '../transforms'; describe(`Transform fn`, () => { describe(`ciRunUrl`, () => { @@ -31,4 +31,32 @@ describe(`Transform fn`, () => { expect(ciRunUrl({ a: 'a' })).not.to.have.property('ciRunUrl'); }); }); + describe(`coveredFilePath`, () => { + it(`should remove the jenkins workspace path`, () => { + const obj = { + staticSiteUrl: + '/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/x-pack/legacy/plugins/reporting/server/browsers/extract/unzip.js', + COVERAGE_INGESTION_KIBANA_ROOT: + '/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana', + }; + expect(coveredFilePath(obj)).to.have.property( + 'coveredFilePath', + 'x-pack/legacy/plugins/reporting/server/browsers/extract/unzip.js' + ); + }); + }); + describe(`itemizeVcs`, () => { + it(`should return a sha url`, () => { + const vcsInfo = [ + 'origin/ingest-code-coverage', + 'f07b34f6206', + `Tre' Seymour`, + `Lorem :) ipsum Tre' λ dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`, + ]; + expect(itemizeVcs(vcsInfo)({}).vcs).to.have.property( + 'vcsUrl', + `https://github.com/elastic/kibana/commit/${vcsInfo[1]}` + ); + }); + }); }); diff --git a/src/dev/code_coverage/ingest_coverage/constants.js b/src/dev/code_coverage/ingest_coverage/constants.js index c2f831b83b83d..a7303f0778d1c 100644 --- a/src/dev/code_coverage/ingest_coverage/constants.js +++ b/src/dev/code_coverage/ingest_coverage/constants.js @@ -17,6 +17,5 @@ * under the License. */ -export const STATIC_SITE_URL_PROP_NAME = 'staticSiteUrl'; export const COVERAGE_INDEX = process.env.COVERAGE_INDEX || 'kibana_code_coverage'; export const TOTALS_INDEX = process.env.TOTALS_INDEX || `kibana_total_code_coverage`; diff --git a/src/dev/code_coverage/ingest_coverage/ingest.js b/src/dev/code_coverage/ingest_coverage/ingest.js index 52b1306c9683b..769fe250a8e18 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest.js +++ b/src/dev/code_coverage/ingest_coverage/ingest.js @@ -20,7 +20,7 @@ const { Client } = require('@elastic/elasticsearch'); import { createFailError } from '@kbn/dev-utils'; import chalk from 'chalk'; -import { green, always } from './utils'; +import { green, always, pretty } from './utils'; import { fromNullable } from './either'; import { COVERAGE_INDEX, TOTALS_INDEX } from './constants'; @@ -98,6 +98,3 @@ function color(whichColor) { return chalk[whichColor].bgWhiteBright(x); }; } -function pretty(x) { - return JSON.stringify(x, null, 2); -} diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js b/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js index 930b52f549f99..2ffb005993619 100644 --- a/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js @@ -17,13 +17,10 @@ * under the License. */ -import expect from '@kbn/expect'; import { spawn } from 'child_process'; import { resolve } from 'path'; import { green, always } from '../utils'; -import { STATIC_SITE_URL_PROP_NAME, COVERAGE_INDEX } from '../constants'; - const ROOT_DIR = resolve(__dirname, '../../../../..'); const MOCKS_DIR = resolve(__dirname, './mocks'); const staticSiteUrlRegexes = { @@ -40,110 +37,43 @@ const env = { NODE_ENV: 'integration_test', COVERAGE_INGESTION_KIBANA_ROOT: '/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana', }; -const includesSiteUrlPredicate = x => x.includes(STATIC_SITE_URL_PROP_NAME); +const includesSiteUrlPredicate = x => x.includes('staticSiteUrl'); const siteUrlLines = specificLinesOnly(includesSiteUrlPredicate); const splitByNewLine = x => x.split('\n'); const siteUrlsSplitByNewLine = siteUrlLines(splitByNewLine); const siteUrlsSplitByNewLineWithoutBlanks = siteUrlsSplitByNewLine(notBlankLines); - -describe('Ingesting Coverage to Cluster', () => { - const verboseArgs = [ - 'scripts/ingest_coverage.js', - '--verbose', - '--vcsInfoPath', - 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', - '--path', - ]; - - const noTotalsPath = 'jest-combined/coverage-summary-NO-total.json'; +const verboseArgs = [ + 'scripts/ingest_coverage.js', + '--verbose', + '--vcsInfoPath', + 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', + '--path', +]; + +describe('Ingesting coverage', () => { const bothIndexesPath = 'jest-combined/coverage-summary-manual-mix.json'; - describe('with NODE_ENV set to "integration_test"', () => { - describe(`and debug || verbose turned on`, () => { - describe(`to the [${COVERAGE_INDEX}] index`, () => { - const mutableCoverageIndexChunks = []; - - beforeAll(done => { - const ingestAndMutateAsync = ingestAndMutate(done); - const ingestAndMutateAsyncWithPath = ingestAndMutateAsync(noTotalsPath); - const verboseIngestAndMutateAsyncWithPath = ingestAndMutateAsyncWithPath(verboseArgs); - verboseIngestAndMutateAsyncWithPath(mutableCoverageIndexChunks); - }); - - it( - 'should result in every posted item having a site url that meets all regex assertions', - always( - siteUrlsSplitByNewLineWithoutBlanks(mutableCoverageIndexChunks).forEach( - expectAllRegexesToPass({ - ...staticSiteUrlRegexes, - endsInDotJsDotHtml: /.js.html$/, - }) - ) - ) - ); - }); - describe(`to both indexes in the same push`, () => { - const mutableBothIndexesChunks = []; - - beforeAll(done => { - const ingestAndMutateAsync = ingestAndMutate(done); - const ingestAndMutateAsyncWithPath = ingestAndMutateAsync(bothIndexesPath); - const verboseIngestAndMutateAsyncWithPath = ingestAndMutateAsyncWithPath(verboseArgs); - verboseIngestAndMutateAsyncWithPath(mutableBothIndexesChunks); - }); + describe(`to the coverage index`, () => { + const mutableCoverageIndexChunks = []; - it( - 'should result in every posted item having a site url that meets all regex assertions', - always( - siteUrlsSplitByNewLineWithoutBlanks(mutableBothIndexesChunks).forEach( - expectAllRegexesToPass(staticSiteUrlRegexes) - ) - ) - ); - - it('should result in the "just logging" message being present in the log', () => { - expect(mutableBothIndexesChunks.some(x => x.includes('Just Logging'))).to.be(true); - }); - it('should result in the "actually sending" message NOT being present in the log', () => { - expect(mutableBothIndexesChunks.every(x => !x.includes('Actually sending...'))).to.be( - true - ); - }); - describe(`with provided vcs info file`, () => { - const filterZero = xs => included => xs.filter(x => x.includes(included))[0]; - const filteredWith = filterZero(mutableBothIndexesChunks); - it('should have a vcs block', () => { - const vcs = 'vcs'; - const portion = filteredWith(vcs); - expect(portion).to.contain(vcs); - }); - it(`should have a branch`, () => { - const branch = `"branch":`; - const portion = filteredWith(branch); - expect(portion).to.contain(branch); - expect(portion).to.contain(`"origin/ingest-code-coverage"`); - }); - it(`should have a sha`, () => { - const sha = `"sha":`; - const portion = filteredWith(sha); - expect(portion).to.contain(sha); - expect(portion).to.contain(`"f07b34f6206"`); - }); - it(`should have an author`, () => { - const author = `"author":`; - const portion = filteredWith(author); - expect(portion).to.contain(author); - expect(portion).to.contain(`"Tre' Seymour"`); - }); - it(`should have a commit msg, truncated`, () => { - const commitMsg = `"commitMsg":`; - const portion = filteredWith(commitMsg); - expect(portion).to.contain(commitMsg); - expect(portion).to.contain(`"Lorem :) ipsum Tre' λ dolor sit amet, consectetur ..."`); - }); - }); - }); + beforeAll(done => { + const ingestAndMutateAsync = ingestAndMutate(done); + const ingestAndMutateAsyncWithPath = ingestAndMutateAsync(bothIndexesPath); + const verboseIngestAndMutateAsyncWithPath = ingestAndMutateAsyncWithPath(verboseArgs); + verboseIngestAndMutateAsyncWithPath(mutableCoverageIndexChunks); }); + + it( + 'should result in every posted item having a site url that meets all regex assertions', + always( + siteUrlsSplitByNewLineWithoutBlanks(mutableCoverageIndexChunks).forEach( + expectAllRegexesToPass({ + ...staticSiteUrlRegexes, + endsInDotJsDotHtml: /.js.html$/, + }) + ) + ) + ); }); }); diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-NO-total.json b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-NO-total.json index f6d5ac2a4c898..e69de29bb2d1d 100644 --- a/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-NO-total.json +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-NO-total.json @@ -1,13340 +0,0 @@ -{ - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/bar/bar.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/bar/bar_section.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/button/button.js": { - "lines": { - "total": 33, - "covered": 28, - "skipped": 0, - "pct": 84.85 - }, - "functions": { - "total": 7, - "covered": 6, - "skipped": 0, - "pct": 85.71 - }, - "statements": { - "total": 33, - "covered": 28, - "skipped": 0, - "pct": 84.85 - }, - "branches": { - "total": 21, - "covered": 16, - "skipped": 0, - "pct": 76.19 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/button/button_group/button_group.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/button/button_icon/button_icon.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/collapse_button/collapse_button.js": { - "lines": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/empty_table_prompt/empty_table_prompt.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/empty_table_prompt/empty_table_prompt_actions.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/empty_table_prompt/empty_table_prompt_message.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/empty_table_prompt/empty_table_prompt_panel.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form/check_box/check_box.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form/check_box/check_box_label.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form/label/label.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form/select/select.js": { - "lines": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form/text_area/text_area.js": { - "lines": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form/text_input/text_input.js": { - "lines": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form_layout/field_group.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form_layout/field_group_section.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/local_nav/local_nav.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/local_nav/local_nav_row.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/local_nav/local_nav_row_section.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/local_nav/local_tab.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/local_nav/local_tabs.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/local_nav/local_title.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/pager/pager.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/pager/pager_button_group.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/controlled_table.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_body.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_header.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_header_cell.js": { - "lines": { - "total": 12, - "covered": 6, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 12, - "covered": 6, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 6, - "covered": 1, - "skipped": 0, - "pct": 16.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_header_check_box_cell.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_info.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_row.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_row_cell.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_row_check_box_cell.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table.js": { - "lines": { - "total": 20, - "covered": 16, - "skipped": 0, - "pct": 80 - }, - "functions": { - "total": 11, - "covered": 8, - "skipped": 0, - "pct": 72.73 - }, - "statements": { - "total": 22, - "covered": 16, - "skipped": 0, - "pct": 72.73 - }, - "branches": { - "total": 14, - "covered": 9, - "skipped": 0, - "pct": 64.29 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_create_button.js": { - "lines": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_delete_button.js": { - "lines": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_loading_prompt.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_no_matches_prompt.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_row.js": { - "lines": { - "total": 11, - "covered": 10, - "skipped": 0, - "pct": 90.91 - }, - "functions": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - }, - "statements": { - "total": 11, - "covered": 10, - "skipped": 0, - "pct": 90.91 - }, - "branches": { - "total": 6, - "covered": 5, - "skipped": 0, - "pct": 83.33 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_tool_bar.js": { - "lines": { - "total": 6, - "covered": 4, - "skipped": 0, - "pct": 66.67 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 4, - "skipped": 0, - "pct": 66.67 - }, - "branches": { - "total": 4, - "covered": 2, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_tool_bar_footer.js": { - "lines": { - "total": 8, - "covered": 6, - "skipped": 0, - "pct": 75 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 8, - "covered": 6, - "skipped": 0, - "pct": 75 - }, - "branches": { - "total": 4, - "covered": 2, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tabs/tab.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tabs/tabs.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tool_bar/tool_bar.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tool_bar/tool_bar_footer.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tool_bar/tool_bar_footer_section.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tool_bar/tool_bar_search_box.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tool_bar/tool_bar_section.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tool_bar/tool_bar_text.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/typography/typography.js": { - "lines": { - "total": 12, - "covered": 12, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 12, - "covered": 12, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/alignment.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/key_codes.js": { - "lines": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/accessibility/accessible_click_keys.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/accessibility/cascading_menu_key_codes.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/accessibility/combo_box_key_codes.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/accessibility/html_id_generator.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/sort/sortable_properties.js": { - "lines": { - "total": 17, - "covered": 17, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 18, - "covered": 18, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 10, - "covered": 8, - "skipped": 0, - "pct": 80 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/apm_oss/index.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/data/public/actions/filters/create_filters_from_event.js": { - "lines": { - "total": 39, - "covered": 3, - "skipped": 0, - "pct": 7.69 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 41, - "covered": 3, - "skipped": 0, - "pct": 7.32 - }, - "branches": { - "total": 30, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/data/public/search/aggs/buckets/_terms_other_bucket_helper.js": { - "lines": { - "total": 100, - "covered": 7, - "skipped": 0, - "pct": 7 - }, - "functions": { - "total": 24, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 110, - "covered": 7, - "skipped": 0, - "pct": 6.36 - }, - "branches": { - "total": 42, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/data/public/search/expressions/create_filter.js": { - "lines": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/elasticsearch/index.js": { - "lines": { - "total": 28, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/elasticsearch/lib/version_health_check.js": { - "lines": { - "total": 10, - "covered": 9, - "skipped": 0, - "pct": 90 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 9, - "skipped": 0, - "pct": 90 - }, - "branches": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/elasticsearch/server/lib/abortable_request_handler.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/elasticsearch/server/lib/create_proxy.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/elasticsearch/server/lib/handle_es_error.js": { - "lines": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/index.js": { - "lines": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 33, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/inject_vars.js": { - "lines": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/ui_setting_defaults.js": { - "lines": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/common/utils/no_white_space.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/common/utils/shorten_dotted_string.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/migrations/migrations.js": { - "lines": { - "total": 264, - "covered": 250, - "skipped": 0, - "pct": 94.7 - }, - "functions": { - "total": 37, - "covered": 35, - "skipped": 0, - "pct": 94.59 - }, - "statements": { - "total": 269, - "covered": 252, - "skipped": 0, - "pct": 93.68 - }, - "branches": { - "total": 190, - "covered": 149, - "skipped": 0, - "pct": 78.42 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/kibana.js": { - "lines": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/dashboard/np_ready/legacy_app.js": { - "lines": { - "total": 64, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 66, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/dashboard/np_ready/listing/dashboard_listing.js": { - "lines": { - "total": 11, - "covered": 10, - "skipped": 0, - "pct": 90.91 - }, - "functions": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - }, - "statements": { - "total": 11, - "covered": 10, - "skipped": 0, - "pct": 90.91 - }, - "branches": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context.js": { - "lines": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.js": { - "lines": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js": { - "lines": { - "total": 313, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 86, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 325, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 137, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/response_handler.js": { - "lines": { - "total": 44, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 45, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/api/anchor.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/helpers/call_after_bindings_workaround.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query/actions.js": { - "lines": { - "total": 57, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 30, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 68, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query/constants.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query/state.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query_parameters/actions.js": { - "lines": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query_parameters/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/fixed_scroll.js": { - "lines": { - "total": 42, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 44, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/index.js": { - "lines": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/no_results.js": { - "lines": { - "total": 11, - "covered": 11, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 11, - "covered": 11, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/unsupported_index_pattern.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/debounce/debounce.js": { - "lines": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/debounce/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/doc_table_strings.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/lib/pager/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/lib/pager/pager.js": { - "lines": { - "total": 24, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 24, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/fetch_error/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field.js": { - "lines": { - "total": 41, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 41, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/field_chooser.js": { - "lines": { - "total": 96, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 102, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 88, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/lib/field_calculator.js": { - "lines": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/help_menu/help_menu_util.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/top_nav/open_search_panel.js": { - "lines": { - "total": 7, - "covered": 4, - "skipped": 0, - "pct": 57.14 - }, - "functions": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "statements": { - "total": 7, - "covered": 4, - "skipped": 0, - "pct": 57.14 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/top_nav/show_open_search_panel.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/load_tutorials.js": { - "lines": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/sample_data_client.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/add_data.js": { - "lines": { - "total": 14, - "covered": 14, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 14, - "covered": 14, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/feature_directory.js": { - "lines": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/home.js": { - "lines": { - "total": 34, - "covered": 31, - "skipped": 0, - "pct": 91.18 - }, - "functions": { - "total": 14, - "covered": 12, - "skipped": 0, - "pct": 85.71 - }, - "statements": { - "total": 34, - "covered": 31, - "skipped": 0, - "pct": 91.18 - }, - "branches": { - "total": 17, - "covered": 14, - "skipped": 0, - "pct": 82.35 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/home_app.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/recently_accessed.js": { - "lines": { - "total": 37, - "covered": 35, - "skipped": 0, - "pct": 94.59 - }, - "functions": { - "total": 8, - "covered": 7, - "skipped": 0, - "pct": 87.5 - }, - "statements": { - "total": 39, - "covered": 37, - "skipped": 0, - "pct": 94.87 - }, - "branches": { - "total": 15, - "covered": 12, - "skipped": 0, - "pct": 80 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/sample_data_set_card.js": { - "lines": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/sample_data_set_cards.js": { - "lines": { - "total": 48, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 54, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/sample_data_view_data_button.js": { - "lines": { - "total": 13, - "covered": 11, - "skipped": 0, - "pct": 84.62 - }, - "functions": { - "total": 5, - "covered": 2, - "skipped": 0, - "pct": 40 - }, - "statements": { - "total": 14, - "covered": 11, - "skipped": 0, - "pct": 78.57 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/synopsis.js": { - "lines": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial_directory.js": { - "lines": { - "total": 41, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 41, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/content.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/footer.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/instruction.js": { - "lines": { - "total": 12, - "covered": 5, - "skipped": 0, - "pct": 41.67 - }, - "functions": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "statements": { - "total": 12, - "covered": 5, - "skipped": 0, - "pct": 41.67 - }, - "branches": { - "total": 6, - "covered": 3, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/instruction_set.js": { - "lines": { - "total": 54, - "covered": 45, - "skipped": 0, - "pct": 83.33 - }, - "functions": { - "total": 17, - "covered": 13, - "skipped": 0, - "pct": 76.47 - }, - "statements": { - "total": 55, - "covered": 45, - "skipped": 0, - "pct": 81.82 - }, - "branches": { - "total": 36, - "covered": 20, - "skipped": 0, - "pct": 55.56 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/introduction.js": { - "lines": { - "total": 12, - "covered": 12, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 12, - "covered": 12, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/number_parameter.js": { - "lines": { - "total": 4, - "covered": 1, - "skipped": 0, - "pct": 25 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 1, - "skipped": 0, - "pct": 25 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/parameter_form.js": { - "lines": { - "total": 8, - "covered": 2, - "skipped": 0, - "pct": 25 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 2, - "skipped": 0, - "pct": 25 - }, - "branches": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/replace_template_strings.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/saved_objects_installer.js": { - "lines": { - "total": 31, - "covered": 25, - "skipped": 0, - "pct": 80.65 - }, - "functions": { - "total": 8, - "covered": 6, - "skipped": 0, - "pct": 75 - }, - "statements": { - "total": 31, - "covered": 25, - "skipped": 0, - "pct": 80.65 - }, - "branches": { - "total": 18, - "covered": 13, - "skipped": 0, - "pct": 72.22 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/status_check_states.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/string_parameter.js": { - "lines": { - "total": 4, - "covered": 1, - "skipped": 0, - "pct": 25 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 1, - "skipped": 0, - "pct": 25 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/tutorial.js": { - "lines": { - "total": 92, - "covered": 51, - "skipped": 0, - "pct": 55.43 - }, - "functions": { - "total": 24, - "covered": 12, - "skipped": 0, - "pct": 50 - }, - "statements": { - "total": 93, - "covered": 51, - "skipped": 0, - "pct": 54.84 - }, - "branches": { - "total": 50, - "covered": 27, - "skipped": 0, - "pct": 54 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/index.js": { - "lines": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 37, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/breadcrumbs.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.js": { - "lines": { - "total": 40, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 42, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/create_index_pattern_wizard.js": { - "lines": { - "total": 54, - "covered": 40, - "skipped": 0, - "pct": 74.07 - }, - "functions": { - "total": 19, - "covered": 10, - "skipped": 0, - "pct": 52.63 - }, - "statements": { - "total": 58, - "covered": 41, - "skipped": 0, - "pct": 70.69 - }, - "branches": { - "total": 19, - "covered": 14, - "skipped": 0, - "pct": 73.68 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/index.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/render.js": { - "lines": { - "total": 7, - "covered": 6, - "skipped": 0, - "pct": 85.71 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 6, - "skipped": 0, - "pct": 85.71 - }, - "branches": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js": { - "lines": { - "total": 131, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 40, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 132, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 39, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_sections.js": { - "lines": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.js": { - "lines": { - "total": 42, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 43, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index_header.js": { - "lines": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/indexed_fields_table.js": { - "lines": { - "total": 22, - "covered": 20, - "skipped": 0, - "pct": 90.91 - }, - "functions": { - "total": 13, - "covered": 11, - "skipped": 0, - "pct": 84.62 - }, - "statements": { - "total": 25, - "covered": 22, - "skipped": 0, - "pct": 88 - }, - "branches": { - "total": 17, - "covered": 12, - "skipped": 0, - "pct": 70.59 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/components/table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/components/table/table.js": { - "lines": { - "total": 19, - "covered": 16, - "skipped": 0, - "pct": 84.21 - }, - "functions": { - "total": 10, - "covered": 7, - "skipped": 0, - "pct": 70 - }, - "statements": { - "total": 19, - "covered": 16, - "skipped": 0, - "pct": 84.21 - }, - "branches": { - "total": 10, - "covered": 9, - "skipped": 0, - "pct": 90 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/lib/get_field_format.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/lib/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/scripted_fields_table.js": { - "lines": { - "total": 44, - "covered": 43, - "skipped": 0, - "pct": 97.73 - }, - "functions": { - "total": 13, - "covered": 12, - "skipped": 0, - "pct": 92.31 - }, - "statements": { - "total": 44, - "covered": 43, - "skipped": 0, - "pct": 97.73 - }, - "branches": { - "total": 12, - "covered": 11, - "skipped": 0, - "pct": 91.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/call_outs/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/header.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/table.js": { - "lines": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/source_filters_table.js": { - "lines": { - "total": 51, - "covered": 50, - "skipped": 0, - "pct": 98.04 - }, - "functions": { - "total": 17, - "covered": 17, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 52, - "covered": 51, - "skipped": 0, - "pct": 98.08 - }, - "branches": { - "total": 14, - "covered": 9, - "skipped": 0, - "pct": 64.29 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/add_filter.js": { - "lines": { - "total": 8, - "covered": 7, - "skipped": 0, - "pct": 87.5 - }, - "functions": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - }, - "statements": { - "total": 8, - "covered": 7, - "skipped": 0, - "pct": 87.5 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/header.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/table.js": { - "lines": { - "total": 34, - "covered": 30, - "skipped": 0, - "pct": 88.24 - }, - "functions": { - "total": 15, - "covered": 13, - "skipped": 0, - "pct": 86.67 - }, - "statements": { - "total": 34, - "covered": 30, - "skipped": 0, - "pct": 88.24 - }, - "branches": { - "total": 12, - "covered": 10, - "skipped": 0, - "pct": 83.33 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index_pattern_table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/_objects.js": { - "lines": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.js": { - "lines": { - "total": 107, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 111, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 44, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/breadcrumbs.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/index.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/objects_table.js": { - "lines": { - "total": 130, - "covered": 108, - "skipped": 0, - "pct": 83.08 - }, - "functions": { - "total": 46, - "covered": 35, - "skipped": 0, - "pct": 76.09 - }, - "statements": { - "total": 135, - "covered": 112, - "skipped": 0, - "pct": 82.96 - }, - "branches": { - "total": 48, - "covered": 34, - "skipped": 0, - "pct": 70.83 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/flyout.js": { - "lines": { - "total": 146, - "covered": 119, - "skipped": 0, - "pct": 81.51 - }, - "functions": { - "total": 43, - "covered": 31, - "skipped": 0, - "pct": 72.09 - }, - "statements": { - "total": 148, - "covered": 120, - "skipped": 0, - "pct": 81.08 - }, - "branches": { - "total": 77, - "covered": 66, - "skipped": 0, - "pct": 85.71 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/header/header.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/header/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/relationships.js": { - "lines": { - "total": 40, - "covered": 25, - "skipped": 0, - "pct": 62.5 - }, - "functions": { - "total": 13, - "covered": 7, - "skipped": 0, - "pct": 53.85 - }, - "statements": { - "total": 40, - "covered": 25, - "skipped": 0, - "pct": 62.5 - }, - "branches": { - "total": 28, - "covered": 8, - "skipped": 0, - "pct": 28.57 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/table.js": { - "lines": { - "total": 38, - "covered": 23, - "skipped": 0, - "pct": 60.53 - }, - "functions": { - "total": 17, - "covered": 6, - "skipped": 0, - "pct": 35.29 - }, - "statements": { - "total": 40, - "covered": 23, - "skipped": 0, - "pct": 57.5 - }, - "branches": { - "total": 20, - "covered": 13, - "skipped": 0, - "pct": 65 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/fetch_export_by_type_and_search.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/fetch_export_objects.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/find_objects.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/get_default_title.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/get_relationships.js": { - "lines": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 7, - "covered": 5, - "skipped": 0, - "pct": 71.43 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/get_saved_object_counts.js": { - "lines": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/get_saved_object_label.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/import_file.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/import_legacy_file.js": { - "lines": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/in_app_url.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/is_same_query.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/log_legacy_import.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/parse_query.js": { - "lines": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 6, - "covered": 5, - "skipped": 0, - "pct": 83.33 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/resolve_import_errors.js": { - "lines": { - "total": 59, - "covered": 59, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 13, - "covered": 13, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 62, - "covered": 62, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 38, - "covered": 36, - "skipped": 0, - "pct": 94.74 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/resolve_saved_objects.js": { - "lines": { - "total": 110, - "covered": 69, - "skipped": 0, - "pct": 62.73 - }, - "functions": { - "total": 23, - "covered": 20, - "skipped": 0, - "pct": 86.96 - }, - "statements": { - "total": 114, - "covered": 73, - "skipped": 0, - "pct": 64.04 - }, - "branches": { - "total": 57, - "covered": 29, - "skipped": 0, - "pct": 50.88 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js": { - "lines": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 37, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js": { - "lines": { - "total": 212, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 54, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 216, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 74, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js": { - "lines": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/help_menu/help_menu_util.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/listing/visualize_listing.js": { - "lines": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/listing/visualize_listing_table.js": { - "lines": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/lib/export/export_dashboards.js": { - "lines": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/lib/import/import_dashboards.js": { - "lines": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/lib/management/saved_objects/inject_meta_attributes.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/lib/management/saved_objects/relationships.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/routes/api/export/index.js": { - "lines": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/routes/api/import/index.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/routes/api/management/index.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/find.js": { - "lines": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/relationships.js": { - "lines": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/scroll.js": { - "lines": { - "total": 26, - "covered": 8, - "skipped": 0, - "pct": 30.77 - }, - "functions": { - "total": 7, - "covered": 3, - "skipped": 0, - "pct": 42.86 - }, - "statements": { - "total": 26, - "covered": 8, - "skipped": 0, - "pct": 30.77 - }, - "branches": { - "total": 12, - "covered": 3, - "skipped": 0, - "pct": 25 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/region_map/public/choropleth_layer.js": { - "lines": { - "total": 206, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 47, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 211, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 90, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/region_map/public/region_map_fn.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/region_map/public/region_map_type.js": { - "lines": { - "total": 28, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/region_map/public/region_map_visualization.js": { - "lines": { - "total": 59, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 60, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 48, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/region_map/public/tooltip_formatter.js": { - "lines": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/index.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/status_page.js": { - "lines": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/components/metric_tiles.js": { - "lines": { - "total": 10, - "covered": 8, - "skipped": 0, - "pct": 80 - }, - "functions": { - "total": 5, - "covered": 3, - "skipped": 0, - "pct": 60 - }, - "statements": { - "total": 10, - "covered": 8, - "skipped": 0, - "pct": 80 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/components/render.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/components/server_status.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/components/status_app.js": { - "lines": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/components/status_table.js": { - "lines": { - "total": 7, - "covered": 4, - "skipped": 0, - "pct": 57.14 - }, - "functions": { - "total": 4, - "covered": 1, - "skipped": 0, - "pct": 25 - }, - "statements": { - "total": 7, - "covered": 4, - "skipped": 0, - "pct": 57.14 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/lib/format_number.js": { - "lines": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/lib/load_status.js": { - "lines": { - "total": 19, - "covered": 9, - "skipped": 0, - "pct": 47.37 - }, - "functions": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - }, - "statements": { - "total": 19, - "covered": 9, - "skipped": 0, - "pct": 47.37 - }, - "branches": { - "total": 7, - "covered": 3, - "skipped": 0, - "pct": 42.86 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/lib/load_status.test.mocks.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/lib/prop_types.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/testbed/index.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/testbed/public/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/testbed/public/testbed.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tests_bundle/find_source_files.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tests_bundle/index.js": { - "lines": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 36, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tests_bundle/tests_entry_template.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tests_bundle/webpackShims/angular-mocks.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js": { - "lines": { - "total": 102, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 103, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 38, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/css_filters.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/geohash_layer.js": { - "lines": { - "total": 55, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 57, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/tile_map_fn.js": { - "lines": { - "total": 7, - "covered": 6, - "skipped": 0, - "pct": 85.71 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 8, - "covered": 7, - "skipped": 0, - "pct": 87.5 - }, - "branches": { - "total": 4, - "covered": 2, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/tile_map_type.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/tile_map_visualization.js": { - "lines": { - "total": 93, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 94, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 52, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/editors/_tooltip_formatter.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/markers/geohash_grid.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/markers/heatmap.js": { - "lines": { - "total": 62, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 63, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 28, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/markers/scaled_circles.js": { - "lines": { - "total": 80, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 24, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 80, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/markers/shaded_circles.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/app.js": { - "lines": { - "total": 151, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 54, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 159, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/breadcrumbs.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/components/timelionhelp_tabs.js": { - "lines": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/components/timelionhelp_tabs_directive.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/fixed_element.js": { - "lines": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js": { - "lines": { - "total": 120, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 134, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 67, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/saved_object_save_as_checkbox.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_expression_input.js": { - "lines": { - "total": 95, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 95, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 36, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_expression_input_helpers.js": { - "lines": { - "total": 88, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 92, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 49, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_grid.js": { - "lines": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_load_sheet.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_options_sheet.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_save_sheet.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/cells/cells.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/chart/chart.js": { - "lines": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/fullscreen/fullscreen.js": { - "lines": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_expression_suggestions/timelion_expression_suggestions.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_help/timelion_help.js": { - "lines": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_interval/timelion_interval.js": { - "lines": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/lib/observe_resize.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.js": { - "lines": { - "total": 18, - "covered": 18, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 19, - "covered": 18, - "skipped": 0, - "pct": 94.74 - }, - "branches": { - "total": 8, - "covered": 6, - "skipped": 0, - "pct": 75 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table.js": { - "lines": { - "total": 104, - "covered": 1, - "skipped": 0, - "pct": 0.96 - }, - "functions": { - "total": 22, - "covered": 1, - "skipped": 0, - "pct": 4.55 - }, - "statements": { - "total": 113, - "covered": 1, - "skipped": 0, - "pct": 0.88 - }, - "branches": { - "total": 61, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table_group.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_table/public/paginated_table/paginated_table.js": { - "lines": { - "total": 32, - "covered": 27, - "skipped": 0, - "pct": 84.38 - }, - "functions": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 35, - "covered": 29, - "skipped": 0, - "pct": 82.86 - }, - "branches": { - "total": 27, - "covered": 18, - "skipped": 0, - "pct": 66.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_table/public/paginated_table/rows.js": { - "lines": { - "total": 47, - "covered": 21, - "skipped": 0, - "pct": 44.68 - }, - "functions": { - "total": 12, - "covered": 7, - "skipped": 0, - "pct": 58.33 - }, - "statements": { - "total": 48, - "covered": 22, - "skipped": 0, - "pct": 45.83 - }, - "branches": { - "total": 28, - "covered": 12, - "skipped": 0, - "pct": 42.86 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_tagcloud/public/components/feedback_message.js": { - "lines": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_tagcloud/public/components/label.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud.js": { - "lines": { - "total": 200, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 53, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 208, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 68, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js": { - "lines": { - "total": 64, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 65, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/flot.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/_generated_/chain.js": { - "lines": { - "total": 1070, - "covered": 612, - "skipped": 0, - "pct": 57.2 - }, - "functions": { - "total": 72, - "covered": 46, - "skipped": 0, - "pct": 63.89 - }, - "statements": { - "total": 1136, - "covered": 623, - "skipped": 0, - "pct": 54.84 - }, - "branches": { - "total": 559, - "covered": 237, - "skipped": 0, - "pct": 42.4 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.axislabels.js": { - "lines": { - "total": 238, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 238, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 123, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.crosshair.js": { - "lines": { - "total": 63, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 63, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.js": { - "lines": { - "total": 1526, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 123, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1653, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 1142, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.selection.js": { - "lines": { - "total": 138, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 145, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 83, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.stack.js": { - "lines": { - "total": 85, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 87, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 60, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.symbol.js": { - "lines": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.time.js": { - "lines": { - "total": 189, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 208, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 155, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/editor_controller.js": { - "lines": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/request_handler.js": { - "lines": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/add_delete_buttons.js": { - "lines": { - "total": 28, - "covered": 28, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 28, - "covered": 28, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 14, - "covered": 12, - "skipped": 0, - "pct": 85.71 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/annotations_editor.js": { - "lines": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/color_picker.js": { - "lines": { - "total": 20, - "covered": 16, - "skipped": 0, - "pct": 80 - }, - "functions": { - "total": 7, - "covered": 6, - "skipped": 0, - "pct": 85.71 - }, - "statements": { - "total": 21, - "covered": 16, - "skipped": 0, - "pct": 76.19 - }, - "branches": { - "total": 10, - "covered": 8, - "skipped": 0, - "pct": 80 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/color_rules.js": { - "lines": { - "total": 32, - "covered": 24, - "skipped": 0, - "pct": 75 - }, - "functions": { - "total": 7, - "covered": 5, - "skipped": 0, - "pct": 71.43 - }, - "statements": { - "total": 35, - "covered": 25, - "skipped": 0, - "pct": 71.43 - }, - "branches": { - "total": 11, - "covered": 5, - "skipped": 0, - "pct": 45.45 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/custom_color_picker.js": { - "lines": { - "total": 15, - "covered": 11, - "skipped": 0, - "pct": 73.33 - }, - "functions": { - "total": 5, - "covered": 3, - "skipped": 0, - "pct": 60 - }, - "statements": { - "total": 15, - "covered": 11, - "skipped": 0, - "pct": 73.33 - }, - "branches": { - "total": 12, - "covered": 4, - "skipped": 0, - "pct": 33.33 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/data_format_picker.js": { - "lines": { - "total": 47, - "covered": 4, - "skipped": 0, - "pct": 8.51 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 49, - "covered": 4, - "skipped": 0, - "pct": 8.16 - }, - "branches": { - "total": 42, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/error.js": { - "lines": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/index_pattern.js": { - "lines": { - "total": 30, - "covered": 7, - "skipped": 0, - "pct": 23.33 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 30, - "covered": 7, - "skipped": 0, - "pct": 23.33 - }, - "branches": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/markdown_editor.js": { - "lines": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/no_data.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config.js": { - "lines": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/query_bar_wrapper.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/series.js": { - "lines": { - "total": 22, - "covered": 3, - "skipped": 0, - "pct": 13.64 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 22, - "covered": 3, - "skipped": 0, - "pct": 13.64 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/series_config.js": { - "lines": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/series_drag_handler.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/series_editor.js": { - "lines": { - "total": 28, - "covered": 3, - "skipped": 0, - "pct": 10.71 - }, - "functions": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 31, - "covered": 3, - "skipped": 0, - "pct": 9.68 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/split.js": { - "lines": { - "total": 17, - "covered": 2, - "skipped": 0, - "pct": 11.76 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 17, - "covered": 2, - "skipped": 0, - "pct": 11.76 - }, - "branches": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js": { - "lines": { - "total": 53, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 53, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor_visualization.js": { - "lines": { - "total": 57, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 58, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 39, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_picker.js": { - "lines": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_with_splits.js": { - "lines": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/visualization.js": { - "lines": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/yes_no.js": { - "lines": { - "total": 11, - "covered": 11, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 11, - "covered": 11, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/agg.js": { - "lines": { - "total": 9, - "covered": 1, - "skipped": 0, - "pct": 11.11 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 1, - "skipped": 0, - "pct": 11.11 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/agg_row.js": { - "lines": { - "total": 8, - "covered": 1, - "skipped": 0, - "pct": 12.5 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 1, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/agg_select.js": { - "lines": { - "total": 24, - "covered": 7, - "skipped": 0, - "pct": 29.17 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 30, - "covered": 7, - "skipped": 0, - "pct": 23.33 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/aggs.js": { - "lines": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/calculation.js": { - "lines": { - "total": 11, - "covered": 2, - "skipped": 0, - "pct": 18.18 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 2, - "skipped": 0, - "pct": 16.67 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/cumulative_sum.js": { - "lines": { - "total": 6, - "covered": 1, - "skipped": 0, - "pct": 16.67 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 1, - "skipped": 0, - "pct": 16.67 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/derivative.js": { - "lines": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/field_select.js": { - "lines": { - "total": 20, - "covered": 4, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 20, - "covered": 4, - "skipped": 0, - "pct": 20 - }, - "branches": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/filter_ratio.js": { - "lines": { - "total": 12, - "covered": 2, - "skipped": 0, - "pct": 16.67 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 2, - "skipped": 0, - "pct": 16.67 - }, - "branches": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/math.js": { - "lines": { - "total": 11, - "covered": 2, - "skipped": 0, - "pct": 18.18 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 2, - "skipped": 0, - "pct": 16.67 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/metric_select.js": { - "lines": { - "total": 35, - "covered": 3, - "skipped": 0, - "pct": 8.57 - }, - "functions": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 36, - "covered": 3, - "skipped": 0, - "pct": 8.33 - }, - "branches": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/moving_average.js": { - "lines": { - "total": 17, - "covered": 4, - "skipped": 0, - "pct": 23.53 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 4, - "skipped": 0, - "pct": 22.22 - }, - "branches": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile.js": { - "lines": { - "total": 12, - "covered": 3, - "skipped": 0, - "pct": 25 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 3, - "skipped": 0, - "pct": 23.08 - }, - "branches": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_ui.js": { - "lines": { - "total": 33, - "covered": 4, - "skipped": 0, - "pct": 12.12 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 4, - "skipped": 0, - "pct": 11.76 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/positive_only.js": { - "lines": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/serial_diff.js": { - "lines": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/series_agg.js": { - "lines": { - "total": 12, - "covered": 2, - "skipped": 0, - "pct": 16.67 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 2, - "skipped": 0, - "pct": 16.67 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/static.js": { - "lines": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_agg.js": { - "lines": { - "total": 8, - "covered": 1, - "skipped": 0, - "pct": 12.5 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 1, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_deviation.js": { - "lines": { - "total": 18, - "covered": 4, - "skipped": 0, - "pct": 22.22 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 4, - "skipped": 0, - "pct": 22.22 - }, - "branches": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_sibling.js": { - "lines": { - "total": 18, - "covered": 3, - "skipped": 0, - "pct": 16.67 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 3, - "skipped": 0, - "pct": 16.67 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/temporary_unsupported_agg.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/top_hit.js": { - "lines": { - "total": 29, - "covered": 6, - "skipped": 0, - "pct": 20.69 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 31, - "covered": 6, - "skipped": 0, - "pct": 19.35 - }, - "branches": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/unsupported_agg.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/vars.js": { - "lines": { - "total": 17, - "covered": 3, - "skipped": 0, - "pct": 17.65 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 19, - "covered": 3, - "skipped": 0, - "pct": 15.79 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/multi_value_row.js": { - "lines": { - "total": 8, - "covered": 3, - "skipped": 0, - "pct": 37.5 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 3, - "skipped": 0, - "pct": 37.5 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/percentile_rank.js": { - "lines": { - "total": 14, - "covered": 3, - "skipped": 0, - "pct": 21.43 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 14, - "covered": 3, - "skipped": 0, - "pct": 21.43 - }, - "branches": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/percentile_rank_values.js": { - "lines": { - "total": 14, - "covered": 2, - "skipped": 0, - "pct": 14.29 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 2, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/icon_select/icon_select.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/agg_to_component.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/calculate_siblings.js": { - "lines": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/charts.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/collection_actions.js": { - "lines": { - "total": 23, - "covered": 22, - "skipped": 0, - "pct": 95.65 - }, - "functions": { - "total": 6, - "covered": 5, - "skipped": 0, - "pct": 83.33 - }, - "statements": { - "total": 27, - "covered": 24, - "skipped": 0, - "pct": 88.89 - }, - "branches": { - "total": 17, - "covered": 8, - "skipped": 0, - "pct": 47.06 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/convert_series_to_vars.js": { - "lines": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_change_handler.js": { - "lines": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 1, - "skipped": 0, - "pct": 25 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_number_handler.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 6, - "covered": 3, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_select_handler.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_text_handler.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 6, - "covered": 3, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_xaxis_formatter.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/detect_ie.js": { - "lines": { - "total": 12, - "covered": 8, - "skipped": 0, - "pct": 66.67 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 12, - "covered": 8, - "skipped": 0, - "pct": 66.67 - }, - "branches": { - "total": 6, - "covered": 3, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/durations.js": { - "lines": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_axis_label_string.js": { - "lines": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - }, - "branches": { - "total": 4, - "covered": 2, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_default_query_language.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_display_name.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_interval.js": { - "lines": { - "total": 27, - "covered": 13, - "skipped": 0, - "pct": 48.15 - }, - "functions": { - "total": 6, - "covered": 1, - "skipped": 0, - "pct": 16.67 - }, - "statements": { - "total": 31, - "covered": 14, - "skipped": 0, - "pct": 45.16 - }, - "branches": { - "total": 17, - "covered": 4, - "skipped": 0, - "pct": 23.53 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/new_metric_agg_fn.js": { - "lines": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/new_series_fn.js": { - "lines": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/re_id_series.js": { - "lines": { - "total": 16, - "covered": 16, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 20, - "covered": 20, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/reorder.js": { - "lines": { - "total": 5, - "covered": 1, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 5, - "covered": 1, - "skipped": 0, - "pct": 20 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/replace_vars.js": { - "lines": { - "total": 11, - "covered": 6, - "skipped": 0, - "pct": 54.55 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 11, - "covered": 6, - "skipped": 0, - "pct": 54.55 - }, - "branches": { - "total": 6, - "covered": 1, - "skipped": 0, - "pct": 16.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/series_change_handler.js": { - "lines": { - "total": 9, - "covered": 1, - "skipped": 0, - "pct": 11.11 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 1, - "skipped": 0, - "pct": 9.09 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/stacked.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/tick_formatter.js": { - "lines": { - "total": 22, - "covered": 18, - "skipped": 0, - "pct": 81.82 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 23, - "covered": 19, - "skipped": 0, - "pct": 82.61 - }, - "branches": { - "total": 10, - "covered": 9, - "skipped": 0, - "pct": 90 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/gauge.js": { - "lines": { - "total": 30, - "covered": 25, - "skipped": 0, - "pct": 83.33 - }, - "functions": { - "total": 8, - "covered": 4, - "skipped": 0, - "pct": 50 - }, - "statements": { - "total": 33, - "covered": 28, - "skipped": 0, - "pct": 84.85 - }, - "branches": { - "total": 21, - "covered": 6, - "skipped": 0, - "pct": 28.57 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/markdown.js": { - "lines": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/metric.js": { - "lines": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/table.js": { - "lines": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/timeseries.js": { - "lines": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/top_n.js": { - "lines": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/everything.js": { - "lines": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/filter.js": { - "lines": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/filter_items.js": { - "lines": { - "total": 25, - "covered": 2, - "skipped": 0, - "pct": 8 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 27, - "covered": 2, - "skipped": 0, - "pct": 7.41 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/filters.js": { - "lines": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/group_by_select.js": { - "lines": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/terms.js": { - "lines": { - "total": 19, - "covered": 18, - "skipped": 0, - "pct": 94.74 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 20, - "covered": 19, - "skipped": 0, - "pct": 95 - }, - "branches": { - "total": 9, - "covered": 6, - "skipped": 0, - "pct": 66.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/unsupported_split.js": { - "lines": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/svg/bomb_icon.js": { - "lines": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/svg/fire_icon.js": { - "lines": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/gauge/series.js": { - "lines": { - "total": 18, - "covered": 12, - "skipped": 0, - "pct": 66.67 - }, - "functions": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "statements": { - "total": 19, - "covered": 13, - "skipped": 0, - "pct": 68.42 - }, - "branches": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/gauge/vis.js": { - "lines": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 39, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/markdown/series.js": { - "lines": { - "total": 17, - "covered": 2, - "skipped": 0, - "pct": 11.76 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 2, - "skipped": 0, - "pct": 11.11 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/markdown/vis.js": { - "lines": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/metric/series.js": { - "lines": { - "total": 19, - "covered": 12, - "skipped": 0, - "pct": 63.16 - }, - "functions": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "statements": { - "total": 20, - "covered": 13, - "skipped": 0, - "pct": 65 - }, - "branches": { - "total": 8, - "covered": 3, - "skipped": 0, - "pct": 37.5 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/metric/vis.js": { - "lines": { - "total": 28, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/config.js": { - "lines": { - "total": 16, - "covered": 2, - "skipped": 0, - "pct": 12.5 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 2, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/is_sortable.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/series.js": { - "lines": { - "total": 15, - "covered": 2, - "skipped": 0, - "pct": 13.33 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 2, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/vis.js": { - "lines": { - "total": 75, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 79, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 58, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/config.js": { - "lines": { - "total": 28, - "covered": 2, - "skipped": 0, - "pct": 7.14 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 28, - "covered": 2, - "skipped": 0, - "pct": 7.14 - }, - "branches": { - "total": 30, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/series.js": { - "lines": { - "total": 19, - "covered": 3, - "skipped": 0, - "pct": 15.79 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 20, - "covered": 3, - "skipped": 0, - "pct": 15 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/vis.js": { - "lines": { - "total": 80, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 84, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 48, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/top_n/series.js": { - "lines": { - "total": 16, - "covered": 2, - "skipped": 0, - "pct": 12.5 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 17, - "covered": 2, - "skipped": 0, - "pct": 11.76 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/top_n/vis.js": { - "lines": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 38, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/contexts/form_validation_context.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/contexts/vis_data_context.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/lib/check_ui_restrictions.js": { - "lines": { - "total": 13, - "covered": 5, - "skipped": 0, - "pct": 38.46 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 5, - "skipped": 0, - "pct": 38.46 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/lib/create_brush_handler.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/lib/fetch_fields.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/lib/set_is_reversed.js": { - "lines": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/lib/validate_interval.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/constants/chart.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/constants/icons.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/constants/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/active_cursor.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/calc_dimensions.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/calculate_coordinates.js": { - "lines": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/get_value_by.js": { - "lines": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/annotation.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/gauge.js": { - "lines": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/gauge_vis.js": { - "lines": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/metric.js": { - "lines": { - "total": 41, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 46, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 40, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/top_n.js": { - "lines": { - "total": 48, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 49, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/index.js": { - "lines": { - "total": 33, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 37, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/area_decorator.js": { - "lines": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/bar_decorator.js": { - "lines": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/model/charts.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/series_styles.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 23, - "covered": 23, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/stack_format.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/vega_visualization.js": { - "lines": { - "total": 38, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 38, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/ems_file_parser.js": { - "lines": { - "total": 14, - "covered": 12, - "skipped": 0, - "pct": 85.71 - }, - "functions": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 16, - "covered": 13, - "skipped": 0, - "pct": 81.25 - }, - "branches": { - "total": 8, - "covered": 4, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/es_query_parser.js": { - "lines": { - "total": 142, - "covered": 115, - "skipped": 0, - "pct": 80.99 - }, - "functions": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 145, - "covered": 117, - "skipped": 0, - "pct": 80.69 - }, - "branches": { - "total": 104, - "covered": 75, - "skipped": 0, - "pct": 72.12 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/search_cache.js": { - "lines": { - "total": 11, - "covered": 11, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 11, - "covered": 11, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/time_cache.js": { - "lines": { - "total": 21, - "covered": 19, - "skipped": 0, - "pct": 90.48 - }, - "functions": { - "total": 5, - "covered": 3, - "skipped": 0, - "pct": 60 - }, - "statements": { - "total": 21, - "covered": 19, - "skipped": 0, - "pct": 90.48 - }, - "branches": { - "total": 12, - "covered": 11, - "skipped": 0, - "pct": 91.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/url_parser.js": { - "lines": { - "total": 9, - "covered": 1, - "skipped": 0, - "pct": 11.11 - }, - "functions": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "statements": { - "total": 9, - "covered": 1, - "skipped": 0, - "pct": 11.11 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/utils.js": { - "lines": { - "total": 11, - "covered": 2, - "skipped": 0, - "pct": 18.18 - }, - "functions": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "statements": { - "total": 11, - "covered": 2, - "skipped": 0, - "pct": 18.18 - }, - "branches": { - "total": 8, - "covered": 1, - "skipped": 0, - "pct": 12.5 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/vega_parser.js": { - "lines": { - "total": 209, - "covered": 154, - "skipped": 0, - "pct": 73.68 - }, - "functions": { - "total": 20, - "covered": 16, - "skipped": 0, - "pct": 80 - }, - "statements": { - "total": 214, - "covered": 156, - "skipped": 0, - "pct": 72.9 - }, - "branches": { - "total": 193, - "covered": 120, - "skipped": 0, - "pct": 62.18 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/vega_view/vega_base_view.js": { - "lines": { - "total": 145, - "covered": 7, - "skipped": 0, - "pct": 4.83 - }, - "functions": { - "total": 26, - "covered": 1, - "skipped": 0, - "pct": 3.85 - }, - "statements": { - "total": 150, - "covered": 7, - "skipped": 0, - "pct": 4.67 - }, - "branches": { - "total": 73, - "covered": 1, - "skipped": 0, - "pct": 1.37 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/vega_view/vega_map_layer.js": { - "lines": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/vega_view/vega_map_view.js": { - "lines": { - "total": 44, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 46, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/vega_view/vega_tooltip.js": { - "lines": { - "total": 24, - "covered": 1, - "skipped": 0, - "pct": 4.17 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 25, - "covered": 1, - "skipped": 0, - "pct": 4 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/vega_view/vega_view.js": { - "lines": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/response_handler.js": { - "lines": { - "total": 46, - "covered": 3, - "skipped": 0, - "pct": 6.52 - }, - "functions": { - "total": 7, - "covered": 1, - "skipped": 0, - "pct": 14.29 - }, - "statements": { - "total": 47, - "covered": 3, - "skipped": 0, - "pct": 6.38 - }, - "branches": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/vis.js": { - "lines": { - "total": 44, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 47, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 24, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/vislib.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/data_array.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/flatten_series.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/labels.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/truncate_labels.js": { - "lines": { - "total": 6, - "covered": 1, - "skipped": 0, - "pct": 16.67 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 1, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/uniq_labels.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/tooltip/_collect_branch.js": { - "lines": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/tooltip/_hierarchical_tooltip_formatter.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/tooltip/_pointseries_tooltip_formatter.js": { - "lines": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 28, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/tooltip/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/tooltip/position_tooltip.js": { - "lines": { - "total": 69, - "covered": 8, - "skipped": 0, - "pct": 11.59 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 75, - "covered": 8, - "skipped": 0, - "pct": 10.67 - }, - "branches": { - "total": 46, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/tooltip/tooltip.js": { - "lines": { - "total": 86, - "covered": 11, - "skipped": 0, - "pct": 12.79 - }, - "functions": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 88, - "covered": 11, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 42, - "covered": 3, - "skipped": 0, - "pct": 7.14 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/flatten_data.js": { - "lines": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - }, - "branches": { - "total": 12, - "covered": 8, - "skipped": 0, - "pct": 66.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/inject_zeros.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/ordered_x_keys.js": { - "lines": { - "total": 26, - "covered": 11, - "skipped": 0, - "pct": 42.31 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 29, - "covered": 13, - "skipped": 0, - "pct": 44.83 - }, - "branches": { - "total": 19, - "covered": 11, - "skipped": 0, - "pct": 57.89 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/uniq_keys.js": { - "lines": { - "total": 23, - "covered": 20, - "skipped": 0, - "pct": 86.96 - }, - "functions": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 23, - "covered": 20, - "skipped": 0, - "pct": 86.96 - }, - "branches": { - "total": 12, - "covered": 6, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/zero_fill_data_array.js": { - "lines": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/zero_filled_array.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_data_label.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_error_handler.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/alerts.js": { - "lines": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/chart_grid.js": { - "lines": { - "total": 39, - "covered": 1, - "skipped": 0, - "pct": 2.56 - }, - "functions": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 47, - "covered": 1, - "skipped": 0, - "pct": 2.13 - }, - "branches": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/chart_title.js": { - "lines": { - "total": 39, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 39, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/data.js": { - "lines": { - "total": 161, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 61, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 168, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 82, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/dispatch.js": { - "lines": { - "total": 141, - "covered": 26, - "skipped": 0, - "pct": 18.44 - }, - "functions": { - "total": 41, - "covered": 6, - "skipped": 0, - "pct": 14.63 - }, - "statements": { - "total": 149, - "covered": 28, - "skipped": 0, - "pct": 18.79 - }, - "branches": { - "total": 97, - "covered": 23, - "skipped": 0, - "pct": 23.71 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/handler.js": { - "lines": { - "total": 69, - "covered": 1, - "skipped": 0, - "pct": 1.45 - }, - "functions": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 71, - "covered": 1, - "skipped": 0, - "pct": 1.41 - }, - "branches": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/vis_config.js": { - "lines": { - "total": 11, - "covered": 1, - "skipped": 0, - "pct": 9.09 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 1, - "skipped": 0, - "pct": 9.09 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis.js": { - "lines": { - "total": 106, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 109, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 51, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_config.js": { - "lines": { - "total": 84, - "covered": 7, - "skipped": 0, - "pct": 8.33 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 89, - "covered": 7, - "skipped": 0, - "pct": 7.87 - }, - "branches": { - "total": 66, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_labels.js": { - "lines": { - "total": 72, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 77, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 36, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_scale.js": { - "lines": { - "total": 118, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 134, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 97, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_title.js": { - "lines": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/scale_modes.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/time_ticks.js": { - "lines": { - "total": 12, - "covered": 12, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 13, - "covered": 13, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/layout.js": { - "lines": { - "total": 54, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 54, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/layout_types.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/chart_split.js": { - "lines": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/chart_title_split.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/x_axis_split.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/y_axis_split.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/gauge_chart/chart_split.js": { - "lines": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/gauge_chart/chart_title_split.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/pie_chart/chart_split.js": { - "lines": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/pie_chart/chart_title_split.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/types/column_layout.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/types/gauge_layout.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/types/pie_layout.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/gauge.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/index.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/pie.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/point_series.js": { - "lines": { - "total": 70, - "covered": 57, - "skipped": 0, - "pct": 81.43 - }, - "functions": { - "total": 17, - "covered": 12, - "skipped": 0, - "pct": 70.59 - }, - "statements": { - "total": 73, - "covered": 58, - "skipped": 0, - "pct": 79.45 - }, - "branches": { - "total": 76, - "covered": 48, - "skipped": 0, - "pct": 63.16 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/_chart.js": { - "lines": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauge_chart.js": { - "lines": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.js": { - "lines": { - "total": 146, - "covered": 1, - "skipped": 0, - "pct": 0.68 - }, - "functions": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 153, - "covered": 1, - "skipped": 0, - "pct": 0.65 - }, - "branches": { - "total": 86, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series.js": { - "lines": { - "total": 103, - "covered": 2, - "skipped": 0, - "pct": 1.94 - }, - "functions": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 108, - "covered": 2, - "skipped": 0, - "pct": 1.85 - }, - "branches": { - "total": 63, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/time_marker.js": { - "lines": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/vis_types.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/gauge_types.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/meter.js": { - "lines": { - "total": 132, - "covered": 3, - "skipped": 0, - "pct": 2.27 - }, - "functions": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 135, - "covered": 3, - "skipped": 0, - "pct": 2.22 - }, - "branches": { - "total": 57, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/_point_series.js": { - "lines": { - "total": 55, - "covered": 1, - "skipped": 0, - "pct": 1.82 - }, - "functions": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 61, - "covered": 1, - "skipped": 0, - "pct": 1.64 - }, - "branches": { - "total": 43, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.js": { - "lines": { - "total": 94, - "covered": 1, - "skipped": 0, - "pct": 1.06 - }, - "functions": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 95, - "covered": 1, - "skipped": 0, - "pct": 1.05 - }, - "branches": { - "total": 38, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.js": { - "lines": { - "total": 133, - "covered": 1, - "skipped": 0, - "pct": 0.75 - }, - "functions": { - "total": 30, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 137, - "covered": 1, - "skipped": 0, - "pct": 0.73 - }, - "branches": { - "total": 107, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/heatmap_chart.js": { - "lines": { - "total": 147, - "covered": 1, - "skipped": 0, - "pct": 0.68 - }, - "functions": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 153, - "covered": 1, - "skipped": 0, - "pct": 0.65 - }, - "branches": { - "total": 80, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.js": { - "lines": { - "total": 77, - "covered": 1, - "skipped": 0, - "pct": 1.3 - }, - "functions": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 78, - "covered": 1, - "skipped": 0, - "pct": 1.28 - }, - "branches": { - "total": 51, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/series_types.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_impl.js": { - "lines": { - "total": 58, - "covered": 26, - "skipped": 0, - "pct": 44.83 - }, - "functions": { - "total": 24, - "covered": 7, - "skipped": 0, - "pct": 29.17 - }, - "statements": { - "total": 59, - "covered": 26, - "skipped": 0, - "pct": 44.07 - }, - "branches": { - "total": 48, - "covered": 19, - "skipped": 0, - "pct": 39.58 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/expressions/vis.js": { - "lines": { - "total": 33, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/calculate_object_hash.js": { - "lines": { - "total": 28, - "covered": 24, - "skipped": 0, - "pct": 85.71 - }, - "functions": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 28, - "covered": 24, - "skipped": 0, - "pct": 85.71 - }, - "branches": { - "total": 16, - "covered": 12, - "skipped": 0, - "pct": 75 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/vis_update.js": { - "lines": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 12, - "covered": 3, - "skipped": 0, - "pct": 25 - }, - "branches": { - "total": 28, - "covered": 2, - "skipped": 0, - "pct": 7.14 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/vis_update_state.js": { - "lines": { - "total": 46, - "covered": 42, - "skipped": 0, - "pct": 91.3 - }, - "functions": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 47, - "covered": 42, - "skipped": 0, - "pct": 89.36 - }, - "branches": { - "total": 38, - "covered": 28, - "skipped": 0, - "pct": 73.68 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/base_vis_type.js": { - "lines": { - "total": 17, - "covered": 10, - "skipped": 0, - "pct": 58.82 - }, - "functions": { - "total": 3, - "covered": 2, - "skipped": 0, - "pct": 66.67 - }, - "statements": { - "total": 17, - "covered": 10, - "skipped": 0, - "pct": 58.82 - }, - "branches": { - "total": 17, - "covered": 9, - "skipped": 0, - "pct": 52.94 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/react_vis_type.js": { - "lines": { - "total": 12, - "covered": 10, - "skipped": 0, - "pct": 83.33 - }, - "functions": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - }, - "statements": { - "total": 12, - "covered": 10, - "skipped": 0, - "pct": 83.33 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - } -} diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-manual-mix.json b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-manual-mix.json index 2554d9131f7c6..baf2b6d500679 100644 --- a/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-manual-mix.json +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-manual-mix.json @@ -1,30 +1,4 @@ { - "total": { - "lines": { - "total": 14817, - "covered": 3377, - "skipped": 0, - "pct": 22.79 - }, - "statements": { - "total": 15507, - "covered": 3453, - "skipped": 0, - "pct": 22.27 - }, - "functions": { - "total": 3286, - "covered": 654, - "skipped": 0, - "pct": 19.9 - }, - "branches": { - "total": 8060, - "covered": 1439, - "skipped": 0, - "pct": 17.85 - } - }, "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/x-pack/legacy/plugins/reporting/server/browsers/extract/unzip.js": { "lines": { "total": 4, @@ -50,109 +24,5 @@ "skipped": 0, "pct": 100 } - }, - "total": { - "lines": { - "total": 14817, - "covered": 3377, - "skipped": 0, - "pct": 22.79 - }, - "statements": { - "total": 15507, - "covered": 3453, - "skipped": 0, - "pct": 22.27 - }, - "functions": { - "total": 3286, - "covered": 654, - "skipped": 0, - "pct": 19.9 - }, - "branches": { - "total": 8060, - "covered": 1439, - "skipped": 0, - "pct": 17.85 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/button/button.js": { - "lines": { - "total": 33, - "covered": 28, - "skipped": 0, - "pct": 84.85 - }, - "functions": { - "total": 7, - "covered": 6, - "skipped": 0, - "pct": 85.71 - }, - "statements": { - "total": 33, - "covered": 28, - "skipped": 0, - "pct": 84.85 - }, - "branches": { - "total": 21, - "covered": 16, - "skipped": 0, - "pct": 76.19 - } - }, - "total": { - "lines": { - "total": 14817, - "covered": 3377, - "skipped": 0, - "pct": 22.79 - }, - "statements": { - "total": 15507, - "covered": 3453, - "skipped": 0, - "pct": 22.27 - }, - "functions": { - "total": 3286, - "covered": 654, - "skipped": 0, - "pct": 19.9 - }, - "branches": { - "total": 8060, - "covered": 1439, - "skipped": 0, - "pct": 17.85 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/button/button_icon/button_icon.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } } } diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary.json b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary.json index 5e6a8b2d3ea25..e69de29bb2d1d 100644 --- a/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary.json +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary.json @@ -1,13366 +0,0 @@ -{ - "total": { - "lines": { - "total": 14817, - "covered": 3377, - "skipped": 0, - "pct": 22.79 - }, - "statements": { - "total": 15507, - "covered": 3453, - "skipped": 0, - "pct": 22.27 - }, - "functions": { - "total": 3286, - "covered": 654, - "skipped": 0, - "pct": 19.9 - }, - "branches": { - "total": 8060, - "covered": 1439, - "skipped": 0, - "pct": 17.85 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/bar/bar.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/bar/bar_section.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/button/button.js": { - "lines": { - "total": 33, - "covered": 28, - "skipped": 0, - "pct": 84.85 - }, - "functions": { - "total": 7, - "covered": 6, - "skipped": 0, - "pct": 85.71 - }, - "statements": { - "total": 33, - "covered": 28, - "skipped": 0, - "pct": 84.85 - }, - "branches": { - "total": 21, - "covered": 16, - "skipped": 0, - "pct": 76.19 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/button/button_group/button_group.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/button/button_icon/button_icon.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/collapse_button/collapse_button.js": { - "lines": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/empty_table_prompt/empty_table_prompt.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/empty_table_prompt/empty_table_prompt_actions.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/empty_table_prompt/empty_table_prompt_message.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/empty_table_prompt/empty_table_prompt_panel.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form/check_box/check_box.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form/check_box/check_box_label.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form/label/label.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form/select/select.js": { - "lines": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form/text_area/text_area.js": { - "lines": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form/text_input/text_input.js": { - "lines": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form_layout/field_group.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/form_layout/field_group_section.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/local_nav/local_nav.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/local_nav/local_nav_row.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/local_nav/local_nav_row_section.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/local_nav/local_tab.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/local_nav/local_tabs.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/local_nav/local_title.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/pager/pager.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/pager/pager_button_group.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/controlled_table.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_body.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_header.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_header_cell.js": { - "lines": { - "total": 12, - "covered": 6, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 12, - "covered": 6, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 6, - "covered": 1, - "skipped": 0, - "pct": 16.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_header_check_box_cell.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_info.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_row.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_row_cell.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/table_row_check_box_cell.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table.js": { - "lines": { - "total": 20, - "covered": 16, - "skipped": 0, - "pct": 80 - }, - "functions": { - "total": 11, - "covered": 8, - "skipped": 0, - "pct": 72.73 - }, - "statements": { - "total": 22, - "covered": 16, - "skipped": 0, - "pct": 72.73 - }, - "branches": { - "total": 14, - "covered": 9, - "skipped": 0, - "pct": 64.29 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_create_button.js": { - "lines": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_delete_button.js": { - "lines": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_loading_prompt.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_no_matches_prompt.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_row.js": { - "lines": { - "total": 11, - "covered": 10, - "skipped": 0, - "pct": 90.91 - }, - "functions": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - }, - "statements": { - "total": 11, - "covered": 10, - "skipped": 0, - "pct": 90.91 - }, - "branches": { - "total": 6, - "covered": 5, - "skipped": 0, - "pct": 83.33 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_tool_bar.js": { - "lines": { - "total": 6, - "covered": 4, - "skipped": 0, - "pct": 66.67 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 4, - "skipped": 0, - "pct": 66.67 - }, - "branches": { - "total": 4, - "covered": 2, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/table/listing_table/listing_table_tool_bar_footer.js": { - "lines": { - "total": 8, - "covered": 6, - "skipped": 0, - "pct": 75 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 8, - "covered": 6, - "skipped": 0, - "pct": 75 - }, - "branches": { - "total": 4, - "covered": 2, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tabs/tab.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tabs/tabs.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tool_bar/tool_bar.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tool_bar/tool_bar_footer.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tool_bar/tool_bar_footer_section.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tool_bar/tool_bar_search_box.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tool_bar/tool_bar_section.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/tool_bar/tool_bar_text.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/components/typography/typography.js": { - "lines": { - "total": 12, - "covered": 12, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 12, - "covered": 12, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/alignment.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/key_codes.js": { - "lines": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/accessibility/accessible_click_keys.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/accessibility/cascading_menu_key_codes.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/accessibility/combo_box_key_codes.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/accessibility/html_id_generator.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/packages/kbn-ui-framework/src/services/sort/sortable_properties.js": { - "lines": { - "total": 17, - "covered": 17, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 18, - "covered": 18, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 10, - "covered": 8, - "skipped": 0, - "pct": 80 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/apm_oss/index.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/data/public/actions/filters/create_filters_from_event.js": { - "lines": { - "total": 39, - "covered": 3, - "skipped": 0, - "pct": 7.69 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 41, - "covered": 3, - "skipped": 0, - "pct": 7.32 - }, - "branches": { - "total": 30, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/data/public/search/aggs/buckets/_terms_other_bucket_helper.js": { - "lines": { - "total": 100, - "covered": 7, - "skipped": 0, - "pct": 7 - }, - "functions": { - "total": 24, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 110, - "covered": 7, - "skipped": 0, - "pct": 6.36 - }, - "branches": { - "total": 42, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/data/public/search/expressions/create_filter.js": { - "lines": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/elasticsearch/index.js": { - "lines": { - "total": 28, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/elasticsearch/lib/version_health_check.js": { - "lines": { - "total": 10, - "covered": 9, - "skipped": 0, - "pct": 90 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 9, - "skipped": 0, - "pct": 90 - }, - "branches": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/elasticsearch/server/lib/abortable_request_handler.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/elasticsearch/server/lib/create_proxy.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/elasticsearch/server/lib/handle_es_error.js": { - "lines": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/index.js": { - "lines": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 33, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/inject_vars.js": { - "lines": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/ui_setting_defaults.js": { - "lines": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/common/utils/no_white_space.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/common/utils/shorten_dotted_string.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/migrations/migrations.js": { - "lines": { - "total": 264, - "covered": 250, - "skipped": 0, - "pct": 94.7 - }, - "functions": { - "total": 37, - "covered": 35, - "skipped": 0, - "pct": 94.59 - }, - "statements": { - "total": 269, - "covered": 252, - "skipped": 0, - "pct": 93.68 - }, - "branches": { - "total": 190, - "covered": 149, - "skipped": 0, - "pct": 78.42 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/kibana.js": { - "lines": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/dashboard/np_ready/legacy_app.js": { - "lines": { - "total": 64, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 66, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/dashboard/np_ready/listing/dashboard_listing.js": { - "lines": { - "total": 11, - "covered": 10, - "skipped": 0, - "pct": 90.91 - }, - "functions": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - }, - "statements": { - "total": 11, - "covered": 10, - "skipped": 0, - "pct": 90.91 - }, - "branches": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context.js": { - "lines": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.js": { - "lines": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js": { - "lines": { - "total": 313, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 86, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 325, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 137, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/response_handler.js": { - "lines": { - "total": 44, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 45, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/api/anchor.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/helpers/call_after_bindings_workaround.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query/actions.js": { - "lines": { - "total": 57, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 30, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 68, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query/constants.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query/state.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query_parameters/actions.js": { - "lines": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query_parameters/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/fixed_scroll.js": { - "lines": { - "total": 42, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 44, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/index.js": { - "lines": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/no_results.js": { - "lines": { - "total": 11, - "covered": 11, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 11, - "covered": 11, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/unsupported_index_pattern.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/debounce/debounce.js": { - "lines": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/debounce/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/doc_table_strings.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/lib/pager/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/lib/pager/pager.js": { - "lines": { - "total": 24, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 24, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/fetch_error/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/discover_field.js": { - "lines": { - "total": 41, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 41, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/field_chooser.js": { - "lines": { - "total": 96, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 102, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 88, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/lib/field_calculator.js": { - "lines": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/help_menu/help_menu_util.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/top_nav/open_search_panel.js": { - "lines": { - "total": 7, - "covered": 4, - "skipped": 0, - "pct": 57.14 - }, - "functions": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "statements": { - "total": 7, - "covered": 4, - "skipped": 0, - "pct": 57.14 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/discover/np_ready/components/top_nav/show_open_search_panel.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/load_tutorials.js": { - "lines": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/sample_data_client.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/add_data.js": { - "lines": { - "total": 14, - "covered": 14, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 14, - "covered": 14, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/feature_directory.js": { - "lines": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/home.js": { - "lines": { - "total": 34, - "covered": 31, - "skipped": 0, - "pct": 91.18 - }, - "functions": { - "total": 14, - "covered": 12, - "skipped": 0, - "pct": 85.71 - }, - "statements": { - "total": 34, - "covered": 31, - "skipped": 0, - "pct": 91.18 - }, - "branches": { - "total": 17, - "covered": 14, - "skipped": 0, - "pct": 82.35 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/home_app.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/recently_accessed.js": { - "lines": { - "total": 37, - "covered": 35, - "skipped": 0, - "pct": 94.59 - }, - "functions": { - "total": 8, - "covered": 7, - "skipped": 0, - "pct": 87.5 - }, - "statements": { - "total": 39, - "covered": 37, - "skipped": 0, - "pct": 94.87 - }, - "branches": { - "total": 15, - "covered": 12, - "skipped": 0, - "pct": 80 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/sample_data_set_card.js": { - "lines": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/sample_data_set_cards.js": { - "lines": { - "total": 48, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 54, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/sample_data_view_data_button.js": { - "lines": { - "total": 13, - "covered": 11, - "skipped": 0, - "pct": 84.62 - }, - "functions": { - "total": 5, - "covered": 2, - "skipped": 0, - "pct": 40 - }, - "statements": { - "total": 14, - "covered": 11, - "skipped": 0, - "pct": 78.57 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/synopsis.js": { - "lines": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial_directory.js": { - "lines": { - "total": 41, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 41, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/content.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/footer.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/instruction.js": { - "lines": { - "total": 12, - "covered": 5, - "skipped": 0, - "pct": 41.67 - }, - "functions": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "statements": { - "total": 12, - "covered": 5, - "skipped": 0, - "pct": 41.67 - }, - "branches": { - "total": 6, - "covered": 3, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/instruction_set.js": { - "lines": { - "total": 54, - "covered": 45, - "skipped": 0, - "pct": 83.33 - }, - "functions": { - "total": 17, - "covered": 13, - "skipped": 0, - "pct": 76.47 - }, - "statements": { - "total": 55, - "covered": 45, - "skipped": 0, - "pct": 81.82 - }, - "branches": { - "total": 36, - "covered": 20, - "skipped": 0, - "pct": 55.56 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/introduction.js": { - "lines": { - "total": 12, - "covered": 12, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 12, - "covered": 12, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/number_parameter.js": { - "lines": { - "total": 4, - "covered": 1, - "skipped": 0, - "pct": 25 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 1, - "skipped": 0, - "pct": 25 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/parameter_form.js": { - "lines": { - "total": 8, - "covered": 2, - "skipped": 0, - "pct": 25 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 2, - "skipped": 0, - "pct": 25 - }, - "branches": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/replace_template_strings.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/saved_objects_installer.js": { - "lines": { - "total": 31, - "covered": 25, - "skipped": 0, - "pct": 80.65 - }, - "functions": { - "total": 8, - "covered": 6, - "skipped": 0, - "pct": 75 - }, - "statements": { - "total": 31, - "covered": 25, - "skipped": 0, - "pct": 80.65 - }, - "branches": { - "total": 18, - "covered": 13, - "skipped": 0, - "pct": 72.22 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/status_check_states.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/string_parameter.js": { - "lines": { - "total": 4, - "covered": 1, - "skipped": 0, - "pct": 25 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 1, - "skipped": 0, - "pct": 25 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/home/np_ready/components/tutorial/tutorial.js": { - "lines": { - "total": 92, - "covered": 51, - "skipped": 0, - "pct": 55.43 - }, - "functions": { - "total": 24, - "covered": 12, - "skipped": 0, - "pct": 50 - }, - "statements": { - "total": 93, - "covered": 51, - "skipped": 0, - "pct": 54.84 - }, - "branches": { - "total": 50, - "covered": 27, - "skipped": 0, - "pct": 54 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/index.js": { - "lines": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 37, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/breadcrumbs.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.js": { - "lines": { - "total": 40, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 42, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/create_index_pattern_wizard.js": { - "lines": { - "total": 54, - "covered": 40, - "skipped": 0, - "pct": 74.07 - }, - "functions": { - "total": 19, - "covered": 10, - "skipped": 0, - "pct": 52.63 - }, - "statements": { - "total": 58, - "covered": 41, - "skipped": 0, - "pct": 70.69 - }, - "branches": { - "total": 19, - "covered": 14, - "skipped": 0, - "pct": 73.68 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/index.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/render.js": { - "lines": { - "total": 7, - "covered": 6, - "skipped": 0, - "pct": 85.71 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 6, - "skipped": 0, - "pct": 85.71 - }, - "branches": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js": { - "lines": { - "total": 131, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 40, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 132, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 39, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_sections.js": { - "lines": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/create_edit_field.js": { - "lines": { - "total": 42, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 43, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/create_edit_field/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/index_header/index_header.js": { - "lines": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/indexed_fields_table.js": { - "lines": { - "total": 22, - "covered": 20, - "skipped": 0, - "pct": 90.91 - }, - "functions": { - "total": 13, - "covered": 11, - "skipped": 0, - "pct": 84.62 - }, - "statements": { - "total": 25, - "covered": 22, - "skipped": 0, - "pct": 88 - }, - "branches": { - "total": 17, - "covered": 12, - "skipped": 0, - "pct": 70.59 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/components/table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/components/table/table.js": { - "lines": { - "total": 19, - "covered": 16, - "skipped": 0, - "pct": 84.21 - }, - "functions": { - "total": 10, - "covered": 7, - "skipped": 0, - "pct": 70 - }, - "statements": { - "total": 19, - "covered": 16, - "skipped": 0, - "pct": 84.21 - }, - "branches": { - "total": 10, - "covered": 9, - "skipped": 0, - "pct": 90 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/lib/get_field_format.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/indexed_fields_table/lib/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/scripted_fields_table.js": { - "lines": { - "total": 44, - "covered": 43, - "skipped": 0, - "pct": 97.73 - }, - "functions": { - "total": 13, - "covered": 12, - "skipped": 0, - "pct": 92.31 - }, - "statements": { - "total": 44, - "covered": 43, - "skipped": 0, - "pct": 97.73 - }, - "branches": { - "total": 12, - "covered": 11, - "skipped": 0, - "pct": 91.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/call_outs/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/header.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/header/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/scripted_fields_table/components/table/table.js": { - "lines": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/source_filters_table.js": { - "lines": { - "total": 51, - "covered": 50, - "skipped": 0, - "pct": 98.04 - }, - "functions": { - "total": 17, - "covered": 17, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 52, - "covered": 51, - "skipped": 0, - "pct": 98.08 - }, - "branches": { - "total": 14, - "covered": 9, - "skipped": 0, - "pct": 64.29 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/add_filter.js": { - "lines": { - "total": 8, - "covered": 7, - "skipped": 0, - "pct": 87.5 - }, - "functions": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - }, - "statements": { - "total": 8, - "covered": 7, - "skipped": 0, - "pct": 87.5 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/add_filter/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/header.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/header/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/source_filters_table/components/table/table.js": { - "lines": { - "total": 34, - "covered": 30, - "skipped": 0, - "pct": 88.24 - }, - "functions": { - "total": 15, - "covered": 13, - "skipped": 0, - "pct": 86.67 - }, - "statements": { - "total": 34, - "covered": 30, - "skipped": 0, - "pct": 88.24 - }, - "branches": { - "total": 12, - "covered": 10, - "skipped": 0, - "pct": 83.33 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index_pattern_table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/_objects.js": { - "lines": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.js": { - "lines": { - "total": 107, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 111, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 44, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/breadcrumbs.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/index.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/objects_table.js": { - "lines": { - "total": 130, - "covered": 108, - "skipped": 0, - "pct": 83.08 - }, - "functions": { - "total": 46, - "covered": 35, - "skipped": 0, - "pct": 76.09 - }, - "statements": { - "total": 135, - "covered": 112, - "skipped": 0, - "pct": 82.96 - }, - "branches": { - "total": 48, - "covered": 34, - "skipped": 0, - "pct": 70.83 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/flyout.js": { - "lines": { - "total": 146, - "covered": 119, - "skipped": 0, - "pct": 81.51 - }, - "functions": { - "total": 43, - "covered": 31, - "skipped": 0, - "pct": 72.09 - }, - "statements": { - "total": 148, - "covered": 120, - "skipped": 0, - "pct": 81.08 - }, - "branches": { - "total": 77, - "covered": 66, - "skipped": 0, - "pct": 85.71 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/header/header.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/header/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/relationships.js": { - "lines": { - "total": 40, - "covered": 25, - "skipped": 0, - "pct": 62.5 - }, - "functions": { - "total": 13, - "covered": 7, - "skipped": 0, - "pct": 53.85 - }, - "statements": { - "total": 40, - "covered": 25, - "skipped": 0, - "pct": 62.5 - }, - "branches": { - "total": 28, - "covered": 8, - "skipped": 0, - "pct": 28.57 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/table.js": { - "lines": { - "total": 38, - "covered": 23, - "skipped": 0, - "pct": 60.53 - }, - "functions": { - "total": 17, - "covered": 6, - "skipped": 0, - "pct": 35.29 - }, - "statements": { - "total": 40, - "covered": 23, - "skipped": 0, - "pct": 57.5 - }, - "branches": { - "total": 20, - "covered": 13, - "skipped": 0, - "pct": 65 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/fetch_export_by_type_and_search.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/fetch_export_objects.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/find_objects.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/get_default_title.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/get_relationships.js": { - "lines": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 7, - "covered": 5, - "skipped": 0, - "pct": 71.43 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/get_saved_object_counts.js": { - "lines": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/get_saved_object_label.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/import_file.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/import_legacy_file.js": { - "lines": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/in_app_url.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/is_same_query.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/log_legacy_import.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/parse_query.js": { - "lines": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 6, - "covered": 5, - "skipped": 0, - "pct": 83.33 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/resolve_import_errors.js": { - "lines": { - "total": 59, - "covered": 59, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 13, - "covered": 13, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 62, - "covered": 62, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 38, - "covered": 36, - "skipped": 0, - "pct": 94.74 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/resolve_saved_objects.js": { - "lines": { - "total": 110, - "covered": 69, - "skipped": 0, - "pct": 62.73 - }, - "functions": { - "total": 23, - "covered": 20, - "skipped": 0, - "pct": 86.96 - }, - "statements": { - "total": 114, - "covered": 73, - "skipped": 0, - "pct": 64.04 - }, - "branches": { - "total": 57, - "covered": 29, - "skipped": 0, - "pct": 50.88 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js": { - "lines": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 37, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js": { - "lines": { - "total": 212, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 54, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 216, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 74, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js": { - "lines": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/help_menu/help_menu_util.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/listing/visualize_listing.js": { - "lines": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/public/visualize/np_ready/listing/visualize_listing_table.js": { - "lines": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/lib/export/export_dashboards.js": { - "lines": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/lib/import/import_dashboards.js": { - "lines": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/lib/management/saved_objects/inject_meta_attributes.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/lib/management/saved_objects/relationships.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/routes/api/export/index.js": { - "lines": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/routes/api/import/index.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/routes/api/management/index.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/find.js": { - "lines": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/relationships.js": { - "lines": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/scroll.js": { - "lines": { - "total": 26, - "covered": 8, - "skipped": 0, - "pct": 30.77 - }, - "functions": { - "total": 7, - "covered": 3, - "skipped": 0, - "pct": 42.86 - }, - "statements": { - "total": 26, - "covered": 8, - "skipped": 0, - "pct": 30.77 - }, - "branches": { - "total": 12, - "covered": 3, - "skipped": 0, - "pct": 25 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/region_map/public/choropleth_layer.js": { - "lines": { - "total": 206, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 47, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 211, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 90, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/region_map/public/region_map_fn.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/region_map/public/region_map_type.js": { - "lines": { - "total": 28, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/region_map/public/region_map_visualization.js": { - "lines": { - "total": 59, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 60, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 48, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/region_map/public/tooltip_formatter.js": { - "lines": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/index.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/status_page.js": { - "lines": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/components/metric_tiles.js": { - "lines": { - "total": 10, - "covered": 8, - "skipped": 0, - "pct": 80 - }, - "functions": { - "total": 5, - "covered": 3, - "skipped": 0, - "pct": 60 - }, - "statements": { - "total": 10, - "covered": 8, - "skipped": 0, - "pct": 80 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/components/render.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/components/server_status.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/components/status_app.js": { - "lines": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/components/status_table.js": { - "lines": { - "total": 7, - "covered": 4, - "skipped": 0, - "pct": 57.14 - }, - "functions": { - "total": 4, - "covered": 1, - "skipped": 0, - "pct": 25 - }, - "statements": { - "total": 7, - "covered": 4, - "skipped": 0, - "pct": 57.14 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/lib/format_number.js": { - "lines": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/lib/load_status.js": { - "lines": { - "total": 19, - "covered": 9, - "skipped": 0, - "pct": 47.37 - }, - "functions": { - "total": 4, - "covered": 3, - "skipped": 0, - "pct": 75 - }, - "statements": { - "total": 19, - "covered": 9, - "skipped": 0, - "pct": 47.37 - }, - "branches": { - "total": 7, - "covered": 3, - "skipped": 0, - "pct": 42.86 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/lib/load_status.test.mocks.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/status_page/public/lib/prop_types.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/testbed/index.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/testbed/public/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/testbed/public/testbed.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tests_bundle/find_source_files.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tests_bundle/index.js": { - "lines": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 36, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tests_bundle/tests_entry_template.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tests_bundle/webpackShims/angular-mocks.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js": { - "lines": { - "total": 102, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 103, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 38, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/css_filters.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/geohash_layer.js": { - "lines": { - "total": 55, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 57, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/tile_map_fn.js": { - "lines": { - "total": 7, - "covered": 6, - "skipped": 0, - "pct": 85.71 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 8, - "covered": 7, - "skipped": 0, - "pct": 87.5 - }, - "branches": { - "total": 4, - "covered": 2, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/tile_map_type.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/tile_map_visualization.js": { - "lines": { - "total": 93, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 94, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 52, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/editors/_tooltip_formatter.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/markers/geohash_grid.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/markers/heatmap.js": { - "lines": { - "total": 62, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 63, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 28, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/markers/scaled_circles.js": { - "lines": { - "total": 80, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 24, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 80, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/tile_map/public/markers/shaded_circles.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/app.js": { - "lines": { - "total": 151, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 54, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 159, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/breadcrumbs.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/components/timelionhelp_tabs.js": { - "lines": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/components/timelionhelp_tabs_directive.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/fixed_element.js": { - "lines": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js": { - "lines": { - "total": 120, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 134, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 67, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/saved_object_save_as_checkbox.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_expression_input.js": { - "lines": { - "total": 95, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 95, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 36, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_expression_input_helpers.js": { - "lines": { - "total": 88, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 92, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 49, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_grid.js": { - "lines": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_load_sheet.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_options_sheet.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_save_sheet.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/cells/cells.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/chart/chart.js": { - "lines": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/fullscreen/fullscreen.js": { - "lines": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_expression_suggestions/timelion_expression_suggestions.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_help/timelion_help.js": { - "lines": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/directives/timelion_interval/timelion_interval.js": { - "lines": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/timelion/public/lib/observe_resize.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.js": { - "lines": { - "total": 18, - "covered": 18, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 19, - "covered": 18, - "skipped": 0, - "pct": 94.74 - }, - "branches": { - "total": 8, - "covered": 6, - "skipped": 0, - "pct": 75 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table.js": { - "lines": { - "total": 104, - "covered": 1, - "skipped": 0, - "pct": 0.96 - }, - "functions": { - "total": 22, - "covered": 1, - "skipped": 0, - "pct": 4.55 - }, - "statements": { - "total": 113, - "covered": 1, - "skipped": 0, - "pct": 0.88 - }, - "branches": { - "total": 61, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_table/public/agg_table/agg_table_group.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_table/public/paginated_table/paginated_table.js": { - "lines": { - "total": 32, - "covered": 27, - "skipped": 0, - "pct": 84.38 - }, - "functions": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 35, - "covered": 29, - "skipped": 0, - "pct": 82.86 - }, - "branches": { - "total": 27, - "covered": 18, - "skipped": 0, - "pct": 66.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_table/public/paginated_table/rows.js": { - "lines": { - "total": 47, - "covered": 21, - "skipped": 0, - "pct": 44.68 - }, - "functions": { - "total": 12, - "covered": 7, - "skipped": 0, - "pct": 58.33 - }, - "statements": { - "total": 48, - "covered": 22, - "skipped": 0, - "pct": 45.83 - }, - "branches": { - "total": 28, - "covered": 12, - "skipped": 0, - "pct": 42.86 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_tagcloud/public/components/feedback_message.js": { - "lines": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_tagcloud/public/components/label.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud.js": { - "lines": { - "total": 200, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 53, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 208, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 68, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js": { - "lines": { - "total": 64, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 65, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/flot.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/_generated_/chain.js": { - "lines": { - "total": 1070, - "covered": 612, - "skipped": 0, - "pct": 57.2 - }, - "functions": { - "total": 72, - "covered": 46, - "skipped": 0, - "pct": 63.89 - }, - "statements": { - "total": 1136, - "covered": 623, - "skipped": 0, - "pct": 54.84 - }, - "branches": { - "total": 559, - "covered": 237, - "skipped": 0, - "pct": 42.4 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.axislabels.js": { - "lines": { - "total": 238, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 238, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 123, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.crosshair.js": { - "lines": { - "total": 63, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 63, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.js": { - "lines": { - "total": 1526, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 123, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1653, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 1142, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.selection.js": { - "lines": { - "total": 138, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 145, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 83, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.stack.js": { - "lines": { - "total": 85, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 87, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 60, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.symbol.js": { - "lines": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timelion/public/webpackShims/jquery.flot.time.js": { - "lines": { - "total": 189, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 208, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 155, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/editor_controller.js": { - "lines": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/request_handler.js": { - "lines": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/add_delete_buttons.js": { - "lines": { - "total": 28, - "covered": 28, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 28, - "covered": 28, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 14, - "covered": 12, - "skipped": 0, - "pct": 85.71 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/annotations_editor.js": { - "lines": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/color_picker.js": { - "lines": { - "total": 20, - "covered": 16, - "skipped": 0, - "pct": 80 - }, - "functions": { - "total": 7, - "covered": 6, - "skipped": 0, - "pct": 85.71 - }, - "statements": { - "total": 21, - "covered": 16, - "skipped": 0, - "pct": 76.19 - }, - "branches": { - "total": 10, - "covered": 8, - "skipped": 0, - "pct": 80 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/color_rules.js": { - "lines": { - "total": 32, - "covered": 24, - "skipped": 0, - "pct": 75 - }, - "functions": { - "total": 7, - "covered": 5, - "skipped": 0, - "pct": 71.43 - }, - "statements": { - "total": 35, - "covered": 25, - "skipped": 0, - "pct": 71.43 - }, - "branches": { - "total": 11, - "covered": 5, - "skipped": 0, - "pct": 45.45 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/custom_color_picker.js": { - "lines": { - "total": 15, - "covered": 11, - "skipped": 0, - "pct": 73.33 - }, - "functions": { - "total": 5, - "covered": 3, - "skipped": 0, - "pct": 60 - }, - "statements": { - "total": 15, - "covered": 11, - "skipped": 0, - "pct": 73.33 - }, - "branches": { - "total": 12, - "covered": 4, - "skipped": 0, - "pct": 33.33 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/data_format_picker.js": { - "lines": { - "total": 47, - "covered": 4, - "skipped": 0, - "pct": 8.51 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 49, - "covered": 4, - "skipped": 0, - "pct": 8.16 - }, - "branches": { - "total": 42, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/error.js": { - "lines": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/index_pattern.js": { - "lines": { - "total": 30, - "covered": 7, - "skipped": 0, - "pct": 23.33 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 30, - "covered": 7, - "skipped": 0, - "pct": 23.33 - }, - "branches": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/markdown_editor.js": { - "lines": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/no_data.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config.js": { - "lines": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/query_bar_wrapper.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/series.js": { - "lines": { - "total": 22, - "covered": 3, - "skipped": 0, - "pct": 13.64 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 22, - "covered": 3, - "skipped": 0, - "pct": 13.64 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/series_config.js": { - "lines": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/series_drag_handler.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/series_editor.js": { - "lines": { - "total": 28, - "covered": 3, - "skipped": 0, - "pct": 10.71 - }, - "functions": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 31, - "covered": 3, - "skipped": 0, - "pct": 9.68 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/split.js": { - "lines": { - "total": 17, - "covered": 2, - "skipped": 0, - "pct": 11.76 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 17, - "covered": 2, - "skipped": 0, - "pct": 11.76 - }, - "branches": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js": { - "lines": { - "total": 53, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 53, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor_visualization.js": { - "lines": { - "total": 57, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 58, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 39, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_picker.js": { - "lines": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_with_splits.js": { - "lines": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/visualization.js": { - "lines": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/yes_no.js": { - "lines": { - "total": 11, - "covered": 11, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 11, - "covered": 11, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/agg.js": { - "lines": { - "total": 9, - "covered": 1, - "skipped": 0, - "pct": 11.11 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 1, - "skipped": 0, - "pct": 11.11 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/agg_row.js": { - "lines": { - "total": 8, - "covered": 1, - "skipped": 0, - "pct": 12.5 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 1, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/agg_select.js": { - "lines": { - "total": 24, - "covered": 7, - "skipped": 0, - "pct": 29.17 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 30, - "covered": 7, - "skipped": 0, - "pct": 23.33 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/aggs.js": { - "lines": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/calculation.js": { - "lines": { - "total": 11, - "covered": 2, - "skipped": 0, - "pct": 18.18 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 2, - "skipped": 0, - "pct": 16.67 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/cumulative_sum.js": { - "lines": { - "total": 6, - "covered": 1, - "skipped": 0, - "pct": 16.67 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 1, - "skipped": 0, - "pct": 16.67 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/derivative.js": { - "lines": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/field_select.js": { - "lines": { - "total": 20, - "covered": 4, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 20, - "covered": 4, - "skipped": 0, - "pct": 20 - }, - "branches": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/filter_ratio.js": { - "lines": { - "total": 12, - "covered": 2, - "skipped": 0, - "pct": 16.67 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 2, - "skipped": 0, - "pct": 16.67 - }, - "branches": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/math.js": { - "lines": { - "total": 11, - "covered": 2, - "skipped": 0, - "pct": 18.18 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 2, - "skipped": 0, - "pct": 16.67 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/metric_select.js": { - "lines": { - "total": 35, - "covered": 3, - "skipped": 0, - "pct": 8.57 - }, - "functions": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 36, - "covered": 3, - "skipped": 0, - "pct": 8.33 - }, - "branches": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/moving_average.js": { - "lines": { - "total": 17, - "covered": 4, - "skipped": 0, - "pct": 23.53 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 4, - "skipped": 0, - "pct": 22.22 - }, - "branches": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile.js": { - "lines": { - "total": 12, - "covered": 3, - "skipped": 0, - "pct": 25 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 3, - "skipped": 0, - "pct": 23.08 - }, - "branches": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_ui.js": { - "lines": { - "total": 33, - "covered": 4, - "skipped": 0, - "pct": 12.12 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 4, - "skipped": 0, - "pct": 11.76 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/positive_only.js": { - "lines": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/serial_diff.js": { - "lines": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/series_agg.js": { - "lines": { - "total": 12, - "covered": 2, - "skipped": 0, - "pct": 16.67 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 2, - "skipped": 0, - "pct": 16.67 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/static.js": { - "lines": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_agg.js": { - "lines": { - "total": 8, - "covered": 1, - "skipped": 0, - "pct": 12.5 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 1, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_deviation.js": { - "lines": { - "total": 18, - "covered": 4, - "skipped": 0, - "pct": 22.22 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 4, - "skipped": 0, - "pct": 22.22 - }, - "branches": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/std_sibling.js": { - "lines": { - "total": 18, - "covered": 3, - "skipped": 0, - "pct": 16.67 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 3, - "skipped": 0, - "pct": 16.67 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/temporary_unsupported_agg.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/top_hit.js": { - "lines": { - "total": 29, - "covered": 6, - "skipped": 0, - "pct": 20.69 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 31, - "covered": 6, - "skipped": 0, - "pct": 19.35 - }, - "branches": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/unsupported_agg.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/vars.js": { - "lines": { - "total": 17, - "covered": 3, - "skipped": 0, - "pct": 17.65 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 19, - "covered": 3, - "skipped": 0, - "pct": 15.79 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/multi_value_row.js": { - "lines": { - "total": 8, - "covered": 3, - "skipped": 0, - "pct": 37.5 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 3, - "skipped": 0, - "pct": 37.5 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/percentile_rank.js": { - "lines": { - "total": 14, - "covered": 3, - "skipped": 0, - "pct": 21.43 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 14, - "covered": 3, - "skipped": 0, - "pct": 21.43 - }, - "branches": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/aggs/percentile_rank/percentile_rank_values.js": { - "lines": { - "total": 14, - "covered": 2, - "skipped": 0, - "pct": 14.29 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 2, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/icon_select/icon_select.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/agg_to_component.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/calculate_siblings.js": { - "lines": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/charts.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/collection_actions.js": { - "lines": { - "total": 23, - "covered": 22, - "skipped": 0, - "pct": 95.65 - }, - "functions": { - "total": 6, - "covered": 5, - "skipped": 0, - "pct": 83.33 - }, - "statements": { - "total": 27, - "covered": 24, - "skipped": 0, - "pct": 88.89 - }, - "branches": { - "total": 17, - "covered": 8, - "skipped": 0, - "pct": 47.06 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/convert_series_to_vars.js": { - "lines": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_change_handler.js": { - "lines": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 1, - "skipped": 0, - "pct": 25 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_number_handler.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 6, - "covered": 3, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_select_handler.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_text_handler.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 6, - "covered": 3, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/create_xaxis_formatter.js": { - "lines": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/detect_ie.js": { - "lines": { - "total": 12, - "covered": 8, - "skipped": 0, - "pct": 66.67 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 12, - "covered": 8, - "skipped": 0, - "pct": 66.67 - }, - "branches": { - "total": 6, - "covered": 3, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/durations.js": { - "lines": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_axis_label_string.js": { - "lines": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - }, - "branches": { - "total": 4, - "covered": 2, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_default_query_language.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_display_name.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/get_interval.js": { - "lines": { - "total": 27, - "covered": 13, - "skipped": 0, - "pct": 48.15 - }, - "functions": { - "total": 6, - "covered": 1, - "skipped": 0, - "pct": 16.67 - }, - "statements": { - "total": 31, - "covered": 14, - "skipped": 0, - "pct": 45.16 - }, - "branches": { - "total": 17, - "covered": 4, - "skipped": 0, - "pct": 23.53 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/new_metric_agg_fn.js": { - "lines": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/new_series_fn.js": { - "lines": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/re_id_series.js": { - "lines": { - "total": 16, - "covered": 16, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 9, - "covered": 9, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 20, - "covered": 20, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/reorder.js": { - "lines": { - "total": 5, - "covered": 1, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 5, - "covered": 1, - "skipped": 0, - "pct": 20 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/replace_vars.js": { - "lines": { - "total": 11, - "covered": 6, - "skipped": 0, - "pct": 54.55 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 11, - "covered": 6, - "skipped": 0, - "pct": 54.55 - }, - "branches": { - "total": 6, - "covered": 1, - "skipped": 0, - "pct": 16.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/series_change_handler.js": { - "lines": { - "total": 9, - "covered": 1, - "skipped": 0, - "pct": 11.11 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 1, - "skipped": 0, - "pct": 9.09 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/stacked.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/lib/tick_formatter.js": { - "lines": { - "total": 22, - "covered": 18, - "skipped": 0, - "pct": 81.82 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 23, - "covered": 19, - "skipped": 0, - "pct": 82.61 - }, - "branches": { - "total": 10, - "covered": 9, - "skipped": 0, - "pct": 90 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/gauge.js": { - "lines": { - "total": 30, - "covered": 25, - "skipped": 0, - "pct": 83.33 - }, - "functions": { - "total": 8, - "covered": 4, - "skipped": 0, - "pct": 50 - }, - "statements": { - "total": 33, - "covered": 28, - "skipped": 0, - "pct": 84.85 - }, - "branches": { - "total": 21, - "covered": 6, - "skipped": 0, - "pct": 28.57 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/markdown.js": { - "lines": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/metric.js": { - "lines": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/table.js": { - "lines": { - "total": 26, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 27, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/timeseries.js": { - "lines": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/panel_config/top_n.js": { - "lines": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/everything.js": { - "lines": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/filter.js": { - "lines": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/filter_items.js": { - "lines": { - "total": 25, - "covered": 2, - "skipped": 0, - "pct": 8 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 27, - "covered": 2, - "skipped": 0, - "pct": 7.41 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/filters.js": { - "lines": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/group_by_select.js": { - "lines": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 9, - "covered": 2, - "skipped": 0, - "pct": 22.22 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/terms.js": { - "lines": { - "total": 19, - "covered": 18, - "skipped": 0, - "pct": 94.74 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 20, - "covered": 19, - "skipped": 0, - "pct": 95 - }, - "branches": { - "total": 9, - "covered": 6, - "skipped": 0, - "pct": 66.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/splits/unsupported_split.js": { - "lines": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/svg/bomb_icon.js": { - "lines": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/svg/fire_icon.js": { - "lines": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/gauge/series.js": { - "lines": { - "total": 18, - "covered": 12, - "skipped": 0, - "pct": 66.67 - }, - "functions": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "statements": { - "total": 19, - "covered": 13, - "skipped": 0, - "pct": 68.42 - }, - "branches": { - "total": 6, - "covered": 2, - "skipped": 0, - "pct": 33.33 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/gauge/vis.js": { - "lines": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 39, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/markdown/series.js": { - "lines": { - "total": 17, - "covered": 2, - "skipped": 0, - "pct": 11.76 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 2, - "skipped": 0, - "pct": 11.11 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/markdown/vis.js": { - "lines": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/metric/series.js": { - "lines": { - "total": 19, - "covered": 12, - "skipped": 0, - "pct": 63.16 - }, - "functions": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "statements": { - "total": 20, - "covered": 13, - "skipped": 0, - "pct": 65 - }, - "branches": { - "total": 8, - "covered": 3, - "skipped": 0, - "pct": 37.5 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/metric/vis.js": { - "lines": { - "total": 28, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/config.js": { - "lines": { - "total": 16, - "covered": 2, - "skipped": 0, - "pct": 12.5 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 2, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/is_sortable.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/series.js": { - "lines": { - "total": 15, - "covered": 2, - "skipped": 0, - "pct": 13.33 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 16, - "covered": 2, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/table/vis.js": { - "lines": { - "total": 75, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 79, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 58, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/config.js": { - "lines": { - "total": 28, - "covered": 2, - "skipped": 0, - "pct": 7.14 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 28, - "covered": 2, - "skipped": 0, - "pct": 7.14 - }, - "branches": { - "total": 30, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/series.js": { - "lines": { - "total": 19, - "covered": 3, - "skipped": 0, - "pct": 15.79 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 20, - "covered": 3, - "skipped": 0, - "pct": 15 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/vis.js": { - "lines": { - "total": 80, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 84, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 48, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/top_n/series.js": { - "lines": { - "total": 16, - "covered": 2, - "skipped": 0, - "pct": 12.5 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 17, - "covered": 2, - "skipped": 0, - "pct": 11.76 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/top_n/vis.js": { - "lines": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 38, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/contexts/form_validation_context.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/contexts/vis_data_context.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/lib/check_ui_restrictions.js": { - "lines": { - "total": 13, - "covered": 5, - "skipped": 0, - "pct": 38.46 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 13, - "covered": 5, - "skipped": 0, - "pct": 38.46 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/lib/create_brush_handler.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/lib/fetch_fields.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/lib/set_is_reversed.js": { - "lines": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/lib/validate_interval.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/constants/chart.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/constants/icons.js": { - "lines": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/constants/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/active_cursor.js": { - "lines": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/calc_dimensions.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/calculate_coordinates.js": { - "lines": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/lib/get_value_by.js": { - "lines": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/annotation.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/gauge.js": { - "lines": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/gauge_vis.js": { - "lines": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/metric.js": { - "lines": { - "total": 41, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 46, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 40, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/top_n.js": { - "lines": { - "total": 48, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 16, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 49, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/index.js": { - "lines": { - "total": 33, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 37, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/area_decorator.js": { - "lines": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/decorators/bar_decorator.js": { - "lines": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/model/charts.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/series_styles.js": { - "lines": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 23, - "covered": 23, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/stack_format.js": { - "lines": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/vega_visualization.js": { - "lines": { - "total": 38, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 38, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/ems_file_parser.js": { - "lines": { - "total": 14, - "covered": 12, - "skipped": 0, - "pct": 85.71 - }, - "functions": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 16, - "covered": 13, - "skipped": 0, - "pct": 81.25 - }, - "branches": { - "total": 8, - "covered": 4, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/es_query_parser.js": { - "lines": { - "total": 142, - "covered": 115, - "skipped": 0, - "pct": 80.99 - }, - "functions": { - "total": 8, - "covered": 8, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 145, - "covered": 117, - "skipped": 0, - "pct": 80.69 - }, - "branches": { - "total": 104, - "covered": 75, - "skipped": 0, - "pct": 72.12 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/search_cache.js": { - "lines": { - "total": 11, - "covered": 11, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 11, - "covered": 11, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/time_cache.js": { - "lines": { - "total": 21, - "covered": 19, - "skipped": 0, - "pct": 90.48 - }, - "functions": { - "total": 5, - "covered": 3, - "skipped": 0, - "pct": 60 - }, - "statements": { - "total": 21, - "covered": 19, - "skipped": 0, - "pct": 90.48 - }, - "branches": { - "total": 12, - "covered": 11, - "skipped": 0, - "pct": 91.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/url_parser.js": { - "lines": { - "total": 9, - "covered": 1, - "skipped": 0, - "pct": 11.11 - }, - "functions": { - "total": 3, - "covered": 1, - "skipped": 0, - "pct": 33.33 - }, - "statements": { - "total": 9, - "covered": 1, - "skipped": 0, - "pct": 11.11 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/utils.js": { - "lines": { - "total": 11, - "covered": 2, - "skipped": 0, - "pct": 18.18 - }, - "functions": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - }, - "statements": { - "total": 11, - "covered": 2, - "skipped": 0, - "pct": 18.18 - }, - "branches": { - "total": 8, - "covered": 1, - "skipped": 0, - "pct": 12.5 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/data_model/vega_parser.js": { - "lines": { - "total": 209, - "covered": 154, - "skipped": 0, - "pct": 73.68 - }, - "functions": { - "total": 20, - "covered": 16, - "skipped": 0, - "pct": 80 - }, - "statements": { - "total": 214, - "covered": 156, - "skipped": 0, - "pct": 72.9 - }, - "branches": { - "total": 193, - "covered": 120, - "skipped": 0, - "pct": 62.18 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/vega_view/vega_base_view.js": { - "lines": { - "total": 145, - "covered": 7, - "skipped": 0, - "pct": 4.83 - }, - "functions": { - "total": 26, - "covered": 1, - "skipped": 0, - "pct": 3.85 - }, - "statements": { - "total": 150, - "covered": 7, - "skipped": 0, - "pct": 4.67 - }, - "branches": { - "total": 73, - "covered": 1, - "skipped": 0, - "pct": 1.37 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/vega_view/vega_map_layer.js": { - "lines": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/vega_view/vega_map_view.js": { - "lines": { - "total": 44, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 46, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/vega_view/vega_tooltip.js": { - "lines": { - "total": 24, - "covered": 1, - "skipped": 0, - "pct": 4.17 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 25, - "covered": 1, - "skipped": 0, - "pct": 4 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vega/public/vega_view/vega_view.js": { - "lines": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/response_handler.js": { - "lines": { - "total": 46, - "covered": 3, - "skipped": 0, - "pct": 6.52 - }, - "functions": { - "total": 7, - "covered": 1, - "skipped": 0, - "pct": 14.29 - }, - "statements": { - "total": 47, - "covered": 3, - "skipped": 0, - "pct": 6.38 - }, - "branches": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/vis.js": { - "lines": { - "total": 44, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 47, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 24, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/vislib.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/data_array.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/flatten_series.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/labels.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/truncate_labels.js": { - "lines": { - "total": 6, - "covered": 1, - "skipped": 0, - "pct": 16.67 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 8, - "covered": 1, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/uniq_labels.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/tooltip/_collect_branch.js": { - "lines": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/tooltip/_hierarchical_tooltip_formatter.js": { - "lines": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/tooltip/_pointseries_tooltip_formatter.js": { - "lines": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 28, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/tooltip/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/tooltip/position_tooltip.js": { - "lines": { - "total": 69, - "covered": 8, - "skipped": 0, - "pct": 11.59 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 75, - "covered": 8, - "skipped": 0, - "pct": 10.67 - }, - "branches": { - "total": 46, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/tooltip/tooltip.js": { - "lines": { - "total": 86, - "covered": 11, - "skipped": 0, - "pct": 12.79 - }, - "functions": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 88, - "covered": 11, - "skipped": 0, - "pct": 12.5 - }, - "branches": { - "total": 42, - "covered": 3, - "skipped": 0, - "pct": 7.14 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/flatten_data.js": { - "lines": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - }, - "branches": { - "total": 12, - "covered": 8, - "skipped": 0, - "pct": 66.67 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/inject_zeros.js": { - "lines": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/ordered_x_keys.js": { - "lines": { - "total": 26, - "covered": 11, - "skipped": 0, - "pct": 42.31 - }, - "functions": { - "total": 3, - "covered": 3, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 29, - "covered": 13, - "skipped": 0, - "pct": 44.83 - }, - "branches": { - "total": 19, - "covered": 11, - "skipped": 0, - "pct": 57.89 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/uniq_keys.js": { - "lines": { - "total": 23, - "covered": 20, - "skipped": 0, - "pct": 86.96 - }, - "functions": { - "total": 5, - "covered": 5, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 23, - "covered": 20, - "skipped": 0, - "pct": 86.96 - }, - "branches": { - "total": 12, - "covered": 6, - "skipped": 0, - "pct": 50 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/zero_fill_data_array.js": { - "lines": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 10, - "covered": 10, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/zero_filled_array.js": { - "lines": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 6, - "covered": 6, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_data_label.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_error_handler.js": { - "lines": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/alerts.js": { - "lines": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/chart_grid.js": { - "lines": { - "total": 39, - "covered": 1, - "skipped": 0, - "pct": 2.56 - }, - "functions": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 47, - "covered": 1, - "skipped": 0, - "pct": 2.13 - }, - "branches": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/chart_title.js": { - "lines": { - "total": 39, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 39, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/data.js": { - "lines": { - "total": 161, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 61, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 168, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 82, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/dispatch.js": { - "lines": { - "total": 141, - "covered": 26, - "skipped": 0, - "pct": 18.44 - }, - "functions": { - "total": 41, - "covered": 6, - "skipped": 0, - "pct": 14.63 - }, - "statements": { - "total": 149, - "covered": 28, - "skipped": 0, - "pct": 18.79 - }, - "branches": { - "total": 97, - "covered": 23, - "skipped": 0, - "pct": 23.71 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/handler.js": { - "lines": { - "total": 69, - "covered": 1, - "skipped": 0, - "pct": 1.45 - }, - "functions": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 71, - "covered": 1, - "skipped": 0, - "pct": 1.41 - }, - "branches": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/vis_config.js": { - "lines": { - "total": 11, - "covered": 1, - "skipped": 0, - "pct": 9.09 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 1, - "skipped": 0, - "pct": 9.09 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis.js": { - "lines": { - "total": 106, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 109, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 51, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_config.js": { - "lines": { - "total": 84, - "covered": 7, - "skipped": 0, - "pct": 8.33 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 89, - "covered": 7, - "skipped": 0, - "pct": 7.87 - }, - "branches": { - "total": 66, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_labels.js": { - "lines": { - "total": 72, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 17, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 77, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 36, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_scale.js": { - "lines": { - "total": 118, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 134, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 97, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_title.js": { - "lines": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 22, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/scale_modes.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/time_ticks.js": { - "lines": { - "total": 12, - "covered": 12, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 4, - "covered": 4, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 13, - "covered": 13, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 2, - "covered": 2, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/index.js": { - "lines": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/layout.js": { - "lines": { - "total": 54, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 9, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 54, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/layout_types.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/chart_split.js": { - "lines": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 20, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/chart_title_split.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/x_axis_split.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/y_axis_split.js": { - "lines": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 8, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/gauge_chart/chart_split.js": { - "lines": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/gauge_chart/chart_title_split.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/pie_chart/chart_split.js": { - "lines": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 5, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/pie_chart/chart_title_split.js": { - "lines": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 10, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 6, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/types/column_layout.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/types/gauge_layout.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/types/pie_layout.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 4, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/gauge.js": { - "lines": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/index.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/pie.js": { - "lines": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 1, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 3, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 2, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/point_series.js": { - "lines": { - "total": 70, - "covered": 57, - "skipped": 0, - "pct": 81.43 - }, - "functions": { - "total": 17, - "covered": 12, - "skipped": 0, - "pct": 70.59 - }, - "statements": { - "total": 73, - "covered": 58, - "skipped": 0, - "pct": 79.45 - }, - "branches": { - "total": 76, - "covered": 48, - "skipped": 0, - "pct": 63.16 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/_chart.js": { - "lines": { - "total": 29, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 32, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauge_chart.js": { - "lines": { - "total": 34, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 7, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 15, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.js": { - "lines": { - "total": 146, - "covered": 1, - "skipped": 0, - "pct": 0.68 - }, - "functions": { - "total": 31, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 153, - "covered": 1, - "skipped": 0, - "pct": 0.65 - }, - "branches": { - "total": 86, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series.js": { - "lines": { - "total": 103, - "covered": 2, - "skipped": 0, - "pct": 1.94 - }, - "functions": { - "total": 23, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 108, - "covered": 2, - "skipped": 0, - "pct": 1.85 - }, - "branches": { - "total": 63, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/time_marker.js": { - "lines": { - "total": 18, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 12, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 14, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/vis_types.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/gauge_types.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/meter.js": { - "lines": { - "total": 132, - "covered": 3, - "skipped": 0, - "pct": 2.27 - }, - "functions": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 135, - "covered": 3, - "skipped": 0, - "pct": 2.22 - }, - "branches": { - "total": 57, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/_point_series.js": { - "lines": { - "total": 55, - "covered": 1, - "skipped": 0, - "pct": 1.82 - }, - "functions": { - "total": 11, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 61, - "covered": 1, - "skipped": 0, - "pct": 1.64 - }, - "branches": { - "total": 43, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.js": { - "lines": { - "total": 94, - "covered": 1, - "skipped": 0, - "pct": 1.06 - }, - "functions": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 95, - "covered": 1, - "skipped": 0, - "pct": 1.05 - }, - "branches": { - "total": 38, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.js": { - "lines": { - "total": 133, - "covered": 1, - "skipped": 0, - "pct": 0.75 - }, - "functions": { - "total": 30, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 137, - "covered": 1, - "skipped": 0, - "pct": 0.73 - }, - "branches": { - "total": 107, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/heatmap_chart.js": { - "lines": { - "total": 147, - "covered": 1, - "skipped": 0, - "pct": 0.68 - }, - "functions": { - "total": 21, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 153, - "covered": 1, - "skipped": 0, - "pct": 0.65 - }, - "branches": { - "total": 80, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.js": { - "lines": { - "total": 77, - "covered": 1, - "skipped": 0, - "pct": 1.3 - }, - "functions": { - "total": 19, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 78, - "covered": 1, - "skipped": 0, - "pct": 1.28 - }, - "branches": { - "total": 51, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/series_types.js": { - "lines": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "functions": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "branches": { - "total": 0, - "covered": 0, - "skipped": 0, - "pct": 100 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_impl.js": { - "lines": { - "total": 58, - "covered": 26, - "skipped": 0, - "pct": 44.83 - }, - "functions": { - "total": 24, - "covered": 7, - "skipped": 0, - "pct": 29.17 - }, - "statements": { - "total": 59, - "covered": 26, - "skipped": 0, - "pct": 44.07 - }, - "branches": { - "total": 48, - "covered": 19, - "skipped": 0, - "pct": 39.58 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/expressions/vis.js": { - "lines": { - "total": 33, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "functions": { - "total": 13, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "statements": { - "total": 35, - "covered": 0, - "skipped": 0, - "pct": 0 - }, - "branches": { - "total": 25, - "covered": 0, - "skipped": 0, - "pct": 0 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/calculate_object_hash.js": { - "lines": { - "total": 28, - "covered": 24, - "skipped": 0, - "pct": 85.71 - }, - "functions": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 28, - "covered": 24, - "skipped": 0, - "pct": 85.71 - }, - "branches": { - "total": 16, - "covered": 12, - "skipped": 0, - "pct": 75 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/vis_update.js": { - "lines": { - "total": 10, - "covered": 2, - "skipped": 0, - "pct": 20 - }, - "functions": { - "total": 1, - "covered": 1, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 12, - "covered": 3, - "skipped": 0, - "pct": 25 - }, - "branches": { - "total": 28, - "covered": 2, - "skipped": 0, - "pct": 7.14 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/vis_update_state.js": { - "lines": { - "total": 46, - "covered": 42, - "skipped": 0, - "pct": 91.3 - }, - "functions": { - "total": 7, - "covered": 7, - "skipped": 0, - "pct": 100 - }, - "statements": { - "total": 47, - "covered": 42, - "skipped": 0, - "pct": 89.36 - }, - "branches": { - "total": 38, - "covered": 28, - "skipped": 0, - "pct": 73.68 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/base_vis_type.js": { - "lines": { - "total": 17, - "covered": 10, - "skipped": 0, - "pct": 58.82 - }, - "functions": { - "total": 3, - "covered": 2, - "skipped": 0, - "pct": 66.67 - }, - "statements": { - "total": 17, - "covered": 10, - "skipped": 0, - "pct": 58.82 - }, - "branches": { - "total": 17, - "covered": 9, - "skipped": 0, - "pct": 52.94 - } - }, - "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/react_vis_type.js": { - "lines": { - "total": 12, - "covered": 10, - "skipped": 0, - "pct": 83.33 - }, - "functions": { - "total": 5, - "covered": 4, - "skipped": 0, - "pct": 80 - }, - "statements": { - "total": 12, - "covered": 10, - "skipped": 0, - "pct": 83.33 - }, - "branches": { - "total": 2, - "covered": 1, - "skipped": 0, - "pct": 50 - } - } -} diff --git a/src/dev/code_coverage/ingest_coverage/transforms.js b/src/dev/code_coverage/ingest_coverage/transforms.js index 0f6b34a39c64a..d5a4d8933e36b 100644 --- a/src/dev/code_coverage/ingest_coverage/transforms.js +++ b/src/dev/code_coverage/ingest_coverage/transforms.js @@ -33,10 +33,7 @@ export const statsAndstaticSiteUrl = (...xs) => { }; }; -export const addJsonSummaryPath = jsonSummaryPath => obj => ({ - jsonSummaryPath: trimLeftFrom('target', jsonSummaryPath), - ...obj, -}); +export const addJsonSummaryPath = jsonSummaryPath => obj => ({ jsonSummaryPath, ...obj }); export const truncate = text => obj => { const { staticSiteUrl } = obj; From 4449ab45d52938a113da451561fac14eab57a696 Mon Sep 17 00:00:00 2001 From: Brandon Morelli Date: Tue, 19 May 2020 19:15:24 -0700 Subject: [PATCH 053/129] docs: update RUM documentation link (#67042) --- .../apm/server/tutorial/instructions/apm_agent_instructions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/apm/server/tutorial/instructions/apm_agent_instructions.ts b/x-pack/plugins/apm/server/tutorial/instructions/apm_agent_instructions.ts index 9695c331e0504..799c12517b7c0 100644 --- a/x-pack/plugins/apm/server/tutorial/instructions/apm_agent_instructions.ts +++ b/x-pack/plugins/apm/server/tutorial/instructions/apm_agent_instructions.ts @@ -507,7 +507,7 @@ var apm = initApm({curlyOpen} See the [integration documentation]({docLink}) for more information.', values: { docLink: - '{config.docs.base_url}guide/en/apm/agent/rum-js/{config.docs.version}/framework-integrations.html' + '{config.docs.base_url}guide/en/apm/agent/rum-js/current/framework-integrations.html' } } ) From 19c625b4305ea3089158469134e77b0d56214fcc Mon Sep 17 00:00:00 2001 From: patrykkopycinski Date: Wed, 20 May 2020 07:19:55 +0200 Subject: [PATCH 054/129] [SIEM] Refactor Timeline.timelineType draft to Timeline.status draft (#66864) --- .../siem/common/types/timeline/index.ts | 26 +++++++-- .../components/signals/actions.test.tsx | 3 +- .../siem/public/common/mock/global_state.ts | 3 +- .../public/common/mock/timeline_results.ts | 6 ++- .../siem/public/graphql/introspection.json | 30 ++++++++++- x-pack/plugins/siem/public/graphql/types.ts | 14 +++-- .../components/open_timeline/helpers.test.ts | 14 +++-- .../containers/all/index.gql_query.ts | 2 +- .../siem/public/timelines/containers/api.ts | 34 ++++++++---- .../timelines/store/timeline/defaults.ts | 5 +- .../timelines/store/timeline/epic.test.ts | 4 +- .../public/timelines/store/timeline/epic.ts | 17 +++--- .../public/timelines/store/timeline/model.ts | 14 +++-- .../timelines/store/timeline/reducer.test.ts | 10 +++- .../server/graphql/timeline/schema.gql.ts | 10 +++- x-pack/plugins/siem/server/graphql/types.ts | 21 ++++++-- .../convert_saved_object_to_savedtimeline.ts | 46 ++++++++++++++-- .../server/lib/timeline/default_timeline.ts | 5 +- .../lib/timeline/pick_saved_timeline.ts | 10 ++-- .../routes/__mocks__/import_timelines.ts | 5 +- .../routes/__mocks__/request_responses.ts | 15 ++++-- .../clean_draft_timelines_route.test.ts | 5 +- .../routes/clean_draft_timelines_route.ts | 8 ++- .../routes/get_draft_timelines_route.test.ts | 11 +++- .../routes/get_draft_timelines_route.ts | 8 ++- .../routes/import_timelines_route.test.ts | 6 +-- .../timeline/routes/import_timelines_route.ts | 10 ++-- .../schemas/clean_draft_timelines_schema.ts | 12 +++++ .../schemas/get_draft_timelines_schema.ts | 12 +++++ .../timeline/routes/utils/export_timelines.ts | 8 ++- .../siem/server/lib/timeline/saved_object.ts | 50 +++++++++++++----- .../lib/timeline/saved_object_mappings.ts | 3 ++ .../es_archives/timeline/data.json.gz | Bin 1827 -> 1832 bytes .../es_archives/timeline/mappings.json | 3 ++ 34 files changed, 333 insertions(+), 97 deletions(-) create mode 100644 x-pack/plugins/siem/server/lib/timeline/routes/schemas/clean_draft_timelines_schema.ts create mode 100644 x-pack/plugins/siem/server/lib/timeline/routes/schemas/get_draft_timelines_schema.ts diff --git a/x-pack/plugins/siem/common/types/timeline/index.ts b/x-pack/plugins/siem/common/types/timeline/index.ts index e87986fd1bdf2..e67eb3182ffa9 100644 --- a/x-pack/plugins/siem/common/types/timeline/index.ts +++ b/x-pack/plugins/siem/common/types/timeline/index.ts @@ -130,23 +130,42 @@ const SavedSortRuntimeType = runtimeTypes.partial({ sortDirection: unionWithNullType(runtimeTypes.string), }); +/* + * Timeline Statuses + */ + +export enum TimelineStatus { + active = 'active', + draft = 'draft', +} + +export const TimelineStatusLiteralRt = runtimeTypes.union([ + runtimeTypes.literal(TimelineStatus.active), + runtimeTypes.literal(TimelineStatus.draft), +]); + +const TimelineStatusLiteralWithNullRt = unionWithNullType(TimelineStatusLiteralRt); + +export type TimelineStatusLiteral = runtimeTypes.TypeOf; +export type TimelineStatusLiteralWithNull = runtimeTypes.TypeOf< + typeof TimelineStatusLiteralWithNullRt +>; + /* * Timeline Types */ export enum TimelineType { default = 'default', - draft = 'draft', template = 'template', } export const TimelineTypeLiteralRt = runtimeTypes.union([ runtimeTypes.literal(TimelineType.template), - runtimeTypes.literal(TimelineType.draft), runtimeTypes.literal(TimelineType.default), ]); -const TimelineTypeLiteralWithNullRt = unionWithNullType(TimelineTypeLiteralRt); +export const TimelineTypeLiteralWithNullRt = unionWithNullType(TimelineTypeLiteralRt); export type TimelineTypeLiteral = runtimeTypes.TypeOf; export type TimelineTypeLiteralWithNull = runtimeTypes.TypeOf; @@ -167,6 +186,7 @@ export const SavedTimelineRuntimeType = runtimeTypes.partial({ dateRange: unionWithNullType(SavedDateRangePickerRuntimeType), savedQueryId: unionWithNullType(runtimeTypes.string), sort: unionWithNullType(SavedSortRuntimeType), + status: unionWithNullType(TimelineStatusLiteralRt), created: unionWithNullType(runtimeTypes.number), createdBy: unionWithNullType(runtimeTypes.string), updated: unionWithNullType(runtimeTypes.number), diff --git a/x-pack/plugins/siem/public/alerts/components/signals/actions.test.tsx b/x-pack/plugins/siem/public/alerts/components/signals/actions.test.tsx index d3be87ce7c39c..d7a8a55077340 100644 --- a/x-pack/plugins/siem/public/alerts/components/signals/actions.test.tsx +++ b/x-pack/plugins/siem/public/alerts/components/signals/actions.test.tsx @@ -15,7 +15,7 @@ import { } from '../../../common/mock/'; import { CreateTimeline, UpdateTimelineLoading } from './types'; import { Ecs } from '../../../graphql/types'; -import { TimelineType } from '../../../../common/types/timeline'; +import { TimelineType, TimelineStatus } from '../../../../common/types/timeline'; jest.mock('apollo-client'); @@ -215,6 +215,7 @@ describe('signals actions', () => { columnId: '@timestamp', sortDirection: 'desc', }, + status: TimelineStatus.draft, title: '', timelineType: TimelineType.default, templateTimelineId: null, diff --git a/x-pack/plugins/siem/public/common/mock/global_state.ts b/x-pack/plugins/siem/public/common/mock/global_state.ts index 63dd6dddfa9c5..da49ebe6552f3 100644 --- a/x-pack/plugins/siem/public/common/mock/global_state.ts +++ b/x-pack/plugins/siem/public/common/mock/global_state.ts @@ -24,7 +24,7 @@ import { DEFAULT_INTERVAL_VALUE, } from '../../../common/constants'; import { networkModel } from '../../network/store'; -import { TimelineType } from '../../../common/types/timeline'; +import { TimelineType, TimelineStatus } from '../../../common/types/timeline'; import { initialPolicyListState } from '../../endpoint_policy/store/policy_list/reducer'; import { initialAlertListState } from '../../endpoint_alerts/store/reducer'; import { initialPolicyDetailsState } from '../../endpoint_policy/store/policy_details/reducer'; @@ -231,6 +231,7 @@ export const mockGlobalState: State = { width: DEFAULT_TIMELINE_WIDTH, isSaving: false, version: null, + status: TimelineStatus.active, }, }, }, diff --git a/x-pack/plugins/siem/public/common/mock/timeline_results.ts b/x-pack/plugins/siem/public/common/mock/timeline_results.ts index 13ac356f67773..5c41812fdb95c 100644 --- a/x-pack/plugins/siem/public/common/mock/timeline_results.ts +++ b/x-pack/plugins/siem/public/common/mock/timeline_results.ts @@ -5,7 +5,7 @@ */ import { FilterStateStore } from '../../../../../../src/plugins/data/common/es_query/filters/meta_filter'; -import { TimelineType } from '../../../common/types/timeline'; +import { TimelineType, TimelineStatus } from '../../../common/types/timeline'; import { OpenTimelineResult } from '../../timelines/components/open_timeline/types'; import { GetAllTimeline, SortFieldTimeline, TimelineResult, Direction } from '../../graphql/types'; @@ -2142,6 +2142,7 @@ export const mockTimelineModel: TimelineModel = { columnId: '@timestamp', sortDirection: Direction.desc, }, + status: TimelineStatus.active, title: 'Test rule', timelineType: TimelineType.default, templateTimelineId: null, @@ -2242,8 +2243,9 @@ export const defaultTimelineProps: CreateTimelineProps = { showCheckboxes: false, showRowRenderers: true, sort: { columnId: '@timestamp', sortDirection: Direction.desc }, + status: TimelineStatus.draft, title: '', - timelineType: TimelineType.draft, + timelineType: TimelineType.default, templateTimelineVersion: null, templateTimelineId: null, version: null, diff --git a/x-pack/plugins/siem/public/graphql/introspection.json b/x-pack/plugins/siem/public/graphql/introspection.json index d6f34255bcc1c..3c8c7c21d72a0 100644 --- a/x-pack/plugins/siem/public/graphql/introspection.json +++ b/x-pack/plugins/siem/public/graphql/introspection.json @@ -253,7 +253,7 @@ { "name": "timelineType", "description": "", - "type": { "kind": "SCALAR", "name": "String", "ofType": null }, + "type": { "kind": "ENUM", "name": "TimelineType", "ofType": null }, "defaultValue": null } ], @@ -9726,6 +9726,14 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "status", + "description": "", + "args": [], + "type": { "kind": "ENUM", "name": "TimelineStatus", "ofType": null }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "title", "description": "", @@ -10353,6 +10361,19 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "ENUM", + "name": "TimelineStatus", + "description": "", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { "name": "active", "description": "", "isDeprecated": false, "deprecationReason": null }, + { "name": "draft", "description": "", "isDeprecated": false, "deprecationReason": null } + ], + "possibleTypes": null + }, { "kind": "SCALAR", "name": "Int", @@ -10377,7 +10398,6 @@ "isDeprecated": false, "deprecationReason": null }, - { "name": "draft", "description": "", "isDeprecated": false, "deprecationReason": null }, { "name": "template", "description": "", @@ -10962,6 +10982,12 @@ "description": "", "type": { "kind": "INPUT_OBJECT", "name": "SortTimelineInput", "ofType": null }, "defaultValue": null + }, + { + "name": "status", + "description": "", + "type": { "kind": "ENUM", "name": "TimelineStatus", "ofType": null }, + "defaultValue": null } ], "interfaces": null, diff --git a/x-pack/plugins/siem/public/graphql/types.ts b/x-pack/plugins/siem/public/graphql/types.ts index c3493c580fa22..eae3887ec0636 100644 --- a/x-pack/plugins/siem/public/graphql/types.ts +++ b/x-pack/plugins/siem/public/graphql/types.ts @@ -143,6 +143,8 @@ export interface TimelineInput { savedQueryId?: Maybe; sort?: Maybe; + + status?: Maybe; } export interface ColumnHeaderInput { @@ -340,9 +342,13 @@ export enum TlsFields { _id = '_id', } +export enum TimelineStatus { + active = 'active', + draft = 'draft', +} + export enum TimelineType { default = 'default', - draft = 'draft', template = 'template', } @@ -1954,6 +1960,8 @@ export interface TimelineResult { sort?: Maybe; + status?: Maybe; + title?: Maybe; templateTimelineId?: Maybe; @@ -2237,7 +2245,7 @@ export interface GetAllTimelineQueryArgs { onlyUserFavorite?: Maybe; - timelineType?: Maybe; + timelineType?: Maybe; } export interface AuthenticationsSourceArgs { timerange: TimerangeInput; @@ -4298,7 +4306,7 @@ export namespace GetAllTimeline { search?: Maybe; sort?: Maybe; onlyUserFavorite?: Maybe; - timelineType?: Maybe; + timelineType?: Maybe; }; export type Query = { diff --git a/x-pack/plugins/siem/public/timelines/components/open_timeline/helpers.test.ts b/x-pack/plugins/siem/public/timelines/components/open_timeline/helpers.test.ts index 350e1a3124497..a97aa29e58c28 100644 --- a/x-pack/plugins/siem/public/timelines/components/open_timeline/helpers.test.ts +++ b/x-pack/plugins/siem/public/timelines/components/open_timeline/helpers.test.ts @@ -36,7 +36,7 @@ import { KueryFilterQueryKind } from '../../../common/store/model'; import { Note } from '../../../common/lib/note'; import moment from 'moment'; import sinon from 'sinon'; -import { TimelineType } from '../../../../common/types/timeline'; +import { TimelineType, TimelineStatus } from '../../../../common/types/timeline'; jest.mock('../../../common/store/inputs/actions'); jest.mock('../../store/timeline/actions'); @@ -299,8 +299,9 @@ describe('helpers', () => { columnId: '@timestamp', sortDirection: 'desc', }, + status: TimelineStatus.draft, title: '', - timelineType: TimelineType.draft, + timelineType: TimelineType.default, templateTimelineId: null, templateTimelineVersion: null, version: '1', @@ -396,8 +397,9 @@ describe('helpers', () => { columnId: '@timestamp', sortDirection: 'desc', }, + status: TimelineStatus.draft, title: '', - timelineType: TimelineType.draft, + timelineType: TimelineType.default, templateTimelineId: null, templateTimelineVersion: null, version: '1', @@ -517,7 +519,7 @@ describe('helpers', () => { }, loadingEventIds: [], title: '', - timelineType: TimelineType.draft, + timelineType: TimelineType.default, templateTimelineId: null, templateTimelineVersion: null, noteIds: [], @@ -535,6 +537,7 @@ describe('helpers', () => { columnId: '@timestamp', sortDirection: 'desc', }, + status: TimelineStatus.draft, width: 1100, id: 'savedObject-1', }); @@ -685,7 +688,7 @@ describe('helpers', () => { }, loadingEventIds: [], title: '', - timelineType: TimelineType.draft, + timelineType: TimelineType.default, templateTimelineId: null, templateTimelineVersion: null, noteIds: [], @@ -703,6 +706,7 @@ describe('helpers', () => { columnId: '@timestamp', sortDirection: 'desc', }, + status: TimelineStatus.draft, width: 1100, id: 'savedObject-1', }); diff --git a/x-pack/plugins/siem/public/timelines/containers/all/index.gql_query.ts b/x-pack/plugins/siem/public/timelines/containers/all/index.gql_query.ts index 76aef8de4ad84..cdbf3e768581b 100644 --- a/x-pack/plugins/siem/public/timelines/containers/all/index.gql_query.ts +++ b/x-pack/plugins/siem/public/timelines/containers/all/index.gql_query.ts @@ -12,7 +12,7 @@ export const allTimelinesQuery = gql` $search: String $sort: SortTimeline $onlyUserFavorite: Boolean - $timelineType: String + $timelineType: TimelineType ) { getAllTimeline( pageInfo: $pageInfo diff --git a/x-pack/plugins/siem/public/timelines/containers/api.ts b/x-pack/plugins/siem/public/timelines/containers/api.ts index cf6229145623d..9f5e65e0fc5af 100644 --- a/x-pack/plugins/siem/public/timelines/containers/api.ts +++ b/x-pack/plugins/siem/public/timelines/containers/api.ts @@ -9,11 +9,11 @@ import { pipe } from 'fp-ts/lib/pipeable'; import { throwErrors } from '../../../../case/common/api'; import { - SavedTimeline, TimelineResponse, TimelineResponseType, - TimelineType, + TimelineStatus, } from '../../../common/types/timeline'; +import { TimelineInput, TimelineType } from '../../graphql/types'; import { TIMELINE_URL, TIMELINE_DRAFT_URL, @@ -31,7 +31,7 @@ import { } from '../../alerts/containers/detection_engine/rules'; interface RequestPostTimeline { - timeline: SavedTimeline; + timeline: TimelineInput; signal?: AbortSignal; } @@ -75,8 +75,8 @@ export const persistTimeline = async ({ timeline, version, }: RequestPersistTimeline): Promise => { - if (timelineId == null && timeline.timelineType === TimelineType.draft) { - const draftTimeline = await cleanDraftTimeline(); + if (timelineId == null && timeline.status === TimelineStatus.draft) { + const draftTimeline = await cleanDraftTimeline({ timelineType: timeline.timelineType! }); return patchTimeline({ timelineId: draftTimeline.data.persistTimeline.timeline.savedObjectId, timeline, @@ -133,14 +133,30 @@ export const exportSelectedTimeline: ExportSelectedData = async ({ return response.body!; }; -export const getDraftTimeline = async (): Promise => { - const response = await KibanaServices.get().http.get(TIMELINE_DRAFT_URL); +export const getDraftTimeline = async ({ + timelineType, +}: { + timelineType: TimelineType; +}): Promise => { + const response = await KibanaServices.get().http.get(TIMELINE_DRAFT_URL, { + query: { + timelineType, + }, + }); return decodeTimelineResponse(response); }; -export const cleanDraftTimeline = async (): Promise => { - const response = await KibanaServices.get().http.post(TIMELINE_DRAFT_URL); +export const cleanDraftTimeline = async ({ + timelineType, +}: { + timelineType: TimelineType; +}): Promise => { + const response = await KibanaServices.get().http.post(TIMELINE_DRAFT_URL, { + body: JSON.stringify({ + timelineType, + }), + }); return decodeTimelineResponse(response); }; diff --git a/x-pack/plugins/siem/public/timelines/store/timeline/defaults.ts b/x-pack/plugins/siem/public/timelines/store/timeline/defaults.ts index 649f1007f370b..5290178092f3e 100644 --- a/x-pack/plugins/siem/public/timelines/store/timeline/defaults.ts +++ b/x-pack/plugins/siem/public/timelines/store/timeline/defaults.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { TimelineType } from '../../../../common/types/timeline'; +import { TimelineType, TimelineStatus } from '../../../../common/types/timeline'; import { Direction } from '../../../graphql/types'; import { DEFAULT_TIMELINE_WIDTH } from '../../components/timeline/body/constants'; @@ -35,7 +35,7 @@ export const timelineDefaults: SubsetTimelineModel & Pick { showCheckboxes: false, showRowRenderers: true, sort: { columnId: '@timestamp', sortDirection: Direction.desc }, + status: TimelineStatus.active, width: 1100, version: 'WzM4LDFd', id: '11169110-fc22-11e9-8ca9-072f15ce2685', @@ -290,6 +291,7 @@ describe('Epic Timeline', () => { templateTimelineVersion: null, timelineType: TimelineType.default, title: 'saved', + status: TimelineStatus.active, }); }); }); diff --git a/x-pack/plugins/siem/public/timelines/store/timeline/epic.ts b/x-pack/plugins/siem/public/timelines/store/timeline/epic.ts index 30305f63dc31a..20c2d1861bd66 100644 --- a/x-pack/plugins/siem/public/timelines/store/timeline/epic.ts +++ b/x-pack/plugins/siem/public/timelines/store/timeline/epic.ts @@ -33,8 +33,13 @@ import { Filter, MatchAllFilter, } from '../../../../../../.../../../src/plugins/data/public'; -import { TimelineType } from '../../../../common/types/timeline'; -import { TimelineInput, ResponseTimeline, TimelineResult } from '../../../graphql/types'; +import { TimelineStatus } from '../../../../common/types/timeline'; +import { + TimelineType, + TimelineInput, + ResponseTimeline, + TimelineResult, +} from '../../../graphql/types'; import { AppApolloClient } from '../../../common/lib/lib'; import { addError } from '../../../common/store/app/actions'; import { NotesById } from '../../../common/store/app/model'; @@ -152,10 +157,8 @@ export const createTimelineEpic = (): Epic< return true; } if (action.type === createTimeline.type && isItAtimelineAction(timelineId)) { - if (timelineObj.timelineType !== 'draft') { - myEpicTimelineId.setTimelineVersion(null); - myEpicTimelineId.setTimelineId(null); - } + myEpicTimelineId.setTimelineVersion(null); + myEpicTimelineId.setTimelineId(null); } else if (action.type === addTimeline.type && isItAtimelineAction(timelineId)) { const addNewTimeline: TimelineModel = get('payload.timeline', action); myEpicTimelineId.setTimelineId(addNewTimeline.savedObjectId); @@ -243,6 +246,7 @@ export const createTimelineEpic = (): Epic< ...savedTimeline, savedObjectId: response.timeline.savedObjectId, version: response.timeline.version, + status: response.timeline.status ?? TimelineStatus.active, timelineType: response.timeline.timelineType ?? TimelineType.default, templateTimelineId: response.timeline.templateTimelineId ?? null, templateTimelineVersion: response.timeline.templateTimelineVersion ?? null, @@ -299,6 +303,7 @@ const timelineInput: TimelineInput = { dateRange: null, savedQueryId: null, sort: null, + status: null, }; export const convertTimelineAsInput = ( diff --git a/x-pack/plugins/siem/public/timelines/store/timeline/model.ts b/x-pack/plugins/siem/public/timelines/store/timeline/model.ts index 8f37636910e2e..df5e2a99e0248 100644 --- a/x-pack/plugins/siem/public/timelines/store/timeline/model.ts +++ b/x-pack/plugins/siem/public/timelines/store/timeline/model.ts @@ -6,11 +6,14 @@ import { Filter } from '../../../../../../../src/plugins/data/public'; -import { TimelineTypeLiteralWithNull } from '../../../../common/types/timeline'; - import { DataProvider } from '../../components/timeline/data_providers/data_provider'; import { Sort } from '../../components/timeline/body/sort'; -import { PinnedEvent, TimelineNonEcsData } from '../../../graphql/types'; +import { + PinnedEvent, + TimelineNonEcsData, + TimelineType, + TimelineStatus, +} from '../../../graphql/types'; import { KueryFilterQuery, SerializedFilterQuery } from '../../../common/store/model'; export const DEFAULT_PAGE_COUNT = 2; // Eui Pager will not render unless this is a minimum of 2 pages @@ -81,7 +84,7 @@ export interface TimelineModel { /** Title */ title: string; /** timelineType: default | template */ - timelineType: TimelineTypeLiteralWithNull; + timelineType: TimelineType; /** an unique id for template timeline */ templateTimelineId: string | null; /** null for default timeline, number for template timeline */ @@ -107,6 +110,8 @@ export interface TimelineModel { showRowRenderers: boolean; /** Specifies which column the timeline is sorted on, and the direction (ascending / descending) */ sort: Sort; + /** status: active | draft */ + status: TimelineStatus; /** Persists the UI state (width) of the timeline flyover */ width: number; /** timeline is saving */ @@ -153,6 +158,7 @@ export type SubsetTimelineModel = Readonly< | 'savedObjectId' | 'version' | 'timelineType' + | 'status' > >; diff --git a/x-pack/plugins/siem/public/timelines/store/timeline/reducer.test.ts b/x-pack/plugins/siem/public/timelines/store/timeline/reducer.test.ts index 65c78ca8efdb2..66cd73a35f946 100644 --- a/x-pack/plugins/siem/public/timelines/store/timeline/reducer.test.ts +++ b/x-pack/plugins/siem/public/timelines/store/timeline/reducer.test.ts @@ -6,7 +6,7 @@ import { cloneDeep, set } from 'lodash/fp'; -import { TimelineType } from '../../../../common/types/timeline'; +import { TimelineType, TimelineStatus } from '../../../../common/types/timeline'; import { IS_OPERATOR, @@ -100,6 +100,7 @@ const timelineByIdMock: TimelineById = { columnId: '@timestamp', sortDirection: Direction.desc, }, + status: TimelineStatus.active, width: DEFAULT_TIMELINE_WIDTH, isSaving: false, version: null, @@ -1131,6 +1132,7 @@ describe('Timeline', () => { columnId: '@timestamp', sortDirection: Direction.desc, }, + status: TimelineStatus.active, pinnedEventIds: {}, pinnedEventsSaveObject: {}, itemsPerPage: 25, @@ -1226,6 +1228,7 @@ describe('Timeline', () => { columnId: '@timestamp', sortDirection: Direction.desc, }, + status: TimelineStatus.active, pinnedEventIds: {}, pinnedEventsSaveObject: {}, itemsPerPage: 25, @@ -1427,6 +1430,7 @@ describe('Timeline', () => { columnId: '@timestamp', sortDirection: Direction.desc, }, + status: TimelineStatus.active, pinnedEventIds: {}, pinnedEventsSaveObject: {}, itemsPerPage: 25, @@ -1522,6 +1526,7 @@ describe('Timeline', () => { columnId: '@timestamp', sortDirection: Direction.desc, }, + status: TimelineStatus.active, pinnedEventIds: {}, pinnedEventsSaveObject: {}, itemsPerPage: 25, @@ -1712,6 +1717,7 @@ describe('Timeline', () => { columnId: '@timestamp', sortDirection: Direction.desc, }, + status: TimelineStatus.active, pinnedEventIds: {}, pinnedEventsSaveObject: {}, itemsPerPage: 50, @@ -1791,6 +1797,7 @@ describe('Timeline', () => { columnId: '@timestamp', sortDirection: Direction.desc, }, + status: TimelineStatus.active, pinnedEventIds: {}, pinnedEventsSaveObject: {}, itemsPerPage: 25, @@ -1894,6 +1901,7 @@ describe('Timeline', () => { columnId: '@timestamp', sortDirection: Direction.desc, }, + status: TimelineStatus.active, pinnedEventIds: {}, pinnedEventsSaveObject: {}, itemsPerPage: 25, diff --git a/x-pack/plugins/siem/server/graphql/timeline/schema.gql.ts b/x-pack/plugins/siem/server/graphql/timeline/schema.gql.ts index 2432af9a379a1..b9aa8534ab0e9 100644 --- a/x-pack/plugins/siem/server/graphql/timeline/schema.gql.ts +++ b/x-pack/plugins/siem/server/graphql/timeline/schema.gql.ts @@ -127,10 +127,14 @@ export const timelineSchema = gql` enum TimelineType { default - draft template } + enum TimelineStatus { + active + draft + } + input TimelineInput { columns: [ColumnHeaderInput!] dataProviders: [DataProviderInput!] @@ -146,6 +150,7 @@ export const timelineSchema = gql` dateRange: DateRangePickerInput savedQueryId: String sort: SortTimelineInput + status: TimelineStatus } input PageInfoTimeline { @@ -245,6 +250,7 @@ export const timelineSchema = gql` savedQueryId: String savedObjectId: String! sort: SortTimelineResult + status: TimelineStatus title: String templateTimelineId: String templateTimelineVersion: Int @@ -279,7 +285,7 @@ export const timelineSchema = gql` extend type Query { getOneTimeline(id: ID!): TimelineResult! - getAllTimeline(pageInfo: PageInfoTimeline, search: String, sort: SortTimeline, onlyUserFavorite: Boolean, timelineType: String): ResponseTimelines! + getAllTimeline(pageInfo: PageInfoTimeline, search: String, sort: SortTimeline, onlyUserFavorite: Boolean, timelineType: TimelineType): ResponseTimelines! } extend type Mutation { diff --git a/x-pack/plugins/siem/server/graphql/types.ts b/x-pack/plugins/siem/server/graphql/types.ts index 5313f4b9df268..4a063647a183d 100644 --- a/x-pack/plugins/siem/server/graphql/types.ts +++ b/x-pack/plugins/siem/server/graphql/types.ts @@ -145,6 +145,8 @@ export interface TimelineInput { savedQueryId?: Maybe; sort?: Maybe; + + status?: Maybe; } export interface ColumnHeaderInput { @@ -342,9 +344,13 @@ export enum TlsFields { _id = '_id', } +export enum TimelineStatus { + active = 'active', + draft = 'draft', +} + export enum TimelineType { default = 'default', - draft = 'draft', template = 'template', } @@ -1956,6 +1962,8 @@ export interface TimelineResult { sort?: Maybe; + status?: Maybe; + title?: Maybe; templateTimelineId?: Maybe; @@ -2239,7 +2247,7 @@ export interface GetAllTimelineQueryArgs { onlyUserFavorite?: Maybe; - timelineType?: Maybe; + timelineType?: Maybe; } export interface AuthenticationsSourceArgs { timerange: TimerangeInput; @@ -2697,7 +2705,7 @@ export namespace QueryResolvers { onlyUserFavorite?: Maybe; - timelineType?: Maybe; + timelineType?: Maybe; } } @@ -8043,6 +8051,8 @@ export namespace TimelineResultResolvers { sort?: SortResolver, TypeParent, TContext>; + status?: StatusResolver, TypeParent, TContext>; + title?: TitleResolver, TypeParent, TContext>; templateTimelineId?: TemplateTimelineIdResolver, TypeParent, TContext>; @@ -8153,6 +8163,11 @@ export namespace TimelineResultResolvers { Parent = TimelineResult, TContext = SiemContext > = Resolver; + export type StatusResolver< + R = Maybe, + Parent = TimelineResult, + TContext = SiemContext + > = Resolver; export type TitleResolver< R = Maybe, Parent = TimelineResult, diff --git a/x-pack/plugins/siem/server/lib/timeline/convert_saved_object_to_savedtimeline.ts b/x-pack/plugins/siem/server/lib/timeline/convert_saved_object_to_savedtimeline.ts index 00fb77bfb1647..3246de2190383 100644 --- a/x-pack/plugins/siem/server/lib/timeline/convert_saved_object_to_savedtimeline.ts +++ b/x-pack/plugins/siem/server/lib/timeline/convert_saved_object_to_savedtimeline.ts @@ -4,23 +4,63 @@ * you may not use this file except in compliance with the Elastic License. */ +import { intersection, type, partial, literal, union, string } from 'io-ts/lib/index'; import { failure } from 'io-ts/lib/PathReporter'; import { pipe } from 'fp-ts/lib/pipeable'; import { map, fold } from 'fp-ts/lib/Either'; import { identity } from 'fp-ts/lib/function'; import { - TimelineSavedObjectRuntimeType, + SavedTimelineRuntimeType, + TimelineTypeLiteralWithNullRt, TimelineSavedObject, TimelineType, + TimelineStatus, } from '../../../common/types/timeline'; +// TODO: Added to support legacy TimelineType.draft, can be removed in 7.10 +export const TimelineSavedObjectWithDraftRuntimeType = intersection([ + type({ + id: string, + version: string, + attributes: partial({ + ...SavedTimelineRuntimeType.props, + timelineType: union([TimelineTypeLiteralWithNullRt, literal('draft')]), + }), + }), + partial({ + savedObjectId: string, + }), +]); + +const getTimelineTypeAndStatus = ( + timelineType: TimelineType | 'draft' | null = TimelineType.default, + status: TimelineStatus | null = TimelineStatus.active +) => { + // TODO: Added to support legacy TimelineType.draft, can be removed in 7.10 + // @ts-ignore + if (timelineType === 'draft') { + return { + timelineType: TimelineType.default, + status: TimelineStatus.draft, + }; + } + + return { + timelineType, + status, + }; +}; + export const convertSavedObjectToSavedTimeline = (savedObject: unknown): TimelineSavedObject => { const timeline = pipe( - TimelineSavedObjectRuntimeType.decode(savedObject), + TimelineSavedObjectWithDraftRuntimeType.decode(savedObject), map(savedTimeline => { const attributes = { ...savedTimeline.attributes, - timelineType: savedTimeline.attributes.timelineType ?? TimelineType.default, + ...getTimelineTypeAndStatus( + savedTimeline.attributes.timelineType, + savedTimeline.attributes.status + ), }; return { savedObjectId: savedTimeline.id, diff --git a/x-pack/plugins/siem/server/lib/timeline/default_timeline.ts b/x-pack/plugins/siem/server/lib/timeline/default_timeline.ts index 710a43df1221d..b0ca3ba71f12b 100644 --- a/x-pack/plugins/siem/server/lib/timeline/default_timeline.ts +++ b/x-pack/plugins/siem/server/lib/timeline/default_timeline.ts @@ -6,7 +6,7 @@ import { Direction } from '../../graphql/types'; import { defaultHeaders } from './default_timeline_headers'; -import { SavedTimeline, TimelineType } from '../../../common/types/timeline'; +import { SavedTimeline, TimelineType, TimelineStatus } from '../../../common/types/timeline'; export const draftTimelineDefaults: SavedTimeline = { columns: defaultHeaders, @@ -15,7 +15,7 @@ export const draftTimelineDefaults: SavedTimeline = { eventType: 'all', filters: [], kqlMode: 'filter', - timelineType: TimelineType.draft, + timelineType: TimelineType.default, kqlQuery: { filterQuery: null, }, @@ -24,4 +24,5 @@ export const draftTimelineDefaults: SavedTimeline = { columnId: '@timestamp', sortDirection: Direction.desc, }, + status: TimelineStatus.draft, }; diff --git a/x-pack/plugins/siem/server/lib/timeline/pick_saved_timeline.ts b/x-pack/plugins/siem/server/lib/timeline/pick_saved_timeline.ts index 3b06adf1b751e..40c568ecda741 100644 --- a/x-pack/plugins/siem/server/lib/timeline/pick_saved_timeline.ts +++ b/x-pack/plugins/siem/server/lib/timeline/pick_saved_timeline.ts @@ -8,7 +8,7 @@ import uuid from 'uuid'; import { isEmpty } from 'lodash/fp'; import { AuthenticatedUser } from '../../../../security/common/model'; import { UNAUTHENTICATED_USER } from '../../../common/constants'; -import { SavedTimeline, TimelineType } from '../../../common/types/timeline'; +import { SavedTimeline, TimelineType, TimelineStatus } from '../../../common/types/timeline'; export const pickSavedTimeline = ( timelineId: string | null, @@ -39,10 +39,10 @@ export const pickSavedTimeline = ( savedTimeline.templateTimelineVersion = savedTimeline.templateTimelineVersion + 1; } } - } else if (savedTimeline.timelineType === TimelineType.draft) { - savedTimeline.timelineType = !isEmpty(savedTimeline.title) - ? TimelineType.default - : TimelineType.draft; + } else if (savedTimeline.status === TimelineStatus.draft) { + savedTimeline.status = !isEmpty(savedTimeline.title) + ? TimelineStatus.active + : TimelineStatus.draft; savedTimeline.templateTimelineId = null; savedTimeline.templateTimelineVersion = null; } else { diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/import_timelines.ts b/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/import_timelines.ts index e06e6c60ac65f..7180f06d853be 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/import_timelines.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/import_timelines.ts @@ -5,7 +5,7 @@ */ import { omit } from 'lodash/fp'; -import { TimelineType } from '../../../../../common/types/timeline'; +import { TimelineType, TimelineStatus } from '../../../../../common/types/timeline'; export const mockDuplicateIdErrors = []; @@ -176,7 +176,8 @@ export const mockGetDraftTimelineValue = { updatedBy: 'angela', noteIds: [], pinnedEventIds: ['k-gi8nABm-sIqJ_scOoS'], - timelineType: TimelineType.draft, + timelineType: TimelineType.default, + status: TimelineStatus.draft, }; export const mockParsedTimelineObject = omit( diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/request_responses.ts b/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/request_responses.ts index 9bcef1f5930d9..470ba1a853b58 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/request_responses.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/request_responses.ts @@ -12,7 +12,7 @@ import { } from '../../../../../common/constants'; import stream from 'stream'; import { requestMock } from '../../../detection_engine/routes/__mocks__'; -import { SavedTimeline, TimelineType } from '../../../../../common/types/timeline'; +import { SavedTimeline, TimelineType, TimelineStatus } from '../../../../../common/types/timeline'; import { updateTimelineSchema } from '../schemas/update_timelines_schema'; import { createTimelineSchema } from '../schemas/create_timelines_schema'; @@ -86,7 +86,8 @@ export const createDraftTimelineWithoutTimelineId = { timeline: inputTimeline, timelineId: null, version: null, - timelineType: TimelineType.draft, + timelineType: TimelineType.default, + status: TimelineStatus.draft, }; export const createTemplateTimelineWithoutTimelineId = { @@ -153,16 +154,22 @@ export const getImportTimelinesRequestEnableOverwrite = (filename?: string) => }, }); -export const getDraftTimelinesRequest = () => +export const getDraftTimelinesRequest = (timelineType: TimelineType) => requestMock.create({ method: 'get', path: TIMELINE_DRAFT_URL, + query: { + timelineType, + }, }); -export const cleanDraftTimelinesRequest = () => +export const cleanDraftTimelinesRequest = (timelineType: TimelineType) => requestMock.create({ method: 'post', path: TIMELINE_DRAFT_URL, + body: { + timelineType, + }, }); export const mockTimelinesSavedObjects = () => ({ diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/clean_draft_timelines_route.test.ts b/x-pack/plugins/siem/server/lib/timeline/routes/clean_draft_timelines_route.test.ts index 231efff35636c..9dc957604d4df 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/clean_draft_timelines_route.test.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/clean_draft_timelines_route.test.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { SecurityPluginSetup } from '../../../../../../plugins/security/server'; +import { TimelineType } from '../../../../common/types/timeline'; import { serverMock, @@ -79,7 +80,7 @@ describe('clean draft timelines', () => { timeline: [], }); - const response = await server.inject(cleanDraftTimelinesRequest(), context); + const response = await server.inject(cleanDraftTimelinesRequest(TimelineType.default), context); expect(mockPersistTimeline).toHaveBeenCalled(); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -98,7 +99,7 @@ describe('clean draft timelines', () => { mockResetTimeline.mockResolvedValue({}); mockGetTimeline.mockResolvedValue({ ...mockGetDraftTimelineValue }); - const response = await server.inject(cleanDraftTimelinesRequest(), context); + const response = await server.inject(cleanDraftTimelinesRequest(TimelineType.default), context); expect(mockPersistTimeline).not.toHaveBeenCalled(); expect(mockResetTimeline).toHaveBeenCalled(); expect(mockGetTimeline).toHaveBeenCalled(); diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/clean_draft_timelines_route.ts b/x-pack/plugins/siem/server/lib/timeline/routes/clean_draft_timelines_route.ts index 0890b65dec4e5..ac962a848368b 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/clean_draft_timelines_route.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/clean_draft_timelines_route.ts @@ -10,8 +10,10 @@ import { transformError, buildSiemResponse } from '../../detection_engine/routes import { TIMELINE_DRAFT_URL } from '../../../../common/constants'; import { buildFrameworkRequest } from './utils/common'; import { SetupPlugins } from '../../../plugin'; +import { buildRouteValidation } from '../../../utils/build_validation/route_validation'; import { getDraftTimeline, resetTimeline, getTimeline, persistTimeline } from '../saved_object'; import { draftTimelineDefaults } from '../default_timeline'; +import { cleanDraftTimelineSchema } from './schemas/clean_draft_timelines_schema'; export const cleanDraftTimelinesRoute = ( router: IRouter, @@ -21,7 +23,9 @@ export const cleanDraftTimelinesRoute = ( router.post( { path: TIMELINE_DRAFT_URL, - validate: {}, + validate: { + body: buildRouteValidation(cleanDraftTimelineSchema), + }, options: { tags: ['access:siem'], }, @@ -33,7 +37,7 @@ export const cleanDraftTimelinesRoute = ( try { const { timeline: [draftTimeline], - } = await getDraftTimeline(frameworkRequest); + } = await getDraftTimeline(frameworkRequest, request.body.timelineType); if (draftTimeline?.savedObjectId) { await resetTimeline(frameworkRequest, [draftTimeline.savedObjectId]); diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/get_draft_timelines_route.test.ts b/x-pack/plugins/siem/server/lib/timeline/routes/get_draft_timelines_route.test.ts index 76a64e9d225a1..e9bceb2c66806 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/get_draft_timelines_route.test.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/get_draft_timelines_route.test.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { SecurityPluginSetup } from '../../../../../../plugins/security/server'; +import { TimelineType } from '../../../../common/types/timeline'; import { serverMock, @@ -80,7 +81,10 @@ describe('get draft timelines', () => { timeline: [], }); - const response = await server.inject(getDraftTimelinesRequest(), context); + const response = await server.inject( + getDraftTimelinesRequest(TimelineType.default), + context + ); expect(mockPersistTimeline).toHaveBeenCalled(); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -97,7 +101,10 @@ describe('get draft timelines', () => { timeline: [mockGetDraftTimelineValue], }); - const response = await server.inject(getDraftTimelinesRequest(), context); + const response = await server.inject( + getDraftTimelinesRequest(TimelineType.default), + context + ); expect(mockPersistTimeline).not.toHaveBeenCalled(); expect(response.status).toEqual(200); expect(response.body).toEqual({ diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/get_draft_timelines_route.ts b/x-pack/plugins/siem/server/lib/timeline/routes/get_draft_timelines_route.ts index 2ff1ec519d2a6..137b2032b8e50 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/get_draft_timelines_route.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/get_draft_timelines_route.ts @@ -10,8 +10,10 @@ import { transformError, buildSiemResponse } from '../../detection_engine/routes import { TIMELINE_DRAFT_URL } from '../../../../common/constants'; import { buildFrameworkRequest } from './utils/common'; import { SetupPlugins } from '../../../plugin'; +import { buildRouteValidation } from '../../../utils/build_validation/route_validation'; import { getDraftTimeline, persistTimeline } from '../saved_object'; import { draftTimelineDefaults } from '../default_timeline'; +import { getDraftTimelineSchema } from './schemas/get_draft_timelines_schema'; export const getDraftTimelinesRoute = ( router: IRouter, @@ -21,7 +23,9 @@ export const getDraftTimelinesRoute = ( router.get( { path: TIMELINE_DRAFT_URL, - validate: {}, + validate: { + query: buildRouteValidation(getDraftTimelineSchema), + }, options: { tags: ['access:siem'], }, @@ -33,7 +37,7 @@ export const getDraftTimelinesRoute = ( try { const { timeline: [draftTimeline], - } = await getDraftTimeline(frameworkRequest); + } = await getDraftTimeline(frameworkRequest, request.query.timelineType); if (draftTimeline?.savedObjectId) { return response.ok({ diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.test.ts b/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.test.ts index 2f5200c87137d..48e22f6af2a7b 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.test.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.test.ts @@ -12,7 +12,7 @@ import { createMockConfig, } from '../../detection_engine/routes/__mocks__'; import { TIMELINE_EXPORT_URL } from '../../../../common/constants'; -import { TimelineType } from '../../../../common/types/timeline'; +import { TimelineStatus } from '../../../../common/types/timeline'; import { SecurityPluginSetup } from '../../../../../../plugins/security/server'; import { @@ -145,13 +145,13 @@ describe('import timelines', () => { test('should Create a new timeline savedObject with given draft timeline', async () => { mockGetTupleDuplicateErrorsAndUniqueTimeline.mockReturnValue([ mockDuplicateIdErrors, - [{ ...mockUniqueParsedObjects[0], timelineType: TimelineType.draft }], + [{ ...mockUniqueParsedObjects[0], status: TimelineStatus.draft }], ]); const mockRequest = getImportTimelinesRequest(); await server.inject(mockRequest, context); expect(mockPersistTimeline.mock.calls[0][3]).toEqual({ ...mockParsedTimelineObject, - timelineType: TimelineType.default, + status: TimelineStatus.active, }); }); diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.ts b/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.ts index bb63d1dce5554..dee8ed5078546 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.ts @@ -39,7 +39,7 @@ import { timelineSavedObjectOmittedFields, } from './utils/import_timelines'; import { createTimelines, getTimeline, getTemplateTimeline } from './utils/create_timelines'; -import { TimelineType } from '../../../../common/types/timeline'; +import { TimelineType, TimelineStatus } from '../../../../common/types/timeline'; import { checkIsFailureCases } from './utils/update_timelines'; const CHUNK_PARSED_OBJECT_SIZE = 10; @@ -154,10 +154,10 @@ export const importTimelinesRoute = ( frameworkRequest, { ...parsedTimelineObject, - timelineType: - parsedTimelineObject.timelineType === TimelineType.draft - ? TimelineType.default - : parsedTimelineObject.timelineType, + status: + parsedTimelineObject.status === TimelineStatus.draft + ? TimelineStatus.active + : parsedTimelineObject.status, }, null, // timelineSavedObjectId null, // timelineVersion diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/schemas/clean_draft_timelines_schema.ts b/x-pack/plugins/siem/server/lib/timeline/routes/schemas/clean_draft_timelines_schema.ts new file mode 100644 index 0000000000000..2f880ee530dd9 --- /dev/null +++ b/x-pack/plugins/siem/server/lib/timeline/routes/schemas/clean_draft_timelines_schema.ts @@ -0,0 +1,12 @@ +/* + * 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 * as rt from 'io-ts'; + +import { TimelineTypeLiteralRt } from '../../../../../common/types/timeline'; + +export const cleanDraftTimelineSchema = rt.type({ + timelineType: TimelineTypeLiteralRt, +}); diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/schemas/get_draft_timelines_schema.ts b/x-pack/plugins/siem/server/lib/timeline/routes/schemas/get_draft_timelines_schema.ts new file mode 100644 index 0000000000000..34cfb5e6e756b --- /dev/null +++ b/x-pack/plugins/siem/server/lib/timeline/routes/schemas/get_draft_timelines_schema.ts @@ -0,0 +1,12 @@ +/* + * 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 * as rt from 'io-ts'; + +import { TimelineTypeLiteralRt } from '../../../../../common/types/timeline'; + +export const getDraftTimelineSchema = rt.type({ + timelineType: TimelineTypeLiteralRt, +}); diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/utils/export_timelines.ts b/x-pack/plugins/siem/server/lib/timeline/routes/utils/export_timelines.ts index 1e64e38ea5b0a..908aeac6b33ca 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/utils/export_timelines.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/utils/export_timelines.ts @@ -16,7 +16,7 @@ import { ExportedNotes, TimelineSavedObject, ExportTimelineNotFoundError, - TimelineType, + TimelineStatus, } from '../../../../../common/types/timeline'; import { NoteSavedObject } from '../../../../../common/types/timeline/note'; import { PinnedEventSavedObject } from '../../../../../common/types/timeline/pinned_event'; @@ -180,10 +180,8 @@ const getTimelinesFromObjects = async ( ...acc, { ...myTimeline, - timelineType: - myTimeline.timelineType === TimelineType.draft - ? TimelineType.default - : myTimeline.timelineType, + status: + myTimeline.status === TimelineStatus.draft ? TimelineStatus.active : myTimeline.status, ...getGlobalEventNotesByTimelineId(timelineNotes), pinnedEventIds: getPinnedEventsIdsByTimelineId(timelinePinnedEventIds), }, diff --git a/x-pack/plugins/siem/server/lib/timeline/saved_object.ts b/x-pack/plugins/siem/server/lib/timeline/saved_object.ts index f95cd01b2b788..1a2a2a9c20a67 100644 --- a/x-pack/plugins/siem/server/lib/timeline/saved_object.ts +++ b/x-pack/plugins/siem/server/lib/timeline/saved_object.ts @@ -10,13 +10,19 @@ import { SavedObjectsFindOptions } from '../../../../../../src/core/server'; import { UNAUTHENTICATED_USER } from '../../../common/constants'; import { NoteSavedObject } from '../../../common/types/timeline/note'; import { PinnedEventSavedObject } from '../../../common/types/timeline/pinned_event'; -import { SavedTimeline, TimelineSavedObject, TimelineType } from '../../../common/types/timeline'; +import { + SavedTimeline, + TimelineSavedObject, + TimelineTypeLiteralWithNull, +} from '../../../common/types/timeline'; import { ResponseTimeline, PageInfoTimeline, SortTimeline, ResponseFavoriteTimeline, TimelineResult, + TimelineType, + TimelineStatus, Maybe, } from '../../graphql/types'; import { FrameworkRequest } from '../framework'; @@ -49,7 +55,7 @@ export interface Timeline { pageInfo: PageInfoTimeline | null, search: string | null, sort: SortTimeline | null, - timelineType: string | null + timelineType: TimelineTypeLiteralWithNull ) => Promise; persistFavorite: ( @@ -62,7 +68,7 @@ export interface Timeline { timelineId: string | null, version: string | null, timeline: SavedTimeline, - timelineType?: TimelineType | null + timelineType?: TimelineTypeLiteralWithNull ) => Promise; deleteTimeline: (request: FrameworkRequest, timelineIds: string[]) => Promise; @@ -98,13 +104,26 @@ export const getTimelineByTemplateTimelineId = async ( /** The filter here is able to handle the legacy data, * which has no timelineType exists in the savedObject */ -const getTimelineTypeFilter = (timelineType: string | null) => { - return timelineType === TimelineType.template - ? `siem-ui-timeline.attributes.timelineType: ${TimelineType.template}` /** Show only whose timelineType exists and equals to "template" */ - : /** Show me every timeline whose timelineType is not "template". - * which includes timelineType === 'default' and - * those timelineType doesn't exists */ - `not siem-ui-timeline.attributes.timelineType: ${TimelineType.template} and not siem-ui-timeline.attributes.timelineType: ${TimelineType.draft}`; +const getTimelineTypeFilter = ( + timelineType: TimelineTypeLiteralWithNull, + includeDraft: boolean +) => { + const typeFilter = + timelineType === TimelineType.template + ? `siem-ui-timeline.attributes.timelineType: ${TimelineType.template}` /** Show only whose timelineType exists and equals to "template" */ + : /** Show me every timeline whose timelineType is not "template". + * which includes timelineType === 'default' and + * those timelineType doesn't exists */ + `not siem-ui-timeline.attributes.timelineType: ${TimelineType.template}`; + + /** Show me every timeline whose status is not "draft". + * which includes status === 'active' and + * those status doesn't exists */ + const draftFilter = includeDraft + ? `siem-ui-timeline.attributes.status: ${TimelineStatus.draft}` + : `not siem-ui-timeline.attributes.status: ${TimelineStatus.draft}`; + + return `${typeFilter} and ${draftFilter}`; }; export const getAllTimeline = async ( @@ -113,7 +132,7 @@ export const getAllTimeline = async ( pageInfo: PageInfoTimeline | null, search: string | null, sort: SortTimeline | null, - timelineType: string | null + timelineType: TimelineTypeLiteralWithNull ): Promise => { const options: SavedObjectsFindOptions = { type: timelineSavedObjectType, @@ -123,18 +142,21 @@ export const getAllTimeline = async ( searchFields: onlyUserFavorite ? ['title', 'description', 'favorite.keySearch'] : ['title', 'description'], - filter: getTimelineTypeFilter(timelineType), + filter: getTimelineTypeFilter(timelineType, false), sortField: sort != null ? sort.sortField : undefined, sortOrder: sort != null ? sort.sortOrder : undefined, }; return getAllSavedTimeline(request, options); }; -export const getDraftTimeline = async (request: FrameworkRequest): Promise => { +export const getDraftTimeline = async ( + request: FrameworkRequest, + timelineType: TimelineTypeLiteralWithNull +): Promise => { const options: SavedObjectsFindOptions = { type: timelineSavedObjectType, perPage: 1, - filter: `siem-ui-timeline.attributes.timelineType: ${TimelineType.draft}`, + filter: getTimelineTypeFilter(timelineType, true), sortField: 'created', sortOrder: 'desc', }; diff --git a/x-pack/plugins/siem/server/lib/timeline/saved_object_mappings.ts b/x-pack/plugins/siem/server/lib/timeline/saved_object_mappings.ts index 4d9ae19bfd6a2..51bff033b8791 100644 --- a/x-pack/plugins/siem/server/lib/timeline/saved_object_mappings.ts +++ b/x-pack/plugins/siem/server/lib/timeline/saved_object_mappings.ts @@ -263,6 +263,9 @@ export const timelineSavedObjectMappings: SavedObjectsType['mappings'] = { }, }, }, + status: { + type: 'keyword', + }, created: { type: 'date', }, diff --git a/x-pack/test/siem_cypress/es_archives/timeline/data.json.gz b/x-pack/test/siem_cypress/es_archives/timeline/data.json.gz index cde2775bddb2402d97cdc4a051852393414cbadd..bc4079ad2a90bdc9a91790c8acd4c0a52b3fe169 100644 GIT binary patch literal 1832 zcmV+@2iN!?iwFP!000026YW}CZ`(E$e$TJa^wbWqs=F=iWm~$gL7TN(vUX@w2((1o zY$Q=5DKAdp|2|TZZQX1unw_;kiWZd)sdN2!&LQb9Cz2$yMFM44k^}6^r-CpCVJawJ z_zQnUff)61JV8^}R#ZhDfH0W>Et@SS!~wh&bCer21~Kr~BNV5^->{NaY)TYP8>c7? zeoG@x9hvsq%fGr1UEuI9-EP9TA?4=JDW@za{VGOUo9k(Vdp z-}2<-OLx<00(|HOa01eh^)Wg^Qvw*m@jFN;|F3F(#$Ir;74F^c=B>Ufu?isd2})Ql zL%y0JD)GN;2BkuMDf{X>x$I;_!8nA$3kX?ampZl3&{mYDx>*I1eX~{dWO@O)y4&fx$wPuTBSzd zwvCDeKGhO&S)L)oh`xh9!{jws@FlaBSe+G$!7J{|ofD3v?@5d1c{JW~UqTYo_lV7Y zh4=-6VX)Gn#5fDb6=oo88>Emi6i;bA4s?e9;o*6QXbM7fmt~dA1$^QJgcP>w#ZUy# zKq8iR&X#^bIc7`S}`>dfoa%+n!NzU^Mf?!lmxg1YoslACWeFCAtmabT) zH8M7T%yI@!qcJ3JCTCpqjR=IU*MdtKh>~_sJBn^PJtDi$($1mg3Rv0^Lp@PV$AQ*2 z6KYk_Mm*TN;;VKGucf<|tr$c7{|awifqvnQN>#4%)-P(&)*3g3F{8CIA^U&?h+B-< zqMmF^9%S&{4W@>wR^OojqcuO-7hPxXQLNIB5maBbwKVH1W@G^ehl;AX>UczI- z<1$A++$Lftvl2`X!ji8X8YzCtt)8;s0ZSOS8{gNTvl7%mM|0&YPvAd<+i02UKzF|6o1td@69QcZxdiU6N>Jj zhhlHMV40@6I_jA>>5PMzZnsS9ur*+?I0a}pEecyRlJ^;psn_O-b`h&+Wvjm}$#Z|R z7_vGrWjdgtE1a?Z#Bsc+B&Y#(VSc(sK3KYeYTH2-KnCj7I-qXCby? zgA@(K4k|=3bXCpPea*;ritvCt#jPi_H3h2M5g&(Xltt)c$FOB8SZ0LUTcX+|uHt|6|L#__~oA?LtwMtrfhgKWth7nWc1t z%&)Ku;6n3@3Rmdh;snNCO^bUK`<2u+-;yb7QmxSE2eZvz6796zbWKCCjL{Kq#JOjk zv7sOQoTJ~3_zXvI-;KCxIy-;xpmn?uuQ~VOFT@WJ-5Ro2p!P&w3mz8Q`h!DzV|;Gc zU~^;bUf??vhTxf{sM3=Q;G>vfI{QI7j~NUlPLSSQN`Fb3>S?BDKb3ys5ryyJ_!VN$ zEMuq`w)EuH%d3mmr&5S+p!6&BZ}3y;Y(_XjpN%*Q6~h?~70ouJOE3Wh6`vh)^YAU@ WnQchSD&x0^#D4*6-u9*NEC2w%W`M!~ literal 1827 zcmV+;2i*7{iwFP!000026YUz?Zre8WdHxDbPwfz^y4%uTwxw$uv{}0)Ylk+4KufgE zMiMoW%Hjn6_mPsE=w@3{?X&?BB#3o*bnZMC($@n?lG!4GvMb2}_T>WsxBy`)AlLkX zKcYaa`Z%7VnQJSmq7Ffr%z>6+3xqg;mjXvQM-vbO?`DPKl=!!#q!pPGgu^B&3WGn= zh(pJwJvz8u2>^pHFo^(j*_Gh%_vxWrEH77hGJ#V_VC+N6Q9c#W&o|2}{R-9@csUS% z%faBfy9H_xq7`sF@V%3C}BA( z`E-t`#DCcwN`)3u_STPb+2n|VNeF`%5U`X~n3dRZ#27@GxX%lNGz4B*HJ7Zn*^9s% zi@@7M#5t-u(i}&(%#o=&j`o$&bpuZm5xjv1m{`?ST^*|CP#v9Ws%tu~YALpuRf--Ax#3=|VY?X_l z2p)n&B!Qqcgf&%hM)t?v`M5P?x9^+^+dex7BuR+;%nDvg!3=tgfS3YbKtSl)Fqk@) zsSZcuNiftj2!_r`8}mf~V z(0VW)R~2o{eZI-fYBw)ix@*~rG19-Wm+Nx$^Kw)wh?S>)&WqNT!x@ZOHO-bYrw>Sg zxax>4>Z!P7nr3w=I;tvEunR-4h2_n<7Ssw&qpIcp%=(?q?+?~JRqJI+A<3m{DufA| zp?aWyr%JVZQdHSSJ($b3i>1FT9emv(~fP2)DSQ;82r=i5|Eut?&}DCZYJNj(KZNp?tJ}?L;WL zf*y*!$%18)>gu>>-lTIL#B{x8T8F`b!Qw!nVYDc0%}CxCJfU8jCE8i6yp`?#wj|H( z&0@&vfg#Uu1M~%4fF_U*CxF5RJjMb1LL1;@!RA?LR>35lELwokFelMI-T->uFS9d@ z&)Y&T66DN|?q5^-HWSyoQeWSJY-6E09a&^$p=H|K%E0c(phyQE?_BR}D62D%wOeSb z9%@G(3Bg33WSSxKiDBInpZ#g8YO`2o_^D zoT89Haq?5E_qhRnxg9Cj#mi3ka3*4++%J=CTPl2lg)_{f=pJ|#9oAks%`s(4Hc{@C zO&+rf+H)WTJlc3c6K2~xFEPV6F=16PrhiaEa<;N0M z7QZV~iq5>WmRohb66gPh$Goi*Z|10Sb@9&>lE#5aj@h;(UTOskF)tIsQ%9l8%~o)K zk{iwbIm%2}&>C!*3`B)R;s6~6D|zJWGkJn>cqY626P@EU4EX0y`~hAf%4ohY703Df z4+0?eOtOl`T8w|D2@q7WrJIE>RUEU#kH=+^TMaa7OY zwW*e{=ZHYR918N9D*_f~{yaJQ{aE4?5i7g2sKVv=baZFj#HenL_4kPNYS-;#(QqwC zF;x9N>%C<>*89hL|5)!I>-~eN_XJGYW2Jwr^jj+Z4hsCi;D^%1q^M)7Fw2ARJ8S?r z)BFy@6*9Oufw5PU;!bsb#r1}6NtGK=t+?lBw$1M+ZPeX#O+&Ga@g6VFxn-S+q3`_c zqu=HE97k~5<+*A)8^0oL-5Q}RO!hv@KMY#o&PKy#SDfL2S{&Eq<P)#>q@11Uu3P Date: Wed, 20 May 2020 09:28:01 +0200 Subject: [PATCH 055/129] [Discover] Improve and unskip a11y context view test (#66959) --- test/accessibility/apps/discover.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/test/accessibility/apps/discover.ts b/test/accessibility/apps/discover.ts index 0168626d4a1a9..a3ddcf8af666d 100644 --- a/test/accessibility/apps/discover.ts +++ b/test/accessibility/apps/discover.ts @@ -21,6 +21,7 @@ import { FtrProviderContext } from '../ftr_provider_context'; export default function({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects(['common', 'discover', 'header', 'share', 'timePicker']); + const retry = getService('retry'); const a11y = getService('a11y'); const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); @@ -33,8 +34,7 @@ export default function({ getService, getPageObjects }: FtrProviderContext) { ['geo.src', 'IN'], ]; - // FLAKY: https://github.com/elastic/kibana/issues/62497 - describe.skip('Discover', () => { + describe('Discover', () => { before(async () => { await esArchiver.load('discover'); await esArchiver.loadIfNeeded('logstash_functional'); @@ -133,7 +133,14 @@ export default function({ getService, getPageObjects }: FtrProviderContext) { // Context view test it('should open context view on a doc', async () => { await docTable.clickRowToggle(); - await (await docTable.getRowActions())[0].click(); + // click the open action + await retry.try(async () => { + const rowActions = await docTable.getRowActions(); + if (!rowActions.length) { + throw new Error('row actions empty, trying again'); + } + await rowActions[0].click(); + }); await a11y.testAppSnapshot(); }); From 42d21bcdcbd423252cfaf12466bbc6b03cfa1b10 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 20 May 2020 10:28:53 +0300 Subject: [PATCH 056/129] [Discover] Deangularize timechart header (#66532) * Deangularize timechart header * Add label attr to options * Watch the interval prop change * Tweaking the UI Mainly moved interval notice to an `append` and copy updates * Remove outdated i18n tokens * fix functional test * Change functional test due to dom changes * fix functional test * remove unecessary translation * remove watcher as it is not necessary anymore * change interval options copies Co-authored-by: Elastic Machine Co-authored-by: cchaos --- .../search/aggs/buckets/_interval_options.ts | 10 +- .../public/application/angular/discover.html | 50 ++---- .../public/application/angular/discover.js | 32 +--- .../components/timechart_header/index.ts | 21 +++ .../timechart_header.test.tsx | 95 +++++++++++ .../timechart_header/timechart_header.tsx | 159 ++++++++++++++++++ .../timechart_header_directive.ts | 32 ++++ .../discover/public/get_inner_angular.ts | 2 + .../apps/discover/_discover_histogram.js | 10 +- test/functional/apps/visualize/_area_chart.js | 4 +- test/functional/apps/visualize/_data_table.js | 4 +- test/functional/page_objects/discover_page.ts | 6 +- .../translations/translations/ja-JP.json | 7 - .../translations/translations/zh-CN.json | 7 - 14 files changed, 342 insertions(+), 97 deletions(-) create mode 100644 src/plugins/discover/public/application/components/timechart_header/index.ts create mode 100644 src/plugins/discover/public/application/components/timechart_header/timechart_header.test.tsx create mode 100644 src/plugins/discover/public/application/components/timechart_header/timechart_header.tsx create mode 100644 src/plugins/discover/public/application/components/timechart_header/timechart_header_directive.ts diff --git a/src/plugins/data/public/search/aggs/buckets/_interval_options.ts b/src/plugins/data/public/search/aggs/buckets/_interval_options.ts index 1c4c04c40a5c1..00cf50c272fa0 100644 --- a/src/plugins/data/public/search/aggs/buckets/_interval_options.ts +++ b/src/plugins/data/public/search/aggs/buckets/_interval_options.ts @@ -52,31 +52,31 @@ export const intervalOptions = [ }, { display: i18n.translate('data.search.aggs.buckets.intervalOptions.hourlyDisplayName', { - defaultMessage: 'Hourly', + defaultMessage: 'Hour', }), val: 'h', }, { display: i18n.translate('data.search.aggs.buckets.intervalOptions.dailyDisplayName', { - defaultMessage: 'Daily', + defaultMessage: 'Day', }), val: 'd', }, { display: i18n.translate('data.search.aggs.buckets.intervalOptions.weeklyDisplayName', { - defaultMessage: 'Weekly', + defaultMessage: 'Week', }), val: 'w', }, { display: i18n.translate('data.search.aggs.buckets.intervalOptions.monthlyDisplayName', { - defaultMessage: 'Monthly', + defaultMessage: 'Month', }), val: 'M', }, { display: i18n.translate('data.search.aggs.buckets.intervalOptions.yearlyDisplayName', { - defaultMessage: 'Yearly', + defaultMessage: 'Year', }), val: 'y', }, diff --git a/src/plugins/discover/public/application/angular/discover.html b/src/plugins/discover/public/application/angular/discover.html index a0f98ea38ef78..d70d5dad9130b 100644 --- a/src/plugins/discover/public/application/angular/discover.html +++ b/src/plugins/discover/public/application/angular/discover.html @@ -101,45 +101,17 @@

    {{screenTitle}}

    class="dscTimechart" ng-if="opts.timefield" > -
    -
    - - - — - - - - - - - - -
    - -
    + + { if (abortController) abortController.abort(); @@ -614,24 +610,6 @@ function discoverController( $scope.state.index = $scope.indexPattern.id; $scope.state.sort = getSortArray($scope.state.sort, $scope.indexPattern); - $scope.getBucketIntervalToolTipText = () => { - return i18n.translate('discover.bucketIntervalTooltip', { - defaultMessage: - 'This interval creates {bucketsDescription} to show in the selected time range, so it has been scaled to {bucketIntervalDescription}', - values: { - bucketsDescription: - $scope.bucketInterval.scale > 1 - ? i18n.translate('discover.bucketIntervalTooltip.tooLargeBucketsText', { - defaultMessage: 'buckets that are too large', - }) - : i18n.translate('discover.bucketIntervalTooltip.tooManyBucketsText', { - defaultMessage: 'too many buckets', - }), - bucketIntervalDescription: $scope.bucketInterval.description, - }, - }); - }; - $scope.opts = { // number of records to fetch, then paginate through sampleSize: config.get(SAMPLE_SIZE_SETTING), @@ -681,12 +659,12 @@ function discoverController( error => addFatalError(core.fatalErrors, error) ) ); - //Handling change oft the histogram interval - $scope.$watch('state.interval', function(newInterval, oldInterval) { - if (newInterval !== oldInterval) { - setAppState({ interval: newInterval }); + + $scope.changeInterval = interval => { + if (interval) { + setAppState({ interval }); } - }); + }; $scope.$watchMulti( ['rows', 'fetchStatus'], diff --git a/src/plugins/discover/public/application/components/timechart_header/index.ts b/src/plugins/discover/public/application/components/timechart_header/index.ts new file mode 100644 index 0000000000000..43473319c318c --- /dev/null +++ b/src/plugins/discover/public/application/components/timechart_header/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { TimechartHeader } from './timechart_header'; +export { createTimechartHeaderDirective } from './timechart_header_directive'; diff --git a/src/plugins/discover/public/application/components/timechart_header/timechart_header.test.tsx b/src/plugins/discover/public/application/components/timechart_header/timechart_header.test.tsx new file mode 100644 index 0000000000000..642774d6be202 --- /dev/null +++ b/src/plugins/discover/public/application/components/timechart_header/timechart_header.test.tsx @@ -0,0 +1,95 @@ +/* + * 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 { mountWithIntl } from 'test_utils/enzyme_helpers'; +import { ReactWrapper } from 'enzyme'; +import { TimechartHeader, TimechartHeaderProps } from './timechart_header'; +import { EuiIconTip } from '@elastic/eui'; +// @ts-ignore +import { findTestSubject } from '@elastic/eui/lib/test'; + +describe('timechart header', function() { + let props: TimechartHeaderProps; + let component: ReactWrapper; + + beforeAll(() => { + props = { + from: 'May 14, 2020 @ 11:05:13.590', + to: 'May 14, 2020 @ 11:20:13.590', + stateInterval: 's', + options: [ + { + display: 'Auto', + val: 'auto', + }, + { + display: 'Millisecond', + val: 'ms', + }, + { + display: 'Second', + val: 's', + }, + ], + onChangeInterval: jest.fn(), + showScaledInfo: undefined, + bucketIntervalDescription: 'second', + bucketIntervalScale: undefined, + }; + }); + + it('TimechartHeader not renders an info text when the showScaledInfo property is not provided', () => { + component = mountWithIntl(); + expect(component.find(EuiIconTip).length).toBe(0); + }); + + it('TimechartHeader renders an info text by providing the showScaledInfo property', () => { + props.showScaledInfo = true; + component = mountWithIntl(); + expect(component.find(EuiIconTip).length).toBe(1); + }); + + it('expect to render the date range', function() { + component = mountWithIntl(); + const datetimeRangeText = findTestSubject(component, 'discoverIntervalDateRange'); + expect(datetimeRangeText.text()).toBe( + 'May 14, 2020 @ 11:05:13.590 - May 14, 2020 @ 11:20:13.590 per' + ); + }); + + it('expects to render a dropdown with the interval options', () => { + component = mountWithIntl(); + const dropdown = findTestSubject(component, 'discoverIntervalSelect'); + expect(dropdown.length).toBe(1); + // @ts-ignore + const values = dropdown.find('option').map(option => option.prop('value')); + expect(values).toEqual(['auto', 'ms', 's']); + // @ts-ignore + const labels = dropdown.find('option').map(option => option.text()); + expect(labels).toEqual(['Auto', 'Millisecond', 'Second']); + }); + + it('should change the interval', function() { + component = mountWithIntl(); + findTestSubject(component, 'discoverIntervalSelect').simulate('change', { + target: { value: 'ms' }, + }); + expect(props.onChangeInterval).toHaveBeenCalled(); + }); +}); diff --git a/src/plugins/discover/public/application/components/timechart_header/timechart_header.tsx b/src/plugins/discover/public/application/components/timechart_header/timechart_header.tsx new file mode 100644 index 0000000000000..077adcb6b006e --- /dev/null +++ b/src/plugins/discover/public/application/components/timechart_header/timechart_header.tsx @@ -0,0 +1,159 @@ +/* + * 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, { useState, useEffect } from 'react'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiToolTip, + EuiText, + EuiSelect, + EuiIconTip, +} from '@elastic/eui'; +import { I18nProvider } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; + +export interface TimechartHeaderProps { + /** + * the query from date string + */ + from: string; + /** + * the query to date string + */ + to: string; + /** + * Interval Options + */ + options: Array<{ display: string; val: string }>; + /** + * changes the interval + */ + onChangeInterval: (interval: string) => void; + /** + * selected interval + */ + stateInterval: string; + /** + * displays the scaled info of the interval + */ + showScaledInfo: boolean | undefined; + /** + * scaled info description + */ + bucketIntervalDescription: string; + /** + * bucket interval scale + */ + bucketIntervalScale: number | undefined; +} + +export function TimechartHeader({ + from, + to, + options, + onChangeInterval, + stateInterval, + showScaledInfo, + bucketIntervalDescription, + bucketIntervalScale, +}: TimechartHeaderProps) { + const [interval, setInterval] = useState(stateInterval); + + useEffect(() => { + setInterval(stateInterval); + }, [stateInterval]); + + const handleIntervalChange = (e: React.ChangeEvent) => { + setInterval(e.target.value); + onChangeInterval(e.target.value); + }; + + return ( + + + + + + {`${from} - ${to} ${ + interval !== 'auto' + ? i18n.translate('discover.timechartHeader.timeIntervalSelect.per', { + defaultMessage: 'per', + }) + : '' + }`} + + + + + val !== 'custom') + .map(({ display, val }) => { + return { + text: display, + value: val, + label: display, + }; + })} + value={interval} + onChange={handleIntervalChange} + append={ + showScaledInfo ? ( + 1 + ? i18n.translate('discover.bucketIntervalTooltip.tooLargeBucketsText', { + defaultMessage: 'buckets that are too large', + }) + : i18n.translate('discover.bucketIntervalTooltip.tooManyBucketsText', { + defaultMessage: 'too many buckets', + }), + bucketIntervalDescription, + }, + })} + color="warning" + size="s" + type="alert" + /> + ) : ( + undefined + ) + } + /> + + + + ); +} diff --git a/src/plugins/discover/public/application/components/timechart_header/timechart_header_directive.ts b/src/plugins/discover/public/application/components/timechart_header/timechart_header_directive.ts new file mode 100644 index 0000000000000..027236cd46521 --- /dev/null +++ b/src/plugins/discover/public/application/components/timechart_header/timechart_header_directive.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 { TimechartHeader } from './timechart_header'; + +export function createTimechartHeaderDirective(reactDirective: any) { + return reactDirective(TimechartHeader, [ + ['from', { watchDepth: 'reference' }], + ['to', { watchDepth: 'reference' }], + ['options', { watchDepth: 'reference' }], + ['onChangeInterval', { watchDepth: 'reference' }], + ['stateInterval', { watchDepth: 'reference' }], + ['showScaledInfo', { watchDepth: 'reference' }], + ['bucketIntervalDescription', { watchDepth: 'reference' }], + ['bucketIntervalScale', { watchDepth: 'reference' }], + ]); +} diff --git a/src/plugins/discover/public/get_inner_angular.ts b/src/plugins/discover/public/get_inner_angular.ts index 1389ac74b84b4..d97bbef7aca25 100644 --- a/src/plugins/discover/public/get_inner_angular.ts +++ b/src/plugins/discover/public/get_inner_angular.ts @@ -59,6 +59,7 @@ import { } from '../../kibana_legacy/public'; import { createDiscoverSidebarDirective } from './application/components/sidebar'; import { createHitsCounterDirective } from '././application/components/hits_counter'; +import { createTimechartHeaderDirective } from './application/components/timechart_header'; import { DiscoverStartPlugins } from './plugin'; import { getScopedHistory } from './kibana_services'; @@ -154,6 +155,7 @@ export function initializeInnerAngularModule( .directive('renderComplete', createRenderCompleteDirective) .directive('discoverSidebar', createDiscoverSidebarDirective) .directive('hitsCounter', createHitsCounterDirective) + .directive('timechartHeader', createTimechartHeaderDirective) .service('debounce', ['$timeout', DebounceProviderTimeout]); } diff --git a/test/functional/apps/discover/_discover_histogram.js b/test/functional/apps/discover/_discover_histogram.js index 0f63510dce431..6f6dfa66f825f 100644 --- a/test/functional/apps/discover/_discover_histogram.js +++ b/test/functional/apps/discover/_discover_histogram.js @@ -69,7 +69,7 @@ export default function({ getService, getPageObjects }) { const fromTime = 'Nov 01, 2017 @ 00:00:00.000'; const toTime = 'Mar 21, 2018 @ 00:00:00.000'; await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); - await PageObjects.discover.setChartInterval('Monthly'); + await PageObjects.discover.setChartInterval('Month'); await PageObjects.header.waitUntilLoadingHasFinished(); const chartCanvasExist = await elasticChart.canvasExists(); expect(chartCanvasExist).to.be(true); @@ -78,7 +78,7 @@ export default function({ getService, getPageObjects }) { const fromTime = 'Mar 01, 2018 @ 00:00:00.000'; const toTime = 'May 01, 2018 @ 00:00:00.000'; await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); - await PageObjects.discover.setChartInterval('Weekly'); + await PageObjects.discover.setChartInterval('Week'); await PageObjects.header.waitUntilLoadingHasFinished(); const chartCanvasExist = await elasticChart.canvasExists(); expect(chartCanvasExist).to.be(true); @@ -88,12 +88,12 @@ export default function({ getService, getPageObjects }) { const toTime = 'Mar 21, 2019 @ 00:00:00.000'; await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); - await PageObjects.discover.setChartInterval('Daily'); + await PageObjects.discover.setChartInterval('Day'); await PageObjects.header.waitUntilLoadingHasFinished(); const chartCanvasExist = await elasticChart.canvasExists(); expect(chartCanvasExist).to.be(true); - const chartIntervalScaledDesc = await PageObjects.discover.getChartIntervalScaledToDesc(); - expect(chartIntervalScaledDesc).to.be('Scaled to 30 days'); + const chartIntervalIconTip = await PageObjects.discover.getChartIntervalWarningIcon(); + expect(chartIntervalIconTip).to.be(true); }); }); } diff --git a/test/functional/apps/visualize/_area_chart.js b/test/functional/apps/visualize/_area_chart.js index 48d36e4d51349..b612a19e235bd 100644 --- a/test/functional/apps/visualize/_area_chart.js +++ b/test/functional/apps/visualize/_area_chart.js @@ -438,7 +438,7 @@ export default function({ getService, getPageObjects }) { log.debug('Click Date Histogram'); await PageObjects.visEditor.selectAggregation('Date Histogram'); await PageObjects.visEditor.selectField('@timestamp'); - await PageObjects.visEditor.setInterval('Yearly'); + await PageObjects.visEditor.setInterval('Year'); await PageObjects.visEditor.clickGo(); // This svg area is composed by 7 years (2013 - 2019). // 7 points are used to draw the upper line (usually called y1) @@ -461,7 +461,7 @@ export default function({ getService, getPageObjects }) { log.debug('Click Date Histogram'); await PageObjects.visEditor.selectAggregation('Date Histogram'); await PageObjects.visEditor.selectField('@timestamp'); - await PageObjects.visEditor.setInterval('Monthly'); + await PageObjects.visEditor.setInterval('Month'); await PageObjects.visEditor.clickGo(); // This svg area is composed by 67 months 3 (2013) + 5 * 12 + 4 (2019) // 67 points are used to draw the upper line (usually called y1) diff --git a/test/functional/apps/visualize/_data_table.js b/test/functional/apps/visualize/_data_table.js index d0136677bb4de..ec0d2f0579ccc 100644 --- a/test/functional/apps/visualize/_data_table.js +++ b/test/functional/apps/visualize/_data_table.js @@ -174,7 +174,7 @@ export default function({ getService, getPageObjects }) { await PageObjects.visEditor.clickBucket('Split rows'); await PageObjects.visEditor.selectAggregation('Date Histogram'); await PageObjects.visEditor.selectField('@timestamp'); - await PageObjects.visEditor.setInterval('Daily'); + await PageObjects.visEditor.setInterval('Day'); await PageObjects.visEditor.clickGo(); const data = await PageObjects.visChart.getTableVisData(); log.debug(data.split('\n')); @@ -196,7 +196,7 @@ export default function({ getService, getPageObjects }) { await PageObjects.visEditor.clickBucket('Split rows'); await PageObjects.visEditor.selectAggregation('Date Histogram'); await PageObjects.visEditor.selectField('@timestamp'); - await PageObjects.visEditor.setInterval('Daily'); + await PageObjects.visEditor.setInterval('Day'); await PageObjects.visEditor.clickGo(); const data = await PageObjects.visChart.getTableVisData(); expect(data.trim().split('\n')).to.be.eql([ diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts index fae82f61f782e..831c76dd8fe46 100644 --- a/test/functional/page_objects/discover_page.ts +++ b/test/functional/page_objects/discover_page.ts @@ -36,7 +36,7 @@ export function DiscoverPageProvider({ getService, getPageObjects }: FtrProvider class DiscoverPage { public async getChartTimespan() { - const el = await find.byCssSelector('.small > label[for="dscResultsIntervalSelector"]'); + const el = await find.byCssSelector('[data-test-subj="discoverIntervalDateRange"]'); return await el.getVisibleText(); } @@ -168,9 +168,9 @@ export function DiscoverPageProvider({ getService, getPageObjects }: FtrProvider return selectedOption.getVisibleText(); } - public async getChartIntervalScaledToDesc() { + public async getChartIntervalWarningIcon() { await header.waitUntilLoadingHasFinished(); - return await testSubjects.getVisibleText('discoverIntervalSelectScaledToDesc'); + return await find.existsByCssSelector('.euiToolTipAnchor'); } public async setChartInterval(interval: string) { diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 21496f1f2f070..f8ade9fad91a6 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -702,14 +702,9 @@ "data.search.aggs.buckets.geotileGridTitle": "ジオタイル", "data.search.aggs.buckets.histogramTitle": "ヒストグラム", "data.search.aggs.buckets.intervalOptions.autoDisplayName": "自動", - "data.search.aggs.buckets.intervalOptions.dailyDisplayName": "日ごと", - "data.search.aggs.buckets.intervalOptions.hourlyDisplayName": "1 時間ごと", "data.search.aggs.buckets.intervalOptions.millisecondDisplayName": "ミリ秒", "data.search.aggs.buckets.intervalOptions.minuteDisplayName": "分", - "data.search.aggs.buckets.intervalOptions.monthlyDisplayName": "月ごと", "data.search.aggs.buckets.intervalOptions.secondDisplayName": "秒", - "data.search.aggs.buckets.intervalOptions.weeklyDisplayName": "週ごと", - "data.search.aggs.buckets.intervalOptions.yearlyDisplayName": "年ごと", "data.search.aggs.buckets.ipRangeLabel": "{fieldName} IP 範囲", "data.search.aggs.buckets.ipRangeTitle": "IPv4 範囲", "data.search.aggs.buckets.rangeTitle": "範囲", @@ -967,7 +962,6 @@ "discover.histogram.partialData.bucketTooltipText": "選択された時間範囲にはこのバケット全体は含まれていませんが、一部データが含まれている可能性があります。", "discover.histogramOfFoundDocumentsAriaLabel": "発見されたドキュメントのヒストグラム", "discover.hitsPluralTitle": "{hits, plural, one {ヒット} other {ヒット}}", - "discover.howToChangeTheTimeTooltip": "時刻を変更するには、ナビゲーションバーのカレンダーアイコンをクリックします", "discover.howToSeeOtherMatchingDocumentsDescription": "これらは検索条件に一致した初めの {sampleSize} 件のドキュメントです。他の結果を表示するには検索条件を絞ってください。 ", "discover.inspectorRequestDataTitle": "データ", "discover.inspectorRequestDescription": "このリクエストは Elasticsearch にクエリをかけ、検索データを取得します。", @@ -1003,7 +997,6 @@ "discover.reloadSavedSearchButton": "検索をリセット", "discover.rootBreadcrumb": "ディスカバリ", "discover.savedSearch.savedObjectName": "保存された検索", - "discover.scaledToDescription": "{bucketIntervalDescription} にスケーリング済み", "discover.searchingTitle": "検索中", "discover.showingDefaultIndexPatternWarningDescription": "デフォルトのインデックスパターン「{loadedIndexPatternTitle}」 ({loadedIndexPatternId}) を表示中", "discover.showingSavedIndexPatternWarningDescription": "保存されたインデックスパターン「{ownIndexPatternTitle}」 ({ownIndexPatternId}) を表示中", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index ff3041e6c5a39..65c8462ec3627 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -703,14 +703,9 @@ "data.search.aggs.buckets.geotileGridTitle": "地理磁贴", "data.search.aggs.buckets.histogramTitle": "Histogram", "data.search.aggs.buckets.intervalOptions.autoDisplayName": "自动", - "data.search.aggs.buckets.intervalOptions.dailyDisplayName": "每日", - "data.search.aggs.buckets.intervalOptions.hourlyDisplayName": "每小时", "data.search.aggs.buckets.intervalOptions.millisecondDisplayName": "毫秒", "data.search.aggs.buckets.intervalOptions.minuteDisplayName": "分钟", - "data.search.aggs.buckets.intervalOptions.monthlyDisplayName": "每月", "data.search.aggs.buckets.intervalOptions.secondDisplayName": "秒", - "data.search.aggs.buckets.intervalOptions.weeklyDisplayName": "每周", - "data.search.aggs.buckets.intervalOptions.yearlyDisplayName": "每年", "data.search.aggs.buckets.ipRangeLabel": "{fieldName} IP 范围", "data.search.aggs.buckets.ipRangeTitle": "IPv4 范围", "data.search.aggs.buckets.rangeTitle": "范围", @@ -968,7 +963,6 @@ "discover.histogram.partialData.bucketTooltipText": "选定的时间范围不包括此整个存储桶,其可能包含部分数据。", "discover.histogramOfFoundDocumentsAriaLabel": "已找到文档的直方图", "discover.hitsPluralTitle": "{hits, plural, one {次命中} other {次命中}}", - "discover.howToChangeTheTimeTooltip": "要更改时间,请单击导航栏中的日历图标", "discover.howToSeeOtherMatchingDocumentsDescription": "以下是匹配您的搜索的前 {sampleSize} 个文档,请优化您的搜索以查看其他文档。 ", "discover.inspectorRequestDataTitle": "数据", "discover.inspectorRequestDescription": "此请求将查询 Elasticsearch 以获取搜索的数据。", @@ -1004,7 +998,6 @@ "discover.reloadSavedSearchButton": "重置搜索", "discover.rootBreadcrumb": "Discover", "discover.savedSearch.savedObjectName": "已保存搜索", - "discover.scaledToDescription": "已缩放至 {bucketIntervalDescription}", "discover.searchingTitle": "正在搜索", "discover.showingDefaultIndexPatternWarningDescription": "显示默认索引模式:“{loadedIndexPatternTitle}” ({loadedIndexPatternId})", "discover.showingSavedIndexPatternWarningDescription": "显示保存的索引模式:“{ownIndexPatternTitle}” ({ownIndexPatternId})", From dfa22d17b92423773fe9e4a4cd37a649188de2d6 Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Wed, 20 May 2020 09:55:02 +0100 Subject: [PATCH 057/129] [Saved Objects] adds support for including hidden types in saved objects client (#66879) As part of the work needed for RBAC & Feature Controls support in Alerting (https://github.com/elastic/kibana/issues/43994) we've identified a need to make the Alert Saved Object type a _hidden_ type. As we still need support for Security and Spaces, we wish to use the standard SavedObjectsClient and its middleware, but currently this isn't possible with _hidden_ types. To address that, this PR adds support for creating a client which includes hidden types. --- ...n-core-server.savedobjectsclientfactory.md | 3 +- ...ientprovideroptions.includedhiddentypes.md | 11 + ...erver.savedobjectsclientprovideroptions.md | 1 + ...ositoryfactory.createinternalrepository.md | 2 +- ...epositoryfactory.createscopedrepository.md | 2 +- ...re-server.savedobjectsrepositoryfactory.md | 4 +- ...tsservicestart.createinternalrepository.md | 2 +- ...ectsservicestart.createscopedrepository.md | 2 +- ...in-core-server.savedobjectsservicestart.md | 4 +- .../saved_objects_service.test.ts | 85 +++++++ .../saved_objects/saved_objects_service.ts | 38 +-- .../saved_objects/service/lib/repository.ts | 6 +- .../lib/scoped_client_provider.test.js | 20 ++ .../service/lib/scoped_client_provider.ts | 8 +- src/core/server/server.api.md | 15 +- .../saved_objects/saved_objects_mixin.js | 6 +- .../server/lib/action_executor.test.ts | 20 +- .../actions/server/lib/action_executor.ts | 12 +- .../server/lib/task_runner_factory.test.ts | 22 +- .../actions/server/lib/task_runner_factory.ts | 8 +- x-pack/plugins/actions/server/plugin.ts | 6 +- .../alerting/server/alerts_client.test.ts | 4 +- .../plugins/alerting/server/alerts_client.ts | 24 +- .../server/alerts_client_factory.test.ts | 4 +- .../alerting/server/alerts_client_factory.ts | 10 +- x-pack/plugins/alerting/server/plugin.test.ts | 2 + x-pack/plugins/alerting/server/plugin.ts | 6 +- .../server/task_runner/task_runner.test.ts | 28 +-- .../server/task_runner/task_runner.ts | 2 +- .../task_runner/task_runner_factory.test.ts | 2 +- .../server/task_runner/task_runner_factory.ts | 4 +- .../encrypted_saved_objects/server/index.ts | 1 + .../encrypted_saved_objects/server/mocks.ts | 10 +- .../server/plugin.test.ts | 12 +- .../encrypted_saved_objects/server/plugin.ts | 15 +- .../server/saved_objects/index.test.ts | 34 ++- .../server/saved_objects/index.ts | 61 ++--- .../server/services/agents/acks.test.ts | 8 +- .../server/services/app_context.ts | 6 +- .../security/server/saved_objects/index.ts | 6 +- .../fixtures/plugins/aad/server/plugin.ts | 8 +- .../server/hidden_saved_object_routes.ts | 235 ++++++++++++++++++ .../api_consumer_plugin/server/index.ts | 30 ++- .../tests/encrypted_saved_objects_api.ts | 11 +- 44 files changed, 615 insertions(+), 185 deletions(-) create mode 100644 docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.includedhiddentypes.md create mode 100644 x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/hidden_saved_object_routes.ts diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientfactory.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientfactory.md index 09c6d63f03dd7..724c1ebbeadf4 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientfactory.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientfactory.md @@ -9,7 +9,8 @@ Describes the factory used to create instances of the Saved Objects Client. Signature: ```typescript -export declare type SavedObjectsClientFactory = ({ request, }: { +export declare type SavedObjectsClientFactory = ({ request, includedHiddenTypes, }: { request: KibanaRequest; + includedHiddenTypes?: string[]; }) => SavedObjectsClientContract; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.includedhiddentypes.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.includedhiddentypes.md new file mode 100644 index 0000000000000..a9483e34b38ce --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.includedhiddentypes.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectsClientProviderOptions](./kibana-plugin-core-server.savedobjectsclientprovideroptions.md) > [includedHiddenTypes](./kibana-plugin-core-server.savedobjectsclientprovideroptions.includedhiddentypes.md) + +## SavedObjectsClientProviderOptions.includedHiddenTypes property + +Signature: + +```typescript +includedHiddenTypes?: string[]; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.md index 4291de765fd44..be1f73f064843 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.md @@ -17,4 +17,5 @@ export interface SavedObjectsClientProviderOptions | Property | Type | Description | | --- | --- | --- | | [excludedWrappers](./kibana-plugin-core-server.savedobjectsclientprovideroptions.excludedwrappers.md) | string[] | | +| [includedHiddenTypes](./kibana-plugin-core-server.savedobjectsclientprovideroptions.includedhiddentypes.md) | string[] | | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createinternalrepository.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createinternalrepository.md index c4b19ca15910f..e39ce020b930c 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createinternalrepository.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createinternalrepository.md @@ -9,5 +9,5 @@ Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsre Signature: ```typescript -createInternalRepository: (extraTypes?: string[]) => ISavedObjectsRepository; +createInternalRepository: (includedHiddenTypes?: string[]) => ISavedObjectsRepository; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createscopedrepository.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createscopedrepository.md index b9007d16d0234..9cd0df9094277 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createscopedrepository.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createscopedrepository.md @@ -9,5 +9,5 @@ Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsre Signature: ```typescript -createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository; +createScopedRepository: (req: KibanaRequest, includedHiddenTypes?: string[]) => ISavedObjectsRepository; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.md index 35b29918edced..dec768b68cd3a 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.md @@ -16,6 +16,6 @@ export interface SavedObjectsRepositoryFactory | Property | Type | Description | | --- | --- | --- | -| [createInternalRepository](./kibana-plugin-core-server.savedobjectsrepositoryfactory.createinternalrepository.md) | (extraTypes?: string[]) => ISavedObjectsRepository | Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the internal Kibana user for authenticating with Elasticsearch. | -| [createScopedRepository](./kibana-plugin-core-server.savedobjectsrepositoryfactory.createscopedrepository.md) | (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository | Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the credentials from the passed in request to authenticate with Elasticsearch. | +| [createInternalRepository](./kibana-plugin-core-server.savedobjectsrepositoryfactory.createinternalrepository.md) | (includedHiddenTypes?: string[]) => ISavedObjectsRepository | Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the internal Kibana user for authenticating with Elasticsearch. | +| [createScopedRepository](./kibana-plugin-core-server.savedobjectsrepositoryfactory.createscopedrepository.md) | (req: KibanaRequest, includedHiddenTypes?: string[]) => ISavedObjectsRepository | Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the credentials from the passed in request to authenticate with Elasticsearch. | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createinternalrepository.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createinternalrepository.md index 4467dd23d87b6..d03e9ca223c53 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createinternalrepository.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createinternalrepository.md @@ -9,5 +9,5 @@ Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsre Signature: ```typescript -createInternalRepository: (extraTypes?: string[]) => ISavedObjectsRepository; +createInternalRepository: (includedHiddenTypes?: string[]) => ISavedObjectsRepository; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createscopedrepository.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createscopedrepository.md index 2840a377026e7..762f77b98e74d 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createscopedrepository.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createscopedrepository.md @@ -9,7 +9,7 @@ Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsre Signature: ```typescript -createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository; +createScopedRepository: (req: KibanaRequest, includedHiddenTypes?: string[]) => ISavedObjectsRepository; ``` ## Remarks diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.md index 5f592adf7acd9..17655bb4878a7 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.md @@ -16,8 +16,8 @@ export interface SavedObjectsServiceStart | Property | Type | Description | | --- | --- | --- | -| [createInternalRepository](./kibana-plugin-core-server.savedobjectsservicestart.createinternalrepository.md) | (extraTypes?: string[]) => ISavedObjectsRepository | Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the internal Kibana user for authenticating with Elasticsearch. | -| [createScopedRepository](./kibana-plugin-core-server.savedobjectsservicestart.createscopedrepository.md) | (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository | Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the credentials from the passed in request to authenticate with Elasticsearch. | +| [createInternalRepository](./kibana-plugin-core-server.savedobjectsservicestart.createinternalrepository.md) | (includedHiddenTypes?: string[]) => ISavedObjectsRepository | Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the internal Kibana user for authenticating with Elasticsearch. | +| [createScopedRepository](./kibana-plugin-core-server.savedobjectsservicestart.createscopedrepository.md) | (req: KibanaRequest, includedHiddenTypes?: string[]) => ISavedObjectsRepository | Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the credentials from the passed in request to authenticate with Elasticsearch. | | [createSerializer](./kibana-plugin-core-server.savedobjectsservicestart.createserializer.md) | () => SavedObjectsSerializer | Creates a [serializer](./kibana-plugin-core-server.savedobjectsserializer.md) that is aware of all registered types. | | [getScopedClient](./kibana-plugin-core-server.savedobjectsservicestart.getscopedclient.md) | (req: KibanaRequest, options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract | Creates a [Saved Objects client](./kibana-plugin-core-server.savedobjectsclientcontract.md) that uses the credentials from the passed in request to authenticate with Elasticsearch. If other plugins have registered Saved Objects client wrappers, these will be applied to extend the functionality of the client.A client that is already scoped to the incoming request is also exposed from the route handler context see [RequestHandlerContext](./kibana-plugin-core-server.requesthandlercontext.md). | | [getTypeRegistry](./kibana-plugin-core-server.savedobjectsservicestart.gettyperegistry.md) | () => ISavedObjectTypeRegistry | Returns the [registry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) containing all registered [saved object types](./kibana-plugin-core-server.savedobjectstype.md) | diff --git a/src/core/server/saved_objects/saved_objects_service.test.ts b/src/core/server/saved_objects/saved_objects_service.test.ts index 819d79803f371..7dea7a017a47d 100644 --- a/src/core/server/saved_objects/saved_objects_service.test.ts +++ b/src/core/server/saved_objects/saved_objects_service.test.ts @@ -35,6 +35,10 @@ import { legacyServiceMock } from '../legacy/legacy_service.mock'; import { httpServiceMock } from '../http/http_service.mock'; import { SavedObjectsClientFactoryProvider } from './service/lib'; import { NodesVersionCompatibility } from '../elasticsearch/version_check/ensure_es_version'; +import { SavedObjectsRepository } from './service/lib/repository'; +import { KibanaRequest } from '../http'; + +jest.mock('./service/lib/repository'); describe('SavedObjectsService', () => { const createCoreContext = ({ @@ -269,5 +273,86 @@ describe('SavedObjectsService', () => { expect(getTypeRegistry()).toBe(typeRegistryInstanceMock); }); }); + + describe('#createScopedRepository', () => { + it('creates a respository scoped to the user', async () => { + const coreContext = createCoreContext({ skipMigration: false }); + const soService = new SavedObjectsService(coreContext); + const coreSetup = createSetupDeps(); + await soService.setup(coreSetup); + const { createScopedRepository } = await soService.start({}); + + const req = {} as KibanaRequest; + createScopedRepository(req); + + expect(coreSetup.elasticsearch.adminClient.asScoped).toHaveBeenCalledWith(req); + + const [ + { + value: { callAsCurrentUser }, + }, + ] = coreSetup.elasticsearch.adminClient.asScoped.mock.results; + + const [ + [, , , callCluster, includedHiddenTypes], + ] = (SavedObjectsRepository.createRepository as jest.Mocked).mock.calls; + + expect(callCluster).toBe(callAsCurrentUser); + expect(includedHiddenTypes).toEqual([]); + }); + + it('creates a respository including hidden types when specified', async () => { + const coreContext = createCoreContext({ skipMigration: false }); + const soService = new SavedObjectsService(coreContext); + const coreSetup = createSetupDeps(); + await soService.setup(coreSetup); + const { createScopedRepository } = await soService.start({}); + + const req = {} as KibanaRequest; + createScopedRepository(req, ['someHiddenType']); + + const [ + [, , , , includedHiddenTypes], + ] = (SavedObjectsRepository.createRepository as jest.Mocked).mock.calls; + + expect(includedHiddenTypes).toEqual(['someHiddenType']); + }); + }); + + describe('#createInternalRepository', () => { + it('creates a respository using the admin user', async () => { + const coreContext = createCoreContext({ skipMigration: false }); + const soService = new SavedObjectsService(coreContext); + const coreSetup = createSetupDeps(); + await soService.setup(coreSetup); + const { createInternalRepository } = await soService.start({}); + + createInternalRepository(); + + const [ + [, , , callCluster, includedHiddenTypes], + ] = (SavedObjectsRepository.createRepository as jest.Mocked).mock.calls; + + expect(coreSetup.elasticsearch.adminClient.callAsInternalUser).toBe(callCluster); + expect(callCluster).toBe(coreSetup.elasticsearch.adminClient.callAsInternalUser); + expect(includedHiddenTypes).toEqual([]); + }); + + it('creates a respository including hidden types when specified', async () => { + const coreContext = createCoreContext({ skipMigration: false }); + const soService = new SavedObjectsService(coreContext); + const coreSetup = createSetupDeps(); + await soService.setup(coreSetup); + const { createInternalRepository } = await soService.start({}); + + createInternalRepository(['someHiddenType']); + + const [ + [, , , , includedHiddenTypes], + ] = (SavedObjectsRepository.createRepository as jest.Mocked).mock.calls; + + expect(includedHiddenTypes).toEqual(['someHiddenType']); + }); + }); }); }); diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index ed4ffef5729ab..373b8bd1d2bc6 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -198,20 +198,23 @@ export interface SavedObjectsServiceStart { * Elasticsearch. * * @param req - The request to create the scoped repository from. - * @param extraTypes - A list of additional hidden types the repository should have access to. + * @param includedHiddenTypes - A list of additional hidden types the repository should have access to. * * @remarks * Prefer using `getScopedClient`. This should only be used when using methods * not exposed on {@link SavedObjectsClientContract} */ - createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository; + createScopedRepository: ( + req: KibanaRequest, + includedHiddenTypes?: string[] + ) => ISavedObjectsRepository; /** * Creates a {@link ISavedObjectsRepository | Saved Objects repository} that * uses the internal Kibana user for authenticating with Elasticsearch. * - * @param extraTypes - A list of additional hidden types the repository should have access to. + * @param includedHiddenTypes - A list of additional hidden types the repository should have access to. */ - createInternalRepository: (extraTypes?: string[]) => ISavedObjectsRepository; + createInternalRepository: (includedHiddenTypes?: string[]) => ISavedObjectsRepository; /** * Creates a {@link SavedObjectsSerializer | serializer} that is aware of all registered types. */ @@ -246,16 +249,19 @@ export interface SavedObjectsRepositoryFactory { * uses the credentials from the passed in request to authenticate with * Elasticsearch. * - * @param extraTypes - A list of additional hidden types the repository should have access to. + * @param includedHiddenTypes - A list of additional hidden types the repository should have access to. */ - createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository; + createScopedRepository: ( + req: KibanaRequest, + includedHiddenTypes?: string[] + ) => ISavedObjectsRepository; /** * Creates a {@link ISavedObjectsRepository | Saved Objects repository} that * uses the internal Kibana user for authenticating with Elasticsearch. * - * @param extraTypes - A list of additional hidden types the repository should have access to. + * @param includedHiddenTypes - A list of additional hidden types the repository should have access to. */ - createInternalRepository: (extraTypes?: string[]) => ISavedObjectsRepository; + createInternalRepository: (includedHiddenTypes?: string[]) => ISavedObjectsRepository; } /** @internal */ @@ -417,26 +423,26 @@ export class SavedObjectsService await migrator.runMigrations(); } - const createRepository = (callCluster: APICaller, extraTypes: string[] = []) => { + const createRepository = (callCluster: APICaller, includedHiddenTypes: string[] = []) => { return SavedObjectsRepository.createRepository( migrator, this.typeRegistry, kibanaConfig.index, callCluster, - extraTypes + includedHiddenTypes ); }; const repositoryFactory: SavedObjectsRepositoryFactory = { - createInternalRepository: (extraTypes?: string[]) => - createRepository(adminClient.callAsInternalUser, extraTypes), - createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => - createRepository(adminClient.asScoped(req).callAsCurrentUser, extraTypes), + createInternalRepository: (includedHiddenTypes?: string[]) => + createRepository(adminClient.callAsInternalUser, includedHiddenTypes), + createScopedRepository: (req: KibanaRequest, includedHiddenTypes?: string[]) => + createRepository(adminClient.asScoped(req).callAsCurrentUser, includedHiddenTypes), }; const clientProvider = new SavedObjectsClientProvider({ - defaultClientFactory({ request }) { - const repository = repositoryFactory.createScopedRepository(request); + defaultClientFactory({ request, includedHiddenTypes }) { + const repository = repositoryFactory.createScopedRepository(request, includedHiddenTypes); return new SavedObjectsClient(repository); }, typeRegistry: this.typeRegistry, diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index 61027130e0eb7..f76b05c4af1b9 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -132,7 +132,7 @@ export class SavedObjectsRepository { typeRegistry: SavedObjectTypeRegistry, indexName: string, callCluster: APICaller, - extraTypes: string[] = [], + includedHiddenTypes: string[] = [], injectedConstructor: any = SavedObjectsRepository ): ISavedObjectsRepository { const mappings = migrator.getActiveMappings(); @@ -140,14 +140,14 @@ export class SavedObjectsRepository { const serializer = new SavedObjectsSerializer(typeRegistry); const visibleTypes = allTypes.filter(type => !typeRegistry.isHidden(type)); - const missingTypeMappings = extraTypes.filter(type => !allTypes.includes(type)); + const missingTypeMappings = includedHiddenTypes.filter(type => !allTypes.includes(type)); if (missingTypeMappings.length > 0) { throw new Error( `Missing mappings for saved objects types: '${missingTypeMappings.join(', ')}'` ); } - const allowedTypes = [...new Set(visibleTypes.concat(extraTypes))]; + const allowedTypes = [...new Set(visibleTypes.concat(includedHiddenTypes))]; return new injectedConstructor({ index: indexName, diff --git a/src/core/server/saved_objects/service/lib/scoped_client_provider.test.js b/src/core/server/saved_objects/service/lib/scoped_client_provider.test.js index aa9448e61009d..a0e1530ed2e26 100644 --- a/src/core/server/saved_objects/service/lib/scoped_client_provider.test.js +++ b/src/core/server/saved_objects/service/lib/scoped_client_provider.test.js @@ -167,3 +167,23 @@ test(`allows all wrappers to be excluded`, () => { expect(firstClientWrapperFactoryMock).not.toHaveBeenCalled(); expect(secondClientWrapperFactoryMock).not.toHaveBeenCalled(); }); + +test(`allows hidden typed to be included`, () => { + const defaultClient = Symbol(); + const defaultClientFactoryMock = jest.fn().mockReturnValue(defaultClient); + const clientProvider = new SavedObjectsClientProvider({ + defaultClientFactory: defaultClientFactoryMock, + typeRegistry: typeRegistryMock.create(), + }); + const request = Symbol(); + + const actualClient = clientProvider.getClient(request, { + includedHiddenTypes: ['task'], + }); + + expect(actualClient).toBe(defaultClient); + expect(defaultClientFactoryMock).toHaveBeenCalledWith({ + request, + includedHiddenTypes: ['task'], + }); +}); diff --git a/src/core/server/saved_objects/service/lib/scoped_client_provider.ts b/src/core/server/saved_objects/service/lib/scoped_client_provider.ts index 24813cd8d9ab8..3250737e1287d 100644 --- a/src/core/server/saved_objects/service/lib/scoped_client_provider.ts +++ b/src/core/server/saved_objects/service/lib/scoped_client_provider.ts @@ -46,8 +46,10 @@ export type SavedObjectsClientWrapperFactory = ( */ export type SavedObjectsClientFactory = ({ request, + includedHiddenTypes, }: { request: KibanaRequest; + includedHiddenTypes?: string[]; }) => SavedObjectsClientContract; /** @@ -64,6 +66,7 @@ export type SavedObjectsClientFactoryProvider = ( */ export interface SavedObjectsClientProviderOptions { excludedWrappers?: string[]; + includedHiddenTypes?: string[]; } /** @@ -121,14 +124,13 @@ export class SavedObjectsClientProvider { getClient( request: KibanaRequest, - options: SavedObjectsClientProviderOptions = {} + { includedHiddenTypes, excludedWrappers = [] }: SavedObjectsClientProviderOptions = {} ): SavedObjectsClientContract { const client = this._clientFactory({ request, + includedHiddenTypes, }); - const excludedWrappers = options.excludedWrappers || []; - return this._wrapperFactories .toPrioritizedArray() .reduceRight((clientToWrap, { id, factory }) => { diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index bb8ee1d8e7a31..fcf9a9e2dedc2 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1840,8 +1840,9 @@ export class SavedObjectsClient { export type SavedObjectsClientContract = Pick; // @public -export type SavedObjectsClientFactory = ({ request, }: { +export type SavedObjectsClientFactory = ({ request, includedHiddenTypes, }: { request: KibanaRequest; + includedHiddenTypes?: string[]; }) => SavedObjectsClientContract; // @public @@ -1851,6 +1852,8 @@ export type SavedObjectsClientFactoryProvider = (repositoryFactory: SavedObjects export interface SavedObjectsClientProviderOptions { // (undocumented) excludedWrappers?: string[]; + // (undocumented) + includedHiddenTypes?: string[]; } // @public @@ -2213,7 +2216,7 @@ export class SavedObjectsRepository { // Warning: (ae-forgotten-export) The symbol "KibanaMigrator" needs to be exported by the entry point index.d.ts // // @internal - static createRepository(migrator: KibanaMigrator, typeRegistry: SavedObjectTypeRegistry, indexName: string, callCluster: APICaller, extraTypes?: string[], injectedConstructor?: any): ISavedObjectsRepository; + static createRepository(migrator: KibanaMigrator, typeRegistry: SavedObjectTypeRegistry, indexName: string, callCluster: APICaller, includedHiddenTypes?: string[], injectedConstructor?: any): ISavedObjectsRepository; delete(type: string, id: string, options?: SavedObjectsDeleteOptions): Promise<{}>; deleteByNamespace(namespace: string, options?: SavedObjectsDeleteByNamespaceOptions): Promise; deleteFromNamespaces(type: string, id: string, namespaces: string[], options?: SavedObjectsDeleteFromNamespacesOptions): Promise<{}>; @@ -2233,8 +2236,8 @@ export class SavedObjectsRepository { // @public export interface SavedObjectsRepositoryFactory { - createInternalRepository: (extraTypes?: string[]) => ISavedObjectsRepository; - createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository; + createInternalRepository: (includedHiddenTypes?: string[]) => ISavedObjectsRepository; + createScopedRepository: (req: KibanaRequest, includedHiddenTypes?: string[]) => ISavedObjectsRepository; } // @public @@ -2285,8 +2288,8 @@ export interface SavedObjectsServiceSetup { // @public export interface SavedObjectsServiceStart { - createInternalRepository: (extraTypes?: string[]) => ISavedObjectsRepository; - createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository; + createInternalRepository: (includedHiddenTypes?: string[]) => ISavedObjectsRepository; + createScopedRepository: (req: KibanaRequest, includedHiddenTypes?: string[]) => ISavedObjectsRepository; createSerializer: () => SavedObjectsSerializer; getScopedClient: (req: KibanaRequest, options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; getTypeRegistry: () => ISavedObjectTypeRegistry; diff --git a/src/legacy/server/saved_objects/saved_objects_mixin.js b/src/legacy/server/saved_objects/saved_objects_mixin.js index 3e71e1989ae7a..26fecc68fda4b 100644 --- a/src/legacy/server/saved_objects/saved_objects_mixin.js +++ b/src/legacy/server/saved_objects/saved_objects_mixin.js @@ -50,17 +50,17 @@ export function savedObjectsMixin(kbnServer, server) { const serializer = kbnServer.newPlatform.start.core.savedObjects.createSerializer(); - const createRepository = (callCluster, extraTypes = []) => { + const createRepository = (callCluster, includedHiddenTypes = []) => { if (typeof callCluster !== 'function') { throw new TypeError('Repository requires a "callCluster" function to be provided.'); } // throw an exception if an extraType is not defined. - extraTypes.forEach(type => { + includedHiddenTypes.forEach(type => { if (!allTypes.includes(type)) { throw new Error(`Missing mappings for saved objects type '${type}'`); } }); - const combinedTypes = visibleTypes.concat(extraTypes); + const combinedTypes = visibleTypes.concat(includedHiddenTypes); const allowedTypes = [...new Set(combinedTypes)]; const config = server.config(); diff --git a/x-pack/plugins/actions/server/lib/action_executor.test.ts b/x-pack/plugins/actions/server/lib/action_executor.test.ts index 4594fc1ddf6d9..f1e5a10e5bbd2 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.test.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.test.ts @@ -18,7 +18,7 @@ import { actionsMock } from '../mocks'; const actionExecutor = new ActionExecutor({ isESOUsingEphemeralEncryptionKey: false }); const services = actionsMock.createServices(); const savedObjectsClient = services.savedObjectsClient; -const encryptedSavedObjectsPlugin = encryptedSavedObjectsMock.createStart(); +const encryptedSavedObjectsClient = encryptedSavedObjectsMock.createClient(); const actionTypeRegistry = actionTypeRegistryMock.create(); const executeParams = { @@ -35,7 +35,7 @@ actionExecutor.initialize({ spaces: spacesMock, getServices: () => services, actionTypeRegistry, - encryptedSavedObjectsPlugin, + encryptedSavedObjectsClient, eventLogger: eventLoggerMock.create(), preconfiguredActions: [], }); @@ -67,11 +67,11 @@ test('successfully executes', async () => { references: [], }; savedObjectsClient.get.mockResolvedValueOnce(actionSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); actionTypeRegistry.get.mockReturnValueOnce(actionType); await actionExecutor.execute(executeParams); - expect(encryptedSavedObjectsPlugin.getDecryptedAsInternalUser).toHaveBeenCalledWith( + expect(encryptedSavedObjectsClient.getDecryptedAsInternalUser).toHaveBeenCalledWith( 'action', '1', { namespace: 'some-namespace' } @@ -108,7 +108,7 @@ test('provides empty config when config and / or secrets is empty', async () => references: [], }; savedObjectsClient.get.mockResolvedValueOnce(actionSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); actionTypeRegistry.get.mockReturnValueOnce(actionType); await actionExecutor.execute(executeParams); @@ -138,7 +138,7 @@ test('throws an error when config is invalid', async () => { references: [], }; savedObjectsClient.get.mockResolvedValueOnce(actionSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); actionTypeRegistry.get.mockReturnValueOnce(actionType); const result = await actionExecutor.execute(executeParams); @@ -171,7 +171,7 @@ test('throws an error when params is invalid', async () => { references: [], }; savedObjectsClient.get.mockResolvedValueOnce(actionSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); actionTypeRegistry.get.mockReturnValueOnce(actionType); const result = await actionExecutor.execute(executeParams); @@ -206,7 +206,7 @@ test('throws an error if actionType is not enabled', async () => { references: [], }; savedObjectsClient.get.mockResolvedValueOnce(actionSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); actionTypeRegistry.get.mockReturnValueOnce(actionType); actionTypeRegistry.ensureActionTypeEnabled.mockImplementationOnce(() => { throw new Error('not enabled for test'); @@ -240,7 +240,7 @@ test('should not throws an error if actionType is preconfigured', async () => { references: [], }; savedObjectsClient.get.mockResolvedValueOnce(actionSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); actionTypeRegistry.get.mockReturnValueOnce(actionType); actionTypeRegistry.ensureActionTypeEnabled.mockImplementationOnce(() => { throw new Error('not enabled for test'); @@ -269,7 +269,7 @@ test('throws an error when passing isESOUsingEphemeralEncryptionKey with value o spaces: spacesMock, getServices: () => services, actionTypeRegistry, - encryptedSavedObjectsPlugin, + encryptedSavedObjectsClient, eventLogger: eventLoggerMock.create(), preconfiguredActions: [], }); diff --git a/x-pack/plugins/actions/server/lib/action_executor.ts b/x-pack/plugins/actions/server/lib/action_executor.ts index 3e9262c05efac..aad93a04248eb 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.ts @@ -14,7 +14,7 @@ import { PreConfiguredAction, Services, } from '../types'; -import { EncryptedSavedObjectsPluginStart } from '../../../encrypted_saved_objects/server'; +import { EncryptedSavedObjectsClient } from '../../../encrypted_saved_objects/server'; import { SpacesServiceSetup } from '../../../spaces/server'; import { EVENT_LOG_ACTIONS } from '../plugin'; import { IEvent, IEventLogger, SAVED_OBJECT_REL_PRIMARY } from '../../../event_log/server'; @@ -23,7 +23,7 @@ export interface ActionExecutorContext { logger: Logger; spaces?: SpacesServiceSetup; getServices: GetServicesFunction; - encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart; + encryptedSavedObjectsClient: EncryptedSavedObjectsClient; actionTypeRegistry: ActionTypeRegistryContract; eventLogger: IEventLogger; preconfiguredActions: PreConfiguredAction[]; @@ -72,7 +72,7 @@ export class ActionExecutor { const { spaces, getServices, - encryptedSavedObjectsPlugin, + encryptedSavedObjectsClient, actionTypeRegistry, eventLogger, preconfiguredActions, @@ -84,7 +84,7 @@ export class ActionExecutor { const { actionTypeId, name, config, secrets } = await getActionInfo( services, - encryptedSavedObjectsPlugin, + encryptedSavedObjectsClient, preconfiguredActions, actionId, namespace.namespace @@ -196,7 +196,7 @@ interface ActionInfo { async function getActionInfo( services: Services, - encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart, + encryptedSavedObjectsClient: EncryptedSavedObjectsClient, preconfiguredActions: PreConfiguredAction[], actionId: string, namespace: string | undefined @@ -222,7 +222,7 @@ async function getActionInfo( const { attributes: { secrets }, - } = await encryptedSavedObjectsPlugin.getDecryptedAsInternalUser('action', actionId, { + } = await encryptedSavedObjectsClient.getDecryptedAsInternalUser('action', actionId, { namespace: namespace === 'default' ? undefined : namespace, }); diff --git a/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts b/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts index f070f714ee508..42ccf5a33ebaa 100644 --- a/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts +++ b/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts @@ -18,7 +18,7 @@ import { ActionTypeDisabledError } from './errors'; const spaceIdToNamespace = jest.fn(); const actionTypeRegistry = actionTypeRegistryMock.create(); -const mockedEncryptedSavedObjectsPlugin = encryptedSavedObjectsMock.createStart(); +const mockedEncryptedSavedObjectsClient = encryptedSavedObjectsMock.createClient(); const mockedActionExecutor = actionExecutorMock.create(); let fakeTimer: sinon.SinonFakeTimers; @@ -59,7 +59,7 @@ const actionExecutorInitializerParams = { logger: loggingServiceMock.create().get(), getServices: jest.fn().mockReturnValue(services), actionTypeRegistry, - encryptedSavedObjectsPlugin: mockedEncryptedSavedObjectsPlugin, + encryptedSavedObjectsClient: mockedEncryptedSavedObjectsClient, eventLogger: eventLoggerMock.create(), preconfiguredActions: [], }; @@ -67,7 +67,7 @@ const taskRunnerFactoryInitializerParams = { spaceIdToNamespace, actionTypeRegistry, logger: loggingServiceMock.create().get(), - encryptedSavedObjectsPlugin: mockedEncryptedSavedObjectsPlugin, + encryptedSavedObjectsClient: mockedEncryptedSavedObjectsClient, getBasePath: jest.fn().mockReturnValue(undefined), getScopedSavedObjectsClient: jest.fn().mockReturnValue(services.savedObjectsClient), }; @@ -106,7 +106,7 @@ test('executes the task by calling the executor with proper parameters', async ( mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' }); spaceIdToNamespace.mockReturnValueOnce('namespace-test'); - mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '3', type: 'action_task_params', attributes: { @@ -122,7 +122,7 @@ test('executes the task by calling the executor with proper parameters', async ( expect(runnerResult).toBeUndefined(); expect(spaceIdToNamespace).toHaveBeenCalledWith('test'); expect( - mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser + mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser ).toHaveBeenCalledWith('action_task_params', '3', { namespace: 'namespace-test' }); expect(mockedActionExecutor.execute).toHaveBeenCalledWith({ actionId: '2', @@ -154,7 +154,7 @@ test('cleans up action_task_params object', async () => { mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' }); spaceIdToNamespace.mockReturnValueOnce('namespace-test'); - mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '3', type: 'action_task_params', attributes: { @@ -177,7 +177,7 @@ test('runs successfully when cleanup fails and logs the error', async () => { mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' }); spaceIdToNamespace.mockReturnValueOnce('namespace-test'); - mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '3', type: 'action_task_params', attributes: { @@ -202,7 +202,7 @@ test('throws an error with suggested retry logic when return status is error', a taskInstance: mockedTaskInstance, }); - mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '3', type: 'action_task_params', attributes: { @@ -237,7 +237,7 @@ test('uses API key when provided', async () => { mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' }); spaceIdToNamespace.mockReturnValueOnce('namespace-test'); - mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '3', type: 'action_task_params', attributes: { @@ -280,7 +280,7 @@ test(`doesn't use API key when not provided`, async () => { mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' }); spaceIdToNamespace.mockReturnValueOnce('namespace-test'); - mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '3', type: 'action_task_params', attributes: { @@ -317,7 +317,7 @@ test(`throws an error when license doesn't support the action type`, async () => taskInstance: mockedTaskInstance, }); - mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '3', type: 'action_task_params', attributes: { diff --git a/x-pack/plugins/actions/server/lib/task_runner_factory.ts b/x-pack/plugins/actions/server/lib/task_runner_factory.ts index 08c5b90edbcb7..a962497f906a9 100644 --- a/x-pack/plugins/actions/server/lib/task_runner_factory.ts +++ b/x-pack/plugins/actions/server/lib/task_runner_factory.ts @@ -8,7 +8,7 @@ import { ActionExecutorContract } from './action_executor'; import { ExecutorError } from './executor_error'; import { Logger, CoreStart, KibanaRequest } from '../../../../../src/core/server'; import { RunContext } from '../../../task_manager/server'; -import { EncryptedSavedObjectsPluginStart } from '../../../encrypted_saved_objects/server'; +import { EncryptedSavedObjectsClient } from '../../../encrypted_saved_objects/server'; import { ActionTypeDisabledError } from './errors'; import { ActionTaskParams, @@ -21,7 +21,7 @@ import { export interface TaskRunnerContext { logger: Logger; actionTypeRegistry: ActionTypeRegistryContract; - encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart; + encryptedSavedObjectsClient: EncryptedSavedObjectsClient; spaceIdToNamespace: SpaceIdToNamespaceFunction; getBasePath: GetBasePathFunction; getScopedSavedObjectsClient: CoreStart['savedObjects']['getScopedClient']; @@ -52,7 +52,7 @@ export class TaskRunnerFactory { const { actionExecutor } = this; const { logger, - encryptedSavedObjectsPlugin, + encryptedSavedObjectsClient, spaceIdToNamespace, getBasePath, getScopedSavedObjectsClient, @@ -65,7 +65,7 @@ export class TaskRunnerFactory { const { attributes: { actionId, params, apiKey }, - } = await encryptedSavedObjectsPlugin.getDecryptedAsInternalUser( + } = await encryptedSavedObjectsClient.getDecryptedAsInternalUser( 'action_task_params', actionTaskParamsId, { namespace } diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index bc7440c8bee4d..75e15815d0787 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -232,12 +232,14 @@ export class ActionsPlugin implements Plugin, Plugi preconfiguredActions, } = this; + const encryptedSavedObjectsClient = plugins.encryptedSavedObjects.getClient(); + actionExecutor!.initialize({ logger, eventLogger: this.eventLogger!, spaces: this.spaces, getServices: this.getServicesFactory(core.savedObjects, core.elasticsearch), - encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects, + encryptedSavedObjectsClient, actionTypeRegistry: actionTypeRegistry!, preconfiguredActions, }); @@ -245,7 +247,7 @@ export class ActionsPlugin implements Plugin, Plugi taskRunnerFactory!.initialize({ logger, actionTypeRegistry: actionTypeRegistry!, - encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects, + encryptedSavedObjectsClient, getBasePath: this.getBasePath, spaceIdToNamespace: this.spaceIdToNamespace, getScopedSavedObjectsClient: core.savedObjects.getScopedClient, diff --git a/x-pack/plugins/alerting/server/alerts_client.test.ts b/x-pack/plugins/alerting/server/alerts_client.test.ts index 6601ccc4f5a73..93b98f6a0fe03 100644 --- a/x-pack/plugins/alerting/server/alerts_client.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client.test.ts @@ -17,7 +17,7 @@ import { encryptedSavedObjectsMock } from '../../../plugins/encrypted_saved_obje const taskManager = taskManagerMock.start(); const alertTypeRegistry = alertTypeRegistryMock.create(); const savedObjectsClient = savedObjectsClientMock.create(); -const encryptedSavedObjects = encryptedSavedObjectsMock.createStart(); +const encryptedSavedObjects = encryptedSavedObjectsMock.createClient(); const alertsClientParams = { taskManager, @@ -29,7 +29,7 @@ const alertsClientParams = { createAPIKey: jest.fn(), invalidateAPIKey: jest.fn(), logger: loggingServiceMock.create().get(), - encryptedSavedObjectsPlugin: encryptedSavedObjects, + encryptedSavedObjectsClient: encryptedSavedObjects, preconfiguredActions: [], }; diff --git a/x-pack/plugins/alerting/server/alerts_client.ts b/x-pack/plugins/alerting/server/alerts_client.ts index ff501055ba9fe..01687f33f631d 100644 --- a/x-pack/plugins/alerting/server/alerts_client.ts +++ b/x-pack/plugins/alerting/server/alerts_client.ts @@ -32,7 +32,7 @@ import { GrantAPIKeyResult as SecurityPluginGrantAPIKeyResult, InvalidateAPIKeyResult as SecurityPluginInvalidateAPIKeyResult, } from '../../../plugins/security/server'; -import { EncryptedSavedObjectsPluginStart } from '../../../plugins/encrypted_saved_objects/server'; +import { EncryptedSavedObjectsClient } from '../../../plugins/encrypted_saved_objects/server'; import { TaskManagerStartContract } from '../../../plugins/task_manager/server'; import { taskInstanceToAlertTaskInstance } from './task_runner/alert_task_instance'; import { deleteTaskIfItExists } from './lib/delete_task_if_it_exists'; @@ -50,7 +50,7 @@ interface ConstructorOptions { taskManager: TaskManagerStartContract; savedObjectsClient: SavedObjectsClientContract; alertTypeRegistry: AlertTypeRegistry; - encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart; + encryptedSavedObjectsClient: EncryptedSavedObjectsClient; spaceId?: string; namespace?: string; getUserName: () => Promise; @@ -128,7 +128,7 @@ export class AlertsClient { params: InvalidateAPIKeyParams ) => Promise; private preconfiguredActions: PreConfiguredAction[]; - encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart; + encryptedSavedObjectsClient: EncryptedSavedObjectsClient; constructor({ alertTypeRegistry, @@ -140,7 +140,7 @@ export class AlertsClient { getUserName, createAPIKey, invalidateAPIKey, - encryptedSavedObjectsPlugin, + encryptedSavedObjectsClient, preconfiguredActions, }: ConstructorOptions) { this.logger = logger; @@ -152,7 +152,7 @@ export class AlertsClient { this.savedObjectsClient = savedObjectsClient; this.createAPIKey = createAPIKey; this.invalidateAPIKey = invalidateAPIKey; - this.encryptedSavedObjectsPlugin = encryptedSavedObjectsPlugin; + this.encryptedSavedObjectsClient = encryptedSavedObjectsClient; this.preconfiguredActions = preconfiguredActions; } @@ -252,7 +252,7 @@ export class AlertsClient { let apiKeyToInvalidate: string | null = null; try { - const decryptedAlert = await this.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser< + const decryptedAlert = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser< RawAlert >('alert', id, { namespace: this.namespace }); apiKeyToInvalidate = decryptedAlert.attributes.apiKey; @@ -281,7 +281,7 @@ export class AlertsClient { let alertSavedObject: SavedObject; try { - alertSavedObject = await this.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser< + alertSavedObject = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser< RawAlert >('alert', id, { namespace: this.namespace }); } catch (e) { @@ -377,7 +377,7 @@ export class AlertsClient { let version: string | undefined; try { - const decryptedAlert = await this.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser< + const decryptedAlert = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser< RawAlert >('alert', id, { namespace: this.namespace }); apiKeyToInvalidate = decryptedAlert.attributes.apiKey; @@ -435,7 +435,7 @@ export class AlertsClient { let version: string | undefined; try { - const decryptedAlert = await this.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser< + const decryptedAlert = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser< RawAlert >('alert', id, { namespace: this.namespace }); apiKeyToInvalidate = decryptedAlert.attributes.apiKey; @@ -479,7 +479,7 @@ export class AlertsClient { let version: string | undefined; try { - const decryptedAlert = await this.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser< + const decryptedAlert = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser< RawAlert >('alert', id, { namespace: this.namespace }); apiKeyToInvalidate = decryptedAlert.attributes.apiKey; @@ -543,7 +543,7 @@ export class AlertsClient { alertId: string; alertInstanceId: string; }) { - const { attributes, version } = await this.savedObjectsClient.get('alert', alertId); + const { attributes, version } = await this.savedObjectsClient.get('alert', alertId); const mutedInstanceIds = attributes.mutedInstanceIds || []; if (!attributes.muteAll && !mutedInstanceIds.includes(alertInstanceId)) { mutedInstanceIds.push(alertInstanceId); @@ -566,7 +566,7 @@ export class AlertsClient { alertId: string; alertInstanceId: string; }) { - const { attributes, version } = await this.savedObjectsClient.get('alert', alertId); + const { attributes, version } = await this.savedObjectsClient.get('alert', alertId); const mutedInstanceIds = attributes.mutedInstanceIds || []; if (!attributes.muteAll && mutedInstanceIds.includes(alertInstanceId)) { await this.savedObjectsClient.update( diff --git a/x-pack/plugins/alerting/server/alerts_client_factory.test.ts b/x-pack/plugins/alerting/server/alerts_client_factory.test.ts index e5aa0a674eccf..cc792d11c890d 100644 --- a/x-pack/plugins/alerting/server/alerts_client_factory.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client_factory.test.ts @@ -24,7 +24,7 @@ const alertsClientFactoryParams: jest.Mocked = { alertTypeRegistry: alertTypeRegistryMock.create(), getSpaceId: jest.fn(), spaceIdToNamespace: jest.fn(), - encryptedSavedObjectsPlugin: encryptedSavedObjectsMock.createStart(), + encryptedSavedObjectsClient: encryptedSavedObjectsMock.createClient(), preconfiguredActions: [], }; const fakeRequest = ({ @@ -64,7 +64,7 @@ test('creates an alerts client with proper constructor arguments', async () => { getUserName: expect.any(Function), createAPIKey: expect.any(Function), invalidateAPIKey: expect.any(Function), - encryptedSavedObjectsPlugin: alertsClientFactoryParams.encryptedSavedObjectsPlugin, + encryptedSavedObjectsClient: alertsClientFactoryParams.encryptedSavedObjectsClient, preconfiguredActions: [], }); }); diff --git a/x-pack/plugins/alerting/server/alerts_client_factory.ts b/x-pack/plugins/alerting/server/alerts_client_factory.ts index 734417e72733e..913b4e2e81fe1 100644 --- a/x-pack/plugins/alerting/server/alerts_client_factory.ts +++ b/x-pack/plugins/alerting/server/alerts_client_factory.ts @@ -9,7 +9,7 @@ import { AlertsClient } from './alerts_client'; import { AlertTypeRegistry, SpaceIdToNamespaceFunction } from './types'; import { KibanaRequest, Logger, SavedObjectsClientContract } from '../../../../src/core/server'; import { InvalidateAPIKeyParams, SecurityPluginSetup } from '../../../plugins/security/server'; -import { EncryptedSavedObjectsPluginStart } from '../../../plugins/encrypted_saved_objects/server'; +import { EncryptedSavedObjectsClient } from '../../../plugins/encrypted_saved_objects/server'; import { TaskManagerStartContract } from '../../../plugins/task_manager/server'; export interface AlertsClientFactoryOpts { @@ -19,7 +19,7 @@ export interface AlertsClientFactoryOpts { securityPluginSetup?: SecurityPluginSetup; getSpaceId: (request: KibanaRequest) => string | undefined; spaceIdToNamespace: SpaceIdToNamespaceFunction; - encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart; + encryptedSavedObjectsClient: EncryptedSavedObjectsClient; preconfiguredActions: PreConfiguredAction[]; } @@ -31,7 +31,7 @@ export class AlertsClientFactory { private securityPluginSetup?: SecurityPluginSetup; private getSpaceId!: (request: KibanaRequest) => string | undefined; private spaceIdToNamespace!: SpaceIdToNamespaceFunction; - private encryptedSavedObjectsPlugin!: EncryptedSavedObjectsPluginStart; + private encryptedSavedObjectsClient!: EncryptedSavedObjectsClient; private preconfiguredActions!: PreConfiguredAction[]; public initialize(options: AlertsClientFactoryOpts) { @@ -45,7 +45,7 @@ export class AlertsClientFactory { this.alertTypeRegistry = options.alertTypeRegistry; this.securityPluginSetup = options.securityPluginSetup; this.spaceIdToNamespace = options.spaceIdToNamespace; - this.encryptedSavedObjectsPlugin = options.encryptedSavedObjectsPlugin; + this.encryptedSavedObjectsClient = options.encryptedSavedObjectsClient; this.preconfiguredActions = options.preconfiguredActions; } @@ -62,7 +62,7 @@ export class AlertsClientFactory { alertTypeRegistry: this.alertTypeRegistry, savedObjectsClient, namespace: this.spaceIdToNamespace(spaceId), - encryptedSavedObjectsPlugin: this.encryptedSavedObjectsPlugin, + encryptedSavedObjectsClient: this.encryptedSavedObjectsClient, async getUserName() { if (!securityPluginSetup) { return null; diff --git a/x-pack/plugins/alerting/server/plugin.test.ts b/x-pack/plugins/alerting/server/plugin.test.ts index 267e68930a5d7..0411899290ab2 100644 --- a/x-pack/plugins/alerting/server/plugin.test.ts +++ b/x-pack/plugins/alerting/server/plugin.test.ts @@ -81,6 +81,7 @@ describe('Alerting Plugin', () => { execute: jest.fn(), getActionsClientWithRequest: jest.fn(), }, + encryptedSavedObjects: encryptedSavedObjectsMock.createStart(), } as unknown) as AlertingPluginsStart ); @@ -125,6 +126,7 @@ describe('Alerting Plugin', () => { getActionsClientWithRequest: jest.fn(), }, spaces: () => null, + encryptedSavedObjects: encryptedSavedObjectsMock.createStart(), } as unknown) as AlertingPluginsStart ); diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts index 7bd515616a3c1..0835365635990 100644 --- a/x-pack/plugins/alerting/server/plugin.ts +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -201,12 +201,14 @@ export class AlertingPlugin { security, } = this; + const encryptedSavedObjectsClient = plugins.encryptedSavedObjects.getClient(); + alertsClientFactory.initialize({ alertTypeRegistry: alertTypeRegistry!, logger, taskManager: plugins.taskManager, securityPluginSetup: security, - encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects, + encryptedSavedObjectsClient, spaceIdToNamespace: this.spaceIdToNamespace, getSpaceId(request: KibanaRequest) { return spaces?.getSpaceId(request); @@ -219,7 +221,7 @@ export class AlertingPlugin { getServices: this.getServicesFactory(core.savedObjects, core.elasticsearch), spaceIdToNamespace: this.spaceIdToNamespace, actionsPlugin: plugins.actions, - encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects, + encryptedSavedObjectsClient, getBasePath: this.getBasePath, eventLogger: this.eventLogger!, }); diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts index e5ec8f587b9d7..98824b8cf4e1a 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts @@ -54,7 +54,7 @@ describe('Task Runner', () => { afterAll(() => fakeTimer.restore()); - const encryptedSavedObjectsPlugin = encryptedSavedObjectsMock.createStart(); + const encryptedSavedObjectsClient = encryptedSavedObjectsMock.createClient(); const services = alertsMock.createAlertServices(); const savedObjectsClient = services.savedObjectsClient; @@ -64,7 +64,7 @@ describe('Task Runner', () => { } = { getServices: jest.fn().mockReturnValue(services), actionsPlugin: actionsMock.createStart(), - encryptedSavedObjectsPlugin, + encryptedSavedObjectsClient, logger: loggingServiceMock.create().get(), spaceIdToNamespace: jest.fn().mockReturnValue(undefined), getBasePath: jest.fn().mockReturnValue(undefined), @@ -123,7 +123,7 @@ describe('Task Runner', () => { taskRunnerFactoryInitializerParams ); savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '1', type: 'alert', attributes: { @@ -197,7 +197,7 @@ describe('Task Runner', () => { taskRunnerFactoryInitializerParams ); savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '1', type: 'alert', attributes: { @@ -316,7 +316,7 @@ describe('Task Runner', () => { taskRunnerFactoryInitializerParams ); savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '1', type: 'alert', attributes: { @@ -403,7 +403,7 @@ describe('Task Runner', () => { taskRunnerFactoryInitializerParams ); savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '1', type: 'alert', attributes: { @@ -434,7 +434,7 @@ describe('Task Runner', () => { ...mockedAlertTypeSavedObject, references: [], }); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '1', type: 'alert', attributes: { @@ -462,7 +462,7 @@ describe('Task Runner', () => { taskRunnerFactoryInitializerParams ); savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '1', type: 'alert', attributes: { @@ -498,7 +498,7 @@ describe('Task Runner', () => { taskRunnerFactoryInitializerParams ); savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '1', type: 'alert', attributes: {}, @@ -537,7 +537,7 @@ describe('Task Runner', () => { ); savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '1', type: 'alert', attributes: { @@ -588,7 +588,7 @@ describe('Task Runner', () => { }); test('recovers gracefully when the Alert Task Runner throws an exception when fetching the encrypted attributes', async () => { - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockImplementation(() => { + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockImplementation(() => { throw new Error('OMG'); }); @@ -624,7 +624,7 @@ describe('Task Runner', () => { ); savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '1', type: 'alert', attributes: { @@ -656,7 +656,7 @@ describe('Task Runner', () => { taskRunnerFactoryInitializerParams ); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '1', type: 'alert', attributes: { @@ -688,7 +688,7 @@ describe('Task Runner', () => { taskRunnerFactoryInitializerParams ); - encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({ + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ id: '1', type: 'alert', attributes: { diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index bf005301adc07..a36152fa17544 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -62,7 +62,7 @@ export class TaskRunner { // scoped with the API key to fetch the remaining data. const { attributes: { apiKey }, - } = await this.context.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser( + } = await this.context.encryptedSavedObjectsClient.getDecryptedAsInternalUser( 'alert', alertId, { namespace } diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts index 96d89bebcc66f..c1318bac48dfb 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts @@ -56,7 +56,7 @@ describe('Task Runner Factory', () => { const taskRunnerFactoryInitializerParams: jest.Mocked = { getServices: jest.fn().mockReturnValue(services), actionsPlugin: actionsMock.createStart(), - encryptedSavedObjectsPlugin, + encryptedSavedObjectsClient: encryptedSavedObjectsPlugin.getClient(), logger: loggingServiceMock.create().get(), spaceIdToNamespace: jest.fn().mockReturnValue(undefined), getBasePath: jest.fn().mockReturnValue(undefined), diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner_factory.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.ts index b58db8c74f7bb..c50e288d2e520 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner_factory.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.ts @@ -5,7 +5,7 @@ */ import { Logger } from '../../../../../src/core/server'; import { RunContext } from '../../../../plugins/task_manager/server'; -import { EncryptedSavedObjectsPluginStart } from '../../../../plugins/encrypted_saved_objects/server'; +import { EncryptedSavedObjectsClient } from '../../../../plugins/encrypted_saved_objects/server'; import { PluginStartContract as ActionsPluginStartContract } from '../../../../plugins/actions/server'; import { AlertType, @@ -21,7 +21,7 @@ export interface TaskRunnerContext { getServices: GetServicesFunction; actionsPlugin: ActionsPluginStartContract; eventLogger: IEventLogger; - encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart; + encryptedSavedObjectsClient: EncryptedSavedObjectsClient; spaceIdToNamespace: SpaceIdToNamespaceFunction; getBasePath: GetBasePathFunction; } diff --git a/x-pack/plugins/encrypted_saved_objects/server/index.ts b/x-pack/plugins/encrypted_saved_objects/server/index.ts index 3b4b91de355c7..c8f7acf952c22 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/index.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/index.ts @@ -10,6 +10,7 @@ import { Plugin } from './plugin'; export { EncryptedSavedObjectTypeRegistration, EncryptionError } from './crypto'; export { EncryptedSavedObjectsPluginSetup, EncryptedSavedObjectsPluginStart } from './plugin'; +export { EncryptedSavedObjectsClient } from './saved_objects'; export const config = { schema: ConfigSchema }; export const plugin = (initializerContext: PluginInitializerContext) => diff --git a/x-pack/plugins/encrypted_saved_objects/server/mocks.ts b/x-pack/plugins/encrypted_saved_objects/server/mocks.ts index 13d7127db7835..bbc3eb1540562 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/mocks.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/mocks.ts @@ -5,6 +5,7 @@ */ import { EncryptedSavedObjectsPluginSetup, EncryptedSavedObjectsPluginStart } from './plugin'; +import { EncryptedSavedObjectsClient } from './saved_objects'; function createEncryptedSavedObjectsSetupMock() { return { @@ -17,11 +18,18 @@ function createEncryptedSavedObjectsSetupMock() { function createEncryptedSavedObjectsStartMock() { return { isEncryptionError: jest.fn(), - getDecryptedAsInternalUser: jest.fn(), + getClient: jest.fn(() => createEncryptedSavedObjectsClienttMock()), } as jest.Mocked; } +function createEncryptedSavedObjectsClienttMock() { + return { + getDecryptedAsInternalUser: jest.fn(), + } as jest.Mocked; +} + export const encryptedSavedObjectsMock = { createSetup: createEncryptedSavedObjectsSetupMock, createStart: createEncryptedSavedObjectsStartMock, + createClient: createEncryptedSavedObjectsClienttMock, }; diff --git a/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts b/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts index 117adba5794d7..e8568e9964c2f 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts @@ -30,12 +30,20 @@ describe('EncryptedSavedObjects Plugin', () => { it('exposes proper contract', async () => { const plugin = new Plugin(coreMock.createPluginInitializerContext()); await plugin.setup(coreMock.createSetup(), { security: securityMock.createSetup() }); - await expect(plugin.start()).toMatchInlineSnapshot(` + + const startContract = plugin.start(); + await expect(startContract).toMatchInlineSnapshot(` Object { - "getDecryptedAsInternalUser": [Function], + "getClient": [Function], "isEncryptionError": [Function], } `); + + expect(startContract.getClient()).toMatchInlineSnapshot(` + Object { + "getDecryptedAsInternalUser": [Function], + } + `); }); }); }); diff --git a/x-pack/plugins/encrypted_saved_objects/server/plugin.ts b/x-pack/plugins/encrypted_saved_objects/server/plugin.ts index 02212f271cf83..948cb94512f2c 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/plugin.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/plugin.ts @@ -4,12 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - Logger, - SavedObjectsBaseOptions, - PluginInitializerContext, - CoreSetup, -} from 'src/core/server'; +import { Logger, PluginInitializerContext, CoreSetup } from 'src/core/server'; import { first } from 'rxjs/operators'; import { SecurityPluginSetup } from '../../security/server'; import { createConfig$ } from './config'; @@ -31,8 +26,9 @@ export interface EncryptedSavedObjectsPluginSetup { usingEphemeralEncryptionKey: boolean; } -export interface EncryptedSavedObjectsPluginStart extends SavedObjectsSetup { +export interface EncryptedSavedObjectsPluginStart { isEncryptionError: (error: Error) => boolean; + getClient: SavedObjectsSetup; } /** @@ -97,12 +93,9 @@ export class Plugin { public start() { this.logger.debug('Starting plugin'); - return { isEncryptionError: (error: Error) => error instanceof EncryptionError, - getDecryptedAsInternalUser: (type: string, id: string, options?: SavedObjectsBaseOptions) => { - return this.savedObjectsSetup.getDecryptedAsInternalUser(type, id, options); - }, + getClient: (includedHiddenTypes?: string[]) => this.savedObjectsSetup(includedHiddenTypes), }; } diff --git a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.test.ts b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.test.ts index c11f6a2b2afa8..8f0eb855676ad 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.test.ts @@ -25,12 +25,13 @@ import { EncryptedSavedObjectsService } from '../crypto'; describe('#setupSavedObjects', () => { let setupContract: SavedObjectsSetup; + let coreStartMock: ReturnType; let coreSetupMock: ReturnType; let mockSavedObjectsRepository: jest.Mocked; let mockSavedObjectTypeRegistry: jest.Mocked; let mockEncryptedSavedObjectsService: jest.Mocked; beforeEach(() => { - const coreStartMock = coreMock.createStart(); + coreStartMock = coreMock.createStart(); mockSavedObjectsRepository = savedObjectsRepositoryMock.create(); coreStartMock.savedObjects.createInternalRepository.mockReturnValue(mockSavedObjectsRepository); @@ -70,6 +71,33 @@ describe('#setupSavedObjects', () => { ).toBeInstanceOf(EncryptedSavedObjectsClientWrapper); }); + it('properly registers client wrapper factory with', () => { + expect(coreSetupMock.savedObjects.addClientWrapper).toHaveBeenCalledTimes(1); + expect(coreSetupMock.savedObjects.addClientWrapper).toHaveBeenCalledWith( + Number.MAX_SAFE_INTEGER, + 'encryptedSavedObjects', + expect.any(Function) + ); + + const [[, , clientFactory]] = coreSetupMock.savedObjects.addClientWrapper.mock.calls; + expect( + clientFactory({ + client: savedObjectsClientMock.create(), + typeRegistry: savedObjectsTypeRegistryMock.create(), + request: httpServerMock.createKibanaRequest(), + }) + ).toBeInstanceOf(EncryptedSavedObjectsClientWrapper); + }); + + describe('#setupContract', () => { + it('includes hiddenTypes when specified', async () => { + await setupContract(['hiddenType']); + expect(coreStartMock.savedObjects.createInternalRepository).toHaveBeenCalledWith([ + 'hiddenType', + ]); + }); + }); + describe('#getDecryptedAsInternalUser', () => { it('includes `namespace` for single-namespace saved objects', async () => { const mockSavedObject: SavedObject = { @@ -82,7 +110,7 @@ describe('#setupSavedObjects', () => { mockSavedObjectTypeRegistry.isSingleNamespace.mockReturnValue(true); await expect( - setupContract.getDecryptedAsInternalUser(mockSavedObject.type, mockSavedObject.id, { + setupContract().getDecryptedAsInternalUser(mockSavedObject.type, mockSavedObject.id, { namespace: 'some-ns', }) ).resolves.toEqual({ @@ -115,7 +143,7 @@ describe('#setupSavedObjects', () => { mockSavedObjectTypeRegistry.isSingleNamespace.mockReturnValue(false); await expect( - setupContract.getDecryptedAsInternalUser(mockSavedObject.type, mockSavedObject.id, { + setupContract().getDecryptedAsInternalUser(mockSavedObject.type, mockSavedObject.id, { namespace: 'some-ns', }) ).resolves.toEqual({ diff --git a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.ts b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.ts index 9eca93ffd0b9e..67bbaab75425a 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.ts @@ -23,7 +23,9 @@ interface SetupSavedObjectsParams { getStartServices: StartServicesAccessor; } -export interface SavedObjectsSetup { +export type SavedObjectsSetup = (includedHiddenTypes?: string[]) => EncryptedSavedObjectsClient; + +export interface EncryptedSavedObjectsClient { getDecryptedAsInternalUser: ( type: string, id: string, @@ -54,33 +56,34 @@ export function setupSavedObjects({ }) ); - const internalRepositoryAndTypeRegistryPromise = getStartServices().then( - ([core]) => - [core.savedObjects.createInternalRepository(), core.savedObjects.getTypeRegistry()] as [ - ISavedObjectsRepository, - ISavedObjectTypeRegistry - ] - ); - - return { - getDecryptedAsInternalUser: async ( - type: string, - id: string, - options?: SavedObjectsBaseOptions - ): Promise> => { - const [internalRepository, typeRegistry] = await internalRepositoryAndTypeRegistryPromise; - const savedObject = await internalRepository.get(type, id, options); - return { - ...savedObject, - attributes: (await service.decryptAttributes( - { - type, - id, - namespace: typeRegistry.isSingleNamespace(type) ? options?.namespace : undefined, - }, - savedObject.attributes as Record - )) as T, - }; - }, + return (includedHiddenTypes?: string[]) => { + const internalRepositoryAndTypeRegistryPromise = getStartServices().then( + ([core]) => + [ + core.savedObjects.createInternalRepository(includedHiddenTypes), + core.savedObjects.getTypeRegistry(), + ] as [ISavedObjectsRepository, ISavedObjectTypeRegistry] + ); + return { + getDecryptedAsInternalUser: async ( + type: string, + id: string, + options?: SavedObjectsBaseOptions + ): Promise> => { + const [internalRepository, typeRegistry] = await internalRepositoryAndTypeRegistryPromise; + const savedObject = await internalRepository.get(type, id, options); + return { + ...savedObject, + attributes: (await service.decryptAttributes( + { + type, + id, + namespace: typeRegistry.isSingleNamespace(type) ? options?.namespace : undefined, + }, + savedObject.attributes as Record + )) as T, + }; + }, + }; }; } diff --git a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts index ae0dedce178a8..0d22529fdb031 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts @@ -22,11 +22,15 @@ import { IngestManagerAppContext } from '../../plugin'; describe('test agent acks services', () => { it('should succeed on valid and matched actions', async () => { const mockSavedObjectsClient = savedObjectsClientMock.create(); - const mockStartEncryptedSOClient = encryptedSavedObjectsMock.createStart(); + const mockStartEncryptedSOPlugin = encryptedSavedObjectsMock.createStart(); appContextService.start(({ - encryptedSavedObjects: mockStartEncryptedSOClient, + encryptedSavedObjects: mockStartEncryptedSOPlugin, } as unknown) as IngestManagerAppContext); + const [ + { value: mockStartEncryptedSOClient }, + ] = mockStartEncryptedSOPlugin.getClient.mock.results; + mockStartEncryptedSOClient.getDecryptedAsInternalUser.mockReturnValue( Promise.resolve({ id: 'action1', diff --git a/x-pack/plugins/ingest_manager/server/services/app_context.ts b/x-pack/plugins/ingest_manager/server/services/app_context.ts index 91b09d651bf5c..9e6220b6958f1 100644 --- a/x-pack/plugins/ingest_manager/server/services/app_context.ts +++ b/x-pack/plugins/ingest_manager/server/services/app_context.ts @@ -6,14 +6,14 @@ import { BehaviorSubject, Observable } from 'rxjs'; import { first } from 'rxjs/operators'; import { SavedObjectsServiceStart, HttpServiceSetup, Logger } from 'src/core/server'; -import { EncryptedSavedObjectsPluginStart } from '../../../encrypted_saved_objects/server'; +import { EncryptedSavedObjectsClient } from '../../../encrypted_saved_objects/server'; import { SecurityPluginSetup } from '../../../security/server'; import { IngestManagerConfigType } from '../../common'; import { IngestManagerAppContext } from '../plugin'; import { CloudSetup } from '../../../cloud/server'; class AppContextService { - private encryptedSavedObjects: EncryptedSavedObjectsPluginStart | undefined; + private encryptedSavedObjects: EncryptedSavedObjectsClient | undefined; private security: SecurityPluginSetup | undefined; private config$?: Observable; private configSubject$?: BehaviorSubject; @@ -25,7 +25,7 @@ class AppContextService { private httpSetup?: HttpServiceSetup; public async start(appContext: IngestManagerAppContext) { - this.encryptedSavedObjects = appContext.encryptedSavedObjects; + this.encryptedSavedObjects = appContext.encryptedSavedObjects?.getClient(); this.security = appContext.security; this.savedObjects = appContext.savedObjects; this.isProductionMode = appContext.isProductionMode; diff --git a/x-pack/plugins/security/server/saved_objects/index.ts b/x-pack/plugins/security/server/saved_objects/index.ts index 7dac745fcf84b..40c17e5429aa8 100644 --- a/x-pack/plugins/security/server/saved_objects/index.ts +++ b/x-pack/plugins/security/server/saved_objects/index.ts @@ -31,12 +31,12 @@ export function setupSavedObjects({ const getKibanaRequest = (request: KibanaRequest | LegacyRequest) => request instanceof KibanaRequest ? request : KibanaRequest.from(request); - savedObjects.setClientFactoryProvider(repositoryFactory => ({ request }) => { + savedObjects.setClientFactoryProvider(repositoryFactory => ({ request, includedHiddenTypes }) => { const kibanaRequest = getKibanaRequest(request); return new SavedObjectsClient( authz.mode.useRbacForRequest(kibanaRequest) - ? repositoryFactory.createInternalRepository() - : repositoryFactory.createScopedRepository(kibanaRequest) + ? repositoryFactory.createInternalRepository(includedHiddenTypes) + : repositoryFactory.createScopedRepository(kibanaRequest, includedHiddenTypes) ); }); diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/server/plugin.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/server/plugin.ts index 0e9c71d8c20c8..4908b3338a10a 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/server/plugin.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/server/plugin.ts @@ -48,9 +48,11 @@ export class FixturePlugin implements Plugin, + deps: PluginsSetup, + hiddenTypes: string[] +) { + router.get( + { + path: '/api/hidden_saved_objects/get-decrypted-as-internal-user/{type}/{id}', + validate: { params: value => ({ value }) }, + }, + async (context, request, response) => { + const [, { encryptedSavedObjects }] = await core.getStartServices(); + const spaceId = deps.spaces.spacesService.getSpaceId(request); + const namespace = deps.spaces.spacesService.spaceIdToNamespace(spaceId); + try { + return response.ok({ + body: await encryptedSavedObjects + .getClient([request.params.type]) + .getDecryptedAsInternalUser(request.params.type, request.params.id, { namespace }), + }); + } catch (err) { + if (encryptedSavedObjects.isEncryptionError(err)) { + return response.badRequest({ body: 'Failed to encrypt attributes' }); + } + + return response.customError({ body: err, statusCode: 500 }); + } + } + ); + + router.get( + { + path: '/api/hidden_saved_objects/_find', + validate: { + query: schema.object({ + per_page: schema.number({ min: 0, defaultValue: 20 }), + page: schema.number({ min: 0, defaultValue: 1 }), + type: schema.oneOf([schema.string(), schema.arrayOf(schema.string())]), + search: schema.maybe(schema.string()), + default_search_operator: schema.oneOf([schema.literal('OR'), schema.literal('AND')], { + defaultValue: 'OR', + }), + search_fields: schema.maybe( + schema.oneOf([schema.string(), schema.arrayOf(schema.string())]) + ), + sort_field: schema.maybe(schema.string()), + has_reference: schema.maybe( + schema.object({ + type: schema.string(), + id: schema.string(), + }) + ), + fields: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])), + filter: schema.maybe(schema.string()), + }), + }, + }, + async (context, request, response) => { + const query = request.query; + const [{ savedObjects }] = await core.getStartServices(); + return response.ok({ + body: await savedObjects + .getScopedClient(request, { includedHiddenTypes: hiddenTypes }) + .find({ + perPage: query.per_page, + page: query.page, + type: Array.isArray(query.type) ? query.type : [query.type], + search: query.search, + defaultSearchOperator: query.default_search_operator, + searchFields: + typeof query.search_fields === 'string' ? [query.search_fields] : query.search_fields, + sortField: query.sort_field, + hasReference: query.has_reference, + fields: typeof query.fields === 'string' ? [query.fields] : query.fields, + filter: query.filter, + }), + }); + } + ); + + router.get( + { + path: '/api/hidden_saved_objects/{type}/{id}', + validate: { params: value => ({ value }) }, + }, + async (context, request, response) => { + const [{ savedObjects }] = await core.getStartServices(); + return response.ok({ + body: await savedObjects + .getScopedClient(request, { includedHiddenTypes: hiddenTypes }) + .get(request.params.type, request.params.id), + }); + } + ); + router.post( + { + path: '/api/hidden_saved_objects/{type}', + validate: { + params: schema.object({ + type: schema.string(), + id: schema.maybe(schema.string()), + }), + query: schema.object({ + overwrite: schema.boolean({ defaultValue: false }), + }), + body: schema.object({ + attributes: schema.recordOf(schema.string(), schema.any()), + migrationVersion: schema.maybe(schema.recordOf(schema.string(), schema.string())), + references: schema.maybe( + schema.arrayOf( + schema.object({ + name: schema.string(), + type: schema.string(), + id: schema.string(), + }) + ) + ), + }), + }, + }, + async (context, request, response) => { + const [{ savedObjects }] = await core.getStartServices(); + const { type, id } = request.params; + const { attributes, migrationVersion, references } = request.body as any; + const options = { id, migrationVersion, references }; + const so = await savedObjects + .getScopedClient(request, { includedHiddenTypes: hiddenTypes }) + .create(type, attributes, options); + return response.ok({ + body: so, + }); + } + ); + router.put( + { + path: '/api/hidden_saved_objects/{type}/{id}', + validate: { + params: schema.object({ + type: schema.string(), + id: schema.string(), + }), + body: schema.object({ + attributes: schema.recordOf(schema.string(), schema.any()), + version: schema.maybe(schema.string()), + references: schema.maybe( + schema.arrayOf( + schema.object({ + name: schema.string(), + type: schema.string(), + id: schema.string(), + }) + ) + ), + }), + }, + }, + async (context, request, response) => { + const [{ savedObjects }] = await core.getStartServices(); + const { type, id } = request.params as any; + const { attributes, version, references } = request.body as any; + const options = { version, references }; + return response.ok({ + body: await savedObjects + .getScopedClient(request, { includedHiddenTypes: hiddenTypes }) + .update(type, id, attributes, options), + }); + } + ); + router.post( + { + path: '/api/hidden_saved_objects/_bulk_get', + validate: { + body: schema.arrayOf( + schema.object({ + type: schema.string(), + id: schema.string(), + fields: schema.maybe(schema.arrayOf(schema.string())), + }) + ), + }, + }, + async (context, request, response) => { + const [{ savedObjects }] = await core.getStartServices(); + return response.ok({ + body: await savedObjects + .getScopedClient(request, { includedHiddenTypes: hiddenTypes }) + .bulkGet(request.body as any), + }); + } + ); + router.post( + { + path: '/api/hidden_saved_objects/_bulk_create', + validate: { + body: schema.arrayOf( + schema.object({ + type: schema.string(), + id: schema.maybe(schema.string()), + attributes: schema.recordOf(schema.string(), schema.any()), + version: schema.maybe(schema.string()), + migrationVersion: schema.maybe(schema.recordOf(schema.string(), schema.string())), + references: schema.maybe( + schema.arrayOf( + schema.object({ + name: schema.string(), + type: schema.string(), + id: schema.string(), + }) + ) + ), + }) + ), + }, + }, + async (context, request, response) => { + const [{ savedObjects }] = await core.getStartServices(); + return response.ok({ + body: await savedObjects + .getScopedClient(request, { includedHiddenTypes: hiddenTypes }) + .bulkCreate(request.body as any), + }); + } + ); +} diff --git a/x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/index.ts b/x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/index.ts index 46bb7f8024620..b0b73a54ceefe 100644 --- a/x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/index.ts +++ b/x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/index.ts @@ -15,31 +15,34 @@ import { EncryptedSavedObjectsPluginStart, } from '../../../../../plugins/encrypted_saved_objects/server'; import { SpacesPluginSetup } from '../../../../../plugins/spaces/server'; +import { registerHiddenSORoutes } from './hidden_saved_object_routes'; const SAVED_OBJECT_WITH_SECRET_TYPE = 'saved-object-with-secret'; +const HIDDEN_SAVED_OBJECT_WITH_SECRET_TYPE = 'hidden-saved-object-with-secret'; const SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE = 'saved-object-with-secret-and-multiple-spaces'; const SAVED_OBJECT_WITHOUT_SECRET_TYPE = 'saved-object-without-secret'; -interface PluginsSetup { +export interface PluginsSetup { encryptedSavedObjects: EncryptedSavedObjectsPluginSetup; spaces: SpacesPluginSetup; } -interface PluginsStart { +export interface PluginsStart { encryptedSavedObjects: EncryptedSavedObjectsPluginStart; spaces: never; } export const plugin: PluginInitializer = () => ({ setup(core: CoreSetup, deps) { - for (const [name, namespaceType] of [ - [SAVED_OBJECT_WITH_SECRET_TYPE, 'single'], - [SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE, 'multiple'], - ] as Array<[string, SavedObjectsNamespaceType]>) { + for (const [name, namespaceType, hidden] of [ + [SAVED_OBJECT_WITH_SECRET_TYPE, 'single', false], + [HIDDEN_SAVED_OBJECT_WITH_SECRET_TYPE, 'single', true], + [SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE, 'multiple', false], + ] as Array<[string, SavedObjectsNamespaceType, boolean]>) { core.savedObjects.registerType({ name, - hidden: false, + hidden, namespaceType, mappings: deepFreeze({ properties: { @@ -68,7 +71,8 @@ export const plugin: PluginInitializer = mappings: deepFreeze({ properties: { publicProperty: { type: 'keyword' } } }), }); - core.http.createRouter().get( + const router = core.http.createRouter(); + router.get( { path: '/api/saved_objects/get-decrypted-as-internal-user/{type}/{id}', validate: { params: value => ({ value }) }, @@ -80,11 +84,9 @@ export const plugin: PluginInitializer = try { return response.ok({ - body: await encryptedSavedObjects.getDecryptedAsInternalUser( - request.params.type, - request.params.id, - { namespace } - ), + body: await encryptedSavedObjects + .getClient() + .getDecryptedAsInternalUser(request.params.type, request.params.id, { namespace }), }); } catch (err) { if (encryptedSavedObjects.isEncryptionError(err)) { @@ -95,6 +97,8 @@ export const plugin: PluginInitializer = } } ); + + registerHiddenSORoutes(router, core, deps, [HIDDEN_SAVED_OBJECT_WITH_SECRET_TYPE]); }, start() {}, stop() {}, diff --git a/x-pack/test/encrypted_saved_objects_api_integration/tests/encrypted_saved_objects_api.ts b/x-pack/test/encrypted_saved_objects_api_integration/tests/encrypted_saved_objects_api.ts index 54b1f00616c94..2c97640b8d650 100644 --- a/x-pack/test/encrypted_saved_objects_api_integration/tests/encrypted_saved_objects_api.ts +++ b/x-pack/test/encrypted_saved_objects_api_integration/tests/encrypted_saved_objects_api.ts @@ -14,6 +14,7 @@ export default function({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const SAVED_OBJECT_WITH_SECRET_TYPE = 'saved-object-with-secret'; + const HIDDEN_SAVED_OBJECT_WITH_SECRET_TYPE = 'hidden-saved-object-with-secret'; const SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE = 'saved-object-with-secret-and-multiple-spaces'; const SAVED_OBJECT_WITHOUT_SECRET_TYPE = 'saved-object-without-secret'; @@ -438,7 +439,7 @@ export default function({ getService }: FtrProviderContext) { afterEach(async () => { await es.deleteByQuery({ index: '.kibana', - q: `type:${SAVED_OBJECT_WITH_SECRET_TYPE} OR type:${SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE} OR type:${SAVED_OBJECT_WITHOUT_SECRET_TYPE}`, + q: `type:${SAVED_OBJECT_WITH_SECRET_TYPE} OR type:${HIDDEN_SAVED_OBJECT_WITH_SECRET_TYPE} OR type:${SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE} OR type:${SAVED_OBJECT_WITHOUT_SECRET_TYPE}`, refresh: true, }); }); @@ -452,6 +453,14 @@ export default function({ getService }: FtrProviderContext) { ); }); + describe('hidden type with `single` namespace saved object', () => { + runTests( + HIDDEN_SAVED_OBJECT_WITH_SECRET_TYPE, + () => '/api/hidden_saved_objects/', + (id, type) => generateRawId(id, type) + ); + }); + describe('with `multiple` namespace saved object', () => { runTests( SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE, From a9234ef034462107a71d8a2dafb9303fe95161fa Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Wed, 20 May 2020 12:54:16 +0200 Subject: [PATCH 058/129] Remove unused license check result from LP Security plugin (#66966) * remove unused license check result * remove outdated test * update licensing tests --- x-pack/legacy/plugins/security/index.ts | 8 -------- .../server/lib/__tests__/replace_injected_vars.js | 10 ---------- .../xpack_main/server/lib/replace_injected_vars.js | 2 +- x-pack/test/licensing_plugin/legacy/updates.ts | 3 --- 4 files changed, 1 insertion(+), 22 deletions(-) diff --git a/x-pack/legacy/plugins/security/index.ts b/x-pack/legacy/plugins/security/index.ts index b1dec2ce82c52..577b23f3418e8 100644 --- a/x-pack/legacy/plugins/security/index.ts +++ b/x-pack/legacy/plugins/security/index.ts @@ -72,14 +72,6 @@ export const security = (kibana: Record) => auditLogger: new AuditLogger(server, 'security', server.config(), xpackInfo), }); - // Legacy xPack Info endpoint returns whatever we return in a callback for `registerLicenseCheckResultsGenerator` - // and the result is consumed by the legacy plugins all over the place, so we should keep it here for now. We assume - // that when legacy callback is called license has been already propagated to the new platform security plugin and - // features are up to date. - xpackInfo - .feature(this.id) - .registerLicenseCheckResultsGenerator(() => securityPlugin.license.getFeatures()); - server.expose({ getUser: async (request: LegacyRequest) => securityPlugin.authc.getCurrentUser(KibanaRequest.from(request)), diff --git a/x-pack/legacy/plugins/xpack_main/server/lib/__tests__/replace_injected_vars.js b/x-pack/legacy/plugins/xpack_main/server/lib/__tests__/replace_injected_vars.js index ae929045cf570..cb70a7cb446a9 100644 --- a/x-pack/legacy/plugins/xpack_main/server/lib/__tests__/replace_injected_vars.js +++ b/x-pack/legacy/plugins/xpack_main/server/lib/__tests__/replace_injected_vars.js @@ -177,16 +177,6 @@ describe('replaceInjectedVars uiExport', () => { }, }); }); - - it('sends the originalInjectedVars if the license check result is not available', async () => { - const originalInjectedVars = { a: 1 }; - const request = buildRequest(); - const server = mockServer(); - server.plugins.xpack_main.info.feature().getLicenseCheckResults.returns(undefined); - - const newVars = await replaceInjectedVars(originalInjectedVars, request, server); - expect(newVars).to.eql(originalInjectedVars); - }); }); // creates a mock server object that defaults to being authenticated with a diff --git a/x-pack/legacy/plugins/xpack_main/server/lib/replace_injected_vars.js b/x-pack/legacy/plugins/xpack_main/server/lib/replace_injected_vars.js index 403bb4e2b334c..f09f97d44bfe8 100644 --- a/x-pack/legacy/plugins/xpack_main/server/lib/replace_injected_vars.js +++ b/x-pack/legacy/plugins/xpack_main/server/lib/replace_injected_vars.js @@ -20,7 +20,7 @@ export async function replaceInjectedVars(originalInjectedVars, request, server) } // not enough license info to make decision one way or another - if (!xpackInfo.isAvailable() || !xpackInfo.feature('security').getLicenseCheckResults()) { + if (!xpackInfo.isAvailable()) { return originalInjectedVars; } diff --git a/x-pack/test/licensing_plugin/legacy/updates.ts b/x-pack/test/licensing_plugin/legacy/updates.ts index 03b61b9db87f8..10661ec529dec 100644 --- a/x-pack/test/licensing_plugin/legacy/updates.ts +++ b/x-pack/test/licensing_plugin/legacy/updates.ts @@ -31,7 +31,6 @@ export default function(ftrContext: FtrProviderContext) { } = await supertest.get('/api/xpack/v1/info').expect(200); expect(legacyInitialLicense.license?.type).to.be('basic'); - expect(legacyInitialLicense.features).to.have.property('security'); expect(legacyInitialLicenseHeaders['kbn-xpack-sig']).to.be.a('string'); await scenario.startTrial(); @@ -42,7 +41,6 @@ export default function(ftrContext: FtrProviderContext) { .expect(200); expect(legacyTrialLicense.license?.type).to.be('trial'); - expect(legacyTrialLicense.features).to.have.property('security'); expect(legacyTrialLicenseHeaders['kbn-xpack-sig']).to.not.be( legacyInitialLicenseHeaders['kbn-xpack-sig'] ); @@ -52,7 +50,6 @@ export default function(ftrContext: FtrProviderContext) { const { body: legacyBasicLicense } = await supertest.get('/api/xpack/v1/info').expect(200); expect(legacyBasicLicense.license?.type).to.be('basic'); - expect(legacyBasicLicense.features).to.have.property('security'); // banner shown only when license expired not just deleted await testSubjects.missingOrFail('licenseExpiredBanner'); From 7f884532426fb14a22abca0ccaffab2426284a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez?= Date: Wed, 20 May 2020 13:27:34 +0200 Subject: [PATCH 059/129] [Logs UI] Restore call to `UsageCollector.countLogs` (#67051) --- x-pack/plugins/infra/server/routes/log_entries/summary.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/plugins/infra/server/routes/log_entries/summary.ts b/x-pack/plugins/infra/server/routes/log_entries/summary.ts index aa4421374ec12..c1d532fa5a083 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/summary.ts +++ b/x-pack/plugins/infra/server/routes/log_entries/summary.ts @@ -20,6 +20,7 @@ import { logEntriesSummaryResponseRT, } from '../../../common/http_api/log_entries'; import { parseFilterQuery } from '../../utils/serialized_query'; +import { UsageCollector } from '../../usage/usage_collector'; const escapeHatch = schema.object({}, { unknowns: 'allow' }); @@ -47,6 +48,8 @@ export const initLogEntriesSummaryRoute = ({ framework, logEntries }: InfraBacke parseFilterQuery(query) ); + UsageCollector.countLogs(); + return response.ok({ body: logEntriesSummaryResponseRT.encode({ data: { From 27fe2650b6ae3ae8d03f1d8f43ff82db250cef1d Mon Sep 17 00:00:00 2001 From: Diana Derevyankina <54894989+DziyanaDzeraviankina@users.noreply.github.com> Date: Wed, 20 May 2020 14:40:37 +0300 Subject: [PATCH 060/129] Move apm tutorial from apm plugin into apm_oss plugin (#66432) * Move apm tutorial from apm plugin into apm_oss plugin Closes #65629 * Fix types issues and some paths * Add unregisterTutorial to tutorials_registry.mock * Add apm path to .i18nrc.json to fix internationalization error * Rename apm path in .i18nrc.json into apmOss and revert some imports paths --- .i18nrc.json | 3 +- .../apm_oss/common/index_pattern_constants.ts | 20 + src/plugins/apm_oss/kibana.json | 4 +- .../plugins/apm_oss}/public/assets/apm.png | Bin src/plugins/apm_oss/public/index.ts | 29 + src/plugins/apm_oss/public/plugin.ts | 33 + src/plugins/apm_oss/public/types.ts | 27 + src/plugins/apm_oss/server/index.ts | 15 + src/plugins/apm_oss/server/plugin.ts | 22 +- .../apm_oss/server/tutorial/envs/on_prem.ts | 203 +++++ src/plugins/apm_oss/server/tutorial/index.ts | 93 ++ .../server/tutorial/index_pattern.json | 0 .../instructions/apm_agent_instructions.ts | 663 +++++++++++++++ .../instructions/apm_server_instructions.ts | 151 ++++ .../tutorials/tutorials_registry.mock.ts | 1 + .../services/tutorials/tutorials_registry.ts | 8 +- .../apm/common/index_pattern_constants.ts | 7 - .../Links/DiscoverLinks/DiscoverLink.tsx | 2 +- .../create_static_index_pattern.ts | 7 +- x-pack/plugins/apm/server/plugin.ts | 38 +- .../tutorial/{envs => }/elastic_cloud.ts | 6 +- .../apm/server/tutorial/envs/on_prem.ts | 246 ------ x-pack/plugins/apm/server/tutorial/index.ts | 113 --- .../instructions/apm_agent_instructions.ts | 805 ------------------ .../instructions/apm_server_instructions.ts | 149 ---- .../translations/translations/ja-JP.json | 226 ++--- .../translations/translations/zh-CN.json | 226 ++--- 27 files changed, 1522 insertions(+), 1575 deletions(-) create mode 100644 src/plugins/apm_oss/common/index_pattern_constants.ts rename {x-pack/plugins/apm => src/plugins/apm_oss}/public/assets/apm.png (100%) create mode 100644 src/plugins/apm_oss/public/index.ts create mode 100644 src/plugins/apm_oss/public/plugin.ts create mode 100644 src/plugins/apm_oss/public/types.ts create mode 100644 src/plugins/apm_oss/server/tutorial/envs/on_prem.ts create mode 100644 src/plugins/apm_oss/server/tutorial/index.ts rename {x-pack/plugins/apm => src/plugins/apm_oss}/server/tutorial/index_pattern.json (100%) create mode 100644 src/plugins/apm_oss/server/tutorial/instructions/apm_agent_instructions.ts create mode 100644 src/plugins/apm_oss/server/tutorial/instructions/apm_server_instructions.ts delete mode 100644 x-pack/plugins/apm/common/index_pattern_constants.ts rename x-pack/plugins/apm/server/tutorial/{envs => }/elastic_cloud.ts (94%) delete mode 100644 x-pack/plugins/apm/server/tutorial/envs/on_prem.ts delete mode 100644 x-pack/plugins/apm/server/tutorial/index.ts delete mode 100644 x-pack/plugins/apm/server/tutorial/instructions/apm_agent_instructions.ts delete mode 100644 x-pack/plugins/apm/server/tutorial/instructions/apm_server_instructions.ts diff --git a/.i18nrc.json b/.i18nrc.json index 034b9da799d3e..9af7f17067b8e 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -56,7 +56,8 @@ "visTypeVislib": "src/plugins/vis_type_vislib", "visTypeXy": "src/plugins/vis_type_xy", "visualizations": "src/plugins/visualizations", - "visualize": "src/plugins/visualize" + "visualize": "src/plugins/visualize", + "apmOss": "src/plugins/apm_oss" }, "exclude": [ "src/legacy/ui/ui_render/ui_render_mixin.js" diff --git a/src/plugins/apm_oss/common/index_pattern_constants.ts b/src/plugins/apm_oss/common/index_pattern_constants.ts new file mode 100644 index 0000000000000..4b1800d984ca1 --- /dev/null +++ b/src/plugins/apm_oss/common/index_pattern_constants.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 const APM_STATIC_INDEX_PATTERN_ID = 'apm_static_index_pattern_id'; diff --git a/src/plugins/apm_oss/kibana.json b/src/plugins/apm_oss/kibana.json index 7d9f0652a1139..46fecb09c7fb6 100644 --- a/src/plugins/apm_oss/kibana.json +++ b/src/plugins/apm_oss/kibana.json @@ -6,6 +6,6 @@ "configPath": [ "apm_oss" ], - "ui": false, - "requiredPlugins": [] + "ui": true, + "requiredPlugins": ["home"] } diff --git a/x-pack/plugins/apm/public/assets/apm.png b/src/plugins/apm_oss/public/assets/apm.png similarity index 100% rename from x-pack/plugins/apm/public/assets/apm.png rename to src/plugins/apm_oss/public/assets/apm.png diff --git a/src/plugins/apm_oss/public/index.ts b/src/plugins/apm_oss/public/index.ts new file mode 100644 index 0000000000000..4af80eec4389b --- /dev/null +++ b/src/plugins/apm_oss/public/index.ts @@ -0,0 +1,29 @@ +/* + * 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 { ApmOssPlugin } from './plugin'; + +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. +export function plugin() { + return new ApmOssPlugin(); +} +export { ApmOssPluginSetup, ApmOssPluginStart } from './types'; + +export { APM_STATIC_INDEX_PATTERN_ID } from '../common/index_pattern_constants'; diff --git a/src/plugins/apm_oss/public/plugin.ts b/src/plugins/apm_oss/public/plugin.ts new file mode 100644 index 0000000000000..86b2a0abd5ab7 --- /dev/null +++ b/src/plugins/apm_oss/public/plugin.ts @@ -0,0 +1,33 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { CoreSetup, CoreStart, Plugin } from 'kibana/public'; +import { ApmOssPluginSetup, ApmOssPluginStart } from './types'; + +export class ApmOssPlugin implements Plugin { + public setup(core: CoreSetup): ApmOssPluginSetup { + return {}; + } + + public start(core: CoreStart): ApmOssPluginStart { + return {}; + } + + public stop() {} +} diff --git a/src/plugins/apm_oss/public/types.ts b/src/plugins/apm_oss/public/types.ts new file mode 100644 index 0000000000000..96eb2081e372b --- /dev/null +++ b/src/plugins/apm_oss/public/types.ts @@ -0,0 +1,27 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface ApmOssPluginSetup {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface ApmOssPluginStart {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface AppPluginStartDependencies {} diff --git a/src/plugins/apm_oss/server/index.ts b/src/plugins/apm_oss/server/index.ts index bd0d23d62500d..d2e7321f39e7b 100644 --- a/src/plugins/apm_oss/server/index.ts +++ b/src/plugins/apm_oss/server/index.ts @@ -17,6 +17,7 @@ * under the License. */ import { schema, TypeOf } from '@kbn/config-schema'; +import apmIndexPattern from './tutorial/index_pattern.json'; import { PluginInitializerContext } from '../../../core/server'; import { APMOSSPlugin } from './plugin'; @@ -40,3 +41,17 @@ export function plugin(initializerContext: PluginInitializerContext) { export type APMOSSConfig = TypeOf; export { APMOSSPluginSetup } from './plugin'; + +export { apmIndexPattern }; + +export { + createNodeAgentInstructions, + createDjangoAgentInstructions, + createFlaskAgentInstructions, + createRailsAgentInstructions, + createRackAgentInstructions, + createJsAgentInstructions, + createGoAgentInstructions, + createJavaAgentInstructions, + createDotNetAgentInstructions, +} from './tutorial/instructions/apm_agent_instructions'; diff --git a/src/plugins/apm_oss/server/plugin.ts b/src/plugins/apm_oss/server/plugin.ts index 9b14d19da90c2..48aed9fa14011 100644 --- a/src/plugins/apm_oss/server/plugin.ts +++ b/src/plugins/apm_oss/server/plugin.ts @@ -18,18 +18,35 @@ */ import { Plugin, CoreSetup, PluginInitializerContext } from 'src/core/server'; import { Observable } from 'rxjs'; +import { take } from 'rxjs/operators'; import { APMOSSConfig } from './'; +import { HomeServerPluginSetup, TutorialProvider } from '../../home/server'; +import { tutorialProvider } from './tutorial'; export class APMOSSPlugin implements Plugin { constructor(private readonly initContext: PluginInitializerContext) { this.initContext = initContext; } - - public setup(core: CoreSetup) { + public async setup(core: CoreSetup, plugins: { home: HomeServerPluginSetup }) { const config$ = this.initContext.config.create(); + const config = await config$.pipe(take(1)).toPromise(); + + const apmTutorialProvider = tutorialProvider({ + indexPatternTitle: config.indexPattern, + indices: { + errorIndices: config.errorIndices, + metricsIndices: config.metricsIndices, + onboardingIndices: config.onboardingIndices, + sourcemapIndices: config.sourcemapIndices, + transactionIndices: config.transactionIndices, + }, + }); + plugins.home.tutorials.registerTutorial(apmTutorialProvider); + return { config$, + getRegisteredTutorialProvider: () => apmTutorialProvider, }; } @@ -39,4 +56,5 @@ export class APMOSSPlugin implements Plugin { export interface APMOSSPluginSetup { config$: Observable; + getRegisteredTutorialProvider(): TutorialProvider; } diff --git a/src/plugins/apm_oss/server/tutorial/envs/on_prem.ts b/src/plugins/apm_oss/server/tutorial/envs/on_prem.ts new file mode 100644 index 0000000000000..477aa36fe3a92 --- /dev/null +++ b/src/plugins/apm_oss/server/tutorial/envs/on_prem.ts @@ -0,0 +1,203 @@ +/* + * 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 { INSTRUCTION_VARIANT } from '../../../../home/server'; +import { + createWindowsServerInstructions, + createEditConfig, + createStartServerUnixSysv, + createStartServerUnix, + createDownloadServerRpm, + createDownloadServerDeb, + createDownloadServerOsx, +} from '../instructions/apm_server_instructions'; +import { + createNodeAgentInstructions, + createDjangoAgentInstructions, + createFlaskAgentInstructions, + createRailsAgentInstructions, + createRackAgentInstructions, + createJsAgentInstructions, + createGoAgentInstructions, + createJavaAgentInstructions, + createDotNetAgentInstructions, +} from '../instructions/apm_agent_instructions'; + +export function onPremInstructions({ + errorIndices, + transactionIndices, + metricsIndices, + sourcemapIndices, + onboardingIndices, +}: { + errorIndices: string; + transactionIndices: string; + metricsIndices: string; + sourcemapIndices: string; + onboardingIndices: string; +}) { + const EDIT_CONFIG = createEditConfig(); + const START_SERVER_UNIX = createStartServerUnix(); + const START_SERVER_UNIX_SYSV = createStartServerUnixSysv(); + + return { + instructionSets: [ + { + title: i18n.translate('apmOss.tutorial.apmServer.title', { + defaultMessage: 'APM Server', + }), + callOut: { + title: i18n.translate('apmOss.tutorial.apmServer.callOut.title', { + defaultMessage: 'Important: Updating to 7.0 or higher', + }), + message: i18n.translate('apmOss.tutorial.apmServer.callOut.message', { + defaultMessage: `Please make sure your APM Server is updated to 7.0 or higher. \ + You can also migrate your 6.x data with the migration assistant found in Kibana's management section.`, + }), + iconType: 'alert', + }, + instructionVariants: [ + { + id: INSTRUCTION_VARIANT.OSX, + instructions: [createDownloadServerOsx(), EDIT_CONFIG, START_SERVER_UNIX], + }, + { + id: INSTRUCTION_VARIANT.DEB, + instructions: [createDownloadServerDeb(), EDIT_CONFIG, START_SERVER_UNIX_SYSV], + }, + { + id: INSTRUCTION_VARIANT.RPM, + instructions: [createDownloadServerRpm(), EDIT_CONFIG, START_SERVER_UNIX_SYSV], + }, + { + id: INSTRUCTION_VARIANT.WINDOWS, + instructions: createWindowsServerInstructions(), + }, + ], + statusCheck: { + title: i18n.translate('apmOss.tutorial.apmServer.statusCheck.title', { + defaultMessage: 'APM Server status', + }), + text: i18n.translate('apmOss.tutorial.apmServer.statusCheck.text', { + defaultMessage: + 'Make sure APM Server is running before you start implementing the APM agents.', + }), + btnLabel: i18n.translate('apmOss.tutorial.apmServer.statusCheck.btnLabel', { + defaultMessage: 'Check APM Server status', + }), + success: i18n.translate('apmOss.tutorial.apmServer.statusCheck.successMessage', { + defaultMessage: 'You have correctly setup APM Server', + }), + error: i18n.translate('apmOss.tutorial.apmServer.statusCheck.errorMessage', { + defaultMessage: + 'No APM Server detected. Please make sure it is running and you have updated to 7.0 or higher.', + }), + esHitsCheck: { + index: onboardingIndices, + query: { + bool: { + filter: [ + { term: { 'processor.event': 'onboarding' } }, + { range: { 'observer.version_major': { gte: 7 } } }, + ], + }, + }, + }, + }, + }, + { + title: i18n.translate('apmOss.tutorial.apmAgents.title', { + defaultMessage: 'APM Agents', + }), + instructionVariants: [ + { + id: INSTRUCTION_VARIANT.JAVA, + instructions: createJavaAgentInstructions(), + }, + { + id: INSTRUCTION_VARIANT.JS, + instructions: createJsAgentInstructions(), + }, + { + id: INSTRUCTION_VARIANT.NODE, + instructions: createNodeAgentInstructions(), + }, + { + id: INSTRUCTION_VARIANT.DJANGO, + instructions: createDjangoAgentInstructions(), + }, + { + id: INSTRUCTION_VARIANT.FLASK, + instructions: createFlaskAgentInstructions(), + }, + { + id: INSTRUCTION_VARIANT.RAILS, + instructions: createRailsAgentInstructions(), + }, + { + id: INSTRUCTION_VARIANT.RACK, + instructions: createRackAgentInstructions(), + }, + { + id: INSTRUCTION_VARIANT.GO, + instructions: createGoAgentInstructions(), + }, + { + id: INSTRUCTION_VARIANT.DOTNET, + instructions: createDotNetAgentInstructions(), + }, + ], + statusCheck: { + title: i18n.translate('apmOss.tutorial.apmAgents.statusCheck.title', { + defaultMessage: 'Agent status', + }), + text: i18n.translate('apmOss.tutorial.apmAgents.statusCheck.text', { + defaultMessage: + 'Make sure your application is running and the agents are sending data.', + }), + btnLabel: i18n.translate('apmOss.tutorial.apmAgents.statusCheck.btnLabel', { + defaultMessage: 'Check agent status', + }), + success: i18n.translate('apmOss.tutorial.apmAgents.statusCheck.successMessage', { + defaultMessage: 'Data successfully received from one or more agents', + }), + error: i18n.translate('apmOss.tutorial.apmAgents.statusCheck.errorMessage', { + defaultMessage: 'No data has been received from agents yet', + }), + esHitsCheck: { + index: [errorIndices, transactionIndices, metricsIndices, sourcemapIndices], + query: { + bool: { + filter: [ + { + terms: { + 'processor.event': ['error', 'transaction', 'metric', 'sourcemap'], + }, + }, + { range: { 'observer.version_major': { gte: 7 } } }, + ], + }, + }, + }, + }, + }, + ], + }; +} diff --git a/src/plugins/apm_oss/server/tutorial/index.ts b/src/plugins/apm_oss/server/tutorial/index.ts new file mode 100644 index 0000000000000..aa775d007de30 --- /dev/null +++ b/src/plugins/apm_oss/server/tutorial/index.ts @@ -0,0 +1,93 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +import { onPremInstructions } from './envs/on_prem'; +import apmIndexPattern from './index_pattern.json'; +import { ArtifactsSchema, TutorialsCategory } from '../../../../../src/plugins/home/server'; +import { APM_STATIC_INDEX_PATTERN_ID } from '../../common/index_pattern_constants'; + +const apmIntro = i18n.translate('apmOss.tutorial.introduction', { + defaultMessage: 'Collect in-depth performance metrics and errors from inside your applications.', +}); + +export const tutorialProvider = ({ + indexPatternTitle, + indices, +}: { + indexPatternTitle: string; + indices: { + errorIndices: string; + transactionIndices: string; + metricsIndices: string; + sourcemapIndices: string; + onboardingIndices: string; + }; +}) => () => { + const savedObjects = [ + { + ...apmIndexPattern, + id: APM_STATIC_INDEX_PATTERN_ID, + attributes: { + ...apmIndexPattern.attributes, + title: indexPatternTitle, + }, + }, + ]; + + const artifacts: ArtifactsSchema = { + dashboards: [ + { + id: '8d3ed660-7828-11e7-8c47-65b845b5cfb3', + linkLabel: i18n.translate('apmOss.tutorial.specProvider.artifacts.dashboards.linkLabel', { + defaultMessage: 'APM dashboard', + }), + isOverview: true, + }, + ], + }; + + return { + id: 'apm', + name: i18n.translate('apmOss.tutorial.specProvider.name', { + defaultMessage: 'APM', + }), + category: TutorialsCategory.OTHER, + shortDescription: apmIntro, + longDescription: i18n.translate('apmOss.tutorial.specProvider.longDescription', { + defaultMessage: + 'Application Performance Monitoring (APM) collects in-depth \ +performance metrics and errors from inside your application. \ +It allows you to monitor the performance of thousands of applications in real time. \ +[Learn more]({learnMoreLink}).', + values: { + learnMoreLink: + '{config.docs.base_url}guide/en/apm/get-started/{config.docs.version}/index.html', + }, + }), + euiIconType: 'apmApp', + artifacts, + onPrem: onPremInstructions(indices), + previewImagePath: '/plugins/apmOss/assets/apm.png', + savedObjects, + savedObjectsInstallMsg: i18n.translate('apmOss.tutorial.specProvider.savedObjectsInstallMsg', { + defaultMessage: 'An APM index pattern is required for some features in the APM UI.', + }), + }; +}; diff --git a/x-pack/plugins/apm/server/tutorial/index_pattern.json b/src/plugins/apm_oss/server/tutorial/index_pattern.json similarity index 100% rename from x-pack/plugins/apm/server/tutorial/index_pattern.json rename to src/plugins/apm_oss/server/tutorial/index_pattern.json diff --git a/src/plugins/apm_oss/server/tutorial/instructions/apm_agent_instructions.ts b/src/plugins/apm_oss/server/tutorial/instructions/apm_agent_instructions.ts new file mode 100644 index 0000000000000..271bcab21172f --- /dev/null +++ b/src/plugins/apm_oss/server/tutorial/instructions/apm_agent_instructions.ts @@ -0,0 +1,663 @@ +/* + * 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'; + +export const createNodeAgentInstructions = (apmServerUrl = '', secretToken = '') => [ + { + title: i18n.translate('apmOss.tutorial.nodeClient.install.title', { + defaultMessage: 'Install the APM agent', + }), + textPre: i18n.translate('apmOss.tutorial.nodeClient.install.textPre', { + defaultMessage: 'Install the APM agent for Node.js as a dependency to your application.', + }), + commands: ['npm install elastic-apm-node --save'], + }, + { + title: i18n.translate('apmOss.tutorial.nodeClient.configure.title', { + defaultMessage: 'Configure the agent', + }), + textPre: i18n.translate('apmOss.tutorial.nodeClient.configure.textPre', { + defaultMessage: + 'Agents are libraries that run inside of your application process. \ +APM services are created programmatically based on the `serviceName`. \ +This agent supports a vararity of frameworks but can also be used with your custom stack.', + }), + commands: `// ${i18n.translate( + 'apmOss.tutorial.nodeClient.configure.commands.addThisToTheFileTopComment', + { + defaultMessage: 'Add this to the VERY top of the first file loaded in your app', + } + )} +var apm = require('elastic-apm-node').start({curlyOpen} + // ${i18n.translate( + 'apmOss.tutorial.nodeClient.configure.commands.setRequiredServiceNameComment', + { + defaultMessage: 'Override service name from package.json', + } + )} + // ${i18n.translate('apmOss.tutorial.nodeClient.configure.commands.allowedCharactersComment', { + defaultMessage: 'Allowed characters: a-z, A-Z, 0-9, -, _, and space', + })} + serviceName: '', + + // ${i18n.translate( + 'apmOss.tutorial.nodeClient.configure.commands.useIfApmRequiresTokenComment', + { + defaultMessage: 'Use if APM Server requires a token', + } + )} + secretToken: '${secretToken}', + + // ${i18n.translate( + 'apmOss.tutorial.nodeClient.configure.commands.setCustomApmServerUrlComment', + { + defaultMessage: 'Set custom APM Server URL (default: {defaultApmServerUrl})', + values: { defaultApmServerUrl: 'http://localhost:8200' }, + } + )} + serverUrl: '${apmServerUrl}' +{curlyClose})`.split('\n'), + textPost: i18n.translate('apmOss.tutorial.nodeClient.configure.textPost', { + defaultMessage: + 'See [the documentation]({documentationLink}) for advanced usage, including how to use with \ +[Babel/ES Modules]({babelEsModulesLink}).', + values: { + documentationLink: '{config.docs.base_url}guide/en/apm/agent/nodejs/current/index.html', + babelEsModulesLink: + '{config.docs.base_url}guide/en/apm/agent/nodejs/current/advanced-setup.html#es-modules', + }, + }), + }, +]; + +export const createDjangoAgentInstructions = (apmServerUrl = '', secretToken = '') => [ + { + title: i18n.translate('apmOss.tutorial.djangoClient.install.title', { + defaultMessage: 'Install the APM agent', + }), + textPre: i18n.translate('apmOss.tutorial.djangoClient.install.textPre', { + defaultMessage: 'Install the APM agent for Python as a dependency.', + }), + commands: ['$ pip install elastic-apm'], + }, + { + title: i18n.translate('apmOss.tutorial.djangoClient.configure.title', { + defaultMessage: 'Configure the agent', + }), + textPre: i18n.translate('apmOss.tutorial.djangoClient.configure.textPre', { + defaultMessage: + 'Agents are libraries that run inside of your application process. \ +APM services are created programmatically based on the `SERVICE_NAME`.', + }), + commands: `# ${i18n.translate( + 'apmOss.tutorial.djangoClient.configure.commands.addAgentComment', + { + defaultMessage: 'Add the agent to the installed apps', + } + )} +INSTALLED_APPS = ( + 'elasticapm.contrib.django', + # ... +) + +ELASTIC_APM = {curlyOpen} + # ${i18n.translate( + 'apmOss.tutorial.djangoClient.configure.commands.setRequiredServiceNameComment', + { + defaultMessage: 'Set required service name. Allowed characters:', + } + )} + # ${i18n.translate('apmOss.tutorial.djangoClient.configure.commands.allowedCharactersComment', { + defaultMessage: 'a-z, A-Z, 0-9, -, _, and space', + })} + 'SERVICE_NAME': '', + + # ${i18n.translate( + 'apmOss.tutorial.djangoClient.configure.commands.useIfApmServerRequiresTokenComment', + { + defaultMessage: 'Use if APM Server requires a token', + } + )} + 'SECRET_TOKEN': '${secretToken}', + + # ${i18n.translate( + 'apmOss.tutorial.djangoClient.configure.commands.setCustomApmServerUrlComment', + { + defaultMessage: 'Set custom APM Server URL (default: {defaultApmServerUrl})', + values: { defaultApmServerUrl: 'http://localhost:8200' }, + } + )} + 'SERVER_URL': '${apmServerUrl}', +{curlyClose} + +# ${i18n.translate('apmOss.tutorial.djangoClient.configure.commands.addTracingMiddlewareComment', { + defaultMessage: 'To send performance metrics, add our tracing middleware:', + })} +MIDDLEWARE = ( + 'elasticapm.contrib.django.middleware.TracingMiddleware', + #... +)`.split('\n'), + textPost: i18n.translate('apmOss.tutorial.djangoClient.configure.textPost', { + defaultMessage: 'See the [documentation]({documentationLink}) for advanced usage.', + values: { + documentationLink: + '{config.docs.base_url}guide/en/apm/agent/python/current/django-support.html', + }, + }), + }, +]; + +export const createFlaskAgentInstructions = (apmServerUrl = '', secretToken = '') => [ + { + title: i18n.translate('apmOss.tutorial.flaskClient.install.title', { + defaultMessage: 'Install the APM agent', + }), + textPre: i18n.translate('apmOss.tutorial.flaskClient.install.textPre', { + defaultMessage: 'Install the APM agent for Python as a dependency.', + }), + commands: ['$ pip install elastic-apm[flask]'], + }, + { + title: i18n.translate('apmOss.tutorial.flaskClient.configure.title', { + defaultMessage: 'Configure the agent', + }), + textPre: i18n.translate('apmOss.tutorial.flaskClient.configure.textPre', { + defaultMessage: + 'Agents are libraries that run inside of your application process. \ +APM services are created programmatically based on the `SERVICE_NAME`.', + }), + commands: `# ${i18n.translate( + 'apmOss.tutorial.flaskClient.configure.commands.initializeUsingEnvironmentVariablesComment', + { + defaultMessage: 'initialize using environment variables', + } + )} +from elasticapm.contrib.flask import ElasticAPM +app = Flask(__name__) +apm = ElasticAPM(app) + +# ${i18n.translate('apmOss.tutorial.flaskClient.configure.commands.configureElasticApmComment', { + defaultMessage: "or configure to use ELASTIC_APM in your application's settings", + })} +from elasticapm.contrib.flask import ElasticAPM +app.config['ELASTIC_APM'] = {curlyOpen} + # ${i18n.translate( + 'apmOss.tutorial.flaskClient.configure.commands.setRequiredServiceNameComment', + { + defaultMessage: 'Set required service name. Allowed characters:', + } + )} + # ${i18n.translate('apmOss.tutorial.flaskClient.configure.commands.allowedCharactersComment', { + defaultMessage: 'a-z, A-Z, 0-9, -, _, and space', + })} + 'SERVICE_NAME': '', + + # ${i18n.translate( + 'apmOss.tutorial.flaskClient.configure.commands.useIfApmServerRequiresTokenComment', + { + defaultMessage: 'Use if APM Server requires a token', + } + )} + 'SECRET_TOKEN': '${secretToken}', + + # ${i18n.translate( + 'apmOss.tutorial.flaskClient.configure.commands.setCustomApmServerUrlComment', + { + defaultMessage: 'Set custom APM Server URL (default: {defaultApmServerUrl})', + values: { defaultApmServerUrl: 'http://localhost:8200' }, + } + )} + 'SERVER_URL': '${apmServerUrl}', +{curlyClose} + +apm = ElasticAPM(app)`.split('\n'), + textPost: i18n.translate('apmOss.tutorial.flaskClient.configure.textPost', { + defaultMessage: 'See the [documentation]({documentationLink}) for advanced usage.', + values: { + documentationLink: + '{config.docs.base_url}guide/en/apm/agent/python/current/flask-support.html', + }, + }), + }, +]; + +export const createRailsAgentInstructions = (apmServerUrl = '', secretToken = '') => [ + { + title: i18n.translate('apmOss.tutorial.railsClient.install.title', { + defaultMessage: 'Install the APM agent', + }), + textPre: i18n.translate('apmOss.tutorial.railsClient.install.textPre', { + defaultMessage: 'Add the agent to your Gemfile.', + }), + commands: [`gem 'elastic-apm'`], + }, + { + title: i18n.translate('apmOss.tutorial.railsClient.configure.title', { + defaultMessage: 'Configure the agent', + }), + textPre: i18n.translate('apmOss.tutorial.railsClient.configure.textPre', { + defaultMessage: + 'APM is automatically started when your app boots. Configure the agent, by creating the config file {configFile}', + values: { configFile: '`config/elastic_apm.yml`' }, + }), + commands: `# config/elastic_apm.yml: + +# Set service name - allowed characters: a-z, A-Z, 0-9, -, _ and space +# Defaults to the name of your Rails app +# service_name: 'my-service' + +# Use if APM Server requires a token +# secret_token: '${secretToken}' + +# Set custom APM Server URL (default: http://localhost:8200) +# server_url: '${apmServerUrl || 'http://localhost:8200'}'`.split('\n'), + textPost: i18n.translate('apmOss.tutorial.railsClient.configure.textPost', { + defaultMessage: + 'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n', + values: { + documentationLink: '{config.docs.base_url}guide/en/apm/agent/ruby/current/index.html', + }, + }), + }, +]; + +export const createRackAgentInstructions = (apmServerUrl = '', secretToken = '') => [ + { + title: i18n.translate('apmOss.tutorial.rackClient.install.title', { + defaultMessage: 'Install the APM agent', + }), + textPre: i18n.translate('apmOss.tutorial.rackClient.install.textPre', { + defaultMessage: 'Add the agent to your Gemfile.', + }), + commands: [`gem 'elastic-apm'`], + }, + { + title: i18n.translate('apmOss.tutorial.rackClient.configure.title', { + defaultMessage: 'Configure the agent', + }), + textPre: i18n.translate('apmOss.tutorial.rackClient.configure.textPre', { + defaultMessage: + 'For Rack or a compatible framework (e.g. Sinatra), include the middleware in your app and start the agent.', + }), + commands: `# config.ru + require 'sinatra/base' + + class MySinatraApp < Sinatra::Base + use ElasticAPM::Middleware + + # ... + end + + ElasticAPM.start( + app: MySinatraApp, # ${i18n.translate( + 'apmOss.tutorial.rackClient.configure.commands.requiredComment', + { + defaultMessage: 'required', + } + )} + config_file: '' # ${i18n.translate( + 'apmOss.tutorial.rackClient.configure.commands.optionalComment', + { + defaultMessage: 'optional, defaults to config/elastic_apm.yml', + } + )} + ) + + run MySinatraApp + + at_exit {curlyOpen} ElasticAPM.stop {curlyClose}`.split('\n'), + }, + { + title: i18n.translate('apmOss.tutorial.rackClient.createConfig.title', { + defaultMessage: 'Create config file', + }), + textPre: i18n.translate('apmOss.tutorial.rackClient.createConfig.textPre', { + defaultMessage: 'Create a config file {configFile}:', + values: { configFile: '`config/elastic_apm.yml`' }, + }), + commands: `# config/elastic_apm.yml: + +# ${i18n.translate('apmOss.tutorial.rackClient.createConfig.commands.setServiceNameComment', { + defaultMessage: 'Set service name - allowed characters: a-z, A-Z, 0-9, -, _ and space', + })} +# ${i18n.translate( + 'apmOss.tutorial.rackClient.createConfig.commands.defaultsToTheNameOfRackAppClassComment', + { + defaultMessage: "Defaults to the name of your Rack app's class.", + } + )} +# service_name: 'my-service' + +# ${i18n.translate( + 'apmOss.tutorial.rackClient.createConfig.commands.useIfApmServerRequiresTokenComment', + { + defaultMessage: 'Use if APM Server requires a token', + } + )} +# secret_token: '${secretToken}' + +# ${i18n.translate('apmOss.tutorial.rackClient.createConfig.commands.setCustomApmServerComment', { + defaultMessage: 'Set custom APM Server URL (default: {defaultServerUrl})', + values: { defaultServerUrl: 'http://localhost:8200' }, + })} +# server_url: '${apmServerUrl || 'http://localhost:8200'}'`.split('\n'), + textPost: i18n.translate('apmOss.tutorial.rackClient.createConfig.textPost', { + defaultMessage: + 'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n', + values: { + documentationLink: '{config.docs.base_url}guide/en/apm/agent/ruby/current/index.html', + }, + }), + }, +]; + +export const createJsAgentInstructions = (apmServerUrl = '') => [ + { + title: i18n.translate('apmOss.tutorial.jsClient.enableRealUserMonitoring.title', { + defaultMessage: 'Enable Real User Monitoring support in APM Server', + }), + textPre: i18n.translate('apmOss.tutorial.jsClient.enableRealUserMonitoring.textPre', { + defaultMessage: + 'APM Server disables RUM support by default. See the [documentation]({documentationLink}) \ +for details on how to enable RUM support.', + values: { + documentationLink: + '{config.docs.base_url}guide/en/apm/server/{config.docs.version}/configuration-rum.html', + }, + }), + }, + { + title: i18n.translate('apmOss.tutorial.jsClient.installDependency.title', { + defaultMessage: 'Set up the Agent as a dependency', + }), + textPre: i18n.translate('apmOss.tutorial.jsClient.installDependency.textPre', { + defaultMessage: + 'You can install the Agent as a dependency to your application with \ +`npm install @elastic/apm-rum --save`.\n\n\ +The Agent can then be initialized and configured in your application like this:', + }), + commands: `import {curlyOpen} init as initApm {curlyClose} from '@elastic/apm-rum' +var apm = initApm({curlyOpen} + + // ${i18n.translate( + 'apmOss.tutorial.jsClient.installDependency.commands.setRequiredServiceNameComment', + { + defaultMessage: + 'Set required service name (allowed characters: a-z, A-Z, 0-9, -, _, and space)', + } + )} + serviceName: 'your-app-name', + + // ${i18n.translate( + 'apmOss.tutorial.jsClient.installDependency.commands.setCustomApmServerUrlComment', + { + defaultMessage: 'Set custom APM Server URL (default: {defaultApmServerUrl})', + values: { defaultApmServerUrl: 'http://localhost:8200' }, + } + )} + serverUrl: '${apmServerUrl}', + + // ${i18n.translate( + 'apmOss.tutorial.jsClient.installDependency.commands.setServiceVersionComment', + { + defaultMessage: 'Set service version (required for source map feature)', + } + )} + serviceVersion: '' +{curlyClose})`.split('\n'), + textPost: i18n.translate('apmOss.tutorial.jsClient.installDependency.textPost', { + defaultMessage: + 'Framework integrations, like React or Angular, have custom dependencies. \ +See the [integration documentation]({docLink}) for more information.', + values: { + docLink: + '{config.docs.base_url}guide/en/apm/agent/rum-js/current/framework-integrations.html', + }, + }), + }, + { + title: i18n.translate('apmOss.tutorial.jsClient.scriptTags.title', { + defaultMessage: 'Set up the Agent with Script Tags', + }), + textPre: i18n.translate('apmOss.tutorial.jsClient.scriptTags.textPre', { + defaultMessage: + "Alternatively, you can use Script tags to set up and configure the Agent. \ +Add a ` + +`.split('\n'), + }, +]; + +export const createGoAgentInstructions = (apmServerUrl = '', secretToken = '') => [ + { + title: i18n.translate('apmOss.tutorial.goClient.install.title', { + defaultMessage: 'Install the APM agent', + }), + textPre: i18n.translate('apmOss.tutorial.goClient.install.textPre', { + defaultMessage: 'Install the APM agent packages for Go.', + }), + commands: ['go get go.elastic.co/apm'], + }, + { + title: i18n.translate('apmOss.tutorial.goClient.configure.title', { + defaultMessage: 'Configure the agent', + }), + textPre: i18n.translate('apmOss.tutorial.goClient.configure.textPre', { + defaultMessage: + 'Agents are libraries that run inside of your application process. \ +APM services are created programmatically based on the executable \ +file name, or the `ELASTIC_APM_SERVICE_NAME` environment variable.', + }), + commands: `# ${i18n.translate( + 'apmOss.tutorial.goClient.configure.commands.initializeUsingEnvironmentVariablesComment', + { + defaultMessage: 'Initialize using environment variables:', + } + )} + +# ${i18n.translate('apmOss.tutorial.goClient.configure.commands.setServiceNameComment', { + defaultMessage: 'Set the service name. Allowed characters: # a-z, A-Z, 0-9, -, _, and space.', + })} +# ${i18n.translate('apmOss.tutorial.goClient.configure.commands.usedExecutableNameComment', { + defaultMessage: + 'If ELASTIC_APM_SERVICE_NAME is not specified, the executable name will be used.', + })} +export ELASTIC_APM_SERVICE_NAME= + +# ${i18n.translate('apmOss.tutorial.goClient.configure.commands.setCustomApmServerUrlComment', { + defaultMessage: 'Set custom APM Server URL (default: {defaultApmServerUrl})', + values: { defaultApmServerUrl: 'http://localhost:8200' }, + })} +export ELASTIC_APM_SERVER_URL=${apmServerUrl} + +# ${i18n.translate('apmOss.tutorial.goClient.configure.commands.useIfApmRequiresTokenComment', { + defaultMessage: 'Use if APM Server requires a token', + })} +export ELASTIC_APM_SECRET_TOKEN=${secretToken} +`.split('\n'), + textPost: i18n.translate('apmOss.tutorial.goClient.configure.textPost', { + defaultMessage: 'See the [documentation]({documentationLink}) for advanced configuration.', + values: { + documentationLink: '{config.docs.base_url}guide/en/apm/agent/go/current/configuration.html', + }, + }), + }, + { + title: i18n.translate('apmOss.tutorial.goClient.instrument.title', { + defaultMessage: 'Instrument your application', + }), + textPre: i18n.translate('apmOss.tutorial.goClient.instrument.textPre', { + defaultMessage: + 'Instrument your Go application by using one of the provided instrumentation modules or \ +by using the tracer API directly.', + }), + commands: `\ +import ( + "net/http" + + "go.elastic.co/apm/module/apmhttp" +) + +func main() {curlyOpen} + mux := http.NewServeMux() + ... + http.ListenAndServe(":8080", apmhttp.Wrap(mux)) +{curlyClose} +`.split('\n'), + textPost: i18n.translate('apmOss.tutorial.goClient.instrument.textPost', { + defaultMessage: + 'See the [documentation]({documentationLink}) for a detailed \ +guide to instrumenting Go source code.', + values: { + documentationLink: + '{config.docs.base_url}guide/en/apm/agent/go/current/instrumenting-source.html', + }, + }), + }, +]; + +export const createJavaAgentInstructions = (apmServerUrl = '', secretToken = '') => [ + { + title: i18n.translate('apmOss.tutorial.javaClient.download.title', { + defaultMessage: 'Download the APM agent', + }), + textPre: i18n.translate('apmOss.tutorial.javaClient.download.textPre', { + defaultMessage: + 'Download the agent jar from [Maven Central]({mavenCentralLink}). \ +Do **not** add the agent as a dependency to your application.', + values: { + mavenCentralLink: 'http://search.maven.org/#search%7Cga%7C1%7Ca%3Aelastic-apm-agent', + }, + }), + }, + { + title: i18n.translate('apmOss.tutorial.javaClient.startApplication.title', { + defaultMessage: 'Start your application with the javaagent flag', + }), + textPre: i18n.translate('apmOss.tutorial.javaClient.startApplication.textPre', { + defaultMessage: + 'Add the `-javaagent` flag and configure the agent with system properties.\n\n \ +* Set required service name (allowed characters: a-z, A-Z, 0-9, -, _, and space)\n \ +* Set custom APM Server URL (default: {customApmServerUrl})\n \ +* Set the base package of your application', + values: { customApmServerUrl: 'http://localhost:8200' }, + }), + commands: `java -javaagent:/path/to/elastic-apm-agent-.jar \\ + -Delastic.apm.service_name=my-application \\ + -Delastic.apm.server_urls=${apmServerUrl || 'http://localhost:8200'} \\ + -Delastic.apm.secret_token=${secretToken} \\ + -Delastic.apm.application_packages=org.example \\ + -jar my-application.jar`.split('\n'), + textPost: i18n.translate('apmOss.tutorial.javaClient.startApplication.textPost', { + defaultMessage: + 'See the [documentation]({documentationLink}) for configuration options and advanced \ +usage.', + values: { + documentationLink: '{config.docs.base_url}guide/en/apm/agent/java/current/index.html', + }, + }), + }, +]; + +export const createDotNetAgentInstructions = (apmServerUrl = '', secretToken = '') => [ + { + title: i18n.translate('apmOss.tutorial.dotNetClient.download.title', { + defaultMessage: 'Download the APM agent', + }), + textPre: i18n.translate('apmOss.tutorial.dotNetClient.download.textPre', { + defaultMessage: + 'Add the the agent package(s) from [NuGet]({allNuGetPackagesLink}) to your .NET application. There are multiple \ + NuGet packages available for different use cases. \n\nFor an ASP.NET Core application with Entity Framework \ + Core download the [Elastic.Apm.NetCoreAll]({netCoreAllApmPackageLink}) package. This package will automatically add every \ + agent component to your application. \n\n In case you would like to to minimize the dependencies, you can use the \ + [Elastic.Apm.AspNetCore]({aspNetCorePackageLink}) package for just \ + ASP.NET Core monitoring or the [Elastic.Apm.EfCore]({efCorePackageLink}) package for just Entity Framework Core monitoring. \n\n \ + In case you only want to use the public Agent API for manual instrumentation use the [Elastic.Apm]({elasticApmPackageLink}) package.', + values: { + allNuGetPackagesLink: 'https://www.nuget.org/packages?q=Elastic.apm', + netCoreAllApmPackageLink: 'https://www.nuget.org/packages/Elastic.Apm.NetCoreAll', + aspNetCorePackageLink: 'https://www.nuget.org/packages/Elastic.Apm.AspNetCore', + efCorePackageLink: 'https://www.nuget.org/packages/Elastic.Apm.EntityFrameworkCore', + elasticApmPackageLink: 'https://www.nuget.org/packages/Elastic.Apm', + }, + }), + }, + { + title: i18n.translate('apmOss.tutorial.dotNetClient.configureApplication.title', { + defaultMessage: 'Add the agent to the application', + }), + textPre: i18n.translate('apmOss.tutorial.dotNetClient.configureApplication.textPre', { + defaultMessage: + 'In case of ASP.NET Core with the `Elastic.Apm.NetCoreAll` package, call the `UseAllElasticApm` \ + method in the `Configure` method within the `Startup.cs` file.', + }), + commands: `public class Startup +{curlyOpen} + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + {curlyOpen} + app.UseAllElasticApm(Configuration); + //…rest of the method + {curlyClose} + //…rest of the class +{curlyClose}`.split('\n'), + textPost: i18n.translate('apmOss.tutorial.dotNetClient.configureApplication.textPost', { + defaultMessage: + 'Passing an `IConfiguration` instance is optional and by doing so, the agent will read config settings through this \ + `IConfiguration` instance (e.g. from the `appsettings.json` file).', + }), + }, + { + title: i18n.translate('apmOss.tutorial.dotNetClient.configureAgent.title', { + defaultMessage: 'Sample appsettings.json file:', + }), + commands: `{curlyOpen} + "ElasticApm": {curlyOpen} + "SecretToken": "${secretToken}", + "ServerUrls": "${apmServerUrl || + 'http://localhost:8200'}", //Set custom APM Server URL (default: http://localhost:8200) + "ServiceName" : "MyApp", //allowed characters: a-z, A-Z, 0-9, -, _, and space. Default is the entry assembly of the application + {curlyClose} +{curlyClose}`.split('\n'), + textPost: i18n.translate('apmOss.tutorial.dotNetClient.configureAgent.textPost', { + defaultMessage: + 'In case you don’t pass an `IConfiguration` instance to the agent (e.g. in case of non ASP.NET Core applications) \ + you can also configure the agent through environment variables. \n \ + See [the documentation]({documentationLink}) for advanced usage.', + values: { + documentationLink: + '{config.docs.base_url}guide/en/apm/agent/dotnet/current/configuration.html', + }, + }), + }, +]; diff --git a/src/plugins/apm_oss/server/tutorial/instructions/apm_server_instructions.ts b/src/plugins/apm_oss/server/tutorial/instructions/apm_server_instructions.ts new file mode 100644 index 0000000000000..228c4f02ac9e8 --- /dev/null +++ b/src/plugins/apm_oss/server/tutorial/instructions/apm_server_instructions.ts @@ -0,0 +1,151 @@ +/* + * 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'; + +export const createEditConfig = () => ({ + title: i18n.translate('apmOss.tutorial.editConfig.title', { + defaultMessage: 'Edit the configuration', + }), + textPre: i18n.translate('apmOss.tutorial.editConfig.textPre', { + defaultMessage: + "If you're using an X-Pack secured version of Elastic Stack, you must specify \ +credentials in the `apm-server.yml` config file.", + }), + commands: [ + 'output.elasticsearch:', + ' hosts: [""]', + ' username: ', + ' password: ', + ], +}); + +const createStartServer = () => ({ + title: i18n.translate('apmOss.tutorial.startServer.title', { + defaultMessage: 'Start APM Server', + }), + textPre: i18n.translate('apmOss.tutorial.startServer.textPre', { + defaultMessage: + 'The server processes and stores application performance metrics in Elasticsearch.', + }), +}); + +export function createStartServerUnixSysv() { + const START_SERVER = createStartServer(); + + return { + title: START_SERVER.title, + textPre: START_SERVER.textPre, + commands: ['service apm-server start'], + }; +} + +export function createStartServerUnix() { + const START_SERVER = createStartServer(); + + return { + title: START_SERVER.title, + textPre: START_SERVER.textPre, + commands: ['./apm-server -e'], + }; +} + +const createDownloadServerTitle = () => + i18n.translate('apmOss.tutorial.downloadServer.title', { + defaultMessage: 'Download and unpack APM Server', + }); + +export const createDownloadServerOsx = () => ({ + title: createDownloadServerTitle(), + commands: [ + 'curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-{config.kibana.version}-darwin-x86_64.tar.gz', + 'tar xzvf apm-server-{config.kibana.version}-darwin-x86_64.tar.gz', + 'cd apm-server-{config.kibana.version}-darwin-x86_64/', + ], +}); + +export const createDownloadServerDeb = () => ({ + title: createDownloadServerTitle(), + commands: [ + 'curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-{config.kibana.version}-amd64.deb', + 'sudo dpkg -i apm-server-{config.kibana.version}-amd64.deb', + ], + textPost: i18n.translate('apmOss.tutorial.downloadServerTitle', { + defaultMessage: 'Looking for the 32-bit packages? See the [Download page]({downloadPageLink}).', + values: { + downloadPageLink: '{config.docs.base_url}downloads/apm/apm-server', + }, + }), +}); + +export const createDownloadServerRpm = () => ({ + title: createDownloadServerTitle(), + commands: [ + 'curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-{config.kibana.version}-x86_64.rpm', + 'sudo rpm -vi apm-server-{config.kibana.version}-x86_64.rpm', + ], + textPost: i18n.translate('apmOss.tutorial.downloadServerRpm', { + defaultMessage: 'Looking for the 32-bit packages? See the [Download page]({downloadPageLink}).', + values: { + downloadPageLink: '{config.docs.base_url}downloads/apm/apm-server', + }, + }), +}); + +export function createWindowsServerInstructions() { + const START_SERVER = createStartServer(); + + return [ + { + title: createDownloadServerTitle(), + textPre: i18n.translate('apmOss.tutorial.windowsServerInstructions.textPre', { + defaultMessage: + '1. Download the APM Server Windows zip file from the \ +[Download page]({downloadPageLink}).\n2. Extract the contents of \ +the zip file into {zipFileExtractFolder}.\n3. Rename the {apmServerDirectory} \ +directory to `APM-Server`.\n4. Open a PowerShell prompt as an Administrator \ +(right-click the PowerShell icon and select \ +**Run As Administrator**). If you are running Windows XP, you might need to download and install \ +PowerShell.\n5. From the PowerShell prompt, run the following commands to install APM Server as a Windows service:', + values: { + downloadPageLink: 'https://www.elastic.co/downloads/apm/apm-server', + zipFileExtractFolder: '`C:\\Program Files`', + apmServerDirectory: '`apm-server-{config.kibana.version}-windows`', + }, + }), + commands: [`cd 'C:\\Program Files\\APM-Server'`, `.\\install-service-apm-server.ps1`], + textPost: i18n.translate('apmOss.tutorial.windowsServerInstructions.textPost', { + defaultMessage: + 'Note: If script execution is disabled on your system, \ +you need to set the execution policy for the current session \ +to allow the script to run. For example: {command}.', + values: { + command: + '`PowerShell.exe -ExecutionPolicy UnRestricted -File .\\install-service-apm-server.ps1`', + }, + }), + }, + createEditConfig(), + { + title: START_SERVER.title, + textPre: START_SERVER.textPre, + commands: ['Start-Service apm-server'], + }, + ]; +} diff --git a/src/plugins/home/server/services/tutorials/tutorials_registry.mock.ts b/src/plugins/home/server/services/tutorials/tutorials_registry.mock.ts index b54b0be4ea2b7..5ff0152062f4b 100644 --- a/src/plugins/home/server/services/tutorials/tutorials_registry.mock.ts +++ b/src/plugins/home/server/services/tutorials/tutorials_registry.mock.ts @@ -26,6 +26,7 @@ import { const createSetupMock = (): jest.Mocked => { const setup = { registerTutorial: jest.fn(), + unregisterTutorial: jest.fn(), addScopedTutorialContextFactory: jest.fn(), }; return setup; diff --git a/src/plugins/home/server/services/tutorials/tutorials_registry.ts b/src/plugins/home/server/services/tutorials/tutorials_registry.ts index e820924d7608d..ed28e42dbcf99 100644 --- a/src/plugins/home/server/services/tutorials/tutorials_registry.ts +++ b/src/plugins/home/server/services/tutorials/tutorials_registry.ts @@ -28,7 +28,7 @@ import { tutorialSchema } from './lib/tutorial_schema'; import { builtInTutorials } from '../../tutorials/register'; export class TutorialsRegistry { - private readonly tutorialProviders: TutorialProvider[] = []; // pre-register all the tutorials we know we want in here + private tutorialProviders: TutorialProvider[] = []; // pre-register all the tutorials we know we want in here private readonly scopedTutorialContextFactories: TutorialContextFactory[] = []; public setup(core: CoreSetup) { @@ -63,6 +63,12 @@ export class TutorialsRegistry { this.tutorialProviders.push(specProvider); }, + unregisterTutorial: (specProvider: TutorialProvider) => { + this.tutorialProviders = this.tutorialProviders.filter( + provider => provider !== specProvider + ); + }, + addScopedTutorialContextFactory: ( scopedTutorialContextFactory: ScopedTutorialContextFactory ) => { diff --git a/x-pack/plugins/apm/common/index_pattern_constants.ts b/x-pack/plugins/apm/common/index_pattern_constants.ts deleted file mode 100644 index bedda56452e0a..0000000000000 --- a/x-pack/plugins/apm/common/index_pattern_constants.ts +++ /dev/null @@ -1,7 +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. - */ - -export const APM_STATIC_INDEX_PATTERN_ID = 'apm_static_index_pattern_id'; diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLink.tsx index a80d1338dd7be..8c3e2c2396cbd 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLink.tsx @@ -11,7 +11,7 @@ import url from 'url'; import rison, { RisonValue } from 'rison-node'; import { useLocation } from '../../../../hooks/useLocation'; import { getTimepickerRisonData } from '../rison_helpers'; -import { APM_STATIC_INDEX_PATTERN_ID } from '../../../../../common/index_pattern_constants'; +import { APM_STATIC_INDEX_PATTERN_ID } from '../../../../../../../../src/plugins/apm_oss/public'; import { useApmPluginContext } from '../../../../hooks/useApmPluginContext'; import { AppMountContextBasePath } from '../../../../context/ApmPluginContext'; diff --git a/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts b/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts index 16546bc6070c2..2e9087b238406 100644 --- a/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts +++ b/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts @@ -3,10 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import apmIndexPattern from '../../tutorial/index_pattern.json'; -import { APM_STATIC_INDEX_PATTERN_ID } from '../../../common/index_pattern_constants'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SavedObjectsErrorHelpers } from '../../../../../../src/core/server/saved_objects'; +import { SavedObjectsErrorHelpers } from '../../../../../../src/core/server'; +import { apmIndexPattern } from '../../../../../../src/plugins/apm_oss/server'; +import { APM_STATIC_INDEX_PATTERN_ID } from '../../../../../../src/plugins/apm_oss/public'; import { hasHistoricalAgentData } from '../services/get_services/has_historical_agent_data'; import { Setup } from '../helpers/setup_request'; import { APMRequestHandlerContext } from '../../routes/typings'; diff --git a/x-pack/plugins/apm/server/plugin.ts b/x-pack/plugins/apm/server/plugin.ts index f5755f998dd32..9a405030e1df0 100644 --- a/x-pack/plugins/apm/server/plugin.ts +++ b/x-pack/plugins/apm/server/plugin.ts @@ -3,6 +3,7 @@ * 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'; import { PluginInitializerContext, Plugin, @@ -25,7 +26,6 @@ import { createApmApi } from './routes/create_apm_api'; import { getApmIndices } from './lib/settings/apm_indices/get_apm_indices'; import { APMConfig, mergeConfigs, APMXPackConfig } from '.'; import { HomeServerPluginSetup } from '../../../../src/plugins/home/server'; -import { tutorialProvider } from './tutorial'; import { CloudSetup } from '../../cloud/server'; import { getInternalSavedObjectsClient } from './lib/helpers/get_internal_saved_objects_client'; import { LicensingPluginSetup } from '../../licensing/public'; @@ -34,6 +34,7 @@ import { createApmTelemetry } from './lib/apm_telemetry'; import { PluginSetupContract as FeaturesPluginSetup } from '../../../plugins/features/server'; import { APM_FEATURE } from './feature'; import { apmIndices, apmTelemetry } from './saved_objects'; +import { createElasticCloudInstructions } from './tutorial/elastic_cloud'; export interface APMPluginSetup { config$: Observable; @@ -96,20 +97,27 @@ export class APMPlugin implements Plugin { }); } - plugins.home.tutorials.registerTutorial( - tutorialProvider({ - isEnabled: this.currentConfig['xpack.apm.ui.enabled'], - indexPatternTitle: this.currentConfig['apm_oss.indexPattern'], - cloud: plugins.cloud, - indices: { - errorIndices: this.currentConfig['apm_oss.errorIndices'], - metricsIndices: this.currentConfig['apm_oss.metricsIndices'], - onboardingIndices: this.currentConfig['apm_oss.onboardingIndices'], - sourcemapIndices: this.currentConfig['apm_oss.sourcemapIndices'], - transactionIndices: this.currentConfig['apm_oss.transactionIndices'] - } - }) - ); + const ossTutorialProvider = plugins.apmOss.getRegisteredTutorialProvider(); + plugins.home.tutorials.unregisterTutorial(ossTutorialProvider); + plugins.home.tutorials.registerTutorial(() => { + const ossPart = ossTutorialProvider({}); + if (this.currentConfig!['xpack.apm.ui.enabled'] && ossPart.artifacts) { + ossPart.artifacts.application = { + path: '/app/apm', + label: i18n.translate( + 'xpack.apm.tutorial.specProvider.artifacts.application.label', + { + defaultMessage: 'Launch APM' + } + ) + }; + } + + return { + ...ossPart, + elasticCloud: createElasticCloudInstructions(plugins.cloud) + }; + }); plugins.features.registerFeature(APM_FEATURE); createApmApi().init(core, { diff --git a/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts b/x-pack/plugins/apm/server/tutorial/elastic_cloud.ts similarity index 94% rename from x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts rename to x-pack/plugins/apm/server/tutorial/elastic_cloud.ts index 98294dddbec41..81de184ac6a9c 100644 --- a/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts +++ b/x-pack/plugins/apm/server/tutorial/elastic_cloud.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { INSTRUCTION_VARIANT } from '../../../../../../src/plugins/home/server'; +import { INSTRUCTION_VARIANT } from '../../../../../src/plugins/home/server'; import { createNodeAgentInstructions, @@ -17,8 +17,8 @@ import { createGoAgentInstructions, createJavaAgentInstructions, createDotNetAgentInstructions -} from '../instructions/apm_agent_instructions'; -import { CloudSetup } from '../../../../cloud/server'; +} from '../../../../../src/plugins/apm_oss/server'; +import { CloudSetup } from '../../../cloud/server'; export function createElasticCloudInstructions(cloudSetup?: CloudSetup) { const apmServerUrl = cloudSetup?.apm.url; diff --git a/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts b/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts deleted file mode 100644 index 1f7b7c8344c1d..0000000000000 --- a/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts +++ /dev/null @@ -1,246 +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'; -import { INSTRUCTION_VARIANT } from '../../../../../../src/plugins/home/server'; -import { - createWindowsServerInstructions, - createEditConfig, - createStartServerUnixSysv, - createStartServerUnix, - createDownloadServerRpm, - createDownloadServerDeb, - createDownloadServerOsx -} from '../instructions/apm_server_instructions'; -import { - createNodeAgentInstructions, - createDjangoAgentInstructions, - createFlaskAgentInstructions, - createRailsAgentInstructions, - createRackAgentInstructions, - createJsAgentInstructions, - createGoAgentInstructions, - createJavaAgentInstructions, - createDotNetAgentInstructions -} from '../instructions/apm_agent_instructions'; - -export function onPremInstructions({ - errorIndices, - transactionIndices, - metricsIndices, - sourcemapIndices, - onboardingIndices -}: { - errorIndices: string; - transactionIndices: string; - metricsIndices: string; - sourcemapIndices: string; - onboardingIndices: string; -}) { - const EDIT_CONFIG = createEditConfig(); - const START_SERVER_UNIX = createStartServerUnix(); - const START_SERVER_UNIX_SYSV = createStartServerUnixSysv(); - - return { - instructionSets: [ - { - title: i18n.translate('xpack.apm.tutorial.apmServer.title', { - defaultMessage: 'APM Server' - }), - callOut: { - title: i18n.translate('xpack.apm.tutorial.apmServer.callOut.title', { - defaultMessage: 'Important: Updating to 7.0 or higher' - }), - message: i18n.translate( - 'xpack.apm.tutorial.apmServer.callOut.message', - { - defaultMessage: `Please make sure your APM Server is updated to 7.0 or higher. \ - You can also migrate your 6.x data with the migration assistant found in Kibana's management section.` - } - ), - iconType: 'alert' - }, - instructionVariants: [ - { - id: INSTRUCTION_VARIANT.OSX, - instructions: [ - createDownloadServerOsx(), - EDIT_CONFIG, - START_SERVER_UNIX - ] - }, - { - id: INSTRUCTION_VARIANT.DEB, - instructions: [ - createDownloadServerDeb(), - EDIT_CONFIG, - START_SERVER_UNIX_SYSV - ] - }, - { - id: INSTRUCTION_VARIANT.RPM, - instructions: [ - createDownloadServerRpm(), - EDIT_CONFIG, - START_SERVER_UNIX_SYSV - ] - }, - { - id: INSTRUCTION_VARIANT.WINDOWS, - instructions: createWindowsServerInstructions() - } - ], - statusCheck: { - title: i18n.translate( - 'xpack.apm.tutorial.apmServer.statusCheck.title', - { - defaultMessage: 'APM Server status' - } - ), - text: i18n.translate( - 'xpack.apm.tutorial.apmServer.statusCheck.text', - { - defaultMessage: - 'Make sure APM Server is running before you start implementing the APM agents.' - } - ), - btnLabel: i18n.translate( - 'xpack.apm.tutorial.apmServer.statusCheck.btnLabel', - { - defaultMessage: 'Check APM Server status' - } - ), - success: i18n.translate( - 'xpack.apm.tutorial.apmServer.statusCheck.successMessage', - { - defaultMessage: 'You have correctly setup APM Server' - } - ), - error: i18n.translate( - 'xpack.apm.tutorial.apmServer.statusCheck.errorMessage', - { - defaultMessage: - 'No APM Server detected. Please make sure it is running and you have updated to 7.0 or higher.' - } - ), - esHitsCheck: { - index: onboardingIndices, - query: { - bool: { - filter: [ - { term: { 'processor.event': 'onboarding' } }, - { range: { 'observer.version_major': { gte: 7 } } } - ] - } - } - } - } - }, - { - title: i18n.translate('xpack.apm.tutorial.apmAgents.title', { - defaultMessage: 'APM Agents' - }), - instructionVariants: [ - { - id: INSTRUCTION_VARIANT.JAVA, - instructions: createJavaAgentInstructions() - }, - { - id: INSTRUCTION_VARIANT.JS, - instructions: createJsAgentInstructions() - }, - { - id: INSTRUCTION_VARIANT.NODE, - instructions: createNodeAgentInstructions() - }, - { - id: INSTRUCTION_VARIANT.DJANGO, - instructions: createDjangoAgentInstructions() - }, - { - id: INSTRUCTION_VARIANT.FLASK, - instructions: createFlaskAgentInstructions() - }, - { - id: INSTRUCTION_VARIANT.RAILS, - instructions: createRailsAgentInstructions() - }, - { - id: INSTRUCTION_VARIANT.RACK, - instructions: createRackAgentInstructions() - }, - { - id: INSTRUCTION_VARIANT.GO, - instructions: createGoAgentInstructions() - }, - { - id: INSTRUCTION_VARIANT.DOTNET, - instructions: createDotNetAgentInstructions() - } - ], - statusCheck: { - title: i18n.translate( - 'xpack.apm.tutorial.apmAgents.statusCheck.title', - { - defaultMessage: 'Agent status' - } - ), - text: i18n.translate( - 'xpack.apm.tutorial.apmAgents.statusCheck.text', - { - defaultMessage: - 'Make sure your application is running and the agents are sending data.' - } - ), - btnLabel: i18n.translate( - 'xpack.apm.tutorial.apmAgents.statusCheck.btnLabel', - { - defaultMessage: 'Check agent status' - } - ), - success: i18n.translate( - 'xpack.apm.tutorial.apmAgents.statusCheck.successMessage', - { - defaultMessage: - 'Data successfully received from one or more agents' - } - ), - error: i18n.translate( - 'xpack.apm.tutorial.apmAgents.statusCheck.errorMessage', - { - defaultMessage: 'No data has been received from agents yet' - } - ), - esHitsCheck: { - index: [ - errorIndices, - transactionIndices, - metricsIndices, - sourcemapIndices - ], - query: { - bool: { - filter: [ - { - terms: { - 'processor.event': [ - 'error', - 'transaction', - 'metric', - 'sourcemap' - ] - } - }, - { range: { 'observer.version_major': { gte: 7 } } } - ] - } - } - } - } - } - ] - }; -} diff --git a/x-pack/plugins/apm/server/tutorial/index.ts b/x-pack/plugins/apm/server/tutorial/index.ts deleted file mode 100644 index 76e2456afa5df..0000000000000 --- a/x-pack/plugins/apm/server/tutorial/index.ts +++ /dev/null @@ -1,113 +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'; -import { onPremInstructions } from './envs/on_prem'; -import { createElasticCloudInstructions } from './envs/elastic_cloud'; -import apmIndexPattern from './index_pattern.json'; -import { CloudSetup } from '../../../cloud/server'; -import { - ArtifactsSchema, - TutorialsCategory -} from '../../../../../src/plugins/home/server'; -import { APM_STATIC_INDEX_PATTERN_ID } from '../../common/index_pattern_constants'; - -const apmIntro = i18n.translate('xpack.apm.tutorial.introduction', { - defaultMessage: - 'Collect in-depth performance metrics and errors from inside your applications.' -}); - -export const tutorialProvider = ({ - isEnabled, - indexPatternTitle, - cloud, - indices -}: { - isEnabled: boolean; - indexPatternTitle: string; - cloud?: CloudSetup; - indices: { - errorIndices: string; - transactionIndices: string; - metricsIndices: string; - sourcemapIndices: string; - onboardingIndices: string; - }; -}) => () => { - const savedObjects = [ - { - ...apmIndexPattern, - id: APM_STATIC_INDEX_PATTERN_ID, - attributes: { - ...apmIndexPattern.attributes, - title: indexPatternTitle - } - } - ]; - - const artifacts: ArtifactsSchema = { - dashboards: [ - { - id: '8d3ed660-7828-11e7-8c47-65b845b5cfb3', - linkLabel: i18n.translate( - 'xpack.apm.tutorial.specProvider.artifacts.dashboards.linkLabel', - { - defaultMessage: 'APM dashboard' - } - ), - isOverview: true - } - ] - }; - - if (isEnabled) { - artifacts.application = { - path: '/app/apm', - label: i18n.translate( - 'xpack.apm.tutorial.specProvider.artifacts.application.label', - { - defaultMessage: 'Launch APM' - } - ) - }; - } - - return { - id: 'apm', - name: i18n.translate('xpack.apm.tutorial.specProvider.name', { - defaultMessage: 'APM' - }), - category: TutorialsCategory.OTHER, - shortDescription: apmIntro, - longDescription: i18n.translate( - 'xpack.apm.tutorial.specProvider.longDescription', - { - defaultMessage: - 'Application Performance Monitoring (APM) collects in-depth \ -performance metrics and errors from inside your application. \ -It allows you to monitor the performance of thousands of applications in real time. \ -[Learn more]({learnMoreLink}).', - values: { - learnMoreLink: - '{config.docs.base_url}guide/en/apm/get-started/{config.docs.version}/index.html' - } - } - ), - euiIconType: 'apmApp', - artifacts, - onPrem: onPremInstructions(indices), - elasticCloud: createElasticCloudInstructions(cloud), - previewImagePath: '/plugins/apm/assets/apm.png', - savedObjects, - savedObjectsInstallMsg: i18n.translate( - 'xpack.apm.tutorial.specProvider.savedObjectsInstallMsg', - { - defaultMessage: - 'An APM index pattern is required for some features in the APM UI.' - } - ) - }; -}; diff --git a/x-pack/plugins/apm/server/tutorial/instructions/apm_agent_instructions.ts b/x-pack/plugins/apm/server/tutorial/instructions/apm_agent_instructions.ts deleted file mode 100644 index 799c12517b7c0..0000000000000 --- a/x-pack/plugins/apm/server/tutorial/instructions/apm_agent_instructions.ts +++ /dev/null @@ -1,805 +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'; - -export const createNodeAgentInstructions = ( - apmServerUrl = '', - secretToken = '' -) => [ - { - title: i18n.translate('xpack.apm.tutorial.nodeClient.install.title', { - defaultMessage: 'Install the APM agent' - }), - textPre: i18n.translate('xpack.apm.tutorial.nodeClient.install.textPre', { - defaultMessage: - 'Install the APM agent for Node.js as a dependency to your application.' - }), - commands: ['npm install elastic-apm-node --save'] - }, - { - title: i18n.translate('xpack.apm.tutorial.nodeClient.configure.title', { - defaultMessage: 'Configure the agent' - }), - textPre: i18n.translate('xpack.apm.tutorial.nodeClient.configure.textPre', { - defaultMessage: - 'Agents are libraries that run inside of your application process. \ -APM services are created programmatically based on the `serviceName`. \ -This agent supports a vararity of frameworks but can also be used with your custom stack.' - }), - commands: `// ${i18n.translate( - 'xpack.apm.tutorial.nodeClient.configure.commands.addThisToTheFileTopComment', - { - defaultMessage: - 'Add this to the VERY top of the first file loaded in your app' - } - )} -var apm = require('elastic-apm-node').start({curlyOpen} - // ${i18n.translate( - 'xpack.apm.tutorial.nodeClient.configure.commands.setRequiredServiceNameComment', - { - defaultMessage: 'Override service name from package.json' - } - )} - // ${i18n.translate( - 'xpack.apm.tutorial.nodeClient.configure.commands.allowedCharactersComment', - { - defaultMessage: 'Allowed characters: a-z, A-Z, 0-9, -, _, and space' - } - )} - serviceName: '', - - // ${i18n.translate( - 'xpack.apm.tutorial.nodeClient.configure.commands.useIfApmRequiresTokenComment', - { - defaultMessage: 'Use if APM Server requires a token' - } - )} - secretToken: '${secretToken}', - - // ${i18n.translate( - 'xpack.apm.tutorial.nodeClient.configure.commands.setCustomApmServerUrlComment', - { - defaultMessage: - 'Set custom APM Server URL (default: {defaultApmServerUrl})', - values: { defaultApmServerUrl: 'http://localhost:8200' } - } - )} - serverUrl: '${apmServerUrl}' -{curlyClose})`.split('\n'), - textPost: i18n.translate( - 'xpack.apm.tutorial.nodeClient.configure.textPost', - { - defaultMessage: - 'See [the documentation]({documentationLink}) for advanced usage, including how to use with \ -[Babel/ES Modules]({babelEsModulesLink}).', - values: { - documentationLink: - '{config.docs.base_url}guide/en/apm/agent/nodejs/current/index.html', - babelEsModulesLink: - '{config.docs.base_url}guide/en/apm/agent/nodejs/current/advanced-setup.html#es-modules' - } - } - ) - } -]; - -export const createDjangoAgentInstructions = ( - apmServerUrl = '', - secretToken = '' -) => [ - { - title: i18n.translate('xpack.apm.tutorial.djangoClient.install.title', { - defaultMessage: 'Install the APM agent' - }), - textPre: i18n.translate('xpack.apm.tutorial.djangoClient.install.textPre', { - defaultMessage: 'Install the APM agent for Python as a dependency.' - }), - commands: ['$ pip install elastic-apm'] - }, - { - title: i18n.translate('xpack.apm.tutorial.djangoClient.configure.title', { - defaultMessage: 'Configure the agent' - }), - textPre: i18n.translate( - 'xpack.apm.tutorial.djangoClient.configure.textPre', - { - defaultMessage: - 'Agents are libraries that run inside of your application process. \ -APM services are created programmatically based on the `SERVICE_NAME`.' - } - ), - commands: `# ${i18n.translate( - 'xpack.apm.tutorial.djangoClient.configure.commands.addAgentComment', - { - defaultMessage: 'Add the agent to the installed apps' - } - )} -INSTALLED_APPS = ( - 'elasticapm.contrib.django', - # ... -) - -ELASTIC_APM = {curlyOpen} - # ${i18n.translate( - 'xpack.apm.tutorial.djangoClient.configure.commands.setRequiredServiceNameComment', - { - defaultMessage: 'Set required service name. Allowed characters:' - } - )} - # ${i18n.translate( - 'xpack.apm.tutorial.djangoClient.configure.commands.allowedCharactersComment', - { - defaultMessage: 'a-z, A-Z, 0-9, -, _, and space' - } - )} - 'SERVICE_NAME': '', - - # ${i18n.translate( - 'xpack.apm.tutorial.djangoClient.configure.commands.useIfApmServerRequiresTokenComment', - { - defaultMessage: 'Use if APM Server requires a token' - } - )} - 'SECRET_TOKEN': '${secretToken}', - - # ${i18n.translate( - 'xpack.apm.tutorial.djangoClient.configure.commands.setCustomApmServerUrlComment', - { - defaultMessage: - 'Set custom APM Server URL (default: {defaultApmServerUrl})', - values: { defaultApmServerUrl: 'http://localhost:8200' } - } - )} - 'SERVER_URL': '${apmServerUrl}', -{curlyClose} - -# ${i18n.translate( - 'xpack.apm.tutorial.djangoClient.configure.commands.addTracingMiddlewareComment', - { - defaultMessage: - 'To send performance metrics, add our tracing middleware:' - } - )} -MIDDLEWARE = ( - 'elasticapm.contrib.django.middleware.TracingMiddleware', - #... -)`.split('\n'), - textPost: i18n.translate( - 'xpack.apm.tutorial.djangoClient.configure.textPost', - { - defaultMessage: - 'See the [documentation]({documentationLink}) for advanced usage.', - values: { - documentationLink: - '{config.docs.base_url}guide/en/apm/agent/python/current/django-support.html' - } - } - ) - } -]; - -export const createFlaskAgentInstructions = ( - apmServerUrl = '', - secretToken = '' -) => [ - { - title: i18n.translate('xpack.apm.tutorial.flaskClient.install.title', { - defaultMessage: 'Install the APM agent' - }), - textPre: i18n.translate('xpack.apm.tutorial.flaskClient.install.textPre', { - defaultMessage: 'Install the APM agent for Python as a dependency.' - }), - commands: ['$ pip install elastic-apm[flask]'] - }, - { - title: i18n.translate('xpack.apm.tutorial.flaskClient.configure.title', { - defaultMessage: 'Configure the agent' - }), - textPre: i18n.translate( - 'xpack.apm.tutorial.flaskClient.configure.textPre', - { - defaultMessage: - 'Agents are libraries that run inside of your application process. \ -APM services are created programmatically based on the `SERVICE_NAME`.' - } - ), - commands: `# ${i18n.translate( - 'xpack.apm.tutorial.flaskClient.configure.commands.initializeUsingEnvironmentVariablesComment', - { - defaultMessage: 'initialize using environment variables' - } - )} -from elasticapm.contrib.flask import ElasticAPM -app = Flask(__name__) -apm = ElasticAPM(app) - -# ${i18n.translate( - 'xpack.apm.tutorial.flaskClient.configure.commands.configureElasticApmComment', - { - defaultMessage: - "or configure to use ELASTIC_APM in your application's settings" - } - )} -from elasticapm.contrib.flask import ElasticAPM -app.config['ELASTIC_APM'] = {curlyOpen} - # ${i18n.translate( - 'xpack.apm.tutorial.flaskClient.configure.commands.setRequiredServiceNameComment', - { - defaultMessage: 'Set required service name. Allowed characters:' - } - )} - # ${i18n.translate( - 'xpack.apm.tutorial.flaskClient.configure.commands.allowedCharactersComment', - { - defaultMessage: 'a-z, A-Z, 0-9, -, _, and space' - } - )} - 'SERVICE_NAME': '', - - # ${i18n.translate( - 'xpack.apm.tutorial.flaskClient.configure.commands.useIfApmServerRequiresTokenComment', - { - defaultMessage: 'Use if APM Server requires a token' - } - )} - 'SECRET_TOKEN': '${secretToken}', - - # ${i18n.translate( - 'xpack.apm.tutorial.flaskClient.configure.commands.setCustomApmServerUrlComment', - { - defaultMessage: - 'Set custom APM Server URL (default: {defaultApmServerUrl})', - values: { defaultApmServerUrl: 'http://localhost:8200' } - } - )} - 'SERVER_URL': '${apmServerUrl}', -{curlyClose} - -apm = ElasticAPM(app)`.split('\n'), - textPost: i18n.translate( - 'xpack.apm.tutorial.flaskClient.configure.textPost', - { - defaultMessage: - 'See the [documentation]({documentationLink}) for advanced usage.', - values: { - documentationLink: - '{config.docs.base_url}guide/en/apm/agent/python/current/flask-support.html' - } - } - ) - } -]; - -export const createRailsAgentInstructions = ( - apmServerUrl = '', - secretToken = '' -) => [ - { - title: i18n.translate('xpack.apm.tutorial.railsClient.install.title', { - defaultMessage: 'Install the APM agent' - }), - textPre: i18n.translate('xpack.apm.tutorial.railsClient.install.textPre', { - defaultMessage: 'Add the agent to your Gemfile.' - }), - commands: [`gem 'elastic-apm'`] - }, - { - title: i18n.translate('xpack.apm.tutorial.railsClient.configure.title', { - defaultMessage: 'Configure the agent' - }), - textPre: i18n.translate( - 'xpack.apm.tutorial.railsClient.configure.textPre', - { - defaultMessage: - 'APM is automatically started when your app boots. Configure the agent, by creating the config file {configFile}', - values: { configFile: '`config/elastic_apm.yml`' } - } - ), - commands: `# config/elastic_apm.yml: - -# Set service name - allowed characters: a-z, A-Z, 0-9, -, _ and space -# Defaults to the name of your Rails app -# service_name: 'my-service' - -# Use if APM Server requires a token -# secret_token: '${secretToken}' - -# Set custom APM Server URL (default: http://localhost:8200) -# server_url: '${apmServerUrl || 'http://localhost:8200'}'`.split('\n'), - textPost: i18n.translate( - 'xpack.apm.tutorial.railsClient.configure.textPost', - { - defaultMessage: - 'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n', - values: { - documentationLink: - '{config.docs.base_url}guide/en/apm/agent/ruby/current/index.html' - } - } - ) - } -]; - -export const createRackAgentInstructions = ( - apmServerUrl = '', - secretToken = '' -) => [ - { - title: i18n.translate('xpack.apm.tutorial.rackClient.install.title', { - defaultMessage: 'Install the APM agent' - }), - textPre: i18n.translate('xpack.apm.tutorial.rackClient.install.textPre', { - defaultMessage: 'Add the agent to your Gemfile.' - }), - commands: [`gem 'elastic-apm'`] - }, - { - title: i18n.translate('xpack.apm.tutorial.rackClient.configure.title', { - defaultMessage: 'Configure the agent' - }), - textPre: i18n.translate('xpack.apm.tutorial.rackClient.configure.textPre', { - defaultMessage: - 'For Rack or a compatible framework (e.g. Sinatra), include the middleware in your app and start the agent.' - }), - commands: `# config.ru - require 'sinatra/base' - - class MySinatraApp < Sinatra::Base - use ElasticAPM::Middleware - - # ... - end - - ElasticAPM.start( - app: MySinatraApp, # ${i18n.translate( - 'xpack.apm.tutorial.rackClient.configure.commands.requiredComment', - { - defaultMessage: 'required' - } - )} - config_file: '' # ${i18n.translate( - 'xpack.apm.tutorial.rackClient.configure.commands.optionalComment', - { - defaultMessage: 'optional, defaults to config/elastic_apm.yml' - } - )} - ) - - run MySinatraApp - - at_exit {curlyOpen} ElasticAPM.stop {curlyClose}`.split('\n') - }, - { - title: i18n.translate('xpack.apm.tutorial.rackClient.createConfig.title', { - defaultMessage: 'Create config file' - }), - textPre: i18n.translate( - 'xpack.apm.tutorial.rackClient.createConfig.textPre', - { - defaultMessage: 'Create a config file {configFile}:', - values: { configFile: '`config/elastic_apm.yml`' } - } - ), - commands: `# config/elastic_apm.yml: - -# ${i18n.translate( - 'xpack.apm.tutorial.rackClient.createConfig.commands.setServiceNameComment', - { - defaultMessage: - 'Set service name - allowed characters: a-z, A-Z, 0-9, -, _ and space' - } - )} -# ${i18n.translate( - 'xpack.apm.tutorial.rackClient.createConfig.commands.defaultsToTheNameOfRackAppClassComment', - { - defaultMessage: "Defaults to the name of your Rack app's class." - } - )} -# service_name: 'my-service' - -# ${i18n.translate( - 'xpack.apm.tutorial.rackClient.createConfig.commands.useIfApmServerRequiresTokenComment', - { - defaultMessage: 'Use if APM Server requires a token' - } - )} -# secret_token: '${secretToken}' - -# ${i18n.translate( - 'xpack.apm.tutorial.rackClient.createConfig.commands.setCustomApmServerComment', - { - defaultMessage: - 'Set custom APM Server URL (default: {defaultServerUrl})', - values: { defaultServerUrl: 'http://localhost:8200' } - } - )} -# server_url: '${apmServerUrl || 'http://localhost:8200'}'`.split('\n'), - textPost: i18n.translate( - 'xpack.apm.tutorial.rackClient.createConfig.textPost', - { - defaultMessage: - 'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n', - values: { - documentationLink: - '{config.docs.base_url}guide/en/apm/agent/ruby/current/index.html' - } - } - ) - } -]; - -export const createJsAgentInstructions = (apmServerUrl = '') => [ - { - title: i18n.translate( - 'xpack.apm.tutorial.jsClient.enableRealUserMonitoring.title', - { - defaultMessage: 'Enable Real User Monitoring support in APM Server' - } - ), - textPre: i18n.translate( - 'xpack.apm.tutorial.jsClient.enableRealUserMonitoring.textPre', - { - defaultMessage: - 'APM Server disables RUM support by default. See the [documentation]({documentationLink}) \ -for details on how to enable RUM support.', - values: { - documentationLink: - '{config.docs.base_url}guide/en/apm/server/{config.docs.version}/configuration-rum.html' - } - } - ) - }, - { - title: i18n.translate( - 'xpack.apm.tutorial.jsClient.installDependency.title', - { - defaultMessage: 'Set up the Agent as a dependency' - } - ), - textPre: i18n.translate( - 'xpack.apm.tutorial.jsClient.installDependency.textPre', - { - defaultMessage: - 'You can install the Agent as a dependency to your application with \ -`npm install @elastic/apm-rum --save`.\n\n\ -The Agent can then be initialized and configured in your application like this:' - } - ), - commands: `import {curlyOpen} init as initApm {curlyClose} from '@elastic/apm-rum' -var apm = initApm({curlyOpen} - - // ${i18n.translate( - 'xpack.apm.tutorial.jsClient.installDependency.commands.setRequiredServiceNameComment', - { - defaultMessage: - 'Set required service name (allowed characters: a-z, A-Z, 0-9, -, _, and space)' - } - )} - serviceName: 'your-app-name', - - // ${i18n.translate( - 'xpack.apm.tutorial.jsClient.installDependency.commands.setCustomApmServerUrlComment', - { - defaultMessage: - 'Set custom APM Server URL (default: {defaultApmServerUrl})', - values: { defaultApmServerUrl: 'http://localhost:8200' } - } - )} - serverUrl: '${apmServerUrl}', - - // ${i18n.translate( - 'xpack.apm.tutorial.jsClient.installDependency.commands.setServiceVersionComment', - { - defaultMessage: 'Set service version (required for source map feature)' - } - )} - serviceVersion: '' -{curlyClose})`.split('\n'), - textPost: i18n.translate( - 'xpack.apm.tutorial.jsClient.installDependency.textPost', - { - defaultMessage: - 'Framework integrations, like React or Angular, have custom dependencies. \ -See the [integration documentation]({docLink}) for more information.', - values: { - docLink: - '{config.docs.base_url}guide/en/apm/agent/rum-js/current/framework-integrations.html' - } - } - ) - }, - { - title: i18n.translate('xpack.apm.tutorial.jsClient.scriptTags.title', { - defaultMessage: 'Set up the Agent with Script Tags' - }), - textPre: i18n.translate('xpack.apm.tutorial.jsClient.scriptTags.textPre', { - defaultMessage: - "Alternatively, you can use Script tags to set up and configure the Agent. \ -Add a ` - -`.split('\n') - } -]; - -export const createGoAgentInstructions = ( - apmServerUrl = '', - secretToken = '' -) => [ - { - title: i18n.translate('xpack.apm.tutorial.goClient.install.title', { - defaultMessage: 'Install the APM agent' - }), - textPre: i18n.translate('xpack.apm.tutorial.goClient.install.textPre', { - defaultMessage: 'Install the APM agent packages for Go.' - }), - commands: ['go get go.elastic.co/apm'] - }, - { - title: i18n.translate('xpack.apm.tutorial.goClient.configure.title', { - defaultMessage: 'Configure the agent' - }), - textPre: i18n.translate('xpack.apm.tutorial.goClient.configure.textPre', { - defaultMessage: - 'Agents are libraries that run inside of your application process. \ -APM services are created programmatically based on the executable \ -file name, or the `ELASTIC_APM_SERVICE_NAME` environment variable.' - }), - commands: `# ${i18n.translate( - 'xpack.apm.tutorial.goClient.configure.commands.initializeUsingEnvironmentVariablesComment', - { - defaultMessage: 'Initialize using environment variables:' - } - )} - -# ${i18n.translate( - 'xpack.apm.tutorial.goClient.configure.commands.setServiceNameComment', - { - defaultMessage: - 'Set the service name. Allowed characters: # a-z, A-Z, 0-9, -, _, and space.' - } - )} -# ${i18n.translate( - 'xpack.apm.tutorial.goClient.configure.commands.usedExecutableNameComment', - { - defaultMessage: - 'If ELASTIC_APM_SERVICE_NAME is not specified, the executable name will be used.' - } - )} -export ELASTIC_APM_SERVICE_NAME= - -# ${i18n.translate( - 'xpack.apm.tutorial.goClient.configure.commands.setCustomApmServerUrlComment', - { - defaultMessage: - 'Set custom APM Server URL (default: {defaultApmServerUrl})', - values: { defaultApmServerUrl: 'http://localhost:8200' } - } - )} -export ELASTIC_APM_SERVER_URL=${apmServerUrl} - -# ${i18n.translate( - 'xpack.apm.tutorial.goClient.configure.commands.useIfApmRequiresTokenComment', - { - defaultMessage: 'Use if APM Server requires a token' - } - )} -export ELASTIC_APM_SECRET_TOKEN=${secretToken} -`.split('\n'), - textPost: i18n.translate('xpack.apm.tutorial.goClient.configure.textPost', { - defaultMessage: - 'See the [documentation]({documentationLink}) for advanced configuration.', - values: { - documentationLink: - '{config.docs.base_url}guide/en/apm/agent/go/current/configuration.html' - } - }) - }, - { - title: i18n.translate('xpack.apm.tutorial.goClient.instrument.title', { - defaultMessage: 'Instrument your application' - }), - textPre: i18n.translate('xpack.apm.tutorial.goClient.instrument.textPre', { - defaultMessage: - 'Instrument your Go application by using one of the provided instrumentation modules or \ -by using the tracer API directly.' - }), - commands: `\ -import ( - "net/http" - - "go.elastic.co/apm/module/apmhttp" -) - -func main() {curlyOpen} - mux := http.NewServeMux() - ... - http.ListenAndServe(":8080", apmhttp.Wrap(mux)) -{curlyClose} -`.split('\n'), - textPost: i18n.translate( - 'xpack.apm.tutorial.goClient.instrument.textPost', - { - defaultMessage: - 'See the [documentation]({documentationLink}) for a detailed \ -guide to instrumenting Go source code.', - values: { - documentationLink: - '{config.docs.base_url}guide/en/apm/agent/go/current/instrumenting-source.html' - } - } - ) - } -]; - -export const createJavaAgentInstructions = ( - apmServerUrl = '', - secretToken = '' -) => [ - { - title: i18n.translate('xpack.apm.tutorial.javaClient.download.title', { - defaultMessage: 'Download the APM agent' - }), - textPre: i18n.translate('xpack.apm.tutorial.javaClient.download.textPre', { - defaultMessage: - 'Download the agent jar from [Maven Central]({mavenCentralLink}). \ -Do **not** add the agent as a dependency to your application.', - values: { - mavenCentralLink: - 'http://search.maven.org/#search%7Cga%7C1%7Ca%3Aelastic-apm-agent' - } - }) - }, - { - title: i18n.translate( - 'xpack.apm.tutorial.javaClient.startApplication.title', - { - defaultMessage: 'Start your application with the javaagent flag' - } - ), - textPre: i18n.translate( - 'xpack.apm.tutorial.javaClient.startApplication.textPre', - { - defaultMessage: - 'Add the `-javaagent` flag and configure the agent with system properties.\n\n \ -* Set required service name (allowed characters: a-z, A-Z, 0-9, -, _, and space)\n \ -* Set custom APM Server URL (default: {customApmServerUrl})\n \ -* Set the base package of your application', - values: { customApmServerUrl: 'http://localhost:8200' } - } - ), - commands: `java -javaagent:/path/to/elastic-apm-agent-.jar \\ - -Delastic.apm.service_name=my-application \\ - -Delastic.apm.server_urls=${apmServerUrl || 'http://localhost:8200'} \\ - -Delastic.apm.secret_token=${secretToken} \\ - -Delastic.apm.application_packages=org.example \\ - -jar my-application.jar`.split('\n'), - textPost: i18n.translate( - 'xpack.apm.tutorial.javaClient.startApplication.textPost', - { - defaultMessage: - 'See the [documentation]({documentationLink}) for configuration options and advanced \ -usage.', - values: { - documentationLink: - '{config.docs.base_url}guide/en/apm/agent/java/current/index.html' - } - } - ) - } -]; - -export const createDotNetAgentInstructions = ( - apmServerUrl = '', - secretToken = '' -) => [ - { - title: i18n.translate('xpack.apm.tutorial.dotNetClient.download.title', { - defaultMessage: 'Download the APM agent' - }), - textPre: i18n.translate( - 'xpack.apm.tutorial.dotNetClient.download.textPre', - { - defaultMessage: - 'Add the the agent package(s) from [NuGet]({allNuGetPackagesLink}) to your .NET application. There are multiple \ - NuGet packages available for different use cases. \n\nFor an ASP.NET Core application with Entity Framework \ - Core download the [Elastic.Apm.NetCoreAll]({netCoreAllApmPackageLink}) package. This package will automatically add every \ - agent component to your application. \n\n In case you would like to to minimize the dependencies, you can use the \ - [Elastic.Apm.AspNetCore]({aspNetCorePackageLink}) package for just \ - ASP.NET Core monitoring or the [Elastic.Apm.EfCore]({efCorePackageLink}) package for just Entity Framework Core monitoring. \n\n \ - In case you only want to use the public Agent API for manual instrumentation use the [Elastic.Apm]({elasticApmPackageLink}) package.', - values: { - allNuGetPackagesLink: 'https://www.nuget.org/packages?q=Elastic.apm', - netCoreAllApmPackageLink: - 'https://www.nuget.org/packages/Elastic.Apm.NetCoreAll', - aspNetCorePackageLink: - 'https://www.nuget.org/packages/Elastic.Apm.AspNetCore', - efCorePackageLink: - 'https://www.nuget.org/packages/Elastic.Apm.EntityFrameworkCore', - elasticApmPackageLink: 'https://www.nuget.org/packages/Elastic.Apm' - } - } - ) - }, - { - title: i18n.translate( - 'xpack.apm.tutorial.dotNetClient.configureApplication.title', - { - defaultMessage: 'Add the agent to the application' - } - ), - textPre: i18n.translate( - 'xpack.apm.tutorial.dotNetClient.configureApplication.textPre', - { - defaultMessage: - 'In case of ASP.NET Core with the `Elastic.Apm.NetCoreAll` package, call the `UseAllElasticApm` \ - method in the `Configure` method within the `Startup.cs` file.' - } - ), - commands: `public class Startup -{curlyOpen} - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - {curlyOpen} - app.UseAllElasticApm(Configuration); - //…rest of the method - {curlyClose} - //…rest of the class -{curlyClose}`.split('\n'), - textPost: i18n.translate( - 'xpack.apm.tutorial.dotNetClient.configureApplication.textPost', - { - defaultMessage: - 'Passing an `IConfiguration` instance is optional and by doing so, the agent will read config settings through this \ - `IConfiguration` instance (e.g. from the `appsettings.json` file).' - } - ) - }, - { - title: i18n.translate( - 'xpack.apm.tutorial.dotNetClient.configureAgent.title', - { - defaultMessage: 'Sample appsettings.json file:' - } - ), - commands: `{curlyOpen} - "ElasticApm": {curlyOpen} - "SecretToken": "${secretToken}", - "ServerUrls": "${apmServerUrl || - 'http://localhost:8200'}", //Set custom APM Server URL (default: http://localhost:8200) - "ServiceName" : "MyApp", //allowed characters: a-z, A-Z, 0-9, -, _, and space. Default is the entry assembly of the application - {curlyClose} -{curlyClose}`.split('\n'), - textPost: i18n.translate( - 'xpack.apm.tutorial.dotNetClient.configureAgent.textPost', - { - defaultMessage: - 'In case you don’t pass an `IConfiguration` instance to the agent (e.g. in case of non ASP.NET Core applications) \ - you can also configure the agent through environment variables. \n \ - See [the documentation]({documentationLink}) for advanced usage.', - values: { - documentationLink: - '{config.docs.base_url}guide/en/apm/agent/dotnet/current/configuration.html' - } - } - ) - } -]; diff --git a/x-pack/plugins/apm/server/tutorial/instructions/apm_server_instructions.ts b/x-pack/plugins/apm/server/tutorial/instructions/apm_server_instructions.ts deleted file mode 100644 index 371c3928802ae..0000000000000 --- a/x-pack/plugins/apm/server/tutorial/instructions/apm_server_instructions.ts +++ /dev/null @@ -1,149 +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'; - -export const createEditConfig = () => ({ - title: i18n.translate('xpack.apm.tutorial.editConfig.title', { - defaultMessage: 'Edit the configuration' - }), - textPre: i18n.translate('xpack.apm.tutorial.editConfig.textPre', { - defaultMessage: - "If you're using an X-Pack secured version of Elastic Stack, you must specify \ -credentials in the `apm-server.yml` config file." - }), - commands: [ - 'output.elasticsearch:', - ' hosts: [""]', - ' username: ', - ' password: ' - ] -}); - -const createStartServer = () => ({ - title: i18n.translate('xpack.apm.tutorial.startServer.title', { - defaultMessage: 'Start APM Server' - }), - textPre: i18n.translate('xpack.apm.tutorial.startServer.textPre', { - defaultMessage: - 'The server processes and stores application performance metrics in Elasticsearch.' - }) -}); - -export function createStartServerUnixSysv() { - const START_SERVER = createStartServer(); - - return { - title: START_SERVER.title, - textPre: START_SERVER.textPre, - commands: ['service apm-server start'] - }; -} - -export function createStartServerUnix() { - const START_SERVER = createStartServer(); - - return { - title: START_SERVER.title, - textPre: START_SERVER.textPre, - commands: ['./apm-server -e'] - }; -} - -const createDownloadServerTitle = () => - i18n.translate('xpack.apm.tutorial.downloadServer.title', { - defaultMessage: 'Download and unpack APM Server' - }); - -export const createDownloadServerOsx = () => ({ - title: createDownloadServerTitle(), - commands: [ - 'curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-{config.kibana.version}-darwin-x86_64.tar.gz', - 'tar xzvf apm-server-{config.kibana.version}-darwin-x86_64.tar.gz', - 'cd apm-server-{config.kibana.version}-darwin-x86_64/' - ] -}); - -export const createDownloadServerDeb = () => ({ - title: createDownloadServerTitle(), - commands: [ - 'curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-{config.kibana.version}-amd64.deb', - 'sudo dpkg -i apm-server-{config.kibana.version}-amd64.deb' - ], - textPost: i18n.translate('xpack.apm.tutorial.downloadServerTitle', { - defaultMessage: - 'Looking for the 32-bit packages? See the [Download page]({downloadPageLink}).', - values: { - downloadPageLink: '{config.docs.base_url}downloads/apm/apm-server' - } - }) -}); - -export const createDownloadServerRpm = () => ({ - title: createDownloadServerTitle(), - commands: [ - 'curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-{config.kibana.version}-x86_64.rpm', - 'sudo rpm -vi apm-server-{config.kibana.version}-x86_64.rpm' - ], - textPost: i18n.translate('xpack.apm.tutorial.downloadServerRpm', { - defaultMessage: - 'Looking for the 32-bit packages? See the [Download page]({downloadPageLink}).', - values: { - downloadPageLink: '{config.docs.base_url}downloads/apm/apm-server' - } - }) -}); - -export function createWindowsServerInstructions() { - const START_SERVER = createStartServer(); - - return [ - { - title: createDownloadServerTitle(), - textPre: i18n.translate( - 'xpack.apm.tutorial.windowsServerInstructions.textPre', - { - defaultMessage: - '1. Download the APM Server Windows zip file from the \ -[Download page]({downloadPageLink}).\n2. Extract the contents of \ -the zip file into {zipFileExtractFolder}.\n3. Rename the {apmServerDirectory} \ -directory to `APM-Server`.\n4. Open a PowerShell prompt as an Administrator \ -(right-click the PowerShell icon and select \ -**Run As Administrator**). If you are running Windows XP, you might need to download and install \ -PowerShell.\n5. From the PowerShell prompt, run the following commands to install APM Server as a Windows service:', - values: { - downloadPageLink: 'https://www.elastic.co/downloads/apm/apm-server', - zipFileExtractFolder: '`C:\\Program Files`', - apmServerDirectory: '`apm-server-{config.kibana.version}-windows`' - } - } - ), - commands: [ - `cd 'C:\\Program Files\\APM-Server'`, - `.\\install-service-apm-server.ps1` - ], - textPost: i18n.translate( - 'xpack.apm.tutorial.windowsServerInstructions.textPost', - { - defaultMessage: - 'Note: If script execution is disabled on your system, \ -you need to set the execution policy for the current session \ -to allow the script to run. For example: {command}.', - values: { - command: - '`PowerShell.exe -ExecutionPolicy UnRestricted -File .\\install-service-apm-server.ps1`' - } - } - ) - }, - createEditConfig(), - { - title: START_SERVER.title, - textPre: START_SERVER.textPre, - commands: ['Start-Service apm-server'] - } - ]; -} diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index f8ade9fad91a6..73b79b2f4cce7 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -124,6 +124,119 @@ "advancedSettings.searchBar.unableToParseQueryErrorMessage": "クエリをパースできません", "advancedSettings.searchBarAriaLabel": "高度な設定を検索", "advancedSettings.voiceAnnouncement.searchResultScreenReaderMessage": "{query} を検索しました。{sectionLenght, plural, one {# セクション} other {# セクション}}に{optionLenght, plural, one {# オプション} other {# オプション}}があります。", + "apmOss.tutorial.apmAgents.statusCheck.btnLabel": "エージェントステータスを確認", + "apmOss.tutorial.apmAgents.statusCheck.errorMessage": "エージェントからまだデータを受け取っていません", + "apmOss.tutorial.apmAgents.statusCheck.successMessage": "1 つまたは複数のエージェントからデータを受け取りました", + "apmOss.tutorial.apmAgents.statusCheck.text": "アプリケーションが実行されていてエージェントがデータを送信していることを確認してください。", + "apmOss.tutorial.apmAgents.statusCheck.title": "エージェントステータス", + "apmOss.tutorial.apmAgents.title": "APM エージェント", + "apmOss.tutorial.apmServer.callOut.message": "ご使用の APM Server を 7.0 以上に更新してあることを確認してください。 Kibana の管理セクションにある移行アシスタントで 6.x データを移行することもできます。", + "apmOss.tutorial.apmServer.callOut.title": "重要:7.0 以上に更新中", + "apmOss.tutorial.apmServer.statusCheck.btnLabel": "APM Server ステータスを確認", + "apmOss.tutorial.apmServer.statusCheck.errorMessage": "APM Server が検出されました。7.0 以上に更新され、動作中であることを確認してください。", + "apmOss.tutorial.apmServer.statusCheck.successMessage": "APM Server が正しくセットアップされました", + "apmOss.tutorial.apmServer.statusCheck.text": "APM エージェントの導入を開始する前に、APM Server が動作していることを確認してください。", + "apmOss.tutorial.apmServer.statusCheck.title": "APM Server ステータス", + "apmOss.tutorial.apmServer.title": "APM Server", + "apmOss.tutorial.djangoClient.configure.commands.addAgentComment": "インストールされたアプリにエージェントを追加します", + "apmOss.tutorial.djangoClient.configure.commands.addTracingMiddlewareComment": "パフォーマンスメトリックを送信するには、追跡ミドルウェアを追加します。", + "apmOss.tutorial.djangoClient.configure.commands.allowedCharactersComment": "a-z、A-Z、0-9、-、_、スペース", + "apmOss.tutorial.djangoClient.configure.commands.setCustomApmServerUrlComment": "カスタム APM Server URL (デフォルト: {defaultApmServerUrl})", + "apmOss.tutorial.djangoClient.configure.commands.setRequiredServiceNameComment": "必要なサーバー名を設定します。使用できる文字:", + "apmOss.tutorial.djangoClient.configure.commands.useIfApmServerRequiresTokenComment": "APM Server にトークンが必要な場合に使います", + "apmOss.tutorial.djangoClient.configure.textPost": "高度な用途に関しては [ドキュメンテーション]({documentationLink}) をご覧ください。", + "apmOss.tutorial.djangoClient.configure.textPre": "エージェントとは、アプリケーションプロセス内で実行されるライブラリです。APM サービスは「SERVICE_NAME」に基づいてプログラムで作成されます。", + "apmOss.tutorial.djangoClient.configure.title": "エージェントの構成", + "apmOss.tutorial.djangoClient.install.textPre": "Python 用の APM エージェントを依存関係としてインストールします。", + "apmOss.tutorial.djangoClient.install.title": "APM エージェントのインストール", + "apmOss.tutorial.dotNetClient.configureAgent.textPost": "エージェントに「IConfiguration」インスタンスが渡されていない場合、(例: 非 ASP.NET Core アプリケーションの場合)、エージェントを環境変数で構成することもできます。\n 高度な用途に関しては [ドキュメンテーション]({documentationLink}) をご覧ください。", + "apmOss.tutorial.dotNetClient.configureAgent.title": "appsettings.json ファイルの例:", + "apmOss.tutorial.dotNetClient.configureApplication.textPost": "「IConfiguration」インスタンスを渡すのは任意であり、これにより、エージェントはこの「IConfiguration」インスタンス (例: 「appsettings.json」ファイル) から構成を読み込みます。", + "apmOss.tutorial.dotNetClient.configureApplication.textPre": "「Elastic.Apm.NetCoreAll」パッケージの ASP.NET Core の場合、「Startup.cs」ファイル内の「Configure」メソドの「UseElasticApm」メソドを呼び出します。", + "apmOss.tutorial.dotNetClient.configureApplication.title": "エージェントをアプリケーションに追加", + "apmOss.tutorial.dotNetClient.download.textPre": "[NuGet]({allNuGetPackagesLink}) から .NET アプリケーションにエージェントパッケージを追加してください。用途の異なる複数の NuGet パッケージがあります。\n\nEntity Framework Core の ASP.NET Core アプリケーションの場合は、[Elastic.Apm.NetCoreAll]({netCoreAllApmPackageLink}) パッケージをダウンロードしてください。このパッケージは、自動的にすべてのエージェントコンポーネントをアプリケーションに追加します。\n\n 依存性を最低限に抑えたい場合、ASP.NET Core の監視のみに [Elastic.Apm.AspNetCore]({aspNetCorePackageLink}) パッケージ、または Entity Framework Core の監視のみに [Elastic.Apm.EfCore]({efCorePackageLink}) パッケージを使用することができます。\n\n 手動インストルメンテーションのみにパブリック Agent API を使用する場合は、[Elastic.Apm]({elasticApmPackageLink}) パッケージを使用してください。", + "apmOss.tutorial.dotNetClient.download.title": "APM エージェントのダウンロード", + "apmOss.tutorial.downloadServer.title": "APM Server をダウンロードして展開します", + "apmOss.tutorial.downloadServerRpm": "32 ビットパッケージをお探しですか?[ダウンロードページ]({downloadPageLink}) をご覧ください。", + "apmOss.tutorial.downloadServerTitle": "32 ビットパッケージをお探しですか?[ダウンロードページ]({downloadPageLink}) をご覧ください。", + "apmOss.tutorial.editConfig.textPre": "Elastic Stack の X-Pack セキュアバージョンをご使用の場合、「apm-server.yml」構成ファイルで認証情報を指定する必要があります。", + "apmOss.tutorial.editConfig.title": "構成を編集する", + "apmOss.tutorial.flaskClient.configure.commands.allowedCharactersComment": "a-z、A-Z、0-9、-、_、スペース", + "apmOss.tutorial.flaskClient.configure.commands.configureElasticApmComment": "またはアプリケーションの設定で ELASTIC_APM を使用するよう構成します。", + "apmOss.tutorial.flaskClient.configure.commands.initializeUsingEnvironmentVariablesComment": "環境変数を使用して初期化します", + "apmOss.tutorial.flaskClient.configure.commands.setCustomApmServerUrlComment": "カスタム APM Server URL (デフォルト: {defaultApmServerUrl})", + "apmOss.tutorial.flaskClient.configure.commands.setRequiredServiceNameComment": "必要なサーバー名を設定します。使用できる文字:", + "apmOss.tutorial.flaskClient.configure.commands.useIfApmServerRequiresTokenComment": "APM Server にトークンが必要な場合に使います", + "apmOss.tutorial.flaskClient.configure.textPost": "高度な用途に関しては [ドキュメンテーション]({documentationLink}) をご覧ください。", + "apmOss.tutorial.flaskClient.configure.textPre": "エージェントとは、アプリケーションプロセス内で実行されるライブラリです。APM サービスは「SERVICE_NAME」に基づいてプログラムで作成されます。", + "apmOss.tutorial.flaskClient.configure.title": "エージェントの構成", + "apmOss.tutorial.flaskClient.install.textPre": "Python 用の APM エージェントを依存関係としてインストールします。", + "apmOss.tutorial.flaskClient.install.title": "APM エージェントのインストール", + "apmOss.tutorial.goClient.configure.commands.initializeUsingEnvironmentVariablesComment": "環境変数を使用して初期化します:", + "apmOss.tutorial.goClient.configure.commands.setCustomApmServerUrlComment": "カスタム APM Server URL (デフォルト: {defaultApmServerUrl})", + "apmOss.tutorial.goClient.configure.commands.setServiceNameComment": "サービス名を設定します。使用できる文字は # a-z、A-Z、0-9、-、_、スペースです。", + "apmOss.tutorial.goClient.configure.commands.usedExecutableNameComment": "ELASTIC_APM_SERVICE_NAME が指定されていない場合、実行可能な名前が使用されます。", + "apmOss.tutorial.goClient.configure.commands.useIfApmRequiresTokenComment": "APM Server にトークンが必要な場合に使います", + "apmOss.tutorial.goClient.configure.textPost": "高度な構成に関しては [ドキュメンテーション]({documentationLink}) をご覧ください。", + "apmOss.tutorial.goClient.configure.textPre": "エージェントとは、アプリケーションプロセス内で実行されるライブラリです。APM サービスは実行ファイル名または「ELASTIC_APM_SERVICE_NAME」環境変数に基づいてプログラムで作成されます。", + "apmOss.tutorial.goClient.configure.title": "エージェントの構成", + "apmOss.tutorial.goClient.install.textPre": "Go の APM エージェントパッケージをインストールします。", + "apmOss.tutorial.goClient.install.title": "APM エージェントのインストール", + "apmOss.tutorial.goClient.instrument.textPost": "Go のソースコードのインストルメンテーションの詳細ガイドは、[ドキュメンテーション]({documentationLink}) をご覧ください。", + "apmOss.tutorial.goClient.instrument.textPre": "提供されたインストルメンテーションモジュールの 1 つ、またはトレーサー API を直接使用して、Go アプリケーションにインストルメンテーションを設定します。", + "apmOss.tutorial.goClient.instrument.title": "アプリケーションのインストルメンテーション", + "apmOss.tutorial.introduction": "アプリケーション内から詳細なパフォーマンスメトリックやエラーを収集します。", + "apmOss.tutorial.javaClient.download.textPre": "[Maven Central]({mavenCentralLink}) からエージェントをダウンロードします。アプリケーションにエージェントを依存関係として「追加しない」でください。", + "apmOss.tutorial.javaClient.download.title": "APM エージェントのダウンロード", + "apmOss.tutorial.javaClient.startApplication.textPost": "構成オプションと高度な用途に関しては、[ドキュメンテーション]({documentationLink}) をご覧ください。", + "apmOss.tutorial.javaClient.startApplication.textPre": "「-javaagent」フラグを追加してエージェントをシステムプロパティで構成します。\n\n * 必要なサービス名を設定します (使用可能な文字は a-z、A-Z、0-9、-、_、スペースです)\n * カスタム APM Server URL (デフォルト: {customApmServerUrl})\n * アプリケーションのベースパッケージを設定します", + "apmOss.tutorial.javaClient.startApplication.title": "javaagent フラグでアプリケーションを起動", + "apmOss.tutorial.jsClient.enableRealUserMonitoring.textPre": "デフォルトでは、APM Server を実行すると RUM サポートは無効になります。RUM サポートを有効にする手順については、[ドキュメンテーション]({documentationLink}) をご覧ください。", + "apmOss.tutorial.jsClient.enableRealUserMonitoring.title": "APM Server のリアルユーザー監視エージェントを有効にする", + "apmOss.tutorial.jsClient.installDependency.commands.setCustomApmServerUrlComment": "カスタム APM Server URL (デフォルト: {defaultApmServerUrl})", + "apmOss.tutorial.jsClient.installDependency.commands.setRequiredServiceNameComment": "必要なサービス名を設定します (使用可能な文字は a-z、A-Z、0-9、-、_、スペースです)", + "apmOss.tutorial.jsClient.installDependency.commands.setServiceVersionComment": "サービスバージョンを設定します (ソースマップ機能に必要)", + "apmOss.tutorial.jsClient.installDependency.textPost": "React や Angular などのフレームワーク統合には、カスタム依存関係があります。詳細は [統合ドキュメント]({docLink}) をご覧ください。", + "apmOss.tutorial.jsClient.installDependency.textPre": "「npm install @elastic/apm-rum --save」でエージェントをアプリケーションへの依存関係としてインストールできます。\n\nその後で以下のようにアプリケーションでエージェントを初期化して構成できます。", + "apmOss.tutorial.jsClient.installDependency.title": "エージェントを依存関係としてセットアップ", + "apmOss.tutorial.jsClient.scriptTags.textPre": "または、スクリプトタグを使用してエージェントのセットアップと構成ができます。` を追加