From 634ce7f83b9189ce26dc5405f72f00709bdd2dba Mon Sep 17 00:00:00 2001 From: Nick Partridge Date: Fri, 3 Sep 2021 10:57:36 -0500 Subject: [PATCH 01/18] [ML] fix heatmap label colors (#110515) (#111140) --- .../public/application/explorer/swimlane_container.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx b/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx index 0c150773d22be..bc00c6a258a07 100644 --- a/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx +++ b/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx @@ -280,10 +280,10 @@ export const SwimlaneContainer: FC = ({ return { x: selection.times.map((v) => v * 1000), y: selection.lanes }; }, [selection, swimlaneData, swimlaneType]); - const swimLaneConfig: HeatmapSpec['config'] = useMemo(() => { + const swimLaneConfig = useMemo(() => { if (!showSwimlane) return {}; - return { + const config: HeatmapSpec['config'] = { onBrushEnd: (e: HeatmapBrushEvent) => { if (!e.cells.length) return; @@ -318,7 +318,7 @@ export const SwimlaneContainer: FC = ({ yAxisLabel: { visible: true, width: Y_AXIS_LABEL_WIDTH, - fill: euiTheme.euiTextSubduedColor, + textColor: euiTheme.euiTextSubduedColor, padding: Y_AXIS_LABEL_PADDING, formatter: (laneLabel: string) => { return laneLabel === '' ? EMPTY_FIELD_VALUE_LABEL : laneLabel; @@ -327,7 +327,7 @@ export const SwimlaneContainer: FC = ({ }, xAxisLabel: { visible: true, - fill: euiTheme.euiTextSubduedColor, + textColor: euiTheme.euiTextSubduedColor, formatter: (v: number) => { timeBuckets.setInterval(`${swimlaneData.interval}s`); const scaledDateFormat = timeBuckets.getScaledDateFormat(); @@ -346,6 +346,8 @@ export const SwimlaneContainer: FC = ({ ...(showLegend ? { maxLegendHeight: LEGEND_HEIGHT } : {}), timeZone: 'UTC', }; + + return config; }, [ showSwimlane, swimlaneType, From b6ab15e9f44b2527d3acba6fb99ccccaa9104390 Mon Sep 17 00:00:00 2001 From: Tim Roes Date: Fri, 3 Sep 2021 17:59:59 +0200 Subject: [PATCH 02/18] Remove kibana.defaultAppId setting (#109798) * Remove kibana.defaultAppId setting * Fix typings * Remove plugin dependency * Use proper navigation method to get to home * Default route for home * Address discover new routing code * Make non existing /kibana URLs working * Fix space awareness * Remove documentation * Remove the setting from docker file * Make defaultRoute forward work properly * Add forward_url tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- docs/setup/settings.asciidoc | 6 --- .../resources/base/bin/kibana-docker | 1 - .../apps/not_found/not_found_route.tsx | 5 +- .../public/application/components/home_app.js | 13 +---- src/plugins/home/public/plugin.ts | 21 +------- src/plugins/kibana_legacy/config.ts | 15 ------ src/plugins/kibana_legacy/kibana.json | 2 +- src/plugins/kibana_legacy/public/index.ts | 4 +- src/plugins/kibana_legacy/public/mocks.ts | 3 -- src/plugins/kibana_legacy/public/plugin.ts | 12 +---- src/plugins/kibana_legacy/server/index.ts | 49 ----------------- src/plugins/url_forwarding/kibana.json | 3 +- .../public/forward_app/forward_app.test.ts | 54 +++++++++++++++++++ .../public/forward_app/forward_app.ts | 15 ++---- src/plugins/url_forwarding/public/mocks.ts | 1 - .../public/navigate_to_default_app.ts | 39 -------------- src/plugins/url_forwarding/public/plugin.ts | 35 +----------- test/functional/apps/home/_home.js | 2 +- 18 files changed, 70 insertions(+), 210 deletions(-) delete mode 100644 src/plugins/kibana_legacy/config.ts delete mode 100644 src/plugins/kibana_legacy/server/index.ts create mode 100644 src/plugins/url_forwarding/public/forward_app/forward_app.test.ts delete mode 100644 src/plugins/url_forwarding/public/navigate_to_default_app.ts diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 203339be638ab..78b776c85c937 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -295,12 +295,6 @@ is an alternative to `elasticsearch.username` and `elasticsearch.password`. | `interpreter.enableInVisualize` | Enables use of interpreter in Visualize. *Default: `true`* -| `kibana.defaultAppId:` - | deprecated:[7.9.0,This setting will be removed in Kibana 8.0.] - Instead, use the <>. - + - The default application to load. *Default: `"home"`* - |[[kibana-index]] `kibana.index:` | deprecated:[7.11.0,This setting will be removed in 8.0.] Multitenancy by changing `kibana.index` will not be supported starting in 8.0. See diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker index 4bb89e1b7e606..adf0be3b5aa54 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker @@ -76,7 +76,6 @@ kibana_vars=( interpreter.enableInVisualize kibana.autocompleteTerminateAfter kibana.autocompleteTimeout - kibana.defaultAppId kibana.index logging.appenders logging.appenders.console diff --git a/src/plugins/discover/public/application/apps/not_found/not_found_route.tsx b/src/plugins/discover/public/application/apps/not_found/not_found_route.tsx index ff515f27201a4..cd16a820cc8f7 100644 --- a/src/plugins/discover/public/application/apps/not_found/not_found_route.tsx +++ b/src/plugins/discover/public/application/apps/not_found/not_found_route.tsx @@ -28,10 +28,7 @@ export function NotFoundRoute(props: NotFoundRouteProps) { useEffect(() => { const path = window.location.hash.substr(1); getUrlTracker().restorePreviousUrl(); - const { navigated } = urlForwarding.navigateToLegacyKibanaUrl(path); - if (!navigated) { - urlForwarding.navigateToDefaultApp(); - } + urlForwarding.navigateToLegacyKibanaUrl(path); const bannerMessage = i18n.translate('discover.noMatchRoute.bannerTitleText', { defaultMessage: 'Page not found', diff --git a/src/plugins/home/public/application/components/home_app.js b/src/plugins/home/public/application/components/home_app.js index ef70dac20d3cc..94413e6af390f 100644 --- a/src/plugins/home/public/application/components/home_app.js +++ b/src/plugins/home/public/application/components/home_app.js @@ -12,19 +12,10 @@ import PropTypes from 'prop-types'; import { Home } from './home'; import { TutorialDirectory } from './tutorial_directory'; import { Tutorial } from './tutorial/tutorial'; -import { HashRouter as Router, Switch, Route } from 'react-router-dom'; +import { HashRouter as Router, Switch, Route, Redirect } from 'react-router-dom'; import { getTutorial } from '../load_tutorials'; import { replaceTemplateStrings } from './tutorial/replace_template_strings'; import { getServices } from '../kibana_services'; -import useMount from 'react-use/lib/useMount'; - -const RedirectToDefaultApp = () => { - useMount(() => { - const { urlForwarding } = getServices(); - urlForwarding.navigateToDefaultApp(); - }); - return null; -}; export function HomeApp({ directories, solutions }) { const { @@ -78,7 +69,7 @@ export function HomeApp({ directories, solutions }) { hasUserIndexPattern={() => indexPatternService.hasUserIndexPattern()} /> - + diff --git a/src/plugins/home/public/plugin.ts b/src/plugins/home/public/plugin.ts index 7dd1d8728ad7f..f6a1566b267ac 100644 --- a/src/plugins/home/public/plugin.ts +++ b/src/plugins/home/public/plugin.ts @@ -14,7 +14,6 @@ import { PluginInitializerContext, } from 'kibana/public'; import { i18n } from '@kbn/i18n'; -import { first } from 'rxjs/operators'; import { EnvironmentService, @@ -137,27 +136,9 @@ export class HomePublicPlugin }; } - public start( - { application: { capabilities, currentAppId$ }, http }: CoreStart, - { urlForwarding }: HomePluginStartDependencies - ) { + public start({ application: { capabilities } }: CoreStart) { this.featuresCatalogueRegistry.start({ capabilities }); - // If the home app is the initial location when loading Kibana... - if ( - window.location.pathname === http.basePath.prepend(HOME_APP_BASE_PATH) && - window.location.hash === '' - ) { - // ...wait for the app to mount initially and then... - currentAppId$.pipe(first()).subscribe((appId) => { - if (appId === 'home') { - // ...navigate to default app set by `kibana.defaultAppId`. - // This doesn't do anything as along as the default settings are kept. - urlForwarding.navigateToDefaultApp({ overwriteHash: false }); - } - }); - } - return { featureCatalogue: this.featuresCatalogueRegistry }; } } diff --git a/src/plugins/kibana_legacy/config.ts b/src/plugins/kibana_legacy/config.ts deleted file mode 100644 index 91083a554bce1..0000000000000 --- a/src/plugins/kibana_legacy/config.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 - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { schema, TypeOf } from '@kbn/config-schema'; - -export const configSchema = schema.object({ - defaultAppId: schema.string({ defaultValue: 'home' }), -}); - -export type ConfigSchema = TypeOf; diff --git a/src/plugins/kibana_legacy/kibana.json b/src/plugins/kibana_legacy/kibana.json index b1d7b10f9527a..afca886ad9376 100644 --- a/src/plugins/kibana_legacy/kibana.json +++ b/src/plugins/kibana_legacy/kibana.json @@ -1,7 +1,7 @@ { "id": "kibanaLegacy", "version": "kibana", - "server": true, + "server": false, "ui": true, "owner": { "name": "Vis Editors", diff --git a/src/plugins/kibana_legacy/public/index.ts b/src/plugins/kibana_legacy/public/index.ts index fa04b192cd177..13271532881cb 100644 --- a/src/plugins/kibana_legacy/public/index.ts +++ b/src/plugins/kibana_legacy/public/index.ts @@ -9,11 +9,9 @@ // TODO: https://github.com/elastic/kibana/issues/110891 /* eslint-disable @kbn/eslint/no_export_all */ -import { PluginInitializerContext } from 'kibana/public'; import { KibanaLegacyPlugin } from './plugin'; -export const plugin = (initializerContext: PluginInitializerContext) => - new KibanaLegacyPlugin(initializerContext); +export const plugin = () => new KibanaLegacyPlugin(); export * from './plugin'; diff --git a/src/plugins/kibana_legacy/public/mocks.ts b/src/plugins/kibana_legacy/public/mocks.ts index 9f79daf0f3505..510e59c7ff190 100644 --- a/src/plugins/kibana_legacy/public/mocks.ts +++ b/src/plugins/kibana_legacy/public/mocks.ts @@ -14,9 +14,6 @@ export type Start = jest.Mocked>; const createSetupContract = (): Setup => ({}); const createStartContract = (): Start => ({ - config: { - defaultAppId: 'home', - }, loadFontAwesome: jest.fn(), loadAngularBootstrap: jest.fn(), }); diff --git a/src/plugins/kibana_legacy/public/plugin.ts b/src/plugins/kibana_legacy/public/plugin.ts index af22ceadaa9e1..e5244c110ad20 100644 --- a/src/plugins/kibana_legacy/public/plugin.ts +++ b/src/plugins/kibana_legacy/public/plugin.ts @@ -6,18 +6,15 @@ * Side Public License, v 1. */ -import { PluginInitializerContext, CoreStart, CoreSetup } from 'kibana/public'; -import { ConfigSchema } from '../config'; +import { CoreStart, CoreSetup } from 'kibana/public'; import { injectHeaderStyle } from './utils/inject_header_style'; export class KibanaLegacyPlugin { - constructor(private readonly initializerContext: PluginInitializerContext) {} - public setup(core: CoreSetup<{}, KibanaLegacyStart>) { return {}; } - public start({ application, http: { basePath }, uiSettings }: CoreStart) { + public start({ uiSettings }: CoreStart) { injectHeaderStyle(uiSettings); return { /** @@ -35,11 +32,6 @@ export class KibanaLegacyPlugin { const { initAngularBootstrap } = await import('./angular_bootstrap'); initAngularBootstrap(); }, - /** - * @deprecated - * Just exported for wiring up with dashboard mode, should not be used. - */ - config: this.initializerContext.config.get(), }; } } diff --git a/src/plugins/kibana_legacy/server/index.ts b/src/plugins/kibana_legacy/server/index.ts deleted file mode 100644 index 90c9c2888c9da..0000000000000 --- a/src/plugins/kibana_legacy/server/index.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 - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { CoreSetup, CoreStart, PluginConfigDescriptor } from 'kibana/server'; -import { get } from 'lodash'; - -import { configSchema, ConfigSchema } from '../config'; - -export const config: PluginConfigDescriptor = { - exposeToBrowser: { - defaultAppId: true, - }, - schema: configSchema, - deprecations: ({ renameFromRoot }) => [ - // TODO: Remove deprecation once defaultAppId is deleted - renameFromRoot('kibana.defaultAppId', 'kibana_legacy.defaultAppId', { silent: true }), - (completeConfig, rootPath, addDeprecation) => { - if ( - get(completeConfig, 'kibana.defaultAppId') === undefined && - get(completeConfig, 'kibana_legacy.defaultAppId') === undefined - ) { - return; - } - addDeprecation({ - message: `kibana.defaultAppId is deprecated and will be removed in 8.0. Please use the \`defaultRoute\` advanced setting instead`, - correctiveActions: { - manualSteps: [ - 'Go to Stack Management > Advanced Settings', - 'Update the "defaultRoute" setting under the General section', - 'Remove "kibana.defaultAppId" from the kibana.yml config file', - ], - }, - }); - }, - ], -}; - -class Plugin { - public setup(core: CoreSetup) {} - - public start(core: CoreStart) {} -} - -export const plugin = () => new Plugin(); diff --git a/src/plugins/url_forwarding/kibana.json b/src/plugins/url_forwarding/kibana.json index a8b0571230b72..3e48cf73de5ef 100644 --- a/src/plugins/url_forwarding/kibana.json +++ b/src/plugins/url_forwarding/kibana.json @@ -6,6 +6,5 @@ "owner": { "name": "Vis Editors", "githubTeam": "kibana-vis-editors" - }, - "requiredPlugins": ["kibanaLegacy"] + } } diff --git a/src/plugins/url_forwarding/public/forward_app/forward_app.test.ts b/src/plugins/url_forwarding/public/forward_app/forward_app.test.ts new file mode 100644 index 0000000000000..c45bde0d67891 --- /dev/null +++ b/src/plugins/url_forwarding/public/forward_app/forward_app.test.ts @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import type { Location } from 'history'; +import type { AppMountParameters, CoreSetup, ScopedHistory } from 'kibana/public'; +import { coreMock } from '../../../../core/public/mocks'; +import type { UrlForwardingStart } from '../plugin'; +import { createLegacyUrlForwardApp } from './forward_app'; + +function createAppMountParams(hash: string): AppMountParameters { + return { + history: { + location: { + hash, + } as Location, + } as ScopedHistory, + } as AppMountParameters; +} + +describe('forward_app', () => { + let coreSetup: CoreSetup<{}, UrlForwardingStart>; + let coreStart: ReturnType; + + beforeEach(() => { + coreSetup = coreMock.createSetup({ basePath: '/base/path' }); + coreStart = coreMock.createStart({ basePath: '/base/path' }); + coreSetup.getStartServices = () => Promise.resolve([coreStart, {}, {} as any]); + }); + + it('should forward to defaultRoute if hash is not a known redirect', async () => { + coreStart.uiSettings.get.mockImplementation((key) => { + if (key === 'defaultRoute') return '/app/defaultApp'; + throw new Error('Mock implementation missing'); + }); + + const app = createLegacyUrlForwardApp(coreSetup, [ + { legacyAppId: 'discover', newAppId: 'discover', rewritePath: (p) => p }, + ]); + await app.mount(createAppMountParams('#/foobar')); + expect(coreStart.application.navigateToUrl).toHaveBeenCalledWith('/base/path/app/defaultApp'); + }); + + it('should not forward to defaultRoute if hash path is a known redirect', async () => { + const app = createLegacyUrlForwardApp(coreSetup, [ + { legacyAppId: 'discover', newAppId: 'discover', rewritePath: (p) => p }, + ]); + await app.mount(createAppMountParams('#/discover')); + expect(coreStart.application.navigateToUrl).not.toHaveBeenCalled(); + }); +}); diff --git a/src/plugins/url_forwarding/public/forward_app/forward_app.ts b/src/plugins/url_forwarding/public/forward_app/forward_app.ts index 96c4fab5f3331..3a66e207f8c26 100644 --- a/src/plugins/url_forwarding/public/forward_app/forward_app.ts +++ b/src/plugins/url_forwarding/public/forward_app/forward_app.ts @@ -23,23 +23,18 @@ export const createLegacyUrlForwardApp = ( async mount(params: AppMountParameters) { const hash = params.history.location.hash.substr(1); - if (!hash) { - const [, , kibanaLegacyStart] = await core.getStartServices(); - kibanaLegacyStart.navigateToDefaultApp(); - } - const [ { application, + uiSettings, http: { basePath }, }, ] = await core.getStartServices(); - const result = await navigateToLegacyKibanaUrl(hash, forwards, basePath, application); - - if (!result.navigated) { - const [, , kibanaLegacyStart] = await core.getStartServices(); - kibanaLegacyStart.navigateToDefaultApp(); + const { navigated } = navigateToLegacyKibanaUrl(hash, forwards, basePath, application); + if (!navigated) { + const defaultRoute = uiSettings.get('defaultRoute'); + application.navigateToUrl(basePath.prepend(defaultRoute)); } return () => {}; diff --git a/src/plugins/url_forwarding/public/mocks.ts b/src/plugins/url_forwarding/public/mocks.ts index 67b521b9d697d..582bb004b655e 100644 --- a/src/plugins/url_forwarding/public/mocks.ts +++ b/src/plugins/url_forwarding/public/mocks.ts @@ -17,7 +17,6 @@ const createSetupContract = (): Setup => ({ const createStartContract = (): Start => ({ getForwards: jest.fn(), - navigateToDefaultApp: jest.fn(), navigateToLegacyKibanaUrl: jest.fn(), }); diff --git a/src/plugins/url_forwarding/public/navigate_to_default_app.ts b/src/plugins/url_forwarding/public/navigate_to_default_app.ts deleted file mode 100644 index 0c934ac9c6844..0000000000000 --- a/src/plugins/url_forwarding/public/navigate_to_default_app.ts +++ /dev/null @@ -1,39 +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 - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { ApplicationStart, IBasePath } from 'kibana/public'; -import { ForwardDefinition } from './plugin'; - -export function navigateToDefaultApp( - defaultAppId: string, - forwards: ForwardDefinition[], - application: ApplicationStart, - basePath: IBasePath, - currentAppId: string | undefined, - overwriteHash: boolean -) { - // navigate to the respective path in the legacy kibana plugin by default (for unmigrated plugins) - let targetAppId = 'kibana'; - let targetAppPath = `#/${defaultAppId}`; - - // try to find an existing redirect for the target path if possible - // this avoids having to load the legacy app just to get redirected to a core application again afterwards - const relevantForward = forwards.find((forward) => defaultAppId.startsWith(forward.legacyAppId)); - if (relevantForward) { - targetAppPath = relevantForward.rewritePath(`/${defaultAppId}`); - targetAppId = relevantForward.newAppId; - } - - // when the correct app is already loaded, just set the hash to the right value - // otherwise use navigateToApp (or setting href in case of kibana app) - if (currentAppId !== targetAppId) { - application.navigateToApp(targetAppId, { path: targetAppPath, replace: true }); - } else if (overwriteHash) { - window.location.hash = targetAppPath; - } -} diff --git a/src/plugins/url_forwarding/public/plugin.ts b/src/plugins/url_forwarding/public/plugin.ts index 1151e853f28ba..ee56ba73eb24e 100644 --- a/src/plugins/url_forwarding/public/plugin.ts +++ b/src/plugins/url_forwarding/public/plugin.ts @@ -7,9 +7,6 @@ */ import { CoreStart, CoreSetup } from 'kibana/public'; -import { KibanaLegacyStart } from 'src/plugins/kibana_legacy/public'; -import { Subscription } from 'rxjs'; -import { navigateToDefaultApp } from './navigate_to_default_app'; import { createLegacyUrlForwardApp } from './forward_app'; import { navigateToLegacyKibanaUrl } from './forward_app/navigate_to_legacy_kibana_url'; @@ -21,8 +18,6 @@ export interface ForwardDefinition { export class UrlForwardingPlugin { private forwardDefinitions: ForwardDefinition[] = []; - private currentAppId: string | undefined; - private currentAppIdSubscription: Subscription | undefined; public setup(core: CoreSetup<{}, UrlForwardingStart>) { core.application.register(createLegacyUrlForwardApp(core, this.forwardDefinitions)); @@ -71,30 +66,8 @@ export class UrlForwardingPlugin { }; } - public start( - { application, http: { basePath }, uiSettings }: CoreStart, - { kibanaLegacy }: { kibanaLegacy: KibanaLegacyStart } - ) { - this.currentAppIdSubscription = application.currentAppId$.subscribe((currentAppId) => { - this.currentAppId = currentAppId; - }); + public start({ application, http: { basePath } }: CoreStart) { return { - /** - * Navigates to the app defined as kibana.defaultAppId. - * This takes redirects into account and uses the right mechanism to navigate. - */ - navigateToDefaultApp: ( - { overwriteHash }: { overwriteHash: boolean } = { overwriteHash: true } - ) => { - navigateToDefaultApp( - kibanaLegacy.config.defaultAppId, - this.forwardDefinitions, - application, - basePath, - this.currentAppId, - overwriteHash - ); - }, /** * Resolves the provided hash using the registered forwards and navigates to the target app. * If a navigation happened, `{ navigated: true }` will be returned. @@ -111,12 +84,6 @@ export class UrlForwardingPlugin { getForwards: () => this.forwardDefinitions, }; } - - public stop() { - if (this.currentAppIdSubscription) { - this.currentAppIdSubscription.unsubscribe(); - } - } } export type UrlForwardingSetup = ReturnType; diff --git a/test/functional/apps/home/_home.js b/test/functional/apps/home/_home.js index 24e672463964d..e3ca3f6761113 100644 --- a/test/functional/apps/home/_home.js +++ b/test/functional/apps/home/_home.js @@ -26,7 +26,7 @@ export default function ({ getService, getPageObjects }) { }); it('clicking on console on homepage should take you to console app', async () => { - await PageObjects.common.navigateToUrl('home'); + await PageObjects.common.navigateToApp('home'); await testSubjects.click('homeDevTools'); const url = await browser.getCurrentUrl(); expect(url.includes('/app/dev_tools#/console')).to.be(true); From a2c848e1d2edc367113241aad8d5b5fc7d40d7a0 Mon Sep 17 00:00:00 2001 From: Jonathan Buttner <56361221+jonathan-buttner@users.noreply.github.com> Date: Fri, 3 Sep 2021 12:00:51 -0400 Subject: [PATCH 03/18] [Cases] Fix connector information disappearing (#110914) * Move intialization to use effect * Fixing fields can't get test working * Fix tests Co-authored-by: Christos Nasikas --- .../jira/use_get_fields_by_issue_type.tsx | 2 +- .../connectors/jira/use_get_issue_types.tsx | 3 +- .../components/edit_connector/index.test.tsx | 80 ++++++++++++++----- .../components/edit_connector/index.tsx | 53 ++++++++---- 4 files changed, 98 insertions(+), 40 deletions(-) diff --git a/x-pack/plugins/cases/public/components/connectors/jira/use_get_fields_by_issue_type.tsx b/x-pack/plugins/cases/public/components/connectors/jira/use_get_fields_by_issue_type.tsx index a4958d91c88aa..686df1022a0d7 100644 --- a/x-pack/plugins/cases/public/components/connectors/jira/use_get_fields_by_issue_type.tsx +++ b/x-pack/plugins/cases/public/components/connectors/jira/use_get_fields_by_issue_type.tsx @@ -57,8 +57,8 @@ export const useGetFieldsByIssueType = ({ }); if (!didCancel.current) { - setIsLoading(false); setFields(res.data ?? {}); + setIsLoading(false); if (res.status && res.status === 'error') { toastNotifications.addDanger({ title: i18n.FIELDS_API_ERROR, diff --git a/x-pack/plugins/cases/public/components/connectors/jira/use_get_issue_types.tsx b/x-pack/plugins/cases/public/components/connectors/jira/use_get_issue_types.tsx index 447491d2a2fff..0d7073f3bf2d4 100644 --- a/x-pack/plugins/cases/public/components/connectors/jira/use_get_issue_types.tsx +++ b/x-pack/plugins/cases/public/components/connectors/jira/use_get_issue_types.tsx @@ -56,13 +56,14 @@ export const useGetIssueTypes = ({ }); if (!didCancel.current) { - setIsLoading(false); const asOptions = (res.data ?? []).map((type) => ({ text: type.name ?? '', value: type.id ?? '', })); + setIssueTypes(res.data ?? []); handleIssueType(asOptions); + setIsLoading(false); if (res.status && res.status === 'error') { toastNotifications.addDanger({ title: i18n.ISSUE_TYPES_API_ERROR, diff --git a/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx b/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx index fb45bf6ac3ae0..eec84cdd8d90f 100644 --- a/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx +++ b/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx @@ -7,16 +7,14 @@ import React from 'react'; import { mount } from 'enzyme'; -import { waitFor } from '@testing-library/react'; +import { render, waitFor, screen } from '@testing-library/react'; import { EditConnector, EditConnectorProps } from './index'; -import { getFormMock, useFormMock } from '../__mock__/form'; import { TestProviders } from '../../common/mock'; import { connectorsMock } from '../../containers/configure/mock'; import { basicCase, basicPush, caseUserActions } from '../../containers/mock'; import { useKibana } from '../../common/lib/kibana'; -jest.mock('../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form'); jest.mock('../../common/lib/kibana'); const useKibanaMock = useKibana as jest.Mocked; @@ -50,17 +48,32 @@ const defaultProps: EditConnectorProps = { }; describe('EditConnector ', () => { - const sampleConnector = '123'; - const formHookMock = getFormMock({ connectorId: sampleConnector }); beforeEach(() => { jest.clearAllMocks(); - useFormMock.mockImplementation(() => ({ form: formHookMock })); useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest.fn().mockReturnValue({ actionTypeTitle: '.servicenow', iconClass: 'logoSecurity', }); }); + it('Renders servicenow connector from case initially', async () => { + const serviceNowProps = { + ...defaultProps, + caseData: { + ...defaultProps.caseData, + connector: { ...defaultProps.caseData.connector, id: 'servicenow-1' }, + }, + }; + + render( + + + + ); + + expect(await screen.findByText('My Connector')).toBeInTheDocument(); + }); + it('Renders no connector, and then edit', async () => { const wrapper = mount( @@ -98,58 +111,81 @@ describe('EditConnector ', () => { expect(wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().exists()).toBeTruthy(); wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click'); - await waitFor(() => expect(onSubmit.mock.calls[0][0]).toBe(sampleConnector)); + await waitFor(() => expect(onSubmit.mock.calls[0][0]).toBe('resilient-2')); }); it('Revert to initial external service on error', async () => { onSubmit.mockImplementation((connector, onSuccess, onError) => { onError(new Error('An error has occurred')); }); + + const props = { + ...defaultProps, + caseData: { + ...defaultProps.caseData, + connector: { ...defaultProps.caseData.connector, id: 'servicenow-1' }, + }, + }; + const wrapper = mount( - + ); - wrapper.find('[data-test-subj="connector-edit"] button').simulate('click'); + wrapper.find('[data-test-subj="connector-edit"] button').simulate('click'); wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); - wrapper.update(); - wrapper.find('button[data-test-subj="dropdown-connector-resilient-2"]').simulate('click'); - wrapper.update(); - - expect(wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().exists()).toBeTruthy(); + await waitFor(() => { + wrapper.update(); + wrapper.find('button[data-test-subj="dropdown-connector-resilient-2"]').simulate('click'); + wrapper.update(); + expect( + wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().exists() + ).toBeTruthy(); + wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click'); + }); - wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click'); await waitFor(() => { wrapper.update(); - expect(formHookMock.setFieldValue).toHaveBeenCalledWith('connectorId', 'none'); + expect(wrapper.find(`[data-test-subj="edit-connectors-submit"]`).exists()).toBeFalsy(); }); + + /** + * If an error is being throw on submit the selected connector should + * be reverted to the initial one. In our test the initial one is the .servicenow-1 + * connector. The title of the .servicenow-1 connector is My Connector. + */ + expect(wrapper.text().includes('My Connector')).toBeTruthy(); }); it('Resets selector on cancel', async () => { const props = { ...defaultProps, + caseData: { + ...defaultProps.caseData, + connector: { ...defaultProps.caseData.connector, id: 'servicenow-1' }, + }, }; + const wrapper = mount( ); - wrapper.find('[data-test-subj="connector-edit"] button').simulate('click'); + wrapper.find('[data-test-subj="connector-edit"] button').simulate('click'); wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); wrapper.update(); wrapper.find('button[data-test-subj="dropdown-connector-resilient-2"]').simulate('click'); wrapper.update(); - wrapper.find(`[data-test-subj="edit-connectors-cancel"]`).last().simulate('click'); + await waitFor(() => { wrapper.update(); - expect(formHookMock.setFieldValue).toBeCalledWith( - 'connectorId', - defaultProps.caseData.connector.id - ); + expect(wrapper.find(`[data-test-subj="edit-connectors-submit"]`).exists()).toBeFalsy(); }); + + expect(wrapper.text().includes('My Connector')).toBeTruthy(); }); it('Renders loading spinner', async () => { diff --git a/x-pack/plugins/cases/public/components/edit_connector/index.tsx b/x-pack/plugins/cases/public/components/edit_connector/index.tsx index df7855fb9ce33..70845f28e1f6b 100644 --- a/x-pack/plugins/cases/public/components/edit_connector/index.tsx +++ b/x-pack/plugins/cases/public/components/edit_connector/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useCallback, useReducer } from 'react'; +import React, { useCallback, useEffect, useReducer } from 'react'; import deepEqual from 'fast-deep-equal'; import { EuiText, @@ -144,17 +144,43 @@ export const EditConnector = React.memo( { ...initialState, fields: caseFields } ); + useEffect(() => { + // Initialize the current connector with the connector information attached to the case if we can find that + // connector in the retrieved connectors from the API call + if (!isLoading) { + dispatch({ + type: 'SET_CURRENT_CONNECTOR', + payload: getConnectorById(caseData.connector.id, connectors), + }); + + // Set the fields initially to whatever is present in the case, this should match with + // the latest user action for an update connector as well + dispatch({ + type: 'SET_FIELDS', + payload: caseFields, + }); + } + }, [caseData.connector.id, connectors, isLoading, caseFields]); + + /** + * There is a race condition with this callback. At some point during the initial mounting of this component, this + * callback will be called. There are a couple problems with this: + * + * 1. If the call occurs before the above useEffect does its dispatches (aka while the connectors are still loading) this will + * result in setting the current connector to null when in fact we might have a valid connector. It could also + * cause issues when setting the fields because if there are no user actions then the getConnectorFieldsFromUserActions + * will return null even when the caseData.connector.fields is valid and populated. + * + * 2. If the call occurs after the above useEffect then the currentConnector should === newConnectorId + * + * As far as I know dispatch is synchronous so if the useEffect runs first it should successfully set currentConnector. If + * onChangeConnector runs first and sets stuff to null, then when useEffect runs it'll switch everything back to what we need it to be + * initially. + */ const onChangeConnector = useCallback( (newConnectorId) => { - // Init - if (currentConnector == null) { - dispatch({ - type: 'SET_CURRENT_CONNECTOR', - payload: getConnectorById(newConnectorId, connectors), - }); - } - // change connect on dropdown action - else if (currentConnector.id !== newConnectorId) { + // change connector on dropdown action + if (currentConnector?.id !== newConnectorId) { dispatch({ type: 'SET_CURRENT_CONNECTOR', payload: getConnectorById(newConnectorId, connectors), @@ -163,14 +189,9 @@ export const EditConnector = React.memo( type: 'SET_FIELDS', payload: getConnectorFieldsFromUserActions(newConnectorId, userActions ?? []), }); - } else if (fields === null) { - dispatch({ - type: 'SET_FIELDS', - payload: getConnectorFieldsFromUserActions(newConnectorId, userActions ?? []), - }); } }, - [currentConnector, fields, userActions, connectors] + [currentConnector, userActions, connectors] ); const onFieldsChange = useCallback( From d840ea6da9315e1ae33982e13804cee75d8ae857 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 3 Sep 2021 09:31:00 -0700 Subject: [PATCH 04/18] Update sync workflow to only run on elastic/kibana (#111171) Signed-off-by: Tyler Smalley --- .github/workflows/sync-main-branch.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/sync-main-branch.yml b/.github/workflows/sync-main-branch.yml index 63465602e8436..3f2ef967d3ee6 100644 --- a/.github/workflows/sync-main-branch.yml +++ b/.github/workflows/sync-main-branch.yml @@ -9,6 +9,7 @@ jobs: sync_latest_from_upstream: runs-on: ubuntu-latest name: Sync latest commits from master branch + if: github.repository == "elastic/kibana" steps: - name: Checkout target repo From c9440bb5ffadf85469e417e2e1548b15cf0cc2fa Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 3 Sep 2021 09:32:33 -0700 Subject: [PATCH 05/18] Revert "Update sync workflow to only run on elastic/kibana (#111171)" (#111181) This reverts commit d840ea6da9315e1ae33982e13804cee75d8ae857. --- .github/workflows/sync-main-branch.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/sync-main-branch.yml b/.github/workflows/sync-main-branch.yml index 3f2ef967d3ee6..63465602e8436 100644 --- a/.github/workflows/sync-main-branch.yml +++ b/.github/workflows/sync-main-branch.yml @@ -9,7 +9,6 @@ jobs: sync_latest_from_upstream: runs-on: ubuntu-latest name: Sync latest commits from master branch - if: github.repository == "elastic/kibana" steps: - name: Checkout target repo From cb27ba01c1d6540aeb54e0fb2303351cc2ce0794 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Fri, 3 Sep 2021 09:58:31 -0700 Subject: [PATCH 06/18] Update sync workflow to only run on elastic/kibana (#111183) Signed-off-by: Tyler Smalley --- .github/workflows/sync-main-branch.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/sync-main-branch.yml b/.github/workflows/sync-main-branch.yml index 63465602e8436..971ff0b9a6351 100644 --- a/.github/workflows/sync-main-branch.yml +++ b/.github/workflows/sync-main-branch.yml @@ -9,6 +9,7 @@ jobs: sync_latest_from_upstream: runs-on: ubuntu-latest name: Sync latest commits from master branch + if: github.repository == 'elastic/kibana' steps: - name: Checkout target repo From df43d253c85fbd6f0afb1eae99948211ef43bed6 Mon Sep 17 00:00:00 2001 From: Michael Dokolin Date: Fri, 3 Sep 2021 19:10:29 +0200 Subject: [PATCH 07/18] [Expressions] Align renderMode with the embeddable viewMode (#110199) * Add preview view mode to the embeddable * Rename display render mode to view * Extract no interactivity render mode to a separate flag --- src/plugins/embeddable/common/types.ts | 1 + .../common/expression_renderers/types.ts | 11 ++++++++--- src/plugins/expressions/public/loader.ts | 1 + .../public/react_expression_renderer.tsx | 1 + src/plugins/expressions/public/render.ts | 7 ++++++- src/plugins/expressions/public/types/index.ts | 1 + .../public/__stories__/render.tsx | 3 ++- .../public/embeddable/visualize_embeddable.ts | 1 + .../functions/external/saved_lens.ts | 1 - .../renderers/__stories__/render.tsx | 3 ++- .../plugins/canvas/public/lib/create_handlers.ts | 3 ++- .../markdown_editor/plugins/lens/processor.tsx | 2 +- .../components/table_basic.test.tsx | 16 ++++++++-------- .../lens/public/embeddable/embeddable.test.tsx | 10 ++++++++-- .../lens/public/embeddable/embeddable.tsx | 1 + .../public/embeddable/expression_wrapper.tsx | 3 +++ .../lens/public/pie_visualization/expression.tsx | 1 + .../pie_visualization/render_function.test.tsx | 6 +++--- .../public/pie_visualization/render_function.tsx | 5 ++--- .../public/xy_visualization/expression.test.tsx | 10 +++++----- .../lens/public/xy_visualization/expression.tsx | 8 +++++--- 21 files changed, 62 insertions(+), 33 deletions(-) diff --git a/src/plugins/embeddable/common/types.ts b/src/plugins/embeddable/common/types.ts index 22d8672e59a37..430b59bc62242 100644 --- a/src/plugins/embeddable/common/types.ts +++ b/src/plugins/embeddable/common/types.ts @@ -12,6 +12,7 @@ import { PersistableStateService } from '../../kibana_utils/common'; export enum ViewMode { EDIT = 'edit', + PREVIEW = 'preview', VIEW = 'view', } diff --git a/src/plugins/expressions/common/expression_renderers/types.ts b/src/plugins/expressions/common/expression_renderers/types.ts index 239cff6143ae7..8547c1a1bec92 100644 --- a/src/plugins/expressions/common/expression_renderers/types.ts +++ b/src/plugins/expressions/common/expression_renderers/types.ts @@ -53,12 +53,11 @@ export type AnyExpressionRenderDefinition = ExpressionRenderDefinition; * This value can be set from a consumer embedding an expression renderer and is accessible * from within the active render function as part of the handlers. * The following modes are supported: - * * display (default): The chart is rendered in a container with the main purpose of viewing the chart (e.g. in a container like dashboard or canvas) + * * view (default): The chart is rendered in a container with the main purpose of viewing the chart (e.g. in a container like dashboard or canvas) * * preview: The chart is rendered in very restricted space (below 100px width and height) and should only show a rough outline * * edit: The chart is rendered within an editor and configuration elements within the chart should be displayed - * * noInteractivity: The chart is rendered in a non-interactive environment and should not provide any affordances for interaction like brushing */ -export type RenderMode = 'noInteractivity' | 'edit' | 'preview' | 'display'; +export type RenderMode = 'edit' | 'preview' | 'view'; export interface IInterpreterRenderHandlers { /** @@ -71,6 +70,12 @@ export interface IInterpreterRenderHandlers { event: (event: any) => void; hasCompatibleActions?: (event: any) => Promise; getRenderMode: () => RenderMode; + + /** + * The chart is rendered in a non-interactive environment and should not provide any affordances for interaction like brushing. + */ + isInteractive: () => boolean; + isSyncColorsEnabled: () => boolean; /** * This uiState interface is actually `PersistedState` from the visualizations plugin, diff --git a/src/plugins/expressions/public/loader.ts b/src/plugins/expressions/public/loader.ts index d0f60eb294060..3ab7473d8d735 100644 --- a/src/plugins/expressions/public/loader.ts +++ b/src/plugins/expressions/public/loader.ts @@ -53,6 +53,7 @@ export class ExpressionLoader { ); this.renderHandler = new ExpressionRenderHandler(element, { + interactive: params?.interactive, onRenderError: params && params.onRenderError, renderMode: params?.renderMode, syncColors: params?.syncColors, diff --git a/src/plugins/expressions/public/react_expression_renderer.tsx b/src/plugins/expressions/public/react_expression_renderer.tsx index 719af1b39f89e..2640be16eae46 100644 --- a/src/plugins/expressions/public/react_expression_renderer.tsx +++ b/src/plugins/expressions/public/react_expression_renderer.tsx @@ -171,6 +171,7 @@ export const ReactExpressionRenderer = ({ }, [ hasCustomRenderErrorHandler, onEvent, + expressionLoaderOptions.interactive, expressionLoaderOptions.renderMode, expressionLoaderOptions.syncColors, ]); diff --git a/src/plugins/expressions/public/render.ts b/src/plugins/expressions/public/render.ts index e7a00867c1005..e9a65d1e8f12e 100644 --- a/src/plugins/expressions/public/render.ts +++ b/src/plugins/expressions/public/render.ts @@ -21,6 +21,7 @@ export interface ExpressionRenderHandlerParams { onRenderError?: RenderErrorHandlerFnType; renderMode?: RenderMode; syncColors?: boolean; + interactive?: boolean; hasCompatibleActions?: (event: ExpressionRendererEvent) => Promise; } @@ -54,6 +55,7 @@ export class ExpressionRenderHandler { onRenderError, renderMode, syncColors, + interactive, hasCompatibleActions = async () => false, }: ExpressionRenderHandlerParams = {} ) { @@ -90,11 +92,14 @@ export class ExpressionRenderHandler { this.eventsSubject.next(data); }, getRenderMode: () => { - return renderMode || 'display'; + return renderMode || 'view'; }, isSyncColorsEnabled: () => { return syncColors || false; }, + isInteractive: () => { + return interactive ?? true; + }, hasCompatibleActions, }; } diff --git a/src/plugins/expressions/public/types/index.ts b/src/plugins/expressions/public/types/index.ts index 5a2198bb4f2e5..172f322f8892a 100644 --- a/src/plugins/expressions/public/types/index.ts +++ b/src/plugins/expressions/public/types/index.ts @@ -44,6 +44,7 @@ export interface IExpressionLoaderParams { customRenderers?: []; uiState?: unknown; inspectorAdapters?: Adapters; + interactive?: boolean; onRenderError?: RenderErrorHandlerFnType; searchSessionId?: string; renderMode?: RenderMode; diff --git a/src/plugins/presentation_util/public/__stories__/render.tsx b/src/plugins/presentation_util/public/__stories__/render.tsx index 2588d2e3294ae..76725d08956bd 100644 --- a/src/plugins/presentation_util/public/__stories__/render.tsx +++ b/src/plugins/presentation_util/public/__stories__/render.tsx @@ -11,8 +11,9 @@ import React, { useRef, useEffect } from 'react'; import { ExpressionRenderDefinition, IInterpreterRenderHandlers } from 'src/plugins/expressions'; export const defaultHandlers: IInterpreterRenderHandlers = { - getRenderMode: () => 'display', + getRenderMode: () => 'view', isSyncColorsEnabled: () => false, + isInteractive: () => true, done: action('done'), onDestroy: action('onDestroy'), reload: action('reload'), diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts index b71542a8beeea..78230a8961967 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts @@ -402,6 +402,7 @@ export class VisualizeEmbeddable searchSessionId: this.input.searchSessionId, syncColors: this.input.syncColors, uiState: this.vis.uiState, + interactive: !this.input.disableTriggers, inspectorAdapters: this.inspectorAdapters, executionContext: context, }; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts index bd844dd3335ef..082a69a874cae 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts @@ -85,7 +85,6 @@ export function savedLens(): ExpressionFunctionDefinition< title: args.title === null ? undefined : args.title, disableTriggers: true, palette: args.palette, - renderMode: 'noInteractivity', }, embeddableType: EmbeddableTypes.lens, generatedAt: Date.now(), diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/__stories__/render.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/__stories__/render.tsx index d87c24b1b7e86..643d7cdedc50d 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/__stories__/render.tsx +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/__stories__/render.tsx @@ -13,8 +13,9 @@ export const defaultHandlers: RendererHandlers = { destroy: () => action('destroy'), getElementId: () => 'element-id', getFilter: () => 'filter', - getRenderMode: () => 'display', + getRenderMode: () => 'view', isSyncColorsEnabled: () => false, + isInteractive: () => true, onComplete: (fn) => undefined, onEmbeddableDestroyed: action('onEmbeddableDestroyed'), onEmbeddableInputChange: action('onEmbeddableInputChange'), diff --git a/x-pack/plugins/canvas/public/lib/create_handlers.ts b/x-pack/plugins/canvas/public/lib/create_handlers.ts index dfc4387bcbf92..3734b1bf53051 100644 --- a/x-pack/plugins/canvas/public/lib/create_handlers.ts +++ b/x-pack/plugins/canvas/public/lib/create_handlers.ts @@ -26,8 +26,9 @@ export const createBaseHandlers = (): IInterpreterRenderHandlers => ({ update() {}, event() {}, onDestroy() {}, - getRenderMode: () => 'display', + getRenderMode: () => 'view', isSyncColorsEnabled: () => false, + isInteractive: () => true, }); export const createHandlers = (baseHandlers = createBaseHandlers()): RendererHandlers => ({ diff --git a/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/processor.tsx b/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/processor.tsx index 18315b1611c56..d0e816a06c7df 100644 --- a/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/processor.tsx +++ b/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/processor.tsx @@ -48,7 +48,7 @@ const LensMarkDownRendererComponent: React.FC = ({ style={{ height: LENS_VISUALIZATION_HEIGHT }} timeRange={timeRange} attributes={attributes} - renderMode="display" + renderMode="view" /> diff --git a/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.test.tsx b/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.test.tsx index a0d137b90e84c..c156b870e7aa3 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.test.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/components/table_basic.test.tsx @@ -151,7 +151,7 @@ describe('DatatableComponent', () => { dispatchEvent={onDispatchEvent} getType={jest.fn()} rowHasRowClickTriggerActions={[false, false, false]} - renderMode="display" + renderMode="view" paletteService={chartPluginMock.createPaletteRegistry()} uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient} /> @@ -427,7 +427,7 @@ describe('DatatableComponent', () => { formatFactory={() => ({ convert: (x) => x } as IFieldFormat)} dispatchEvent={onDispatchEvent} getType={jest.fn()} - renderMode="display" + renderMode="view" paletteService={chartPluginMock.createPaletteRegistry()} uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient} /> @@ -457,7 +457,7 @@ describe('DatatableComponent', () => { formatFactory={() => ({ convert: (x) => x } as IFieldFormat)} dispatchEvent={onDispatchEvent} getType={jest.fn()} - renderMode="display" + renderMode="view" paletteService={chartPluginMock.createPaletteRegistry()} uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient} /> @@ -485,7 +485,7 @@ describe('DatatableComponent', () => { formatFactory={() => ({ convert: (x) => x } as IFieldFormat)} dispatchEvent={onDispatchEvent} getType={jest.fn()} - renderMode="display" + renderMode="view" paletteService={chartPluginMock.createPaletteRegistry()} uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient} /> @@ -546,7 +546,7 @@ describe('DatatableComponent', () => { formatFactory={() => ({ convert: (x) => x } as IFieldFormat)} dispatchEvent={onDispatchEvent} getType={jest.fn()} - renderMode="display" + renderMode="view" paletteService={chartPluginMock.createPaletteRegistry()} uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient} /> @@ -581,7 +581,7 @@ describe('DatatableComponent', () => { formatFactory={() => ({ convert: (x) => x } as IFieldFormat)} dispatchEvent={onDispatchEvent} getType={jest.fn()} - renderMode="display" + renderMode="view" paletteService={chartPluginMock.createPaletteRegistry()} uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient} /> @@ -616,7 +616,7 @@ describe('DatatableComponent', () => { formatFactory={() => ({ convert: (x) => x } as IFieldFormat)} dispatchEvent={onDispatchEvent} getType={jest.fn()} - renderMode="display" + renderMode="view" paletteService={chartPluginMock.createPaletteRegistry()} uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient} /> @@ -650,7 +650,7 @@ describe('DatatableComponent', () => { formatFactory={() => ({ convert: (x) => x } as IFieldFormat)} dispatchEvent={onDispatchEvent} getType={jest.fn()} - renderMode="display" + renderMode="view" paletteService={chartPluginMock.createPaletteRegistry()} uiSettings={({ get: jest.fn() } as unknown) as IUiSettingsClient} /> diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.test.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.test.tsx index a0831e8a73b57..be20118ba2941 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.test.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.test.tsx @@ -566,7 +566,8 @@ describe('embeddable', () => { timeRange, query, filters, - renderMode: 'noInteractivity', + renderMode: 'view', + disableTriggers: true, } as LensEmbeddableInput; const embeddable = new Embeddable( @@ -599,7 +600,12 @@ describe('embeddable', () => { await embeddable.initializeSavedVis(input); embeddable.render(mountpoint); - expect(expressionRenderer.mock.calls[0][0].renderMode).toEqual('noInteractivity'); + expect(expressionRenderer.mock.calls[0][0]).toEqual( + expect.objectContaining({ + interactive: false, + renderMode: 'view', + }) + ); }); it('should merge external context with query and filters of the saved object', async () => { diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index 7e87dd3076faa..d10423c76686c 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -361,6 +361,7 @@ export class Embeddable searchSessionId={this.externalSearchContext.searchSessionId} handleEvent={this.handleEvent} onData$={this.updateActiveData} + interactive={!input.disableTriggers} renderMode={input.renderMode} syncColors={input.syncColors} hasCompatibleActions={this.hasCompatibleActions} diff --git a/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx b/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx index 1116b4a0d3963..c827fe74cc52b 100644 --- a/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx +++ b/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx @@ -38,6 +38,7 @@ export interface ExpressionWrapperProps { expression: string | null; errors: ErrorMessage[] | undefined; variables?: Record; + interactive?: boolean; searchContext: ExecutionContextSearch; searchSessionId?: string; handleEvent: (event: ExpressionRendererEvent) => void; @@ -113,6 +114,7 @@ export function ExpressionWrapper({ searchContext, variables, handleEvent, + interactive, searchSessionId, onData$, renderMode, @@ -137,6 +139,7 @@ export function ExpressionWrapper({ padding="s" variables={variables} expression={expression} + interactive={interactive} searchContext={searchContext} searchSessionId={searchSessionId} onData$={onData$} diff --git a/x-pack/plugins/lens/public/pie_visualization/expression.tsx b/x-pack/plugins/lens/public/pie_visualization/expression.tsx index c1b9f4c799e64..c947d50d5b910 100644 --- a/x-pack/plugins/lens/public/pie_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/expression.tsx @@ -44,6 +44,7 @@ export const getPieRenderer = (dependencies: { {...config} formatFactory={dependencies.formatFactory} chartsThemeService={dependencies.chartsThemeService} + interactive={handlers.isInteractive()} paletteService={dependencies.paletteService} onClickValue={onClickValue} renderMode={handlers.getRenderMode()} diff --git a/x-pack/plugins/lens/public/pie_visualization/render_function.test.tsx b/x-pack/plugins/lens/public/pie_visualization/render_function.test.tsx index 93f16c49061e4..209d7ff652ea1 100644 --- a/x-pack/plugins/lens/public/pie_visualization/render_function.test.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/render_function.test.tsx @@ -77,7 +77,7 @@ describe('PieVisualization component', () => { onClickValue: jest.fn(), chartsThemeService, paletteService: chartPluginMock.createPaletteRegistry(), - renderMode: 'display' as const, + renderMode: 'view' as const, syncColors: false, }; } @@ -302,10 +302,10 @@ describe('PieVisualization component', () => { `); }); - test('does not set click listener on noInteractivity render mode', () => { + test('does not set click listener on non-interactive mode', () => { const defaultArgs = getDefaultArgs(); const component = shallow( - + ); expect(component.find(Settings).first().prop('onElementClick')).toBeUndefined(); }); diff --git a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx index 41b96ff4324ae..a0a845dc96007 100644 --- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx @@ -55,6 +55,7 @@ export function PieComponent( props: PieExpressionProps & { formatFactory: FormatFactory; chartsThemeService: ChartsPluginSetup['theme']; + interactive?: boolean; paletteService: PaletteRegistry; onClickValue: (data: LensFilterEvent['data']) => void; renderMode: RenderMode; @@ -289,9 +290,7 @@ export function PieComponent( } legendPosition={legendPosition || Position.Right} legendMaxDepth={nestedLegend ? undefined : 1 /* Color is based only on first layer */} - onElementClick={ - props.renderMode !== 'noInteractivity' ? onElementClickHandler : undefined - } + onElementClick={props.interactive ?? true ? onElementClickHandler : undefined} legendAction={getLegendAction(firstTable, onClickValue)} theme={{ ...chartTheme, diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx index a41ad59ebee93..3994aadd9a989 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx @@ -480,7 +480,7 @@ describe('xy_expression', () => { defaultProps = { formatFactory: getFormatSpy, timeZone: 'UTC', - renderMode: 'display', + renderMode: 'view', chartsThemeService, chartsActiveCursorService, paletteService, @@ -1064,11 +1064,11 @@ describe('xy_expression', () => { }); }); - test('onBrushEnd is not set on noInteractivity mode', () => { + test('onBrushEnd is not set on non-interactive mode', () => { const { args, data } = sampleArgs(); const wrapper = mountWithIntl( - + ); expect(wrapper.find(Settings).first().prop('onBrushEnd')).toBeUndefined(); @@ -1334,11 +1334,11 @@ describe('xy_expression', () => { }); }); - test('onElementClick is not triggering event on noInteractivity mode', () => { + test('onElementClick is not triggering event on non-interactive mode', () => { const { args, data } = sampleArgs(); const wrapper = mountWithIntl( - + ); expect(wrapper.find(Settings).first().prop('onElementClick')).toBeUndefined(); diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx index f8dff65969d57..75d14d9b48ee3 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx @@ -93,6 +93,7 @@ export type XYChartRenderProps = XYChartProps & { formatFactory: FormatFactory; timeZone: string; minInterval: number | undefined; + interactive?: boolean; onClickValue: (data: LensFilterEvent['data']) => void; onSelectRange: (data: LensBrushEvent['data']) => void; renderMode: RenderMode; @@ -160,6 +161,7 @@ export const getXyChartRenderer = (dependencies: { paletteService={dependencies.paletteService} timeZone={dependencies.timeZone} minInterval={calculateMinInterval(config)} + interactive={handlers.isInteractive()} onClickValue={onClickValue} onSelectRange={onSelectRange} renderMode={handlers.getRenderMode()} @@ -233,7 +235,7 @@ export function XYChart({ minInterval, onClickValue, onSelectRange, - renderMode, + interactive = true, syncColors, }: XYChartRenderProps) { const { @@ -528,8 +530,8 @@ export function XYChart({ }} rotation={shouldRotate ? 90 : 0} xDomain={xDomain} - onBrushEnd={renderMode !== 'noInteractivity' ? brushHandler : undefined} - onElementClick={renderMode !== 'noInteractivity' ? clickHandler : undefined} + onBrushEnd={interactive ? brushHandler : undefined} + onElementClick={interactive ? clickHandler : undefined} legendAction={getLegendAction( filteredLayers, data.tables, From df22a8e19744e83c478791a7a4ad6828d081db1d Mon Sep 17 00:00:00 2001 From: Tim Roes Date: Fri, 3 Sep 2021 19:12:42 +0200 Subject: [PATCH 08/18] Change Graph ownership (#111157) --- .github/CODEOWNERS | 3 ++- x-pack/plugins/graph/kibana.json | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9a09ea1de6943..0949c5d742435 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -16,10 +16,11 @@ /src/plugins/discover/ @elastic/kibana-data-discovery /x-pack/plugins/discover_enhanced/ @elastic/kibana-data-discovery /test/functional/apps/discover/ @elastic/kibana-data-discovery +/x-pack/plugins/graph/ @elastic/kibana-data-discovery +/x-pack/test/functional/apps/graph @elastic/kibana-data-discovery # Vis Editors /x-pack/plugins/lens/ @elastic/kibana-vis-editors -/x-pack/plugins/graph/ @elastic/kibana-vis-editors /src/plugins/advanced_settings/ @elastic/kibana-vis-editors /src/plugins/charts/ @elastic/kibana-vis-editors /src/plugins/management/ @elastic/kibana-vis-editors diff --git a/x-pack/plugins/graph/kibana.json b/x-pack/plugins/graph/kibana.json index 463893e2425ac..cc732e67995ba 100644 --- a/x-pack/plugins/graph/kibana.json +++ b/x-pack/plugins/graph/kibana.json @@ -9,7 +9,7 @@ "configPath": ["xpack", "graph"], "requiredBundles": ["kibanaUtils", "kibanaReact", "home"], "owner": { - "name": "Vis Editors", - "githubTeam": "kibana-vis-editors" + "name": "Data Discovery", + "githubTeam": "kibana-data-discovery" } } From 167b876a8adb27104d9fd09cd8eea4413a137bc4 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen <43350163+qn895@users.noreply.github.com> Date: Fri, 3 Sep 2021 12:12:48 -0500 Subject: [PATCH 09/18] [ML] Fix issue with AD data points not showing up because missing indices (#110899) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../application/services/anomaly_explorer_charts_service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts index 7a81a7ecb1e34..32c6aeb6b7553 100644 --- a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts +++ b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts @@ -590,7 +590,7 @@ export class AnomalyExplorerChartsService { return mlResultsService .getMetricData( Array.isArray(config.datafeedConfig.indices) - ? config.datafeedConfig.indices[0] + ? config.datafeedConfig.indices.join() : config.datafeedConfig.indices, entityFields, datafeedQuery, @@ -777,7 +777,7 @@ export class AnomalyExplorerChartsService { return mlResultsService .getEventDistributionData( Array.isArray(config.datafeedConfig.indices) - ? config.datafeedConfig.indices[0] + ? config.datafeedConfig.indices.join() : config.datafeedConfig.indices, splitField, filterField, From a9d73311e01b9d1cabea033608b6268c2bf501a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Fri, 3 Sep 2021 20:06:36 +0100 Subject: [PATCH 10/18] [Docs] Logging settings: add explanation of `appenders`, `loggers` and `root` (#111013) --- docs/settings/logging-settings.asciidoc | 28 ++++++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/docs/settings/logging-settings.asciidoc b/docs/settings/logging-settings.asciidoc index aa38d54305eec..77f3bd90a911a 100644 --- a/docs/settings/logging-settings.asciidoc +++ b/docs/settings/logging-settings.asciidoc @@ -4,6 +4,16 @@ Logging settings ++++ +{kib} relies on three high-level entities to set the logging service: appenders, loggers, and root. + +- Appenders define where log messages are displayed (stdout or console) and their layout (`pattern` or `json`). They also allow you to specify if you want the logs stored and, if so, where (file on the disk). +- Loggers define what logging settings, such as the level of verbosity and the appenders, to apply to a particular context. Each log entry context provides information about the service or plugin that emits it and any of its sub-parts, for example, `metrics.ops` or `elasticsearch.query`. +- Root is a logger that applies to all the log entries in {kib}. + +Refer to the <> for common configuration use cases. To learn more about possible configuration values, go to {kibana-ref}/logging-service.html[{kib}'s Logging service]. + +[[log-settings-compatibility]] +==== Backwards compatibility Compatibility with the legacy logging system is assured until the end of the `v7` version. All log messages handled by `root` context (default) are forwarded to the legacy logging service. The logging configuration is validated against the predefined schema and if there are @@ -12,10 +22,12 @@ any issues with it, {kib} will fail to start with the detailed error message. NOTE: When you switch to the new logging configuration, you will start seeing duplicate log entries in both formats. These will be removed when the `default` appender is no longer required. +[[log-settings-examples]] +==== Examples Here are some configuration examples for the most common logging use cases: [[log-to-file-example]] -==== Log to a file +===== Log to a file Log the default log format to a file instead of to stdout (the default). @@ -33,10 +45,10 @@ logging: ---- [[log-in-json-ECS-example]] -==== Log in json format +===== Log in JSON format -Log the default log format to json layout instead of pattern (the default). -With `json` layout log messages will be formatted as JSON strings in https://www.elastic.co/guide/en/ecs/current/ecs-reference.html[ECS format] that includes a timestamp, log level, logger, message text and any other metadata that may be associated with the log message itself +Log the default log format to JSON layout instead of pattern (the default). +With `json` layout, log messages will be formatted as JSON strings in https://www.elastic.co/guide/en/ecs/current/ecs-reference.html[ECS format] that includes a timestamp, log level, logger, message text and any other metadata that may be associated with the log message itself. [source,yaml] ---- @@ -51,7 +63,7 @@ logging: ---- [[log-with-meta-to-stdout]] -==== Log with meta to stdout +===== Log with meta to stdout Include `%meta` in your pattern layout: @@ -69,7 +81,7 @@ logging: ---- [[log-elasticsearch-queries]] -==== Log {es} queries +===== Log {es} queries [source,yaml] -- @@ -89,7 +101,7 @@ logging: -- [[change-overall-log-level]] -==== Change overall log level. +===== Change overall log level [source,yaml] ---- @@ -99,7 +111,7 @@ logging: ---- [[customize-specific-log-records]] -==== Customize specific log records +===== Customize specific log records Here is a detailed configuration example that can be used to configure _loggers_, _appenders_ and _layouts_: [source,yaml] From 9b20c8086720b48912377bea628296b209bc8b80 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 3 Sep 2021 15:17:06 -0400 Subject: [PATCH 11/18] Fix ML alert not allowed in Uptime app. (#111180) --- x-pack/plugins/uptime/server/kibana.index.ts | 30 ++++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/uptime/server/kibana.index.ts b/x-pack/plugins/uptime/server/kibana.index.ts index c303c78273331..3b1001daf0515 100644 --- a/x-pack/plugins/uptime/server/kibana.index.ts +++ b/x-pack/plugins/uptime/server/kibana.index.ts @@ -46,7 +46,11 @@ export const initServerWithKibana = ( management: { insightsAndAlerting: ['triggersActions'], }, - alerting: ['xpack.uptime.alerts.tls', 'xpack.uptime.alerts.monitorStatus'], + alerting: [ + 'xpack.uptime.alerts.tls', + 'xpack.uptime.alerts.monitorStatus', + 'xpack.uptime.alerts.durationAnomaly', + ], privileges: { all: { app: ['uptime', 'kibana'], @@ -58,10 +62,18 @@ export const initServerWithKibana = ( }, alerting: { rule: { - all: ['xpack.uptime.alerts.tls', 'xpack.uptime.alerts.monitorStatus'], + all: [ + 'xpack.uptime.alerts.tls', + 'xpack.uptime.alerts.monitorStatus', + 'xpack.uptime.alerts.durationAnomaly', + ], }, alert: { - all: ['xpack.uptime.alerts.tls', 'xpack.uptime.alerts.monitorStatus'], + all: [ + 'xpack.uptime.alerts.tls', + 'xpack.uptime.alerts.monitorStatus', + 'xpack.uptime.alerts.durationAnomaly', + ], }, }, management: { @@ -79,10 +91,18 @@ export const initServerWithKibana = ( }, alerting: { rule: { - read: ['xpack.uptime.alerts.tls', 'xpack.uptime.alerts.monitorStatus'], + read: [ + 'xpack.uptime.alerts.tls', + 'xpack.uptime.alerts.monitorStatus', + 'xpack.uptime.alerts.durationAnomaly', + ], }, alert: { - read: ['xpack.uptime.alerts.tls', 'xpack.uptime.alerts.monitorStatus'], + read: [ + 'xpack.uptime.alerts.tls', + 'xpack.uptime.alerts.monitorStatus', + 'xpack.uptime.alerts.durationAnomaly', + ], }, }, management: { From c6aa4f625cc804fde7b78d86f552a8ac0c2f55d7 Mon Sep 17 00:00:00 2001 From: Dmitry Shevchenko Date: Fri, 3 Sep 2021 21:38:45 +0200 Subject: [PATCH 12/18] Fix exceptions page table pagination (#111000) --- .../src/typescript_types/index.ts | 2 +- .../src/use_exception_lists/index.ts | 123 +++++++++--------- .../found_exception_list_schema.mock.ts | 2 +- .../hooks/use_exception_lists.test.ts | 82 ++++++------ .../rules/all/exceptions/columns.tsx | 3 +- .../rules/all/exceptions/exceptions_table.tsx | 46 +++++-- .../rules/all/exceptions/types.ts | 13 ++ 7 files changed, 156 insertions(+), 115 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/types.ts diff --git a/packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts b/packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts index 1909bcb1bcc2e..31f763101c258 100644 --- a/packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts +++ b/packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts @@ -40,7 +40,7 @@ export interface UseExceptionListsProps { http: HttpStart; namespaceTypes: NamespaceType[]; notifications: NotificationsStart; - pagination?: Pagination; + initialPagination?: Pagination; showTrustedApps: boolean; showEventFilters: boolean; } diff --git a/packages/kbn-securitysolution-list-hooks/src/use_exception_lists/index.ts b/packages/kbn-securitysolution-list-hooks/src/use_exception_lists/index.ts index 0bd4c6c705668..722a7918c4127 100644 --- a/packages/kbn-securitysolution-list-hooks/src/use_exception_lists/index.ts +++ b/packages/kbn-securitysolution-list-hooks/src/use_exception_lists/index.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { useEffect, useMemo, useRef, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import type { ExceptionListSchema, UseExceptionListsProps, @@ -17,7 +17,19 @@ import { fetchExceptionLists } from '@kbn/securitysolution-list-api'; import { getFilters } from '@kbn/securitysolution-list-utils'; export type Func = () => void; -export type ReturnExceptionLists = [boolean, ExceptionListSchema[], Pagination, Func | null]; +export type ReturnExceptionLists = [ + loading: boolean, + exceptionLists: ExceptionListSchema[], + pagination: Pagination, + setPagination: React.Dispatch>, + fetchLists: Func | null +]; + +const DEFAULT_PAGINATION = { + page: 1, + perPage: 20, + total: 0, +}; /** * Hook for fetching ExceptionLists @@ -29,17 +41,13 @@ export type ReturnExceptionLists = [boolean, ExceptionListSchema[], Pagination, * @param notifications kibana service for displaying toasters * @param showTrustedApps boolean - include/exclude trusted app lists * @param showEventFilters boolean - include/exclude event filters lists - * @param pagination + * @param initialPagination * */ export const useExceptionLists = ({ errorMessage, http, - pagination = { - page: 1, - perPage: 20, - total: 0, - }, + initialPagination = DEFAULT_PAGINATION, filterOptions = {}, namespaceTypes, notifications, @@ -47,9 +55,9 @@ export const useExceptionLists = ({ showEventFilters = false, }: UseExceptionListsProps): ReturnExceptionLists => { const [exceptionLists, setExceptionLists] = useState([]); - const [paginationInfo, setPagination] = useState(pagination); + const [pagination, setPagination] = useState(initialPagination); const [loading, setLoading] = useState(true); - const fetchExceptionListsRef = useRef(null); + const abortCtrlRef = useRef(); const namespaceTypesAsString = useMemo(() => namespaceTypes.join(','), [namespaceTypes]); const filters = useMemo( @@ -58,66 +66,57 @@ export const useExceptionLists = ({ [namespaceTypes, filterOptions, showTrustedApps, showEventFilters] ); - useEffect(() => { - let isSubscribed = true; - const abortCtrl = new AbortController(); + const fetchData = useCallback(async (): Promise => { + try { + setLoading(true); - const fetchData = async (): Promise => { - try { - setLoading(true); + abortCtrlRef.current = new AbortController(); - const { page, per_page: perPage, total, data } = await fetchExceptionLists({ - filters, - http, - namespaceTypes: namespaceTypesAsString, - pagination: { - page: pagination.page, - perPage: pagination.perPage, - }, - signal: abortCtrl.signal, - }); + const { page, per_page: perPage, total, data } = await fetchExceptionLists({ + filters, + http, + namespaceTypes: namespaceTypesAsString, + pagination: { + page: pagination.page, + perPage: pagination.perPage, + }, + signal: abortCtrlRef.current.signal, + }); - if (isSubscribed) { - setPagination({ - page, - perPage, - total, - }); - setExceptionLists(data); - setLoading(false); - } - } catch (error) { - if (isSubscribed) { - notifications.toasts.addError(error, { - title: errorMessage, - }); - setExceptionLists([]); - setPagination({ - page: 1, - perPage: 20, - total: 0, - }); - setLoading(false); - } + setPagination({ + page, + perPage, + total, + }); + setExceptionLists(data); + setLoading(false); + } catch (error) { + if (error.name !== 'AbortError') { + notifications.toasts.addError(error, { + title: errorMessage, + }); + setExceptionLists([]); + setPagination(DEFAULT_PAGINATION); + setLoading(false); } - }; - - fetchData(); - - fetchExceptionListsRef.current = fetchData; - return (): void => { - isSubscribed = false; - abortCtrl.abort(); - }; + } }, [ errorMessage, - notifications, - pagination.page, - pagination.perPage, filters, - namespaceTypesAsString, http, + namespaceTypesAsString, + notifications.toasts, + pagination.page, + pagination.perPage, ]); - return [loading, exceptionLists, paginationInfo, fetchExceptionListsRef.current]; + useEffect(() => { + fetchData(); + + return (): void => { + abortCtrlRef.current?.abort(); + }; + }, [fetchData]); + + return [loading, exceptionLists, pagination, setPagination, fetchData]; }; diff --git a/x-pack/plugins/lists/common/schemas/response/found_exception_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/response/found_exception_list_schema.mock.ts index e3611120348f4..e5e41b5fe4a85 100644 --- a/x-pack/plugins/lists/common/schemas/response/found_exception_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/response/found_exception_list_schema.mock.ts @@ -12,6 +12,6 @@ import { getExceptionListSchemaMock } from './exception_list_schema.mock'; export const getFoundExceptionListSchemaMock = (): FoundExceptionListSchema => ({ data: [getExceptionListSchemaMock()], page: 1, - per_page: 1, + per_page: 20, total: 1, }); diff --git a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_lists.test.ts b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_lists.test.ts index 4987de321c556..810fcaa15494f 100644 --- a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_lists.test.ts +++ b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_lists.test.ts @@ -41,13 +41,13 @@ describe('useExceptionLists', () => { errorMessage: 'Uh oh', filterOptions: {}, http: mockKibanaHttpService, - namespaceTypes: ['single', 'agnostic'], - notifications: mockKibanaNotificationsService, - pagination: { + initialPagination: { page: 1, perPage: 20, total: 0, }, + namespaceTypes: ['single', 'agnostic'], + notifications: mockKibanaNotificationsService, showEventFilters: false, showTrustedApps: false, }) @@ -62,7 +62,8 @@ describe('useExceptionLists', () => { perPage: 20, total: 0, }, - null, + expect.any(Function), + expect.any(Function), ]); }); }); @@ -77,13 +78,13 @@ describe('useExceptionLists', () => { errorMessage: 'Uh oh', filterOptions: {}, http: mockKibanaHttpService, - namespaceTypes: ['single', 'agnostic'], - notifications: mockKibanaNotificationsService, - pagination: { + initialPagination: { page: 1, perPage: 20, total: 0, }, + namespaceTypes: ['single', 'agnostic'], + notifications: mockKibanaNotificationsService, showEventFilters: false, showTrustedApps: false, }) @@ -100,10 +101,11 @@ describe('useExceptionLists', () => { expectedListItemsResult, { page: 1, - perPage: 1, + perPage: 20, total: 1, }, - result.current[3], + expect.any(Function), + expect.any(Function), ]); }); }); @@ -117,13 +119,13 @@ describe('useExceptionLists', () => { errorMessage: 'Uh oh', filterOptions: {}, http: mockKibanaHttpService, - namespaceTypes: ['single', 'agnostic'], - notifications: mockKibanaNotificationsService, - pagination: { + initialPagination: { page: 1, perPage: 20, total: 0, }, + namespaceTypes: ['single', 'agnostic'], + notifications: mockKibanaNotificationsService, showEventFilters: false, showTrustedApps: true, }) @@ -153,13 +155,13 @@ describe('useExceptionLists', () => { errorMessage: 'Uh oh', filterOptions: {}, http: mockKibanaHttpService, - namespaceTypes: ['single', 'agnostic'], - notifications: mockKibanaNotificationsService, - pagination: { + initialPagination: { page: 1, perPage: 20, total: 0, }, + namespaceTypes: ['single', 'agnostic'], + notifications: mockKibanaNotificationsService, showEventFilters: false, showTrustedApps: false, }) @@ -189,13 +191,13 @@ describe('useExceptionLists', () => { errorMessage: 'Uh oh', filterOptions: {}, http: mockKibanaHttpService, - namespaceTypes: ['single', 'agnostic'], - notifications: mockKibanaNotificationsService, - pagination: { + initialPagination: { page: 1, perPage: 20, total: 0, }, + namespaceTypes: ['single', 'agnostic'], + notifications: mockKibanaNotificationsService, showEventFilters: true, showTrustedApps: false, }) @@ -225,13 +227,13 @@ describe('useExceptionLists', () => { errorMessage: 'Uh oh', filterOptions: {}, http: mockKibanaHttpService, - namespaceTypes: ['single', 'agnostic'], - notifications: mockKibanaNotificationsService, - pagination: { + initialPagination: { page: 1, perPage: 20, total: 0, }, + namespaceTypes: ['single', 'agnostic'], + notifications: mockKibanaNotificationsService, showEventFilters: false, showTrustedApps: false, }) @@ -264,13 +266,13 @@ describe('useExceptionLists', () => { name: 'Sample Endpoint', }, http: mockKibanaHttpService, - namespaceTypes: ['single', 'agnostic'], - notifications: mockKibanaNotificationsService, - pagination: { + initialPagination: { page: 1, perPage: 20, total: 0, }, + namespaceTypes: ['single', 'agnostic'], + notifications: mockKibanaNotificationsService, showEventFilters: false, showTrustedApps: false, }) @@ -302,9 +304,9 @@ describe('useExceptionLists', () => { errorMessage, filterOptions, http, + initialPagination, namespaceTypes, notifications, - pagination, showEventFilters, showTrustedApps, }) => @@ -312,9 +314,9 @@ describe('useExceptionLists', () => { errorMessage, filterOptions, http, + initialPagination, namespaceTypes, notifications, - pagination, showEventFilters, showTrustedApps, }), @@ -323,13 +325,13 @@ describe('useExceptionLists', () => { errorMessage: 'Uh oh', filterOptions: {}, http: mockKibanaHttpService, - namespaceTypes: ['single'], - notifications: mockKibanaNotificationsService, - pagination: { + initialPagination: { page: 1, perPage: 20, total: 0, }, + namespaceTypes: ['single'], + notifications: mockKibanaNotificationsService, showEventFilters: false, showTrustedApps: false, }, @@ -344,13 +346,13 @@ describe('useExceptionLists', () => { errorMessage: 'Uh oh', filterOptions: {}, http: mockKibanaHttpService, - namespaceTypes: ['single', 'agnostic'], - notifications: mockKibanaNotificationsService, - pagination: { + initialPagination: { page: 1, perPage: 20, total: 0, }, + namespaceTypes: ['single', 'agnostic'], + notifications: mockKibanaNotificationsService, showEventFilters: false, showTrustedApps: false, }); @@ -372,13 +374,13 @@ describe('useExceptionLists', () => { errorMessage: 'Uh oh', filterOptions: {}, http: mockKibanaHttpService, - namespaceTypes: ['single', 'agnostic'], - notifications: mockKibanaNotificationsService, - pagination: { + initialPagination: { page: 1, perPage: 20, total: 0, }, + namespaceTypes: ['single', 'agnostic'], + notifications: mockKibanaNotificationsService, showEventFilters: false, showTrustedApps: false, }) @@ -390,8 +392,8 @@ describe('useExceptionLists', () => { expect(typeof result.current[3]).toEqual('function'); - if (result.current[3] != null) { - result.current[3](); + if (result.current[4] != null) { + result.current[4](); } // NOTE: Only need one call here because hook already initilaized await waitForNextUpdate(); @@ -411,13 +413,13 @@ describe('useExceptionLists', () => { errorMessage: 'Uh oh', filterOptions: {}, http: mockKibanaHttpService, - namespaceTypes: ['single', 'agnostic'], - notifications: mockKibanaNotificationsService, - pagination: { + initialPagination: { page: 1, perPage: 20, total: 0, }, + namespaceTypes: ['single', 'agnostic'], + notifications: mockKibanaNotificationsService, showEventFilters: false, showTrustedApps: false, }) diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx index 582ca0252604c..1ef3c3d3c5414 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx @@ -15,8 +15,9 @@ import { FormatUrl } from '../../../../../../common/components/link_to'; import * as i18n from './translations'; import { ExceptionListInfo } from './use_all_exception_lists'; import { ExceptionOverflowDisplay } from './exceptions_overflow_display'; +import { ExceptionsTableItem } from './types'; -export type AllExceptionListsColumns = EuiBasicTableColumn; +export type AllExceptionListsColumns = EuiBasicTableColumn; export const getAllExceptionListsColumns = ( onExport: (arg: { id: string; listId: string; namespaceType: NamespaceType }) => () => void, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx index 206976e6c0c1a..23bf634cb1081 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx @@ -7,6 +7,7 @@ import React, { useMemo, useEffect, useCallback, useState } from 'react'; import { + CriteriaWithPagination, EuiBasicTable, EuiEmptyPrompt, EuiLoadingContent, @@ -37,6 +38,7 @@ import { SecurityPageName } from '../../../../../../../common/constants'; import { useUserData } from '../../../../../components/user_info'; import { userHasPermissions } from '../../helpers'; import { useListsConfig } from '../../../../../containers/detection_engine/lists/use_lists_config'; +import { ExceptionsTableItem } from './types'; export type Func = () => Promise; @@ -74,7 +76,13 @@ export const ExceptionListsTable = React.memo(() => { exceptionReferenceModalInitialState ); const [filters, setFilters] = useState(undefined); - const [loadingExceptions, exceptions, pagination, refreshExceptions] = useExceptionLists({ + const [ + loadingExceptions, + exceptions, + pagination, + setPagination, + refreshExceptions, + ] = useExceptionLists({ errorMessage: i18n.ERROR_EXCEPTION_LISTS, filterOptions: filters, http, @@ -125,7 +133,7 @@ export const ExceptionListsTable = React.memo(() => { try { setDeletingListIds((ids) => [...ids, id]); if (refreshExceptions != null) { - await refreshExceptions(); + refreshExceptions(); } if (exceptionsListsRef[id] != null && exceptionsListsRef[id].rules.length === 0) { @@ -153,7 +161,7 @@ export const ExceptionListsTable = React.memo(() => { } catch (error) { handleDeleteError(error); } finally { - setDeletingListIds((ids) => [...ids.filter((_id) => _id !== id)]); + setDeletingListIds((ids) => ids.filter((_id) => _id !== id)); } }, [ @@ -326,11 +334,27 @@ export const ExceptionListsTable = React.memo(() => { setExportDownload({}); }, []); - const tableItems = (exceptionListsWithRuleRefs ?? []).map((item) => ({ - ...item, - isDeleting: deletingListIds.includes(item.id), - isExporting: exportingListIds.includes(item.id), - })); + const tableItems = useMemo( + () => + (exceptionListsWithRuleRefs ?? []).map((item) => ({ + ...item, + isDeleting: deletingListIds.includes(item.id), + isExporting: exportingListIds.includes(item.id), + })), + [deletingListIds, exceptionListsWithRuleRefs, exportingListIds] + ); + + const handlePaginationChange = useCallback( + (criteria: CriteriaWithPagination) => { + const { index, size } = criteria.page; + setPagination((currentPagination) => ({ + ...currentPagination, + perPage: size, + page: index + 1, + })); + }, + [setPagination] + ); return ( <> @@ -367,14 +391,14 @@ export const ExceptionListsTable = React.memo(() => { numberSelectedItems={0} onRefresh={handleRefresh} /> - data-test-subj="exceptions-table" columns={exceptionsColumns} isSelectable={hasPermissions} itemId="id" items={tableItems} noItemsMessage={emptyPrompt} - onChange={() => {}} + onChange={handlePaginationChange} pagination={paginationMemo} /> @@ -400,3 +424,5 @@ export const ExceptionListsTable = React.memo(() => { ); }); + +ExceptionListsTable.displayName = 'ExceptionListsTable'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/types.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/types.ts new file mode 100644 index 0000000000000..d7cbb924071f2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/types.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ExceptionListInfo } from './use_all_exception_lists'; + +export interface ExceptionsTableItem extends ExceptionListInfo { + isDeleting: boolean; + isExporting: boolean; +} From 7c4e4f507beadd5e5cdd3db46410cb50ef4982bc Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Fri, 3 Sep 2021 21:17:46 +0100 Subject: [PATCH 13/18] chore(NA): replace babel config files by inline presets by default in the jsts_transpiler rule (#110620) * chore(NA): replace babel config files by inline presets by default in the js_ts_transpiler rule * chore(NA): update @kbn/ace build to exclude worker file * chore(NA): remove config file support Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- packages/elastic-datemath/.babelrc | 3 --- packages/kbn-ace/.babelrc | 6 ----- packages/kbn-ace/BUILD.bazel | 2 ++ packages/kbn-alerts/.babelrc | 4 --- packages/kbn-alerts/.babelrc.browser | 4 --- packages/kbn-alerts/BUILD.bazel | 2 +- packages/kbn-analytics/.babelrc | 3 --- packages/kbn-analytics/.babelrc.browser | 3 --- packages/kbn-analytics/BUILD.bazel | 2 +- packages/kbn-apm-config-loader/.babelrc | 3 --- packages/kbn-apm-utils/.babelrc | 3 --- packages/kbn-babel-code-parser/.babelrc | 3 --- packages/kbn-cli-dev-mode/.babelrc | 3 --- packages/kbn-config-schema/.babelrc | 3 --- packages/kbn-config/.babelrc | 3 --- packages/kbn-crypto/.babelrc | 3 --- packages/kbn-dev-utils/.babelrc | 3 --- packages/kbn-docs-utils/.babelrc | 3 --- packages/kbn-es-archiver/.babelrc | 3 --- packages/kbn-es-query/.babelrc | 3 --- packages/kbn-es-query/.babelrc.browser | 3 --- packages/kbn-es-query/BUILD.bazel | 2 +- packages/kbn-es/.babelrc | 3 --- packages/kbn-field-types/.babelrc | 3 --- packages/kbn-i18n/.babelrc | 3 --- packages/kbn-i18n/.babelrc.browser | 3 --- packages/kbn-i18n/BUILD.bazel | 2 +- packages/kbn-interpreter/.babelrc | 3 --- packages/kbn-io-ts-utils/.babelrc | 3 --- packages/kbn-legacy-logging/.babelrc | 3 --- packages/kbn-logging/.babelrc | 3 --- packages/kbn-mapbox-gl/.babelrc | 3 --- packages/kbn-monaco/.babelrc | 3 --- packages/kbn-monaco/.babelrc.browser | 3 --- packages/kbn-monaco/BUILD.bazel | 2 +- packages/kbn-optimizer/.babelrc | 4 --- packages/kbn-plugin-generator/.babelrc | 3 --- packages/kbn-plugin-helpers/.babelrc | 3 --- packages/kbn-rule-data-utils/.babelrc | 3 --- .../.babelrc | 4 --- .../.babelrc.browser | 4 --- .../BUILD.bazel | 2 +- .../kbn-securitysolution-es-utils/.babelrc | 4 --- .../kbn-securitysolution-hook-utils/.babelrc | 4 --- .../.babelrc.browser | 4 --- .../BUILD.bazel | 2 +- .../.babelrc | 4 --- .../.babelrc.browser | 4 --- .../BUILD.bazel | 2 +- .../.babelrc | 4 --- .../.babelrc.browser | 4 --- .../BUILD.bazel | 2 +- .../kbn-securitysolution-io-ts-types/.babelrc | 4 --- .../.babelrc.browser | 4 --- .../BUILD.bazel | 2 +- .../kbn-securitysolution-io-ts-utils/.babelrc | 4 --- .../.babelrc.browser | 4 --- .../BUILD.bazel | 2 +- .../kbn-securitysolution-list-api/.babelrc | 4 --- .../.babelrc.browser | 4 --- .../kbn-securitysolution-list-api/BUILD.bazel | 2 +- .../.babelrc | 4 --- .../.babelrc.browser | 4 --- .../BUILD.bazel | 2 +- .../kbn-securitysolution-list-hooks/.babelrc | 4 --- .../.babelrc.browser | 4 --- .../BUILD.bazel | 2 +- .../kbn-securitysolution-list-utils/.babelrc | 4 --- .../.babelrc.browser | 4 --- .../BUILD.bazel | 2 +- packages/kbn-securitysolution-t-grid/.babelrc | 4 --- .../.babelrc.browser | 4 --- .../kbn-securitysolution-t-grid/BUILD.bazel | 2 +- packages/kbn-securitysolution-utils/.babelrc | 4 --- packages/kbn-server-http-tools/.babelrc | 3 --- packages/kbn-server-route-repository/.babelrc | 3 --- packages/kbn-std/.babelrc | 3 --- packages/kbn-storybook/.babelrc | 3 --- packages/kbn-telemetry-tools/.babelrc | 3 --- packages/kbn-test/.babelrc | 4 --- packages/kbn-tinymath/babel.config.js | 19 -------------- .../kbn-typed-react-router-config/.babelrc | 3 --- .../.babelrc.browser | 3 --- .../kbn-typed-react-router-config/BUILD.bazel | 2 +- packages/kbn-ui-shared-deps/.babelrc | 3 --- packages/kbn-utility-types/.babelrc | 3 --- packages/kbn-utils/.babelrc | 3 --- src/dev/bazel/jsts_transpiler.bzl | 26 ++++++++++++++----- 88 files changed, 39 insertions(+), 277 deletions(-) delete mode 100644 packages/elastic-datemath/.babelrc delete mode 100644 packages/kbn-ace/.babelrc delete mode 100644 packages/kbn-alerts/.babelrc delete mode 100644 packages/kbn-alerts/.babelrc.browser delete mode 100644 packages/kbn-analytics/.babelrc delete mode 100644 packages/kbn-analytics/.babelrc.browser delete mode 100644 packages/kbn-apm-config-loader/.babelrc delete mode 100644 packages/kbn-apm-utils/.babelrc delete mode 100644 packages/kbn-babel-code-parser/.babelrc delete mode 100644 packages/kbn-cli-dev-mode/.babelrc delete mode 100644 packages/kbn-config-schema/.babelrc delete mode 100644 packages/kbn-config/.babelrc delete mode 100644 packages/kbn-crypto/.babelrc delete mode 100644 packages/kbn-dev-utils/.babelrc delete mode 100644 packages/kbn-docs-utils/.babelrc delete mode 100644 packages/kbn-es-archiver/.babelrc delete mode 100644 packages/kbn-es-query/.babelrc delete mode 100644 packages/kbn-es-query/.babelrc.browser delete mode 100644 packages/kbn-es/.babelrc delete mode 100644 packages/kbn-field-types/.babelrc delete mode 100644 packages/kbn-i18n/.babelrc delete mode 100644 packages/kbn-i18n/.babelrc.browser delete mode 100644 packages/kbn-interpreter/.babelrc delete mode 100644 packages/kbn-io-ts-utils/.babelrc delete mode 100644 packages/kbn-legacy-logging/.babelrc delete mode 100644 packages/kbn-logging/.babelrc delete mode 100644 packages/kbn-mapbox-gl/.babelrc delete mode 100644 packages/kbn-monaco/.babelrc delete mode 100644 packages/kbn-monaco/.babelrc.browser delete mode 100644 packages/kbn-optimizer/.babelrc delete mode 100644 packages/kbn-plugin-generator/.babelrc delete mode 100644 packages/kbn-plugin-helpers/.babelrc delete mode 100644 packages/kbn-rule-data-utils/.babelrc delete mode 100644 packages/kbn-securitysolution-autocomplete/.babelrc delete mode 100644 packages/kbn-securitysolution-autocomplete/.babelrc.browser delete mode 100644 packages/kbn-securitysolution-es-utils/.babelrc delete mode 100644 packages/kbn-securitysolution-hook-utils/.babelrc delete mode 100644 packages/kbn-securitysolution-hook-utils/.babelrc.browser delete mode 100644 packages/kbn-securitysolution-io-ts-alerting-types/.babelrc delete mode 100644 packages/kbn-securitysolution-io-ts-alerting-types/.babelrc.browser delete mode 100644 packages/kbn-securitysolution-io-ts-list-types/.babelrc delete mode 100644 packages/kbn-securitysolution-io-ts-list-types/.babelrc.browser delete mode 100644 packages/kbn-securitysolution-io-ts-types/.babelrc delete mode 100644 packages/kbn-securitysolution-io-ts-types/.babelrc.browser delete mode 100644 packages/kbn-securitysolution-io-ts-utils/.babelrc delete mode 100644 packages/kbn-securitysolution-io-ts-utils/.babelrc.browser delete mode 100644 packages/kbn-securitysolution-list-api/.babelrc delete mode 100644 packages/kbn-securitysolution-list-api/.babelrc.browser delete mode 100644 packages/kbn-securitysolution-list-constants/.babelrc delete mode 100644 packages/kbn-securitysolution-list-constants/.babelrc.browser delete mode 100644 packages/kbn-securitysolution-list-hooks/.babelrc delete mode 100644 packages/kbn-securitysolution-list-hooks/.babelrc.browser delete mode 100644 packages/kbn-securitysolution-list-utils/.babelrc delete mode 100644 packages/kbn-securitysolution-list-utils/.babelrc.browser delete mode 100644 packages/kbn-securitysolution-t-grid/.babelrc delete mode 100644 packages/kbn-securitysolution-t-grid/.babelrc.browser delete mode 100644 packages/kbn-securitysolution-utils/.babelrc delete mode 100644 packages/kbn-server-http-tools/.babelrc delete mode 100644 packages/kbn-server-route-repository/.babelrc delete mode 100644 packages/kbn-std/.babelrc delete mode 100644 packages/kbn-storybook/.babelrc delete mode 100644 packages/kbn-telemetry-tools/.babelrc delete mode 100644 packages/kbn-test/.babelrc delete mode 100644 packages/kbn-tinymath/babel.config.js delete mode 100644 packages/kbn-typed-react-router-config/.babelrc delete mode 100644 packages/kbn-typed-react-router-config/.babelrc.browser delete mode 100644 packages/kbn-ui-shared-deps/.babelrc delete mode 100644 packages/kbn-utility-types/.babelrc delete mode 100644 packages/kbn-utils/.babelrc diff --git a/packages/elastic-datemath/.babelrc b/packages/elastic-datemath/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/elastic-datemath/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-ace/.babelrc b/packages/kbn-ace/.babelrc deleted file mode 100644 index 30ffbd24e1f18..0000000000000 --- a/packages/kbn-ace/.babelrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": [ - "src/ace/modes/x_json/worker/x_json.ace.worker.js" - ] -} diff --git a/packages/kbn-ace/BUILD.bazel b/packages/kbn-ace/BUILD.bazel index 5b9c38b16b53a..a13863b765d35 100644 --- a/packages/kbn-ace/BUILD.bazel +++ b/packages/kbn-ace/BUILD.bazel @@ -45,6 +45,8 @@ jsts_transpiler( srcs = SRCS, additional_args = [ "--copy-files", + "--ignore", + "**/*/src/ace/modes/x_json/worker/x_json.ace.worker.js", "--quiet" ], build_pkg_name = package_name(), diff --git a/packages/kbn-alerts/.babelrc b/packages/kbn-alerts/.babelrc deleted file mode 100644 index 40a198521b903..0000000000000 --- a/packages/kbn-alerts/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-alerts/.babelrc.browser b/packages/kbn-alerts/.babelrc.browser deleted file mode 100644 index 71bbfbcd6eb2f..0000000000000 --- a/packages/kbn-alerts/.babelrc.browser +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-alerts/BUILD.bazel b/packages/kbn-alerts/BUILD.bazel index a571380202cd6..91c575346fff7 100644 --- a/packages/kbn-alerts/BUILD.bazel +++ b/packages/kbn-alerts/BUILD.bazel @@ -57,7 +57,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-analytics/.babelrc b/packages/kbn-analytics/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-analytics/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-analytics/.babelrc.browser b/packages/kbn-analytics/.babelrc.browser deleted file mode 100644 index dc6a77bbe0bcd..0000000000000 --- a/packages/kbn-analytics/.babelrc.browser +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"] -} diff --git a/packages/kbn-analytics/BUILD.bazel b/packages/kbn-analytics/BUILD.bazel index ca8cdcbffbb52..cc65746e890ce 100644 --- a/packages/kbn-analytics/BUILD.bazel +++ b/packages/kbn-analytics/BUILD.bazel @@ -42,7 +42,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-apm-config-loader/.babelrc b/packages/kbn-apm-config-loader/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-apm-config-loader/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-apm-utils/.babelrc b/packages/kbn-apm-utils/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-apm-utils/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-babel-code-parser/.babelrc b/packages/kbn-babel-code-parser/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-babel-code-parser/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-cli-dev-mode/.babelrc b/packages/kbn-cli-dev-mode/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-cli-dev-mode/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-config-schema/.babelrc b/packages/kbn-config-schema/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-config-schema/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-config/.babelrc b/packages/kbn-config/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-config/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-crypto/.babelrc b/packages/kbn-crypto/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-crypto/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-dev-utils/.babelrc b/packages/kbn-dev-utils/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-dev-utils/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-docs-utils/.babelrc b/packages/kbn-docs-utils/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-docs-utils/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-es-archiver/.babelrc b/packages/kbn-es-archiver/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-es-archiver/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-es-query/.babelrc b/packages/kbn-es-query/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-es-query/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-es-query/.babelrc.browser b/packages/kbn-es-query/.babelrc.browser deleted file mode 100644 index dc6a77bbe0bcd..0000000000000 --- a/packages/kbn-es-query/.babelrc.browser +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"] -} diff --git a/packages/kbn-es-query/BUILD.bazel b/packages/kbn-es-query/BUILD.bazel index d4a531d308f6e..b3d861d937c8b 100644 --- a/packages/kbn-es-query/BUILD.bazel +++ b/packages/kbn-es-query/BUILD.bazel @@ -76,7 +76,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-es/.babelrc b/packages/kbn-es/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-es/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-field-types/.babelrc b/packages/kbn-field-types/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-field-types/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-i18n/.babelrc b/packages/kbn-i18n/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-i18n/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-i18n/.babelrc.browser b/packages/kbn-i18n/.babelrc.browser deleted file mode 100644 index dc6a77bbe0bcd..0000000000000 --- a/packages/kbn-i18n/.babelrc.browser +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"] -} diff --git a/packages/kbn-i18n/BUILD.bazel b/packages/kbn-i18n/BUILD.bazel index 62d5fb1d75a46..49d5603b2c516 100644 --- a/packages/kbn-i18n/BUILD.bazel +++ b/packages/kbn-i18n/BUILD.bazel @@ -65,7 +65,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-interpreter/.babelrc b/packages/kbn-interpreter/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-interpreter/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-io-ts-utils/.babelrc b/packages/kbn-io-ts-utils/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-io-ts-utils/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-legacy-logging/.babelrc b/packages/kbn-legacy-logging/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-legacy-logging/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-logging/.babelrc b/packages/kbn-logging/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-logging/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-mapbox-gl/.babelrc b/packages/kbn-mapbox-gl/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-mapbox-gl/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-monaco/.babelrc b/packages/kbn-monaco/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-monaco/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-monaco/.babelrc.browser b/packages/kbn-monaco/.babelrc.browser deleted file mode 100644 index dc6a77bbe0bcd..0000000000000 --- a/packages/kbn-monaco/.babelrc.browser +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"] -} diff --git a/packages/kbn-monaco/BUILD.bazel b/packages/kbn-monaco/BUILD.bazel index 3656210cb6b1b..d2d9bf3f9a00c 100644 --- a/packages/kbn-monaco/BUILD.bazel +++ b/packages/kbn-monaco/BUILD.bazel @@ -56,7 +56,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) webpack( diff --git a/packages/kbn-optimizer/.babelrc b/packages/kbn-optimizer/.babelrc deleted file mode 100644 index 1685d1644d94a..0000000000000 --- a/packages/kbn-optimizer/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.js"] -} diff --git a/packages/kbn-plugin-generator/.babelrc b/packages/kbn-plugin-generator/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-plugin-generator/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-plugin-helpers/.babelrc b/packages/kbn-plugin-helpers/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-plugin-helpers/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-rule-data-utils/.babelrc b/packages/kbn-rule-data-utils/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-rule-data-utils/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-securitysolution-autocomplete/.babelrc b/packages/kbn-securitysolution-autocomplete/.babelrc deleted file mode 100644 index 40a198521b903..0000000000000 --- a/packages/kbn-securitysolution-autocomplete/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-autocomplete/.babelrc.browser b/packages/kbn-securitysolution-autocomplete/.babelrc.browser deleted file mode 100644 index 71bbfbcd6eb2f..0000000000000 --- a/packages/kbn-securitysolution-autocomplete/.babelrc.browser +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-autocomplete/BUILD.bazel b/packages/kbn-securitysolution-autocomplete/BUILD.bazel index 53cd7b4f8d3e1..ac90a0479ce2a 100644 --- a/packages/kbn-securitysolution-autocomplete/BUILD.bazel +++ b/packages/kbn-securitysolution-autocomplete/BUILD.bazel @@ -72,7 +72,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-securitysolution-es-utils/.babelrc b/packages/kbn-securitysolution-es-utils/.babelrc deleted file mode 100644 index 40a198521b903..0000000000000 --- a/packages/kbn-securitysolution-es-utils/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-hook-utils/.babelrc b/packages/kbn-securitysolution-hook-utils/.babelrc deleted file mode 100644 index b17a19d6faf3f..0000000000000 --- a/packages/kbn-securitysolution-hook-utils/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-hook-utils/.babelrc.browser b/packages/kbn-securitysolution-hook-utils/.babelrc.browser deleted file mode 100644 index 71bbfbcd6eb2f..0000000000000 --- a/packages/kbn-securitysolution-hook-utils/.babelrc.browser +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-hook-utils/BUILD.bazel b/packages/kbn-securitysolution-hook-utils/BUILD.bazel index de007b34eeb21..bc7fd3bce1412 100644 --- a/packages/kbn-securitysolution-hook-utils/BUILD.bazel +++ b/packages/kbn-securitysolution-hook-utils/BUILD.bazel @@ -54,7 +54,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/.babelrc b/packages/kbn-securitysolution-io-ts-alerting-types/.babelrc deleted file mode 100644 index b17a19d6faf3f..0000000000000 --- a/packages/kbn-securitysolution-io-ts-alerting-types/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/.babelrc.browser b/packages/kbn-securitysolution-io-ts-alerting-types/.babelrc.browser deleted file mode 100644 index 71bbfbcd6eb2f..0000000000000 --- a/packages/kbn-securitysolution-io-ts-alerting-types/.babelrc.browser +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel b/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel index 940c6d589da11..cdee3a2f92540 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel +++ b/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel @@ -55,7 +55,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-securitysolution-io-ts-list-types/.babelrc b/packages/kbn-securitysolution-io-ts-list-types/.babelrc deleted file mode 100644 index 40a198521b903..0000000000000 --- a/packages/kbn-securitysolution-io-ts-list-types/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-io-ts-list-types/.babelrc.browser b/packages/kbn-securitysolution-io-ts-list-types/.babelrc.browser deleted file mode 100644 index 71bbfbcd6eb2f..0000000000000 --- a/packages/kbn-securitysolution-io-ts-list-types/.babelrc.browser +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel b/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel index 07ed552cdc408..ff4f2e80cbd37 100644 --- a/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel +++ b/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel @@ -53,7 +53,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-securitysolution-io-ts-types/.babelrc b/packages/kbn-securitysolution-io-ts-types/.babelrc deleted file mode 100644 index 40a198521b903..0000000000000 --- a/packages/kbn-securitysolution-io-ts-types/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-io-ts-types/.babelrc.browser b/packages/kbn-securitysolution-io-ts-types/.babelrc.browser deleted file mode 100644 index 71bbfbcd6eb2f..0000000000000 --- a/packages/kbn-securitysolution-io-ts-types/.babelrc.browser +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-io-ts-types/BUILD.bazel b/packages/kbn-securitysolution-io-ts-types/BUILD.bazel index adabf9708a59f..fe2247ac0b614 100644 --- a/packages/kbn-securitysolution-io-ts-types/BUILD.bazel +++ b/packages/kbn-securitysolution-io-ts-types/BUILD.bazel @@ -53,7 +53,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-securitysolution-io-ts-utils/.babelrc b/packages/kbn-securitysolution-io-ts-utils/.babelrc deleted file mode 100644 index 40a198521b903..0000000000000 --- a/packages/kbn-securitysolution-io-ts-utils/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-io-ts-utils/.babelrc.browser b/packages/kbn-securitysolution-io-ts-utils/.babelrc.browser deleted file mode 100644 index 71bbfbcd6eb2f..0000000000000 --- a/packages/kbn-securitysolution-io-ts-utils/.babelrc.browser +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-io-ts-utils/BUILD.bazel b/packages/kbn-securitysolution-io-ts-utils/BUILD.bazel index 346bd19451abd..24819bdd16a33 100644 --- a/packages/kbn-securitysolution-io-ts-utils/BUILD.bazel +++ b/packages/kbn-securitysolution-io-ts-utils/BUILD.bazel @@ -57,7 +57,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-securitysolution-list-api/.babelrc b/packages/kbn-securitysolution-list-api/.babelrc deleted file mode 100644 index 40a198521b903..0000000000000 --- a/packages/kbn-securitysolution-list-api/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-list-api/.babelrc.browser b/packages/kbn-securitysolution-list-api/.babelrc.browser deleted file mode 100644 index 71bbfbcd6eb2f..0000000000000 --- a/packages/kbn-securitysolution-list-api/.babelrc.browser +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-list-api/BUILD.bazel b/packages/kbn-securitysolution-list-api/BUILD.bazel index 6858a9389119f..52a134456cdd9 100644 --- a/packages/kbn-securitysolution-list-api/BUILD.bazel +++ b/packages/kbn-securitysolution-list-api/BUILD.bazel @@ -56,7 +56,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-securitysolution-list-constants/.babelrc b/packages/kbn-securitysolution-list-constants/.babelrc deleted file mode 100644 index 40a198521b903..0000000000000 --- a/packages/kbn-securitysolution-list-constants/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-list-constants/.babelrc.browser b/packages/kbn-securitysolution-list-constants/.babelrc.browser deleted file mode 100644 index 71bbfbcd6eb2f..0000000000000 --- a/packages/kbn-securitysolution-list-constants/.babelrc.browser +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-list-constants/BUILD.bazel b/packages/kbn-securitysolution-list-constants/BUILD.bazel index 9b3de9520f6a1..db4dd94091abf 100644 --- a/packages/kbn-securitysolution-list-constants/BUILD.bazel +++ b/packages/kbn-securitysolution-list-constants/BUILD.bazel @@ -45,7 +45,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-securitysolution-list-hooks/.babelrc b/packages/kbn-securitysolution-list-hooks/.babelrc deleted file mode 100644 index 40a198521b903..0000000000000 --- a/packages/kbn-securitysolution-list-hooks/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-list-hooks/.babelrc.browser b/packages/kbn-securitysolution-list-hooks/.babelrc.browser deleted file mode 100644 index 71bbfbcd6eb2f..0000000000000 --- a/packages/kbn-securitysolution-list-hooks/.babelrc.browser +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-list-hooks/BUILD.bazel b/packages/kbn-securitysolution-list-hooks/BUILD.bazel index ba8c579bb97de..2a9666bd1429e 100644 --- a/packages/kbn-securitysolution-list-hooks/BUILD.bazel +++ b/packages/kbn-securitysolution-list-hooks/BUILD.bazel @@ -62,7 +62,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-securitysolution-list-utils/.babelrc b/packages/kbn-securitysolution-list-utils/.babelrc deleted file mode 100644 index 40a198521b903..0000000000000 --- a/packages/kbn-securitysolution-list-utils/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-list-utils/.babelrc.browser b/packages/kbn-securitysolution-list-utils/.babelrc.browser deleted file mode 100644 index 71bbfbcd6eb2f..0000000000000 --- a/packages/kbn-securitysolution-list-utils/.babelrc.browser +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-list-utils/BUILD.bazel b/packages/kbn-securitysolution-list-utils/BUILD.bazel index 4701723286eff..eb33eb1a03b66 100644 --- a/packages/kbn-securitysolution-list-utils/BUILD.bazel +++ b/packages/kbn-securitysolution-list-utils/BUILD.bazel @@ -58,7 +58,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-securitysolution-t-grid/.babelrc b/packages/kbn-securitysolution-t-grid/.babelrc deleted file mode 100644 index 40a198521b903..0000000000000 --- a/packages/kbn-securitysolution-t-grid/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-t-grid/.babelrc.browser b/packages/kbn-securitysolution-t-grid/.babelrc.browser deleted file mode 100644 index 71bbfbcd6eb2f..0000000000000 --- a/packages/kbn-securitysolution-t-grid/.babelrc.browser +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-securitysolution-t-grid/BUILD.bazel b/packages/kbn-securitysolution-t-grid/BUILD.bazel index f9a6a5d7934ad..dd4e73af95720 100644 --- a/packages/kbn-securitysolution-t-grid/BUILD.bazel +++ b/packages/kbn-securitysolution-t-grid/BUILD.bazel @@ -54,7 +54,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-securitysolution-utils/.babelrc b/packages/kbn-securitysolution-utils/.babelrc deleted file mode 100644 index 40a198521b903..0000000000000 --- a/packages/kbn-securitysolution-utils/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.ts", "**/*.test.tsx"] -} diff --git a/packages/kbn-server-http-tools/.babelrc b/packages/kbn-server-http-tools/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-server-http-tools/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-server-route-repository/.babelrc b/packages/kbn-server-route-repository/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-server-route-repository/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-std/.babelrc b/packages/kbn-std/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-std/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-storybook/.babelrc b/packages/kbn-storybook/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-storybook/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-telemetry-tools/.babelrc b/packages/kbn-telemetry-tools/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-telemetry-tools/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-test/.babelrc b/packages/kbn-test/.babelrc deleted file mode 100644 index 1685d1644d94a..0000000000000 --- a/packages/kbn-test/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"], - "ignore": ["**/*.test.js"] -} diff --git a/packages/kbn-tinymath/babel.config.js b/packages/kbn-tinymath/babel.config.js deleted file mode 100644 index b4a118df51af5..0000000000000 --- a/packages/kbn-tinymath/babel.config.js +++ /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 - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - env: { - web: { - presets: ['@kbn/babel-preset/webpack_preset'], - }, - node: { - presets: ['@kbn/babel-preset/node_preset'], - }, - }, - ignore: ['**/*.test.ts', '**/*.test.tsx'], -}; diff --git a/packages/kbn-typed-react-router-config/.babelrc b/packages/kbn-typed-react-router-config/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-typed-react-router-config/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-typed-react-router-config/.babelrc.browser b/packages/kbn-typed-react-router-config/.babelrc.browser deleted file mode 100644 index dc6a77bbe0bcd..0000000000000 --- a/packages/kbn-typed-react-router-config/.babelrc.browser +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/webpack_preset"] -} diff --git a/packages/kbn-typed-react-router-config/BUILD.bazel b/packages/kbn-typed-react-router-config/BUILD.bazel index be346f8321fad..7fccc53bd7449 100644 --- a/packages/kbn-typed-react-router-config/BUILD.bazel +++ b/packages/kbn-typed-react-router-config/BUILD.bazel @@ -56,7 +56,7 @@ jsts_transpiler( name = "target_web", srcs = SRCS, build_pkg_name = package_name(), - config_file = ".babelrc.browser" + web = True, ) ts_config( diff --git a/packages/kbn-ui-shared-deps/.babelrc b/packages/kbn-ui-shared-deps/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-ui-shared-deps/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-utility-types/.babelrc b/packages/kbn-utility-types/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-utility-types/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/packages/kbn-utils/.babelrc b/packages/kbn-utils/.babelrc deleted file mode 100644 index 7da72d1779128..0000000000000 --- a/packages/kbn-utils/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@kbn/babel-preset/node_preset"] -} diff --git a/src/dev/bazel/jsts_transpiler.bzl b/src/dev/bazel/jsts_transpiler.bzl index 03033bbfa83f8..5116c73adb3c7 100644 --- a/src/dev/bazel/jsts_transpiler.bzl +++ b/src/dev/bazel/jsts_transpiler.bzl @@ -2,28 +2,42 @@ load("@npm//@babel/cli:index.bzl", _babel = "babel") -def jsts_transpiler(name, srcs, build_pkg_name, root_input_dir = "src", config_file = ".babelrc", additional_args = ["--quiet"], **kwargs): +def jsts_transpiler(name, srcs, build_pkg_name, web = False, root_input_dir = "src", additional_args = ["--quiet"], **kwargs): """A macro around the autogenerated babel rule. Args: name: target name srcs: list of sources + build_pkg_name: package name into the build folder + web: setup the correct presets to consume the outputs in the browser, defaults to "False" and optimizes for node root_input_dir: defines the root input dir to transpile files from, defaults to "src" - config_file: transpiler config file, it defaults to a package local .babelrc additional_args: Any additional extra arguments, defaults to --quiet **kwargs: the rest """ + + inline_presets = [ + "--presets", + ] + + if web: + inline_presets += [ + "@kbn/babel-preset/webpack_preset", + ] + else: + inline_presets += [ + "@kbn/babel-preset/node_preset", + ] + args = [ "./%s/%s" % (build_pkg_name, root_input_dir), - "--config-file", - "./%s/%s" % (build_pkg_name, config_file), "--out-dir", "$(@D)", + "--no-babelrc", "--extensions", ".ts,.tsx,.js", - ] + additional_args + ] + inline_presets + additional_args - data = [config_file] + srcs + [ + data = srcs + [ "//packages/kbn-babel-preset", ] From 9132b43128bbf8ad943577dd6043a320459d92f4 Mon Sep 17 00:00:00 2001 From: ymao1 Date: Fri, 3 Sep 2021 18:48:45 -0400 Subject: [PATCH 14/18] [Alerting][Docs] Add de-duplication example to ES query docs + update email docs wording (#111026) * Change to allowlist * Adding example to es query rule * Apply suggestions from code review Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com> Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com> --- .../connectors/action-types/email.asciidoc | 2 +- .../alerting/rule-types/es-query.asciidoc | 30 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/docs/management/connectors/action-types/email.asciidoc b/docs/management/connectors/action-types/email.asciidoc index 98d7b2591a572..131ff5ea5e9f6 100644 --- a/docs/management/connectors/action-types/email.asciidoc +++ b/docs/management/connectors/action-types/email.asciidoc @@ -107,7 +107,7 @@ For other email servers, you can check the list of well-known services that Node [[elasticcloud]] ==== Sending email from Elastic Cloud -IMPORTANT: These instructions require you to link:{cloud}/ec-watcher.html#ec-watcher-whitelist[whitelist] the email addresses that notifications get sent first. +IMPORTANT: These instructions require you to link:{cloud}/ec-watcher.html#ec-watcher-whitelist[allowlist] the email addresses that notifications get sent. Use the following connector settings to send email from Elastic Cloud: diff --git a/docs/user/alerting/rule-types/es-query.asciidoc b/docs/user/alerting/rule-types/es-query.asciidoc index 5615c79a6c9c7..65d39ba170c3c 100644 --- a/docs/user/alerting/rule-types/es-query.asciidoc +++ b/docs/user/alerting/rule-types/es-query.asciidoc @@ -60,4 +60,32 @@ image::user/alerting/images/rule-types-es-query-valid.png[Test {es} query return * An error message is shown if the query is invalid. + [role="screenshot"] -image::user/alerting/images/rule-types-es-query-invalid.png[Test {es} query shows error when invalid] \ No newline at end of file +image::user/alerting/images/rule-types-es-query-invalid.png[Test {es} query shows error when invalid] + +[float] +==== Match de-duplication + +The {es} query rule type performs de-duplication of document matches across rule executions. If you configure the rule with a schedule interval smaller than the time window, and a document matches a query in multiple rule executions, it will be alerted on only once. + +Suppose you have a rule configured to run every minute. The rule uses a time window of 1 hour and checks if there are more than 99 matches for the query. The {es} query rule type will do the following: + +[cols="3*<"] +|=== + +| `Execution 1 (0:00)` +| Rule finds 113 matches in the last hour: `113 > 99` +| Rule is active and user will be alerted. + +| `Execution 2 (0:01)` +| Rule finds 127 matches in the last hour. 105 of the matches are duplicates that were alerted on in Execution 1, so you actually have 22 matches: `22 !> 99` +| No alert. + +| `Execution 3 (0:02)` +| Rule finds 159 matches in the last hour. 88 of the matches are duplicates that were alerted on in Execution 1, so you actually have 71 matches: `71 !> 99` +| No alert. + +| `Execution 4 (0:03)` +| Rule finds 190 matches in the last hour. 71 of them are duplicates that were alerted on in Exeuction 1, so you actually have 119 matches: `119 > 99` +| Rule is active and user will be alerted. + +|=== \ No newline at end of file From 61e533f253bbd3c1f123ffd660e0fd31c760a8e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Sun, 5 Sep 2021 07:14:06 +0200 Subject: [PATCH 15/18] [APM] Clean up readme (#110973) * [APM] Clean up readme * Update linting.md * Update testing.md * Update testing.md * Update testing.md * Update plugin-list.asciidoc Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- docs/developer/plugin-list.asciidoc | 2 +- x-pack/plugins/apm/dev_docs/feature_flags.md | 14 +++ x-pack/plugins/apm/dev_docs/linting.md | 22 +++++ x-pack/plugins/apm/dev_docs/local_setup.md | 50 +++++++++++ x-pack/plugins/apm/dev_docs/testing.md | 66 ++++++++++++++ x-pack/plugins/apm/readme.md | 93 ++------------------ x-pack/plugins/apm/scripts/test/README.md | 64 +------------- 7 files changed, 162 insertions(+), 149 deletions(-) create mode 100644 x-pack/plugins/apm/dev_docs/feature_flags.md create mode 100644 x-pack/plugins/apm/dev_docs/linting.md create mode 100644 x-pack/plugins/apm/dev_docs/local_setup.md create mode 100644 x-pack/plugins/apm/dev_docs/testing.md diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index d2d543ff59d59..dfb62f23445ed 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -350,7 +350,7 @@ The plugin exposes the static DefaultEditorController class to consume. |{kib-repo}blob/{branch}/x-pack/plugins/apm/readme.md[apm] -|To access an elasticsearch instance that has live data you have two options: +|Local setup documentation |{kib-repo}blob/{branch}/x-pack/plugins/banners/README.md[banners] diff --git a/x-pack/plugins/apm/dev_docs/feature_flags.md b/x-pack/plugins/apm/dev_docs/feature_flags.md new file mode 100644 index 0000000000000..9f722dd5eac5a --- /dev/null +++ b/x-pack/plugins/apm/dev_docs/feature_flags.md @@ -0,0 +1,14 @@ +## Feature flags + +To set up a flagged feature, add the name of the feature key (`apm:myFeature`) to [commmon/ui_settings_keys.ts](./common/ui_settings_keys.ts) and the feature parameters to [server/ui_settings.ts](./server/ui_settings.ts). + +Test for the feature like: + +```js +import { myFeatureEnabled } from '../ui_settings_keys'; +if (core.uiSettings.get(myFeatureEnabled)) { + doStuff(); +} +``` + +Settings can be managed in Kibana under Stack Management > Advanced Settings > Observability. \ No newline at end of file diff --git a/x-pack/plugins/apm/dev_docs/linting.md b/x-pack/plugins/apm/dev_docs/linting.md new file mode 100644 index 0000000000000..a4fd3094f121c --- /dev/null +++ b/x-pack/plugins/apm/dev_docs/linting.md @@ -0,0 +1,22 @@ +## Linting + +_Note: Run the following commands from the root of Kibana._ + +### Typescript + +``` +node scripts/type_check.js --project x-pack/plugins/apm/tsconfig.json +``` + +### Prettier + +``` +yarn prettier "./x-pack/plugins/apm/**/*.{tsx,ts,js}" --write +``` + +### ESLint + +``` +node scripts/eslint.js x-pack/legacy/plugins/apm +``` +diff --git a/x-pack/plugins/apm/dev_docs/feature_flags.md b/x-pack/plugins/apm/dev_docs/feature_flags.md diff --git a/x-pack/plugins/apm/dev_docs/local_setup.md b/x-pack/plugins/apm/dev_docs/local_setup.md new file mode 100644 index 0000000000000..d977f44445148 --- /dev/null +++ b/x-pack/plugins/apm/dev_docs/local_setup.md @@ -0,0 +1,50 @@ +## Local environment setup + +### Kibana + +``` +git clone git@github.com:elastic/kibana.git +cd kibana/ +yarn kbn bootstrap +yarn start --no-base-path +``` + +### APM Server, Elasticsearch and data + +To access an elasticsearch instance that has live data you have two options: + +#### A. Connect to Elasticsearch on Cloud (internal devs only) + +Find the credentials for the cluster [here](https://github.com/elastic/apm-dev/blob/master/docs/credentials/apm-ui-clusters.md#apmelstcco) + +#### B. Start Elastic Stack and APM data generators + +``` +git clone git@github.com:elastic/apm-integration-testing.git +cd apm-integration-testing/ +./scripts/compose.py start master --all --no-kibana +``` + +_Docker Compose is required_ + +### Setup default APM users + +APM behaves differently depending on which the role and permissions a logged in user has. To create the users run: + +```sh +node x-pack/plugins/apm/scripts/create-apm-users-and-roles.js --username admin --password changeme --kibana-url http://localhost:5601 --role-suffix +``` + +This will create: + +**apm_read_user**: Read only user + +**apm_power_user**: Read+write user. + +## Debugging Elasticsearch queries + +All APM api endpoints accept `_inspect=true` as a query param that will result in the underlying ES query being outputted in the Kibana backend process. + +Example: +`/api/apm/services/my_service?_inspect=true` +diff --git a/x-pack/plugins/apm/dev_docs/linting.md b/x-pack/plugins/apm/dev_docs/linting.md diff --git a/x-pack/plugins/apm/dev_docs/testing.md b/x-pack/plugins/apm/dev_docs/testing.md new file mode 100644 index 0000000000000..93f32111048c1 --- /dev/null +++ b/x-pack/plugins/apm/dev_docs/testing.md @@ -0,0 +1,66 @@ +# Testing + +## Unit Tests (Jest) + +``` +node scripts/test/jest [--watch] [--updateSnapshot] +``` + +#### Coverage + +HTML coverage report can be found in target/coverage/jest after tests have run. + +``` +open target/coverage/jest/index.html +``` + +--- + +## API Tests + +API tests are separated in two suites: + +- a basic license test suite [default] +- a trial license test suite (the equivalent of gold+) + +``` +node scripts/test/api [--trial] [--help] +``` + +The API tests are located in `x-pack/test/apm_api_integration/`. + +**API Test tips** + +- For debugging access Elasticsearch on http://localhost:9220 (`elastic` / `changeme`) +- To update snapshots append `--updateSnapshots` to the functional_test_runner command + +--- + +## E2E Tests (Cypress) + +``` +node scripts/test/e2e [--trial] [--help] +``` + +The E2E tests are located [here](../../ftr_e2e) + +--- + +## Functional tests (Security and Correlations tests) +TODO: We could try moving this tests to the new e2e tests located at `x-pack/plugins/apm/ftr_e2e`. + +**Start server** + +``` +node scripts/functional_tests_server --config x-pack/test/functional/config.js +``` + +**Run tests** + +``` +node scripts/functional_test_runner --config x-pack/test/functional/config.js --grep='APM specs' +``` + +APM tests are located in `x-pack/test/functional/apps/apm`. +For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme) +diff --git a/x-pack/plugins/apm/scripts/test/README.md b/x-pack/plugins/apm/scripts/test/README.md diff --git a/x-pack/plugins/apm/readme.md b/x-pack/plugins/apm/readme.md index a331bb4e9f116..fe7e77d28986c 100644 --- a/x-pack/plugins/apm/readme.md +++ b/x-pack/plugins/apm/readme.md @@ -2,105 +2,28 @@ ## Local environment setup -### Kibana - -``` -git clone git@github.com:elastic/kibana.git -cd kibana/ -yarn kbn bootstrap -yarn start --no-base-path -``` - -### APM Server, Elasticsearch and data - -To access an elasticsearch instance that has live data you have two options: - -#### A. Connect to Elasticsearch on Cloud (internal devs only) - -Find the credentials for the cluster [here](https://github.com/elastic/apm-dev/blob/master/docs/credentials/apm-ui-clusters.md#apmelstcco) - -#### B. Start Elastic Stack and APM data generators - -``` -git clone git@github.com:elastic/apm-integration-testing.git -cd apm-integration-testing/ -./scripts/compose.py start master --all --no-kibana -``` - -_Docker Compose is required_ +[Local setup documentation](./dev_docs/local_setup.md) ## Testing -Go to [tests documentation](./scripts/test/README.md) +[Testing documentation](./dev_docs/testing.md) ## Linting -_Note: Run the following commands from `kibana/`._ - -### Typescript - -``` -node scripts/type_check.js --project x-pack/plugins/apm/tsconfig.json -``` - -### Prettier - -``` -yarn prettier "./x-pack/plugins/apm/**/*.{tsx,ts,js}" --write -``` - -### ESLint - -``` -node scripts/eslint.js x-pack/legacy/plugins/apm -``` - -## Setup default APM users - -APM behaves differently depending on which the role and permissions a logged in user has. To create the users run: - -```sh -node x-pack/plugins/apm/scripts/create-apm-users-and-roles.js --username admin --password changeme --kibana-url http://localhost:5601 --role-suffix -``` - -This will create: - -**apm_read_user**: Read only user - -**apm_power_user**: Read+write user. - -## Debugging Elasticsearch queries - -All APM api endpoints accept `_inspect=true` as a query param that will result in the underlying ES query being outputted in the Kibana backend process. - -Example: -`/api/apm/services/my_service?_inspect=true` +[Linting documentation](./dev_docs/linting.md) ## Storybook -Start the [Storybook](https://storybook.js.org/) development environment with -`yarn storybook apm`. All files with a .stories.tsx extension will be loaded. -You can access the development environment at http://localhost:9001. - -## Experimental features settings - -To set up a flagged feature, add the name of the feature key (`apm:myFeature`) to [commmon/ui_settings_keys.ts](./common/ui_settings_keys.ts) and the feature parameters to [server/ui_settings.ts](./server/ui_settings.ts). - -Test for the feature like: - -```js -import { myFeatureEnabled } from '../ui_settings_keys'; -if (core.uiSettings.get(myFeatureEnabled)) { - doStuff(); -} +**Start** +``` +yarn storybook apm ``` -Settings can be managed in Kibana under Stack Management > Advanced Settings > Observability. +All files with a .stories.tsx extension will be loaded. You can access the development environment at http://localhost:9001. ## Further resources - -- [Cypress integration tests](./e2e/README.md) - [VSCode setup instructions](./dev_docs/vscode_setup.md) - [Github PR commands](./dev_docs/github_commands.md) - [Routing and Linking](./dev_docs/routing_and_linking.md) - [Telemetry](./dev_docs/telemetry.md) +- [Features flags](./dev_docs/feature_flags.md) diff --git a/x-pack/plugins/apm/scripts/test/README.md b/x-pack/plugins/apm/scripts/test/README.md index b241b2efdfd99..2b5e4212ea08f 100644 --- a/x-pack/plugins/apm/scripts/test/README.md +++ b/x-pack/plugins/apm/scripts/test/README.md @@ -1,63 +1 @@ -## Unit Tests (Jest) - -``` -node scripts/tests/jest [--watch] [--updateSnapshot] -``` - -#### Coverage - -HTML coverage report can be found in target/coverage/jest after tests have run. - -``` -open target/coverage/jest/index.html -``` - ---- - -## API Tests - -API tests are separated in two suites: - -- a basic license test suite [default] -- a trial license test suite (the equivalent of gold+) - -``` -node scripts/tests/api [--trial] [--help] -``` - -The API tests are located in `x-pack/test/apm_api_integration/`. - -**API Test tips** - -- For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme) -- To update snapshots append `--updateSnapshots` to the functional_test_runner command - ---- - -## E2E Tests (Cypress) - -``` -node scripts/tests/e2e [--trial] [--help] -``` - -The E2E tests are located [here](../../ftr_e2e) - ---- - -## Functional tests (Security and Correlations tests) -TODO: We could try moving this tests to the new e2e tests located at `x-pack/plugins/apm/ftr_e2e`. - -**Start server** - -``` -node scripts/functional_tests_server --config x-pack/test/functional/config.js -``` - -**Run tests** - -``` -node scripts/functional_test_runner --config x-pack/test/functional/config.js --grep='APM specs' -``` - -APM tests are located in `x-pack/test/functional/apps/apm`. -For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme) +Go to [testing documentation](../../dev_docs/testing.md) \ No newline at end of file From f955947d4e66ad0be65649c31ae852c80bbefafd Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 6 Sep 2021 01:10:52 +0100 Subject: [PATCH 16/18] skip flaky suite (#110970) --- .../saved_objects/migrationsv2/test_helpers/retry.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/server/saved_objects/migrationsv2/test_helpers/retry.test.ts b/src/core/server/saved_objects/migrationsv2/test_helpers/retry.test.ts index 246f61c71ae4d..ff5bf3d01c641 100644 --- a/src/core/server/saved_objects/migrationsv2/test_helpers/retry.test.ts +++ b/src/core/server/saved_objects/migrationsv2/test_helpers/retry.test.ts @@ -8,7 +8,8 @@ import { retryAsync } from './retry_async'; -describe('retry', () => { +// FLAKY: https://github.com/elastic/kibana/issues/110970 +describe.skip('retry', () => { it('retries throwing functions until they succeed', async () => { let i = 0; await expect( From 907a34076f83a0995dcec8bbaf4854c0085c0184 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 6 Sep 2021 01:17:07 +0100 Subject: [PATCH 17/18] skip failing es promotion suites (#111240) --- .../apis/uptime/rest/telemetry_collectors_fleet.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors_fleet.ts b/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors_fleet.ts index 768b65453fabc..49fcdb8eba4f1 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors_fleet.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors_fleet.ts @@ -14,7 +14,8 @@ export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const client = getService('es'); - describe('telemetry collectors fleet', () => { + // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/111240 + describe.skip('telemetry collectors fleet', () => { before('generating data', async () => { await getService('esArchiver').load( 'x-pack/test/functional/es_archives/uptime/blank_data_stream' From 4416a31aa7bc6e619ee732b72534aac153688f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?= Date: Mon, 6 Sep 2021 09:10:04 +0200 Subject: [PATCH 18/18] [Osquery] Fix support for disabled security (#110547) --- package.json | 2 +- .../action_results/use_action_privileges.tsx | 12 --- .../osquery/public/common/page_paths.ts | 2 - .../plugins/osquery/public/components/app.tsx | 9 ++ .../osquery/public/components/empty_state.tsx | 86 +++++++++++++++++++ .../components/manage_integration_link.tsx | 16 ++-- .../public/live_queries/form/index.tsx | 16 ++-- .../public/packs/common/add_pack_query.tsx | 4 +- .../osquery/public/packs/common/pack_form.tsx | 4 +- .../public/routes/saved_queries/edit/form.tsx | 5 +- .../public/routes/saved_queries/new/form.tsx | 5 +- .../scheduled_query_groups/edit/index.tsx | 5 +- .../osquery/public/saved_queries/constants.ts | 1 + .../saved_queries/saved_query_flyout.tsx | 3 +- .../public/saved_queries/use_saved_query.ts | 3 +- .../saved_queries/use_update_saved_query.ts | 3 +- .../scheduled_query_groups/form/index.tsx | 6 +- .../queries/ecs_mapping_editor_field.tsx | 3 +- .../queries/query_flyout.tsx | 7 +- ...duled_query_group_queries_status_table.tsx | 70 ++++++++++++--- .../use_scheduled_query_group_query_errors.ts | 9 +- ...cheduled_query_group_query_last_results.ts | 84 +++++++++++------- .../privileges_check_route.ts | 32 +++---- yarn.lock | 8 +- 24 files changed, 280 insertions(+), 115 deletions(-) create mode 100644 x-pack/plugins/osquery/public/components/empty_state.tsx diff --git a/package.json b/package.json index e603190c72698..5aabfc66e4637 100644 --- a/package.json +++ b/package.json @@ -348,7 +348,7 @@ "react-moment-proptypes": "^1.7.0", "react-monaco-editor": "^0.41.2", "react-popper-tooltip": "^2.10.1", - "react-query": "^3.21.0", + "react-query": "^3.21.1", "react-redux": "^7.2.0", "react-resizable": "^1.7.5", "react-resize-detector": "^4.2.0", diff --git a/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx b/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx index 2c80c874e89fa..6d0477b22edee 100644 --- a/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx +++ b/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx @@ -6,28 +6,16 @@ */ import { useQuery } from 'react-query'; - -import { i18n } from '@kbn/i18n'; import { useKibana } from '../common/lib/kibana'; -import { useErrorToast } from '../common/hooks/use_error_toast'; export const useActionResultsPrivileges = () => { const { http } = useKibana().services; - const setErrorToast = useErrorToast(); return useQuery( ['actionResultsPrivileges'], () => http.get('/internal/osquery/privileges_check'), { keepPreviousData: true, - select: (response) => response?.has_all_requested ?? false, - onSuccess: () => setErrorToast(), - onError: (error: Error) => - setErrorToast(error, { - title: i18n.translate('xpack.osquery.action_results_privileges.fetchError', { - defaultMessage: 'Error while fetching action results privileges', - }), - }), } ); }; diff --git a/x-pack/plugins/osquery/public/common/page_paths.ts b/x-pack/plugins/osquery/public/common/page_paths.ts index 0e0d8310ae8be..8df1006da181a 100644 --- a/x-pack/plugins/osquery/public/common/page_paths.ts +++ b/x-pack/plugins/osquery/public/common/page_paths.ts @@ -27,8 +27,6 @@ export interface DynamicPagePathValues { [key: string]: string; } -export const BASE_PATH = '/app/fleet'; - // If routing paths are changed here, please also check to see if // `pagePathGetters()`, below, needs any modifications export const PAGE_ROUTING_PATHS = { diff --git a/x-pack/plugins/osquery/public/components/app.tsx b/x-pack/plugins/osquery/public/components/app.tsx index 44407139ab492..33fb6ac6a2adf 100644 --- a/x-pack/plugins/osquery/public/components/app.tsx +++ b/x-pack/plugins/osquery/public/components/app.tsx @@ -5,6 +5,8 @@ * 2.0. */ +/* eslint-disable react-hooks/rules-of-hooks */ + import React, { useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiTabs, EuiTab } from '@elastic/eui'; @@ -14,10 +16,17 @@ import { Container, Nav, Wrapper } from './layouts'; import { OsqueryAppRoutes } from '../routes'; import { useRouterNavigate } from '../common/lib/kibana'; import { ManageIntegrationLink } from './manage_integration_link'; +import { useOsqueryIntegrationStatus } from '../common/hooks'; +import { OsqueryAppEmptyState } from './empty_state'; const OsqueryAppComponent = () => { const location = useLocation(); const section = useMemo(() => location.pathname.split('/')[1] ?? 'overview', [location.pathname]); + const { data: osqueryIntegration, isFetched } = useOsqueryIntegrationStatus(); + + if (isFetched && osqueryIntegration.install_status !== 'installed') { + return ; + } return ( diff --git a/x-pack/plugins/osquery/public/components/empty_state.tsx b/x-pack/plugins/osquery/public/components/empty_state.tsx new file mode 100644 index 0000000000000..1ee0d496c0ddc --- /dev/null +++ b/x-pack/plugins/osquery/public/components/empty_state.tsx @@ -0,0 +1,86 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiButton } from '@elastic/eui'; + +import { KibanaPageTemplate } from '../../../../../src/plugins/kibana_react/public'; +import { INTEGRATIONS_PLUGIN_ID } from '../../../fleet/common'; +import { pagePathGetters } from '../../../fleet/public'; +import { isModifiedEvent, isLeftClickEvent, useKibana } from '../common/lib/kibana'; +import { OsqueryIcon } from './osquery_icon'; +import { useBreadcrumbs } from '../common/hooks/use_breadcrumbs'; +import { OSQUERY_INTEGRATION_NAME } from '../../common'; + +const OsqueryAppEmptyStateComponent = () => { + useBreadcrumbs('base'); + + const { + application: { getUrlForApp, navigateToApp }, + } = useKibana().services; + + const integrationHref = useMemo(() => { + return getUrlForApp(INTEGRATIONS_PLUGIN_ID, { + path: pagePathGetters.integration_details_overview({ + pkgkey: OSQUERY_INTEGRATION_NAME, + })[1], + }); + }, [getUrlForApp]); + + const integrationClick = useCallback( + (event) => { + if (!isModifiedEvent(event) && isLeftClickEvent(event)) { + event.preventDefault(); + return navigateToApp(INTEGRATIONS_PLUGIN_ID, { + path: pagePathGetters.integration_details_overview({ + pkgkey: OSQUERY_INTEGRATION_NAME, + })[1], + }); + } + }, + [navigateToApp] + ); + + const pageHeader = useMemo( + () => ({ + iconType: OsqueryIcon, + pageTitle: ( + + ), + description: ( + + ), + rightSideItems: [ + // eslint-disable-next-line @elastic/eui/href-or-on-click + + + , + ], + }), + [integrationClick, integrationHref] + ); + + return ; +}; + +export const OsqueryAppEmptyState = React.memo(OsqueryAppEmptyStateComponent); diff --git a/x-pack/plugins/osquery/public/components/manage_integration_link.tsx b/x-pack/plugins/osquery/public/components/manage_integration_link.tsx index 44b923860e1a8..32779ded46c50 100644 --- a/x-pack/plugins/osquery/public/components/manage_integration_link.tsx +++ b/x-pack/plugins/osquery/public/components/manage_integration_link.tsx @@ -24,11 +24,9 @@ const ManageIntegrationLinkComponent = () => { const integrationHref = useMemo(() => { if (osqueryIntegration) { return getUrlForApp(INTEGRATIONS_PLUGIN_ID, { - path: - '#' + - pagePathGetters.integration_details_policies({ - pkgkey: `${osqueryIntegration.name}-${osqueryIntegration.version}`, - })[1], + path: pagePathGetters.integration_details_policies({ + pkgkey: `${osqueryIntegration.name}-${osqueryIntegration.version}`, + })[1], }); } }, [getUrlForApp, osqueryIntegration]); @@ -39,11 +37,9 @@ const ManageIntegrationLinkComponent = () => { event.preventDefault(); if (osqueryIntegration) { return navigateToApp(INTEGRATIONS_PLUGIN_ID, { - path: - '#' + - pagePathGetters.integration_details_policies({ - pkgkey: `${osqueryIntegration.name}-${osqueryIntegration.version}`, - })[1], + path: pagePathGetters.integration_details_policies({ + pkgkey: `${osqueryIntegration.name}-${osqueryIntegration.version}`, + })[1], }); } } diff --git a/x-pack/plugins/osquery/public/live_queries/form/index.tsx b/x-pack/plugins/osquery/public/live_queries/form/index.tsx index 987be904c87e6..69b02dee8b9f7 100644 --- a/x-pack/plugins/osquery/public/live_queries/form/index.tsx +++ b/x-pack/plugins/osquery/public/live_queries/form/index.tsx @@ -114,7 +114,7 @@ const LiveQueryFormComponent: React.FC = ({ ), }); - const { setFieldValue, submit } = form; + const { setFieldValue, submit, isSubmitting } = form; const actionId = useMemo(() => data?.actions[0].action_id, [data?.actions]); const agentIds = useMemo(() => data?.actions[0].agents, [data?.actions]); @@ -185,7 +185,10 @@ const LiveQueryFormComponent: React.FC = ({ )} - + = ({ ), [ - agentSelected, - permissions.writeSavedQueries, - handleShowSaveQueryFlout, queryComponentProps, + singleAgentMode, + permissions.writeSavedQueries, + agentSelected, queryValueProvided, resultsStatus, - singleAgentMode, + handleShowSaveQueryFlout, + isSubmitting, submit, ] ); diff --git a/x-pack/plugins/osquery/public/packs/common/add_pack_query.tsx b/x-pack/plugins/osquery/public/packs/common/add_pack_query.tsx index 2d58e2dfe9522..d1115898b4e40 100644 --- a/x-pack/plugins/osquery/public/packs/common/add_pack_query.tsx +++ b/x-pack/plugins/osquery/public/packs/common/add_pack_query.tsx @@ -51,7 +51,7 @@ const AddPackQueryFormComponent = ({ handleSubmit }) => { }, }, }); - const { submit } = form; + const { submit, isSubmitting } = form; const createSavedQueryMutation = useMutation( (payload) => http.post(`/internal/osquery/saved_query`, { body: JSON.stringify(payload) }), @@ -108,7 +108,7 @@ const AddPackQueryFormComponent = ({ handleSubmit }) => { - + {'Add query'} diff --git a/x-pack/plugins/osquery/public/packs/common/pack_form.tsx b/x-pack/plugins/osquery/public/packs/common/pack_form.tsx index 86d4d8dff6ba6..ab0984e808943 100644 --- a/x-pack/plugins/osquery/public/packs/common/pack_form.tsx +++ b/x-pack/plugins/osquery/public/packs/common/pack_form.tsx @@ -40,7 +40,7 @@ const PackFormComponent = ({ data, handleSubmit }) => { }, }, }); - const { submit } = form; + const { submit, isSubmitting } = form; return (
@@ -50,7 +50,7 @@ const PackFormComponent = ({ data, handleSubmit }) => { - + {'Save pack'} diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx index a7596575b90c4..617d83821d08d 100644 --- a/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx +++ b/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx @@ -38,6 +38,7 @@ const EditSavedQueryFormComponent: React.FC = ({ defaultValue, handleSubmit, }); + const { submit, isSubmitting } = form; return (
@@ -58,12 +59,12 @@ const EditSavedQueryFormComponent: React.FC = ({ = ({ defaultValue, handleSubmit, }); + const { submit, isSubmitting } = form; return ( @@ -54,12 +55,12 @@ const NewSavedQueryFormComponent: React.FC = ({ { const { data } = useScheduledQueryGroup({ scheduledQueryGroupId }); - useBreadcrumbs('scheduled_query_group_edit', { scheduledQueryGroupName: data?.name ?? '' }); + useBreadcrumbs('scheduled_query_group_edit', { + scheduledQueryGroupId: data?.id ?? '', + scheduledQueryGroupName: data?.name ?? '', + }); const LeftColumn = useMemo( () => ( diff --git a/x-pack/plugins/osquery/public/saved_queries/constants.ts b/x-pack/plugins/osquery/public/saved_queries/constants.ts index 69ca805e3e8fa..8edcfd00d1788 100644 --- a/x-pack/plugins/osquery/public/saved_queries/constants.ts +++ b/x-pack/plugins/osquery/public/saved_queries/constants.ts @@ -6,3 +6,4 @@ */ export const SAVED_QUERIES_ID = 'savedQueryList'; +export const SAVED_QUERY_ID = 'savedQuery'; diff --git a/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx b/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx index 6d14943a6bc84..8c35a359a9baf 100644 --- a/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx @@ -42,6 +42,7 @@ const SavedQueryFlyoutComponent: React.FC = ({ defaultValue defaultValue, handleSubmit, }); + const { submit, isSubmitting } = form; return ( @@ -72,7 +73,7 @@ const SavedQueryFlyoutComponent: React.FC = ({ defaultValue - + { queryClient.invalidateQueries(SAVED_QUERIES_ID); + queryClient.invalidateQueries([SAVED_QUERY_ID, { savedQueryId }]); navigateToApp(PLUGIN_ID, { path: pagePathGetters.saved_queries() }); toasts.addSuccess( i18n.translate('xpack.osquery.editSavedQuery.successToastMessageText', { diff --git a/x-pack/plugins/osquery/public/scheduled_query_groups/form/index.tsx b/x-pack/plugins/osquery/public/scheduled_query_groups/form/index.tsx index 685960ecd202e..3598a9fd2e44c 100644 --- a/x-pack/plugins/osquery/public/scheduled_query_groups/form/index.tsx +++ b/x-pack/plugins/osquery/public/scheduled_query_groups/form/index.tsx @@ -88,7 +88,7 @@ const ScheduledQueryGroupFormComponent: React.FC = `scheduled_query_groups/${editMode ? defaultValue?.id : ''}` ); - const { isLoading, mutateAsync } = useMutation( + const { mutateAsync } = useMutation( (payload: Record) => editMode && defaultValue?.id ? http.put(packagePolicyRouteService.getUpdatePath(defaultValue.id), { @@ -248,7 +248,7 @@ const ScheduledQueryGroupFormComponent: React.FC = ), }); - const { setFieldValue, submit } = form; + const { setFieldValue, submit, isSubmitting } = form; const policyIdEuiFieldProps = useMemo( () => ({ isDisabled: !!defaultValue, options: agentPolicyOptions }), @@ -368,7 +368,7 @@ const ScheduledQueryGroupFormComponent: React.FC = ( ) )(args); - if (fieldRequiredError && (!!(!editForm && args.formData.value?.field.length) || editForm)) { + // @ts-expect-error update types + if (fieldRequiredError && ((!editForm && args.formData['value.field'].length) || editForm)) { return fieldRequiredError; } diff --git a/x-pack/plugins/osquery/public/scheduled_query_groups/queries/query_flyout.tsx b/x-pack/plugins/osquery/public/scheduled_query_groups/queries/query_flyout.tsx index cae9711694f29..d38c1b2118f24 100644 --- a/x-pack/plugins/osquery/public/scheduled_query_groups/queries/query_flyout.tsx +++ b/x-pack/plugins/osquery/public/scheduled_query_groups/queries/query_flyout.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import { isEmpty } from 'lodash'; import { EuiCallOut, EuiFlyout, @@ -66,7 +67,7 @@ const QueryFlyoutComponent: React.FC = ({ if (isValid && ecsFieldValue) { onSave({ ...payload, - ecs_mapping: ecsFieldValue, + ...(isEmpty(ecsFieldValue) ? {} : { ecs_mapping: ecsFieldValue }), }); onClose(); } @@ -81,7 +82,7 @@ const QueryFlyoutComponent: React.FC = ({ [integrationPackageVersion] ); - const { submit, setFieldValue, reset } = form; + const { submit, setFieldValue, reset, isSubmitting } = form; const [{ query }] = useFormData({ form, @@ -245,7 +246,7 @@ const QueryFlyoutComponent: React.FC = ({ - + = ({ toggleErrors, expanded, }) => { + const data = useKibana().services.data; + const [logsIndexPattern, setLogsIndexPattern] = useState(undefined); + const { data: lastResultsData, isFetched } = useScheduledQueryGroupQueryLastResults({ actionId, agentIds, interval, + logsIndexPattern, }); const { data: errorsData, isFetched: errorsFetched } = useScheduledQueryGroupQueryErrors({ actionId, agentIds, interval, + logsIndexPattern, }); const handleErrorsToggle = useCallback(() => toggleErrors({ queryId, interval }), [ @@ -409,20 +414,41 @@ const ScheduledQueryLastResults: React.FC = ({ toggleErrors, ]); + useEffect(() => { + const fetchLogsIndexPattern = async () => { + const indexPattern = await data.indexPatterns.find('logs-*'); + + setLogsIndexPattern(indexPattern[0]); + }; + fetchLogsIndexPattern(); + }, [data.indexPatterns]); + if (!isFetched || !errorsFetched) { return ; } - if (!lastResultsData) { + if (!lastResultsData && !errorsData?.total) { return <>{'-'}; } return ( - {lastResultsData.first_event_ingested_time?.value ? ( - - <>{moment(lastResultsData.first_event_ingested_time?.value).fromNow()} + {lastResultsData?.['@timestamp'] ? ( + + {' '} + + + } + > + ) : ( '-' @@ -432,10 +458,17 @@ const ScheduledQueryLastResults: React.FC = ({ - {lastResultsData?.doc_count ?? 0} + {lastResultsData?.docCount ?? 0} - {'Documents'} + + + @@ -443,10 +476,17 @@ const ScheduledQueryLastResults: React.FC = ({ - {lastResultsData?.unique_agents?.value ?? 0} + {lastResultsData?.uniqueAgentsCount ?? 0} - {'Agents'} + + + @@ -458,7 +498,15 @@ const ScheduledQueryLastResults: React.FC = ({ - {'Errors'} + + {' '} + + { const data = useKibana().services.data; @@ -28,9 +30,8 @@ export const useScheduledQueryGroupQueryErrors = ({ return useQuery( ['scheduledQueryErrors', { actionId, interval }], async () => { - const indexPattern = await data.indexPatterns.find('logs-*'); const searchSource = await data.search.searchSource.create({ - index: indexPattern[0], + index: logsIndexPattern, fields: ['*'], sort: [ { @@ -80,7 +81,7 @@ export const useScheduledQueryGroupQueryErrors = ({ }, { keepPreviousData: true, - enabled: !!(!skip && actionId && interval && agentIds?.length), + enabled: !!(!skip && actionId && interval && agentIds?.length && logsIndexPattern), select: (response) => response.rawResponse.hits ?? [], refetchOnReconnect: false, refetchOnWindowFocus: false, diff --git a/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts b/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts index f972640e25986..7cfd6be461e05 100644 --- a/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts +++ b/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts @@ -6,13 +6,14 @@ */ import { useQuery } from 'react-query'; - +import { IndexPattern } from '../../../../../src/plugins/data/common'; import { useKibana } from '../common/lib/kibana'; interface UseScheduledQueryGroupQueryLastResultsProps { actionId: string; agentIds?: string[]; interval: number; + logsIndexPattern?: IndexPattern; skip?: boolean; } @@ -20,6 +21,7 @@ export const useScheduledQueryGroupQueryLastResults = ({ actionId, agentIds, interval, + logsIndexPattern, skip = false, }: UseScheduledQueryGroupQueryLastResultsProps) => { const data = useKibana().services.data; @@ -27,23 +29,9 @@ export const useScheduledQueryGroupQueryLastResults = ({ return useQuery( ['scheduledQueryLastResults', { actionId }], async () => { - const indexPattern = await data.indexPatterns.find('logs-*'); - const searchSource = await data.search.searchSource.create({ - index: indexPattern[0], - size: 0, - aggs: { - runs: { - terms: { - field: 'response_id', - order: { first_event_ingested_time: 'desc' }, - size: 1, - }, - aggs: { - first_event_ingested_time: { min: { field: '@timestamp' } }, - unique_agents: { cardinality: { field: 'agent.id' } }, - }, - }, - }, + const lastResultsSearchSource = await data.search.searchSource.create({ + index: logsIndexPattern, + size: 1, query: { // @ts-expect-error update types bool: { @@ -59,26 +47,62 @@ export const useScheduledQueryGroupQueryLastResults = ({ action_id: actionId, }, }, - { - range: { - '@timestamp': { - gte: `now-${interval * 2}s`, - lte: 'now', - }, - }, - }, ], }, }, }); - return searchSource.fetch$().toPromise(); + const lastResultsResponse = await lastResultsSearchSource.fetch$().toPromise(); + + const responseId = lastResultsResponse.rawResponse?.hits?.hits[0]?._source?.response_id; + + if (responseId) { + const aggsSearchSource = await data.search.searchSource.create({ + index: logsIndexPattern, + size: 0, + aggs: { + unique_agents: { cardinality: { field: 'agent.id' } }, + }, + query: { + // @ts-expect-error update types + bool: { + should: agentIds?.map((agentId) => ({ + match_phrase: { + 'agent.id': agentId, + }, + })), + minimum_should_match: 1, + filter: [ + { + match_phrase: { + action_id: actionId, + }, + }, + { + match_phrase: { + response_id: responseId, + }, + }, + ], + }, + }, + }); + + const aggsResponse = await aggsSearchSource.fetch$().toPromise(); + + return { + '@timestamp': lastResultsResponse.rawResponse?.hits?.hits[0]?.fields?.['@timestamp'], + // @ts-expect-error update types + uniqueAgentsCount: aggsResponse.rawResponse.aggregations?.unique_agents?.value, + docCount: aggsResponse.rawResponse?.hits?.total, + }; + } + + return null; }, { keepPreviousData: true, - enabled: !!(!skip && actionId && interval && agentIds?.length), - // @ts-expect-error update types - select: (response) => response.rawResponse.aggregations?.runs?.buckets[0] ?? [], + enabled: !!(!skip && actionId && interval && agentIds?.length && logsIndexPattern), refetchOnReconnect: false, refetchOnWindowFocus: false, } diff --git a/x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts b/x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts index 80c335c1c46d3..d9683d23deb13 100644 --- a/x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts +++ b/x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts @@ -9,7 +9,6 @@ import { OSQUERY_INTEGRATION_NAME, PLUGIN_ID } from '../../../common'; import { IRouter } from '../../../../../../src/core/server'; import { OsqueryAppContext } from '../../lib/osquery_app_context_services'; -// eslint-disable-next-line @typescript-eslint/no-unused-vars export const privilegesCheckRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { router.get( { @@ -20,23 +19,26 @@ export const privilegesCheckRoute = (router: IRouter, osqueryContext: OsqueryApp }, }, async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asCurrentUser; - - const privileges = ( - await esClient.security.hasPrivileges({ - body: { - index: [ - { - names: [`logs-${OSQUERY_INTEGRATION_NAME}.result*`], - privileges: ['read'], - }, - ], + if (osqueryContext.security.authz.mode.useRbacForRequest(request)) { + const checkPrivileges = osqueryContext.security.authz.checkPrivilegesDynamicallyWithRequest( + request + ); + const { hasAllRequested } = await checkPrivileges({ + elasticsearch: { + cluster: [], + index: { + [`logs-${OSQUERY_INTEGRATION_NAME}.result*`]: ['read'], + }, }, - }) - ).body; + }); + + return response.ok({ + body: `${hasAllRequested}`, + }); + } return response.ok({ - body: privileges, + body: 'true', }); } ); diff --git a/yarn.lock b/yarn.lock index 4d49a2f06e1e9..f0a1ff1278f4e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23379,10 +23379,10 @@ react-popper@^2.2.4: react-fast-compare "^3.0.1" warning "^4.0.2" -react-query@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.21.0.tgz#2e099a7906c38eeeb750e8b9b12121a21fa8d9ef" - integrity sha512-5rY5J8OD9f4EdkytjSsdCO+pqbJWKwSIMETfh/UyxqyjLURHE0IhlB+IPNPrzzu/dzK0rRxi5p0IkcCdSfizDQ== +react-query@^3.21.1: + version "3.21.1" + resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.21.1.tgz#8fe4df90bf6c6a93e0552ea9baff211d1b28f6e0" + integrity sha512-aKFLfNJc/m21JBXJk7sR9tDUYPjotWA4EHAKvbZ++GgxaY+eI0tqBxXmGBuJo0Pisis1W4pZWlZgoRv9yE8yjA== dependencies: "@babel/runtime" "^7.5.5" broadcast-channel "^3.4.1"