From bb9eaf78a6ac1c01a32b33766f9252de58d6a3a7 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Wed, 6 May 2020 16:06:40 -0700 Subject: [PATCH 01/23] Fixed create new connector from alert flyout form throw an error messages in external plugins. (#65539) * Fixed create new connector from alert flyout form throw an error messages in external plugins. * Fixed due to comments --- .../builtin_action_types/es_index.test.tsx | 27 +++-------- .../builtin_action_types/es_index.tsx | 4 +- .../builtin_action_types/pagerduty.test.tsx | 45 +++---------------- .../builtin_action_types/pagerduty.tsx | 4 +- .../builtin_action_types/slack.test.tsx | 45 +++---------------- .../components/builtin_action_types/slack.tsx | 4 +- .../application/context/alerts_context.tsx | 2 +- .../action_connector_form.test.tsx | 43 ++++-------------- .../action_connector_form.tsx | 14 ++++-- .../connector_add_flyout.tsx | 4 ++ .../connector_add_modal.tsx | 28 +++++------- .../connector_edit_flyout.tsx | 3 ++ .../triggers_actions_ui/public/types.ts | 3 +- 13 files changed, 64 insertions(+), 162 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.test.tsx index 567e96e05881d..04dc7b484ed48 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.test.tsx @@ -11,7 +11,6 @@ import { registerBuiltInActionTypes } from './index'; import { ActionTypeModel, ActionParamsProps } from '../../../types'; import { IndexActionParams, EsIndexActionConnector } from './types'; import { coreMock } from '../../../../../../../src/core/public/mocks'; -import { ActionsConnectorsContextProvider } from '../../context/actions_connectors_context'; jest.mock('../../../common/index_controls', () => ({ firstFieldOption: jest.fn(), getFields: jest.fn(), @@ -165,25 +164,13 @@ describe('IndexActionConnectorFields renders', () => { }, } as EsIndexActionConnector; const wrapper = mountWithIntl( - { - return new Promise(() => {}); - }, - docLinks: deps!.docLinks, - }} - > - {}} - editActionSecrets={() => {}} - /> - + {}} + editActionSecrets={() => {}} + http={deps!.http} + /> ); await act(async () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.tsx index 028638a403893..861d6ad7284c2 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.tsx @@ -33,7 +33,6 @@ import { getIndexPatterns, } from '../../../common/index_controls'; import { AddMessageVariables } from '../add_message_variables'; -import { useActionsConnectorsContext } from '../../context/actions_connectors_context'; export function getActionType(): ActionTypeModel { return { @@ -79,8 +78,7 @@ export function getActionType(): ActionTypeModel { const IndexActionConnectorFields: React.FunctionComponent> = ({ action, editActionConfig, errors }) => { - const { http } = useActionsConnectorsContext(); +>> = ({ action, editActionConfig, errors, http }) => { const { index, refresh, executionTimeField } = action.config; const [hasTimeFieldCheckbox, setTimeFieldCheckboxState] = useState( executionTimeField != null diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty.test.tsx index ae894346be59c..f628457dc5162 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty.test.tsx @@ -6,7 +6,6 @@ import React, { FunctionComponent } from 'react'; import { mountWithIntl, nextTick } from 'test_utils/enzyme_helpers'; import { act } from 'react-dom/test-utils'; -import { coreMock } from '../../../../../../../src/core/public/mocks'; import { TypeRegistry } from '../../type_registry'; import { registerBuiltInActionTypes } from './index'; import { ActionTypeModel, ActionParamsProps } from '../../../types'; @@ -16,7 +15,6 @@ import { SeverityActionOptions, PagerDutyActionConnector, } from './types'; -import { ActionsConnectorsContextProvider } from '../../context/actions_connectors_context'; const ACTION_TYPE_ID = '.pagerduty'; let actionTypeModel: ActionTypeModel; @@ -29,24 +27,7 @@ beforeAll(async () => { if (getResult !== null) { actionTypeModel = getResult; } - const mocks = coreMock.createSetup(); - const [ - { - application: { capabilities }, - }, - ] = await mocks.getStartServices(); deps = { - toastNotifications: mocks.notifications.toasts, - http: mocks.http, - capabilities: { - ...capabilities, - actions: { - delete: true, - save: true, - show: true, - }, - }, - actionTypeRegistry: actionTypeRegistry as any, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, }; }); @@ -148,25 +129,13 @@ describe('PagerDutyActionConnectorFields renders', () => { }, } as PagerDutyActionConnector; const wrapper = mountWithIntl( - { - return new Promise(() => {}); - }, - docLinks: deps!.docLinks, - }} - > - {}} - editActionSecrets={() => {}} - /> - + {}} + editActionSecrets={() => {}} + docLinks={deps!.docLinks} + /> ); await act(async () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty.tsx index 6f30cd41590ed..5ad1f2fffecce 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty.tsx @@ -25,7 +25,6 @@ import { PagerDutyActionParams, PagerDutyActionConnector } from './types'; import pagerDutySvg from './pagerduty.svg'; import { AddMessageVariables } from '../add_message_variables'; import { hasMustacheTokens } from '../../lib/has_mustache_tokens'; -import { useActionsConnectorsContext } from '../../context/actions_connectors_context'; export function getActionType(): ActionTypeModel { return { @@ -105,8 +104,7 @@ export function getActionType(): ActionTypeModel { const PagerDutyActionConnectorFields: React.FunctionComponent> = ({ errors, action, editActionConfig, editActionSecrets }) => { - const { docLinks } = useActionsConnectorsContext(); +>> = ({ errors, action, editActionConfig, editActionSecrets, docLinks }) => { const { apiUrl } = action.config; const { routingKey } = action.secrets; return ( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack.test.tsx index 0c9204ae5e176..a2865b27bc06c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack.test.tsx @@ -6,12 +6,10 @@ import React, { FunctionComponent } from 'react'; import { mountWithIntl, nextTick } from 'test_utils/enzyme_helpers'; import { act } from 'react-dom/test-utils'; -import { coreMock } from '../../../../../../../src/core/public/mocks'; import { TypeRegistry } from '../../type_registry'; import { registerBuiltInActionTypes } from './index'; import { ActionTypeModel, ActionParamsProps } from '../../../types'; import { SlackActionParams, SlackActionConnector } from './types'; -import { ActionsConnectorsContextProvider } from '../../context/actions_connectors_context'; const ACTION_TYPE_ID = '.slack'; let actionTypeModel: ActionTypeModel; @@ -25,24 +23,7 @@ beforeAll(async () => { if (getResult !== null) { actionTypeModel = getResult; } - const mocks = coreMock.createSetup(); - const [ - { - application: { capabilities }, - }, - ] = await mocks.getStartServices(); deps = { - toastNotifications: mocks.notifications.toasts, - http: mocks.http, - capabilities: { - ...capabilities, - actions: { - delete: true, - save: true, - show: true, - }, - }, - actionTypeRegistry: actionTypeRegistry as any, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, }; }); @@ -119,25 +100,13 @@ describe('SlackActionFields renders', () => { config: {}, } as SlackActionConnector; const wrapper = mountWithIntl( - { - return new Promise(() => {}); - }, - docLinks: deps!.docLinks, - }} - > - {}} - editActionSecrets={() => {}} - /> - + {}} + editActionSecrets={() => {}} + docLinks={deps!.docLinks} + /> ); await act(async () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack.tsx index 1cdde6dd77975..03f7a2f492d54 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack.tsx @@ -15,7 +15,6 @@ import { } from '../../../types'; import { SlackActionParams, SlackActionConnector } from './types'; import { AddMessageVariables } from '../add_message_variables'; -import { useActionsConnectorsContext } from '../../context/actions_connectors_context'; export function getActionType(): ActionTypeModel { return { @@ -76,8 +75,7 @@ export function getActionType(): ActionTypeModel { const SlackActionFields: React.FunctionComponent> = ({ action, editActionSecrets, errors }) => { - const { docLinks } = useActionsConnectorsContext(); +>> = ({ action, editActionSecrets, errors, docLinks }) => { const { webhookUrl } = action.secrets; return ( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/context/alerts_context.tsx b/x-pack/plugins/triggers_actions_ui/public/application/context/alerts_context.tsx index 09547f5c8ea66..95620a5be8474 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/context/alerts_context.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/context/alerts_context.tsx @@ -49,7 +49,7 @@ export const AlertsContextProvider = ({ export const useAlertsContext = () => { const ctx = useContext(AlertsContext); if (!ctx) { - throw new Error('ActionsConnectorsContext has not been set.'); + throw new Error('AlertsContext has not been set.'); } return ctx; }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx index 3b78096c4c644..17a1d929a0def 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx @@ -9,29 +9,14 @@ import { coreMock } from '../../../../../../../src/core/public/mocks'; import { actionTypeRegistryMock } from '../../action_type_registry.mock'; import { ValidationResult, ActionConnector } from '../../../types'; import { ActionConnectorForm } from './action_connector_form'; -import { ActionsConnectorsContextProvider } from '../../context/actions_connectors_context'; const actionTypeRegistry = actionTypeRegistryMock.create(); describe('action_connector_form', () => { let deps: any; beforeAll(async () => { const mocks = coreMock.createSetup(); - const [ - { - application: { capabilities }, - }, - ] = await mocks.getStartServices(); deps = { - toastNotifications: mocks.notifications.toasts, http: mocks.http, - capabilities: { - ...capabilities, - actions: { - delete: true, - save: true, - show: true, - }, - }, actionTypeRegistry: actionTypeRegistry as any, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, }; @@ -63,25 +48,15 @@ describe('action_connector_form', () => { let wrapper; if (deps) { wrapper = mountWithIntl( - { - return new Promise(() => {}); - }, - docLinks: deps!.docLinks, - }} - > - {}} - errors={{ name: [] }} - /> - + {}} + errors={{ name: [] }} + http={deps!.http} + actionTypeRegistry={deps!.actionTypeRegistry} + docLinks={deps!.docLinks} + /> ); } const connectorNameField = wrapper?.find('[data-test-subj="nameInput"]'); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx index 564b38bd0516a..6bb8a8f4e4c10 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx @@ -15,9 +15,10 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { HttpSetup, DocLinksStart } from 'kibana/public'; import { ReducerAction } from './connector_reducer'; -import { ActionConnector, IErrorObject } from '../../../types'; -import { useActionsConnectorsContext } from '../../context/actions_connectors_context'; +import { ActionConnector, IErrorObject, ActionTypeModel } from '../../../types'; +import { TypeRegistry } from '../../type_registry'; export function validateBaseProperties(actionObject: ActionConnector) { const validationResult = { errors: {} }; @@ -46,6 +47,9 @@ interface ActionConnectorProps { body: { message: string; error: string }; }; errors: IErrorObject; + http: HttpSetup; + actionTypeRegistry: TypeRegistry; + docLinks: DocLinksStart; } export const ActionConnectorForm = ({ @@ -54,8 +58,10 @@ export const ActionConnectorForm = ({ actionTypeName, serverError, errors, + http, + actionTypeRegistry, + docLinks, }: ActionConnectorProps) => { - const { actionTypeRegistry, docLinks } = useActionsConnectorsContext(); const setActionProperty = (key: string, value: any) => { dispatch({ command: { type: 'setProperty' }, payload: { key, value } }); }; @@ -150,6 +156,8 @@ export const ActionConnectorForm = ({ errors={errors} editActionConfig={setActionConfigProperty} editActionSecrets={setActionSecretsProperty} + http={http} + docLinks={docLinks} /> ) : null} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx index 80294e8b73dc8..c9844f4e10864 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx @@ -52,6 +52,7 @@ export const ConnectorAddFlyout = ({ capabilities, actionTypeRegistry, reloadConnectors, + docLinks, } = useActionsConnectorsContext(); const [actionType, setActionType] = useState(undefined); const [hasActionsUpgradeableByTrial, setHasActionsUpgradeableByTrial] = useState(false); @@ -114,6 +115,9 @@ export const ConnectorAddFlyout = ({ connector={connector} dispatch={dispatch} errors={errors} + actionTypeRegistry={actionTypeRegistry} + http={http} + docLinks={docLinks} /> ); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index a31336f38bdcd..8312f2b151082 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -25,7 +25,6 @@ import { createActionConnector } from '../../lib/action_connector_api'; import { TypeRegistry } from '../../type_registry'; import './connector_add_modal.scss'; import { PLUGIN } from '../../constants/plugin'; -import { ActionsConnectorsContextProvider } from '../../context/actions_connectors_context'; import { hasSaveActionsCapability } from '../../lib/capabilities'; interface ConnectorAddModalProps { @@ -156,23 +155,16 @@ export const ConnectorAddModal = ({ - - - + diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx index b86524efe19ea..4a0effcbd6825 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx @@ -182,6 +182,9 @@ export const ConnectorEditFlyout = ({ errors={errors} actionTypeName={connector.actionType} dispatch={dispatch} + actionTypeRegistry={actionTypeRegistry} + http={http} + docLinks={docLinks} /> ) : ( diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 47cb7067296ce..6f33bcb8b226d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { HttpSetup } from 'kibana/public'; +import { HttpSetup, DocLinksStart } from 'kibana/public'; import { ActionGroup } from '../../alerting/common'; import { ActionType } from '../../actions/common'; import { TypeRegistry } from './application/type_registry'; @@ -27,6 +27,7 @@ export interface ActionConnectorFieldsProps { editActionConfig: (property: string, value: any) => void; editActionSecrets: (property: string, value: any) => void; errors: { [key: string]: string[] }; + docLinks: DocLinksStart; http?: HttpSetup; } From 4a440427a6270a3727d7aef9b9af2f9cacd9a30d Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 6 May 2020 16:45:15 -0700 Subject: [PATCH 02/23] [functional tests] add some missing awaits (#65566) --- test/functional/apps/timelion/index.js | 2 +- test/functional/page_objects/settings_page.ts | 4 ++-- test/functional/services/find.ts | 2 +- test/plugin_functional/test_suites/core_plugins/rendering.ts | 4 ++-- x-pack/test/functional/apps/index_management/home_page.ts | 2 +- x-pack/test/functional/apps/lens/index.ts | 2 +- x-pack/test/functional/page_objects/index_management_page.ts | 2 +- x-pack/test/functional/page_objects/lens_page.ts | 2 +- x-pack/test/functional/page_objects/security_page.js | 4 ++-- .../test/functional/services/logs_ui/log_entry_categories.ts | 2 +- x-pack/test/functional/services/logs_ui/log_entry_rate.ts | 2 +- x-pack/test/functional/services/logs_ui/log_stream.ts | 2 +- x-pack/test/functional/services/uptime/monitor.ts | 5 +++-- .../apps/triggers_actions_ui/home_page.ts | 4 ++-- .../page_objects/triggers_actions_ui_page.ts | 2 +- 15 files changed, 21 insertions(+), 20 deletions(-) diff --git a/test/functional/apps/timelion/index.js b/test/functional/apps/timelion/index.js index 3b5167addf4e6..021fa24397850 100644 --- a/test/functional/apps/timelion/index.js +++ b/test/functional/apps/timelion/index.js @@ -28,7 +28,7 @@ export default function({ getService, loadTestFile }) { before(async function() { log.debug('Starting timelion before method'); - browser.setWindowSize(1280, 800); + await browser.setWindowSize(1280, 800); await esArchiver.loadIfNeeded('logstash_functional'); await kibanaServer.uiSettings.replace({ defaultIndex: 'logstash-*' }); }); diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts index 81d22838d1e8b..b7a6e10efd7dc 100644 --- a/test/functional/page_objects/settings_page.ts +++ b/test/functional/page_objects/settings_page.ts @@ -33,7 +33,7 @@ export function SettingsPageProvider({ getService, getPageObjects }: FtrProvider class SettingsPage { async clickNavigation() { - find.clickDisplayedByCssSelector('.app-link:nth-child(5) a'); + await find.clickDisplayedByCssSelector('.app-link:nth-child(5) a'); } async clickLinkText(text: string) { @@ -110,7 +110,7 @@ export function SettingsPageProvider({ getService, getPageObjects }: FtrProvider } async toggleAdvancedSettingCheckbox(propertyName: string) { - testSubjects.click(`advancedSetting-editField-${propertyName}`); + await testSubjects.click(`advancedSetting-editField-${propertyName}`); await PageObjects.header.waitUntilLoadingHasFinished(); await testSubjects.click(`advancedSetting-saveButton`); await PageObjects.header.waitUntilLoadingHasFinished(); diff --git a/test/functional/services/find.ts b/test/functional/services/find.ts index 312668b718dc0..bdcc5ba95e9fb 100644 --- a/test/functional/services/find.ts +++ b/test/functional/services/find.ts @@ -476,7 +476,7 @@ export async function FindProvider({ getService }: FtrProviderContext) { value: string ): Promise { log.debug(`Find.waitForAttributeToChange('${selector}', '${attribute}', '${value}')`); - retry.waitFor(`${attribute} to equal "${value}"`, async () => { + await retry.waitFor(`${attribute} to equal "${value}"`, async () => { const el = await this.byCssSelector(selector); return value === (await el.getAttribute(attribute)); }); diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index 097833750bc80..b8e26b8e6ffcb 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -40,8 +40,8 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider const find = getService('find'); const testSubjects = getService('testSubjects'); - const navigateTo = (path: string) => - browser.navigateTo(`${PageObjects.common.getHostPort()}${path}`); + const navigateTo = async (path: string) => + await browser.navigateTo(`${PageObjects.common.getHostPort()}${path}`); const navigateToApp = async (title: string) => { await appsMenu.clickLink(title); return browser.execute(() => { diff --git a/x-pack/test/functional/apps/index_management/home_page.ts b/x-pack/test/functional/apps/index_management/home_page.ts index 046b8ec44b9fa..5ed6064314af8 100644 --- a/x-pack/test/functional/apps/index_management/home_page.ts +++ b/x-pack/test/functional/apps/index_management/home_page.ts @@ -34,7 +34,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Index templates', () => { it('renders the index templates tab', async () => { // Navigate to the index templates tab - pageObjects.indexManagement.changeTabs('templatesTab'); + await pageObjects.indexManagement.changeTabs('templatesTab'); await pageObjects.header.waitUntilLoadingHasFinished(); diff --git a/x-pack/test/functional/apps/lens/index.ts b/x-pack/test/functional/apps/lens/index.ts index 857cbe15463b9..53e800bae3f6d 100644 --- a/x-pack/test/functional/apps/lens/index.ts +++ b/x-pack/test/functional/apps/lens/index.ts @@ -15,7 +15,7 @@ export default function({ getService, loadTestFile }: FtrProviderContext) { describe('lens app', () => { before(async () => { log.debug('Starting lens before method'); - browser.setWindowSize(1280, 800); + await browser.setWindowSize(1280, 800); await esArchiver.loadIfNeeded('logstash_functional'); await esArchiver.loadIfNeeded('lens/basic'); }); diff --git a/x-pack/test/functional/page_objects/index_management_page.ts b/x-pack/test/functional/page_objects/index_management_page.ts index 1ae23b24156d0..453b283ab969d 100644 --- a/x-pack/test/functional/page_objects/index_management_page.ts +++ b/x-pack/test/functional/page_objects/index_management_page.ts @@ -57,7 +57,7 @@ export function IndexManagementPageProvider({ getService }: FtrProviderContext) }); }, async changeTabs(tab: 'indicesTab' | 'templatesTab') { - return await testSubjects.click(tab); + await testSubjects.click(tab); }, }; } diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index c4dcf63941cd5..7425ed25728c2 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -150,7 +150,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont } await testSubjects.click('confirmSaveSavedObjectButton'); - retry.waitForWithTimeout('Save modal to disappear', 1000, () => + await retry.waitForWithTimeout('Save modal to disappear', 1000, () => testSubjects .missingOrFail('confirmSaveSavedObjectButton') .then(() => true) diff --git a/x-pack/test/functional/page_objects/security_page.js b/x-pack/test/functional/page_objects/security_page.js index 08895de815b39..ae26a831d4172 100644 --- a/x-pack/test/functional/page_objects/security_page.js +++ b/x-pack/test/functional/page_objects/security_page.js @@ -394,9 +394,9 @@ export function SecurityPageProvider({ getService, getPageObjects }) { }); } }) //clicking save button - .then(function() { + .then(async () => { log.debug('click save button'); - testSubjects.click('roleFormSaveButton'); + await testSubjects.click('roleFormSaveButton'); }) .then(function() { return PageObjects.common.sleep(5000); diff --git a/x-pack/test/functional/services/logs_ui/log_entry_categories.ts b/x-pack/test/functional/services/logs_ui/log_entry_categories.ts index b9a400b155679..70d8622e620ef 100644 --- a/x-pack/test/functional/services/logs_ui/log_entry_categories.ts +++ b/x-pack/test/functional/services/logs_ui/log_entry_categories.ts @@ -13,7 +13,7 @@ export function LogEntryCategoriesPageProvider({ getPageObjects, getService }: F return { async navigateTo() { - pageObjects.infraLogs.navigateToTab('log-categories'); + await pageObjects.infraLogs.navigateToTab('log-categories'); }, async getSetupScreen(): Promise { diff --git a/x-pack/test/functional/services/logs_ui/log_entry_rate.ts b/x-pack/test/functional/services/logs_ui/log_entry_rate.ts index 96c69e85aa0a4..ffaa6ce08a1dc 100644 --- a/x-pack/test/functional/services/logs_ui/log_entry_rate.ts +++ b/x-pack/test/functional/services/logs_ui/log_entry_rate.ts @@ -13,7 +13,7 @@ export function LogEntryRatePageProvider({ getPageObjects, getService }: FtrProv return { async navigateTo() { - pageObjects.infraLogs.navigateToTab('log-rate'); + await pageObjects.infraLogs.navigateToTab('log-rate'); }, async getSetupScreen(): Promise { diff --git a/x-pack/test/functional/services/logs_ui/log_stream.ts b/x-pack/test/functional/services/logs_ui/log_stream.ts index 75486534cf5cc..5fa950a86e696 100644 --- a/x-pack/test/functional/services/logs_ui/log_stream.ts +++ b/x-pack/test/functional/services/logs_ui/log_stream.ts @@ -15,7 +15,7 @@ export function LogStreamPageProvider({ getPageObjects, getService }: FtrProvide return { async navigateTo(params?: TabsParams['stream']) { - pageObjects.infraLogs.navigateToTab('stream', params); + await pageObjects.infraLogs.navigateToTab('stream', params); }, async getColumnHeaderLabels(): Promise { diff --git a/x-pack/test/functional/services/uptime/monitor.ts b/x-pack/test/functional/services/uptime/monitor.ts index a3e3d953e2eb7..b6689737e8618 100644 --- a/x-pack/test/functional/services/uptime/monitor.ts +++ b/x-pack/test/functional/services/uptime/monitor.ts @@ -38,8 +38,9 @@ export function UptimeMonitorProvider({ getService }: FtrProviderContext) { async checkForPingListTimestamps(timestamps: string[]): Promise { return retry.tryForTime(10000, async () => { await Promise.all( - timestamps.map(timestamp => - testSubjects.existOrFail(`xpack.uptime.pingList.ping-${timestamp}`) + timestamps.map( + async timestamp => + await testSubjects.existOrFail(`xpack.uptime.pingList.ping-${timestamp}`) ) ); }); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts index 2edab1b164a1b..bd793883eed90 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts @@ -29,7 +29,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Connectors tab', () => { it('renders the connectors tab', async () => { // Navigate to the connectors tab - pageObjects.triggersActionsUI.changeTabs('connectorsTab'); + await pageObjects.triggersActionsUI.changeTabs('connectorsTab'); await pageObjects.header.waitUntilLoadingHasFinished(); @@ -45,7 +45,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Alerts tab', () => { it('renders the alerts tab', async () => { // Navigate to the alerts tab - pageObjects.triggersActionsUI.changeTabs('alertsTab'); + await pageObjects.triggersActionsUI.changeTabs('alertsTab'); await pageObjects.header.waitUntilLoadingHasFinished(); diff --git a/x-pack/test/functional_with_es_ssl/page_objects/triggers_actions_ui_page.ts b/x-pack/test/functional_with_es_ssl/page_objects/triggers_actions_ui_page.ts index ca7f064e20690..2cd094f9045c5 100644 --- a/x-pack/test/functional_with_es_ssl/page_objects/triggers_actions_ui_page.ts +++ b/x-pack/test/functional_with_es_ssl/page_objects/triggers_actions_ui_page.ts @@ -120,7 +120,7 @@ export function TriggersActionsPageProvider({ getService }: FtrProviderContext) await find.clickDisplayedByCssSelector(`[data-test-subj="alertsList"] [title="${name}"]`); }, async changeTabs(tab: 'alertsTab' | 'connectorsTab') { - return await testSubjects.click(tab); + await testSubjects.click(tab); }, async toggleSwitch(testSubject: string) { const switchBtn = await testSubjects.find(testSubject); From 74187fd80d91b184e8886d514f284d92ff63dd84 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Wed, 6 May 2020 18:19:15 -0700 Subject: [PATCH 03/23] Extended alerting documentation with information about using Kibana keystore and action types for preconfigured connectors (#65201) * Extended alerting documentation with information about using Kibana keystore and action types for preconfigured connectors * Fixed due to comments and merged two preconfig pages * Fixed due to review comments * Update docs/user/alerting/action-types/index.asciidoc Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com> * Fixed due to comments * - Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com> --- docs/user/alerting/action-types.asciidoc | 6 +- .../user/alerting/action-types/email.asciidoc | 31 +++++++ .../user/alerting/action-types/index.asciidoc | 22 +++++ .../alerting/action-types/pagerduty.asciidoc | 23 +++++ .../alerting/action-types/server-log.asciidoc | 11 +++ .../user/alerting/action-types/slack.asciidoc | 18 ++++ .../alerting/action-types/webhook.asciidoc | 30 +++++++ ...pre-configured-action-type-select-type.png | Bin 274678 -> 104497 bytes .../pre-configured-action-types.asciidoc | 61 -------------- .../pre-configured-connectors.asciidoc | 79 +++++++++++++----- 10 files changed, 197 insertions(+), 84 deletions(-) delete mode 100644 docs/user/alerting/pre-configured-action-types.asciidoc diff --git a/docs/user/alerting/action-types.asciidoc b/docs/user/alerting/action-types.asciidoc index 8794c389d72bc..09878b3059ac8 100644 --- a/docs/user/alerting/action-types.asciidoc +++ b/docs/user/alerting/action-types.asciidoc @@ -43,11 +43,10 @@ see https://www.elastic.co/subscriptions[the subscription page]. [[create-connectors]] === Preconfigured connectors and action types -You can create connectors for actions in <> or via the action API. -For out-of-the-box and standardized connectors, you can <> +For out-of-the-box and standardized connectors, you can <> before {kib} starts. -Action type with only preconfigured connectors could be specified as a <>. +If you preconfigure a connector, you can also <>. include::action-types/email.asciidoc[] include::action-types/index.asciidoc[] @@ -56,4 +55,3 @@ include::action-types/server-log.asciidoc[] include::action-types/slack.asciidoc[] include::action-types/webhook.asciidoc[] include::pre-configured-connectors.asciidoc[] -include::pre-configured-action-types.asciidoc[] diff --git a/docs/user/alerting/action-types/email.asciidoc b/docs/user/alerting/action-types/email.asciidoc index 794fc14005f2f..689d870d9cadc 100644 --- a/docs/user/alerting/action-types/email.asciidoc +++ b/docs/user/alerting/action-types/email.asciidoc @@ -19,6 +19,37 @@ Username:: username for 'login' type authentication. Password:: password for 'login' type authentication. [float] +[[Preconfigured-email-configuration]] +==== Preconfigured action type + +[source,text] +-- + id: 'my-email' + name: preconfigured-email-action-type + actionTypeId: .email + config: + from: testsender@test.com <1.1> + host: validhostname <1.2> + port: 8080 <1.3> + secure: false <1.4> + secrets: + user: testuser <2.1> + password: passwordkeystorevalue <2.2> +-- + +`config` defines the action type specific to the configuration and contains the following properties: + +<1.1> `from:` is an email address and correspond to *Sender*. +<1.2> `host:` is a string and correspond to *Host*. +<1.3> `port:` is a number and correspond to *Port*. +<1.4> `secure:` is a boolean and correspond to *Secure*. + +`secrets` defines action type sensitive configuration: + +<2.1> `user:` is a string and correspond to *User*. +<2.2> `password:` is a string and correspond to *Password*. Should be stored in the <>. + + [[email-action-configuration]] ==== Action configuration diff --git a/docs/user/alerting/action-types/index.asciidoc b/docs/user/alerting/action-types/index.asciidoc index 625b8f704b7c6..4f5254e3311d8 100644 --- a/docs/user/alerting/action-types/index.asciidoc +++ b/docs/user/alerting/action-types/index.asciidoc @@ -15,6 +15,28 @@ Index:: The {es} index to be written to. Refresh:: Setting for the {ref}/docs-refresh.html[refresh] policy for the write request. Execution time field:: This field will be automatically set to the time the alert condition was detected. +[float] +[[Preconfigured-index-configuration]] +==== Preconfigured action type + +[source,text] +-- + id: 'my-index' + name: action-type-index + actionTypeId: .index + config: + index: .kibana <1> + refresh: true <2> + executionTimeField: somedate <3> +-- + +`config` defines the action type specific to the configuration and contains the following properties: + +<1> `index:` is a string and correspond to *Index*. +<2> `refresh:` is a boolean and correspond to *Refresh*. +<3> `executionTimeField:` is a string and correspond to *Execution time field*. + + [float] [[index-action-configuration]] ==== Action configuration diff --git a/docs/user/alerting/action-types/pagerduty.asciidoc b/docs/user/alerting/action-types/pagerduty.asciidoc index 673b4f6263e18..957c035b028f6 100644 --- a/docs/user/alerting/action-types/pagerduty.asciidoc +++ b/docs/user/alerting/action-types/pagerduty.asciidoc @@ -135,6 +135,29 @@ Name:: The name of the connector. The name is used to identify a connector API URL:: An optional PagerDuty event URL. Defaults to `https://events.pagerduty.com/v2/enqueue`. If you are using the <> setting, make sure the hostname is whitelisted. Integration Key:: A 32 character PagerDuty Integration Key for an integration on a service, also referred to as the routing key. +[float] +[[Preconfigured-pagerduty-configuration]] +==== Preconfigured action type + +[source,text] +-- + id: 'my-pagerduty' + name: preconfigured-pagerduty-action-type + actionTypeId: .pagerduty + config: + apiUrl: https://test.host <1.1> + secrets: + routingKey: testroutingkey <2.1> +-- + +`config` defines the action type specific to the configuration and contains the following properties: + +<1.1> `apiUrl:` is URL string and correspond to *API URL*. + +`secrets` defines action type sensitive configuration: + +<2.1> `routingKey:` is a string and correspond to *Integration Key*. + [float] [[pagerduty-action-configuration]] ==== Action configuration diff --git a/docs/user/alerting/action-types/server-log.asciidoc b/docs/user/alerting/action-types/server-log.asciidoc index 8f888785626c9..f08dbe5542f0f 100644 --- a/docs/user/alerting/action-types/server-log.asciidoc +++ b/docs/user/alerting/action-types/server-log.asciidoc @@ -12,6 +12,17 @@ Server log connectors have the following configuration properties: Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action. +[float] +[[Preconfigured-server-log-configuration]] +==== Preconfigured action type + +[source,text] +-- + id: 'my-server-log' + name: test + actionTypeId: .server-log +-- + [float] [[server-log-action-configuration]] ==== Action configuration diff --git a/docs/user/alerting/action-types/slack.asciidoc b/docs/user/alerting/action-types/slack.asciidoc index c0965d65bfdbe..195093536bc04 100644 --- a/docs/user/alerting/action-types/slack.asciidoc +++ b/docs/user/alerting/action-types/slack.asciidoc @@ -13,6 +13,24 @@ Slack connectors have the following configuration properties: Name:: The name of the connector. The name is used to identify a connector in the management UI connector listing, or in the connector list when configuring an action. Webhook URL:: The URL of the incoming webhook. See https://api.slack.com/messaging/webhooks#getting_started[Slack Incoming Webhooks] for instructions on generating this URL. If you are using the <> setting, make sure the hostname is whitelisted. +[float] +[[Preconfigured-slack-configuration]] +==== Preconfigured action type + +[source,text] +-- + id: 'my-slack' + name: preconfigured-slack-action-type + actionTypeId: .slack + config: + webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz' <1> +-- + +`config` defines the action type specific to the configuration and contains the following properties: + +<1> `webhookUrl:` is URL string and correspond to *Webhook URL*. + + [float] [[slack-action-configuration]] ==== Action configuration diff --git a/docs/user/alerting/action-types/webhook.asciidoc b/docs/user/alerting/action-types/webhook.asciidoc index 64bfa6a1d6364..f4c108426642d 100644 --- a/docs/user/alerting/action-types/webhook.asciidoc +++ b/docs/user/alerting/action-types/webhook.asciidoc @@ -17,6 +17,36 @@ Headers:: A set of key-value pairs sent as headers with the request User:: An optional username. If set, HTTP basic authentication is used. Currently only basic authentication is supported. Password:: An optional password. If set, HTTP basic authentication is used. Currently only basic authentication is supported. +[float] +[[Preconfigured-webhook-configuration]] +==== Preconfigured action type + +[source,text] +-- + id: 'my-webhook' + name: preconfigured-webhook-action-type + actionTypeId: .webhook + config: + url: https://test.host <1.1> + method: POST <1.2> + headers: <1.3> + testheader: testvalue + secrets: + user: testuser <2.1> + password: passwordkeystorevalue <2.2> +-- + +`config` defines the action type specific to the configuration and contains the following properties: + +<1.1> `url:` is URL string and correspond to *URL*. +<1.2> `method:` is a string and correspond to *Method*. +<1.3> `headers:` is Record and correspond to *Headers*. + +`secrets` defines action type sensitive configuration: + +<2.1> `user:` is a string and correspond to *User*. +<2.2> `password:` is a string and correspond to *Password*. Should be stored in the <>. + [float] [[webhook-action-configuration]] ==== Action configuration diff --git a/docs/user/alerting/images/pre-configured-action-type-select-type.png b/docs/user/alerting/images/pre-configured-action-type-select-type.png index 5f555f851cd816d6a13162e6b86125eee2d24299..29e5a29edc7c0608d06386e1c95bc14899f8c044 100644 GIT binary patch literal 104497 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 literal 274678 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 Wj6`}@mHYzyck-zIADM>{xBd@%%m;!1 diff --git a/docs/user/alerting/pre-configured-action-types.asciidoc b/docs/user/alerting/pre-configured-action-types.asciidoc deleted file mode 100644 index 780a2119037b1..0000000000000 --- a/docs/user/alerting/pre-configured-action-types.asciidoc +++ /dev/null @@ -1,61 +0,0 @@ -[role="xpack"] -[[pre-configured-action-types]] - -== Preconfigured action types - -A preconfigure an action type has all the information it needs prior to startup. -A preconfigured action type offers the following capabilities: - -- Requires no setup. Configuration and credentials needed to execute an -action are predefined. -- Has only <>. -- Connectors of the preconfigured action type cannot be edited or deleted. - -[float] -[[preconfigured-action-type-example]] -=== Creating a preconfigured action - -In the `kibana.yml` file: - -. Exclude the action type from `xpack.actions.enabledActionTypes`. -. Add all its connectors. - -The following example shows a valid configuration of preconfigured action type with one out-of-the box connector. - -```js - xpack.actions.enabledActionTypes: ['.slack', '.email', '.index'] <1> - xpack.actions.preconfigured: <2> - - id: 'my-server-log' - actionTypeId: .server-log - name: 'Server log #xyz' -``` - -<1> `enabledActionTypes` should exclude preconfigured action type to prevent creating and deleting connectors. -<2> `preconfigured` is the setting for defining the list of available connectors for the preconfigured action type. - -[float] -[[pre-configured-action-type-alert-form]] -=== Attaching a preconfigured action to an alert - -To attach an action to an alert, -select from a list of available action types, and -then select the *Server log* type. This action type was configured previously. - -[role="screenshot"] -image::images/pre-configured-action-type-alert-form.png[Create alert with selected Server log action type] - -[float] -[[managing-pre-configured-action-types]] -=== Managing preconfigured actions - -Connectors with preconfigured actions appear in the connector list, regardless of which space the user is in. -They are tagged as “preconfigured” and cannot be deleted. - -[role="screenshot"] -image::images/pre-configured-action-type-managing.png[Connectors managing tab with pre-cofigured] - -Clicking *Create connector* shows the list of available action types. -Preconfigured action types are not included because you can't create a connector with a preconfigured action type. - -[role="screenshot"] -image::images/pre-configured-action-type-select-type.png[Pre-configured connector create menu] diff --git a/docs/user/alerting/pre-configured-connectors.asciidoc b/docs/user/alerting/pre-configured-connectors.asciidoc index 4c408da92f579..5ff4ea15df561 100644 --- a/docs/user/alerting/pre-configured-connectors.asciidoc +++ b/docs/user/alerting/pre-configured-connectors.asciidoc @@ -1,11 +1,10 @@ [role="xpack"] -[[pre-configured-connectors]] +[[pre-configured-action-types-and-connectors]] -== Preconfigured connectors +== Preconfigured connectors and action types -You can preconfigure an action connector to have all the information it needs prior to startup +You can preconfigure an action type or a connector to have all the information it needs prior to startup by adding it to the `kibana.yml` file. -Sensitive configuration information, such as credentials, can use the {kib} keystore. Preconfigured connectors offer the following capabilities: @@ -14,11 +13,15 @@ action are predefined, including the connector name and ID. - Appear in all spaces because they are not saved objects. - Cannot be edited or deleted. +Sensitive configuration information, such as credentials, can use the <>. + +A preconfigured action types has only preconfigured connectors. Preconfigured connectors can belong to either the preconfigured action type or to the regular action type. + [float] [[preconfigured-connector-example]] -=== Example of a preconfigured connector +=== Creating a preconfigured connector -The following example shows a valid configuration 2 out-of-the box connector. +The following example shows a valid configuration of two out-of-the box connectors: <> and <>. ```js xpack.actions.preconfigured: @@ -49,26 +52,30 @@ The following example shows a valid configuration 2 out-of-the box connector. [NOTE] ============================================== -Sensitive properties, such as passwords, can also be stored in the {kib} keystore. +Sensitive properties, such as passwords, can also be stored in the <>. ============================================== [float] -[[pre-configured-connector-alert-form]] -=== Creating an alert with a preconfigured connector +[[preconfigured-action-type-example]] +=== Creating a preconfigured action type -When attaching an action to an alert, -select from a list of available action types, and -then select the Slack or Webhook type. Those action types were configured previously. -The preconfigured connector is installed and is automatically selected. +In the `kibana.yml` file: -[role="screenshot"] -image::images/alert-pre-configured-slack-connector.png[Create alert with selected Slack action type] +. Exclude the action type from `xpack.actions.enabledActionTypes`. +. Add all its preconfigured connectors. -The dropdown is populated with additional preconfigured Slack connectors. -The `preconfigured` label distinguishes them from space-aware connectors that use saved objects. +The following example shows a valid configuration of preconfigured action type with one out-of-the box connector. -[role="screenshot"] -image::images/alert-pre-configured-connectors-dropdown.png[Dropdown list with pre-cofigured connectors] +```js + xpack.actions.enabledActionTypes: ['.slack', '.email', '.index'] <1> + xpack.actions.preconfigured: <2> + - id: 'my-server-log' + actionTypeId: .server-log + name: 'Server log #xyz' +``` + +<1> `enabledActionTypes` should exclude preconfigured action type to prevent creating and deleting connectors. +<2> `preconfigured` is the setting for defining the list of available connectors for the preconfigured action type. [float] [[managing-pre-configured-connectors]] @@ -85,3 +92,37 @@ A message indicates that this is a preconfigured connector. [role="screenshot"] image::images/pre-configured-connectors-view-screen.png[Pre-configured connector view details] + +The connector details preview is disabled for preconfigured connectors. + +[role="screenshot"] +image::images/pre-configured-action-type-managing.png[Connectors managing tab with pre-cofigured] + + +[float] +[[managing-pre-configured-action-types]] +=== Managing preconfigured action types + +Clicking *Create connector* shows the list of available action types. +Disabled action types are not included. + +[role="screenshot"] +image::images/pre-configured-action-type-select-type.png[Pre-configured connector create menu] + +[float] +[[pre-configured-connector-alert-form]] +=== Alert with a preconfigured connector + +When attaching an action to an alert, +select from a list of available action types, and +then select the Slack or Webhook type. Those action types were configured previously. +The preconfigured connector is installed and is automatically selected. + +[role="screenshot"] +image::images/alert-pre-configured-slack-connector.png[Create alert with selected Slack action type] + +The dropdown is populated with additional preconfigured Slack connectors. +The `preconfigured` label distinguishes them from space-aware connectors that use saved objects. + +[role="screenshot"] +image::images/alert-pre-configured-connectors-dropdown.png[Dropdown list with pre-cofigured connectors] From 4a6ecc84a64f9eaef7cb825768eb7932b3b7c539 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Thu, 7 May 2020 08:26:11 +0200 Subject: [PATCH 04/23] move core provier to NP. allows to run tests on every page (#64929) * move core provier to NP. allows to run tests on every page * remove no-base-path * pass whole KbnTestServer config * fix build path * another id * np * build kibana tests plugins. it is used in xpack tests Co-authored-by: Elastic Machine --- .../plugins/core_provider_plugin/index.ts | 36 ------------------- .../plugins/core_provider_plugin/kibana.json | 8 +++++ .../core_provider_plugin/public/index.ts | 34 +++++++++++++----- .../core_provider_plugin/tsconfig.json | 2 +- .../plugins/core_provider_plugin/types.ts | 6 ++-- .../test_suites/core_plugins/ui_plugins.ts | 8 ----- test/scripts/jenkins_xpack_build_kibana.sh | 1 + x-pack/test/functional/config.js | 3 -- x-pack/test/licensing_plugin/config.public.ts | 2 +- 9 files changed, 40 insertions(+), 60 deletions(-) delete mode 100644 test/plugin_functional/plugins/core_provider_plugin/index.ts create mode 100644 test/plugin_functional/plugins/core_provider_plugin/kibana.json diff --git a/test/plugin_functional/plugins/core_provider_plugin/index.ts b/test/plugin_functional/plugins/core_provider_plugin/index.ts deleted file mode 100644 index 01f3a67c6b554..0000000000000 --- a/test/plugin_functional/plugins/core_provider_plugin/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { resolve } from 'path'; -import { Legacy } from '../../../../kibana'; - -// eslint-disable-next-line import/no-default-export -export default function CoreProviderPlugin(kibana: any) { - const config: Legacy.PluginSpecOptions = { - id: 'core-provider', - require: [], - publicDir: resolve(__dirname, 'public'), - init: (server: Legacy.Server) => ({}), - uiExports: { - hacks: [resolve(__dirname, 'public/index')], - }, - }; - - return new kibana.Plugin(config); -} diff --git a/test/plugin_functional/plugins/core_provider_plugin/kibana.json b/test/plugin_functional/plugins/core_provider_plugin/kibana.json new file mode 100644 index 0000000000000..1d5c5824d6b97 --- /dev/null +++ b/test/plugin_functional/plugins/core_provider_plugin/kibana.json @@ -0,0 +1,8 @@ +{ + "id": "core_provider_plugin", + "version": "0.0.1", + "kibanaVersion": "kibana", + "optionalPlugins": ["core_plugin_a", "core_plugin_b", "licensing"], + "server": false, + "ui": true +} diff --git a/test/plugin_functional/plugins/core_provider_plugin/public/index.ts b/test/plugin_functional/plugins/core_provider_plugin/public/index.ts index c74928203db56..2f271fe5ef65b 100644 --- a/test/plugin_functional/plugins/core_provider_plugin/public/index.ts +++ b/test/plugin_functional/plugins/core_provider_plugin/public/index.ts @@ -16,13 +16,31 @@ * specific language governing permissions and limitations * under the License. */ -import { npSetup, npStart } from 'ui/new_platform'; +import { Plugin, CoreSetup, CoreStart } from 'kibana/public'; import '../types'; -window.__coreProvider = { - setup: npSetup, - start: npStart, - testUtils: { - delay: (ms: number) => new Promise(res => setTimeout(res, ms)), - }, -}; +export const plugin = () => new CoreProviderPlugin(); + +class CoreProviderPlugin implements Plugin { + private setupDeps?: { core: CoreSetup; plugins: Record }; + public setup(core: CoreSetup, plugins: Record) { + this.setupDeps = { + core, + plugins, + }; + } + + public start(core: CoreStart, plugins: Record) { + window.__coreProvider = { + setup: this.setupDeps!, + start: { + core, + plugins, + }, + testUtils: { + delay: (ms: number) => new Promise(res => setTimeout(res, ms)), + }, + }; + } + public stop() {} +} diff --git a/test/plugin_functional/plugins/core_provider_plugin/tsconfig.json b/test/plugin_functional/plugins/core_provider_plugin/tsconfig.json index c29959197958d..baedb5f2f621b 100644 --- a/test/plugin_functional/plugins/core_provider_plugin/tsconfig.json +++ b/test/plugin_functional/plugins/core_provider_plugin/tsconfig.json @@ -8,7 +8,7 @@ "index.ts", "types.ts", "public/**/*.ts", - "../../../../typings/**/*", + "../../../../typings/**/*" ], "exclude": [] } diff --git a/test/plugin_functional/plugins/core_provider_plugin/types.ts b/test/plugin_functional/plugins/core_provider_plugin/types.ts index bf19578c37baa..cae3b604ecd95 100644 --- a/test/plugin_functional/plugins/core_provider_plugin/types.ts +++ b/test/plugin_functional/plugins/core_provider_plugin/types.ts @@ -16,17 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -import { LegacyCoreSetup, LegacyCoreStart } from 'kibana/public'; +import { CoreSetup, CoreStart } from 'kibana/public'; declare global { interface Window { __coreProvider: { setup: { - core: LegacyCoreSetup; + core: CoreSetup; plugins: Record; }; start: { - core: LegacyCoreStart; + core: CoreStart; plugins: Record; }; testUtils: { diff --git a/test/plugin_functional/test_suites/core_plugins/ui_plugins.ts b/test/plugin_functional/test_suites/core_plugins/ui_plugins.ts index 8ddd0ff96ba8f..b2393443989f9 100644 --- a/test/plugin_functional/test_suites/core_plugins/ui_plugins.ts +++ b/test/plugin_functional/test_suites/core_plugins/ui_plugins.ts @@ -47,14 +47,6 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider await PageObjects.common.navigateToApp('settings'); }); - it('to injectedMetadata service', async () => { - expect( - await browser.execute(() => { - return window.__coreProvider.setup.core.injectedMetadata.getKibanaBuildNumber(); - }) - ).to.be.a('number'); - }); - it('to start services via coreSetup.getStartServices', async () => { expect( await browser.executeAsync(async cb => { diff --git a/test/scripts/jenkins_xpack_build_kibana.sh b/test/scripts/jenkins_xpack_build_kibana.sh index 8dc41639fa946..c962b962b1e5e 100755 --- a/test/scripts/jenkins_xpack_build_kibana.sh +++ b/test/scripts/jenkins_xpack_build_kibana.sh @@ -5,6 +5,7 @@ source src/dev/ci_setup/setup_env.sh echo " -> building kibana platform plugins" node scripts/build_kibana_platform_plugins \ + --scan-dir "$KIBANA_DIR/test/plugin_functional/plugins" \ --scan-dir "$XPACK_DIR/test/plugin_functional/plugins" \ --scan-dir "$XPACK_DIR/test/functional_with_es_ssl/fixtures/plugins" \ --scan-dir "$XPACK_DIR/test/alerting_api_integration/plugins" \ diff --git a/x-pack/test/functional/config.js b/x-pack/test/functional/config.js index f6b80b1b9fc67..4c78758de448c 100644 --- a/x-pack/test/functional/config.js +++ b/x-pack/test/functional/config.js @@ -146,9 +146,6 @@ export default async function({ readConfigFile }) { uptime: { pathname: '/app/uptime', }, - apm: { - pathname: '/app/apm', - }, ml: { pathname: '/app/ml', }, diff --git a/x-pack/test/licensing_plugin/config.public.ts b/x-pack/test/licensing_plugin/config.public.ts index 42209aa49bcb4..adde6320119d1 100644 --- a/x-pack/test/licensing_plugin/config.public.ts +++ b/x-pack/test/licensing_plugin/config.public.ts @@ -14,9 +14,9 @@ export default async function({ readConfigFile }: FtrConfigProviderContext) { ...commonConfig.getAll(), testFiles: [require.resolve('./public')], kbnTestServer: { + ...commonConfig.get('kbnTestServer'), serverArgs: [ ...commonConfig.get('kbnTestServer.serverArgs'), - // Required to load new platform plugin provider via `--plugin-path` flag. '--env.name=development', `--plugin-path=${path.resolve( From c5d4d9e68a3c1d9f617778f4fe09837f69338b6e Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Thu, 7 May 2020 10:12:46 +0300 Subject: [PATCH 05/23] =?UTF-8?q?Migrate=20test=20plugins=20=E2=87=92=20NP?= =?UTF-8?q?=20(kbn=5Ftp=5Frun=5Fpipeline)=20(#64780)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Migrated kbn_tp_run_pipeline to the new Platform * Updated config. * Added tsconfig. * Updated index.ts for tests * updated tsconfig * Updated typescript task * fixed tests * Fixed tests * updated comment Co-authored-by: Elastic Machine --- src/dev/typescript/projects.ts | 3 ++ test/interpreter_functional/config.ts | 3 ++ .../plugins/kbn_tp_run_pipeline/index.ts | 49 ------------------- .../plugins/kbn_tp_run_pipeline/kibana.json | 13 +++++ .../plugins/kbn_tp_run_pipeline/package.json | 9 ++++ .../public/{np_ready => }/app/app.tsx | 0 .../{np_ready => }/app/components/main.tsx | 2 +- .../kbn_tp_run_pipeline/public/index.ts | 10 +++- .../kbn_tp_run_pipeline/public/legacy.ts | 39 --------------- .../public/np_ready/index.ts | 28 ----------- .../public/{np_ready => }/plugin.ts | 0 .../public/{np_ready => }/services.ts | 2 +- .../public/{np_ready => }/types.ts | 0 .../plugins/kbn_tp_run_pipeline/tsconfig.json | 14 ++++++ .../test_suites/run_pipeline/basic.ts | 9 ++-- .../test_suites/run_pipeline/helpers.ts | 13 ++++- test/scripts/jenkins_build_kibana.sh | 1 + test/tsconfig.json | 3 +- 18 files changed, 73 insertions(+), 125 deletions(-) delete mode 100644 test/interpreter_functional/plugins/kbn_tp_run_pipeline/index.ts create mode 100644 test/interpreter_functional/plugins/kbn_tp_run_pipeline/kibana.json rename test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/{np_ready => }/app/app.tsx (100%) rename test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/{np_ready => }/app/components/main.tsx (99%) delete mode 100644 test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/legacy.ts delete mode 100644 test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/index.ts rename test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/{np_ready => }/plugin.ts (100%) rename test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/{np_ready => }/services.ts (91%) rename test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/{np_ready => }/types.ts (100%) create mode 100644 test/interpreter_functional/plugins/kbn_tp_run_pipeline/tsconfig.json diff --git a/src/dev/typescript/projects.ts b/src/dev/typescript/projects.ts index a13f61af60173..5019c8bd22341 100644 --- a/src/dev/typescript/projects.ts +++ b/src/dev/typescript/projects.ts @@ -50,6 +50,9 @@ export const PROJECTS = [ ...glob .sync('test/plugin_functional/plugins/*/tsconfig.json', { cwd: REPO_ROOT }) .map(path => new Project(resolve(REPO_ROOT, path))), + ...glob + .sync('test/interpreter_functional/plugins/*/tsconfig.json', { cwd: REPO_ROOT }) + .map(path => new Project(resolve(REPO_ROOT, path))), ]; export function filterProjectsByFlag(projectFlag?: string) { diff --git a/test/interpreter_functional/config.ts b/test/interpreter_functional/config.ts index 0fe7df4d50715..d3cfcea9823e9 100644 --- a/test/interpreter_functional/config.ts +++ b/test/interpreter_functional/config.ts @@ -50,6 +50,9 @@ export default async function({ readConfigFile }: FtrConfigProviderContext) { ...functionalConfig.get('kbnTestServer'), serverArgs: [ ...functionalConfig.get('kbnTestServer.serverArgs'), + + // Required to load new platform plugins via `--plugin-path` flag. + '--env.name=development', ...plugins.map( pluginDir => `--plugin-path=${path.resolve(__dirname, 'plugins', pluginDir)}` ), diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/index.ts b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/index.ts deleted file mode 100644 index 1d5564ec06e4e..0000000000000 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/index.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import { Legacy } from 'kibana'; -import { - ArrayOrItem, - LegacyPluginApi, - LegacyPluginSpec, - LegacyPluginOptions, -} from 'src/legacy/plugin_discovery/types'; - -// eslint-disable-next-line import/no-default-export -export default function(kibana: LegacyPluginApi): ArrayOrItem { - const pluginSpec: Partial = { - id: 'kbn_tp_run_pipeline', - uiExports: { - app: { - title: 'Run Pipeline', - description: 'This is a sample plugin to test running pipeline expressions', - main: 'plugins/kbn_tp_run_pipeline/legacy', - }, - }, - - init(server: Legacy.Server) { - // The following lines copy over some configuration variables from Kibana - // to this plugin. This will be needed when embedding visualizations, so that e.g. - // region map is able to get its configuration. - server.injectUiAppVars('kbn_tp_run_pipeline', async () => { - return server.getInjectedUiAppVars('kibana'); - }); - }, - }; - return new kibana.Plugin(pluginSpec); -} diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/kibana.json b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/kibana.json new file mode 100644 index 0000000000000..f0c1c3a34fbc0 --- /dev/null +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/kibana.json @@ -0,0 +1,13 @@ +{ + "id": "kbn_tp_run_pipeline", + "version": "0.0.1", + "kibanaVersion": "kibana", + "requiredPlugins": [ + "data", + "savedObjects", + "kibanaUtils", + "expressions" + ], + "server": false, + "ui": true +} diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json index 338e85038922d..ebc74be937ef0 100644 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json @@ -1,6 +1,7 @@ { "name": "kbn_tp_run_pipeline", "version": "1.0.0", + "main": "target/test/interpreter_functional/plugins/kbn_tp_run_pipeline", "kibana": { "version": "kibana", "templateVersion": "1.0.0" @@ -10,5 +11,13 @@ "@elastic/eui": "22.3.1", "react": "^16.12.0", "react-dom": "^16.12.0" + }, + "scripts": { + "kbn": "node ../../../../scripts/kbn.js", + "build": "rm -rf './target' && tsc" + }, + "devDependencies": { + "@kbn/plugin-helpers": "9.0.2", + "typescript": "3.7.2" } } diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/app/app.tsx b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app/app.tsx similarity index 100% rename from test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/app/app.tsx rename to test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app/app.tsx diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/app/components/main.tsx b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app/components/main.tsx similarity index 99% rename from test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/app/components/main.tsx rename to test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app/components/main.tsx index a50248a5b6fa3..ace2af2b4f0cf 100644 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/app/components/main.tsx +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app/components/main.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { EuiPage, EuiPageBody, EuiPageContent, EuiPageContentHeader } from '@elastic/eui'; import { first } from 'rxjs/operators'; import { IInterpreterRenderHandlers, ExpressionValue } from 'src/plugins/expressions'; -import { RequestAdapter, DataAdapter } from '../../../../../../../../src/plugins/inspector'; +import { RequestAdapter, DataAdapter } from '../../../../../../../src/plugins/inspector'; import { Adapters, ExpressionRenderHandler } from '../../types'; import { getExpressions } from '../../services'; diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/index.ts b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/index.ts index c4cc7175d6157..d7a764b581c01 100644 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/index.ts +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/index.ts @@ -17,4 +17,12 @@ * under the License. */ -export * from './np_ready'; +import { PluginInitializer, PluginInitializerContext } from 'src/core/public'; +import { Plugin, StartDeps } from './plugin'; +export { StartDeps }; + +export const plugin: PluginInitializer = ( + initializerContext: PluginInitializerContext +) => { + return new Plugin(initializerContext); +}; diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/legacy.ts b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/legacy.ts deleted file mode 100644 index a7cd313038d69..0000000000000 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/legacy.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { PluginInitializerContext } from 'src/core/public'; -import { npSetup, npStart } from 'ui/new_platform'; - -import { plugin } from './np_ready'; - -// This is required so some default styles and required scripts/Angular modules are loaded, -// or the timezone setting is correctly applied. -import 'ui/autoload/all'; -// Used to run esaggs queries -import 'uiExports/fieldFormats'; -import 'uiExports/search'; -// Used for kibana_context function - -import 'uiExports/savedObjectTypes'; -import 'uiExports/interpreter'; - -const pluginInstance = plugin({} as PluginInitializerContext); - -export const setup = pluginInstance.setup(npSetup.core, npSetup.plugins); -export const start = pluginInstance.start(npStart.core, npStart.plugins); diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/index.ts b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/index.ts deleted file mode 100644 index d7a764b581c01..0000000000000 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { PluginInitializer, PluginInitializerContext } from 'src/core/public'; -import { Plugin, StartDeps } from './plugin'; -export { StartDeps }; - -export const plugin: PluginInitializer = ( - initializerContext: PluginInitializerContext -) => { - return new Plugin(initializerContext); -}; diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/plugin.ts b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/plugin.ts similarity index 100% rename from test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/plugin.ts rename to test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/plugin.ts diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/services.ts b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/services.ts similarity index 91% rename from test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/services.ts rename to test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/services.ts index a700727d87299..4972911d5894f 100644 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/services.ts +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/services.ts @@ -17,7 +17,7 @@ * under the License. */ -import { createGetterSetter } from '../../../../../../src/plugins/kibana_utils/public'; +import { createGetterSetter } from '../../../../../src/plugins/kibana_utils/public'; import { ExpressionsStart } from './types'; export const [getExpressions, setExpressions] = createGetterSetter('Expressions'); diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/types.ts b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/types.ts similarity index 100% rename from test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/np_ready/types.ts rename to test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/types.ts diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/tsconfig.json b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/tsconfig.json new file mode 100644 index 0000000000000..5fcaeafbb0d85 --- /dev/null +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../../../tsconfig.json", + "compilerOptions": { + "outDir": "./target", + "skipLibCheck": true + }, + "include": [ + "index.ts", + "public/**/*.ts", + "public/**/*.tsx", + "../../../../typings/**/*", + ], + "exclude": [] +} diff --git a/test/interpreter_functional/test_suites/run_pipeline/basic.ts b/test/interpreter_functional/test_suites/run_pipeline/basic.ts index a2172dd2da1ba..51ad789143c54 100644 --- a/test/interpreter_functional/test_suites/run_pipeline/basic.ts +++ b/test/interpreter_functional/test_suites/run_pipeline/basic.ts @@ -113,10 +113,11 @@ export default function({ await expectExpression('partial_test_2', metricExpr, context).toMatchSnapshot() ).toMatchScreenshot(); - const regionMapExpr = `regionmap visConfig='{"metric":{"accessor":1,"format":{"id":"number"}},"bucket":{"accessor":0}}'`; - await ( - await expectExpression('partial_test_3', regionMapExpr, context).toMatchSnapshot() - ).toMatchScreenshot(); + // TODO: should be uncommented when the region map is migrated to the new platform + // const regionMapExpr = `regionmap visConfig='{"metric":{"accessor":1,"format":{"id":"number"}},"bucket":{"accessor":0}}'`; + // await ( + // await expectExpression('partial_test_3', regionMapExpr, context).toMatchSnapshot() + // ).toMatchScreenshot(); }); }); }); diff --git a/test/interpreter_functional/test_suites/run_pipeline/helpers.ts b/test/interpreter_functional/test_suites/run_pipeline/helpers.ts index 00693845bb266..2486fb0e1fbd0 100644 --- a/test/interpreter_functional/test_suites/run_pipeline/helpers.ts +++ b/test/interpreter_functional/test_suites/run_pipeline/helpers.ts @@ -21,6 +21,17 @@ import expect from '@kbn/expect'; import { ExpressionValue } from 'src/plugins/expressions'; import { FtrProviderContext } from '../../../functional/ftr_provider_context'; +declare global { + interface Window { + runPipeline: ( + expressions: string, + context?: ExpressionValue, + initialContext?: ExpressionValue + ) => any; + renderPipelineResponse: (context?: ExpressionValue) => Promise; + } +} + export type ExpressionResult = any; export type ExpectExpression = ( @@ -165,7 +176,7 @@ export function expectExpressionProvider({ log.debug('starting to render'); const result = await browser.executeAsync( (_context: ExpressionResult, done: (renderResult: any) => void) => - window.renderPipelineResponse(_context).then(renderResult => { + window.renderPipelineResponse(_context).then((renderResult: any) => { done(renderResult); return renderResult; }), diff --git a/test/scripts/jenkins_build_kibana.sh b/test/scripts/jenkins_build_kibana.sh index 1f6e09fad19e9..e3f46e7a6ada4 100755 --- a/test/scripts/jenkins_build_kibana.sh +++ b/test/scripts/jenkins_build_kibana.sh @@ -6,6 +6,7 @@ echo " -> building kibana platform plugins" node scripts/build_kibana_platform_plugins \ --oss \ --scan-dir "$KIBANA_DIR/test/plugin_functional/plugins" \ + --scan-dir "$KIBANA_DIR/test/interpreter_functional/plugins" \ --verbose; # doesn't persist, also set in kibanaPipeline.groovy diff --git a/test/tsconfig.json b/test/tsconfig.json index 5a3716e620fed..a270144bd49fe 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -19,6 +19,7 @@ "typings/**/*" ], "exclude": [ - "plugin_functional/plugins/**/*" + "plugin_functional/plugins/**/*", + "interpreter_functional/plugins/**/*" ] } From 642b03b41d06c6613004c9ea82b6420498f2bda3 Mon Sep 17 00:00:00 2001 From: Alexey Antonov Date: Thu, 7 May 2020 10:56:36 +0300 Subject: [PATCH 06/23] [ESLint] update @kbn/eslint/no-restricted-paths rule to allow imports mocks from folder (#65471) --- .eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc.js b/.eslintrc.js index dde0ce010d4d4..56c06902e062b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -238,6 +238,7 @@ module.exports = { ], from: [ '(src|x-pack)/plugins/**/(public|server)/**/*', + '!(src|x-pack)/plugins/**/(public|server)/mocks/index.{js,ts}', '!(src|x-pack)/plugins/**/(public|server)/(index|mocks).{js,ts,tsx}', ], allowSameFolder: true, From 15eec5a9ee40ec2faa5d02c71c0adcaba58f3407 Mon Sep 17 00:00:00 2001 From: MadameSheema Date: Thu, 7 May 2020 09:59:04 +0200 Subject: [PATCH 07/23] [SIEM] Fixes test flakiness (#65510) * adds 'Configures a new connector' test * refactor code * updates configure_cases screen selectors * removes 'configure connector' test flakiness --- .../integration/cases_connectors.spec.ts | 47 +++++++++++++++++ x-pack/plugins/siem/cypress/objects/case.ts | 14 +++++ .../plugins/siem/cypress/screens/all_cases.ts | 2 + .../siem/cypress/screens/configure_cases.ts | 30 +++++++++++ .../plugins/siem/cypress/tasks/all_cases.ts | 10 +++- .../siem/cypress/tasks/configure_cases.ts | 52 +++++++++++++++++++ .../configure_cases/connectors_dropdown.tsx | 4 +- 7 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/siem/cypress/integration/cases_connectors.spec.ts create mode 100644 x-pack/plugins/siem/cypress/screens/configure_cases.ts create mode 100644 x-pack/plugins/siem/cypress/tasks/configure_cases.ts diff --git a/x-pack/plugins/siem/cypress/integration/cases_connectors.spec.ts b/x-pack/plugins/siem/cypress/integration/cases_connectors.spec.ts new file mode 100644 index 0000000000000..2d650b1bbd9d1 --- /dev/null +++ b/x-pack/plugins/siem/cypress/integration/cases_connectors.spec.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { serviceNowConnector } from '../objects/case'; + +import { TOASTER } from '../screens/configure_cases'; + +import { goToEditExternalConnection } from '../tasks/all_cases'; +import { + addServiceNowConnector, + openAddNewConnectorOption, + saveChanges, + selectLastConnectorCreated, +} from '../tasks/configure_cases'; +import { loginAndWaitForPageWithoutDateRange } from '../tasks/login'; + +import { CASES } from '../urls/navigation'; + +describe('Cases connectors', () => { + before(() => { + cy.server(); + cy.route('POST', '**/api/action').as('createConnector'); + cy.route('POST', '**/api/cases/configure').as('saveConnector'); + }); + + it('Configures a new connector', () => { + loginAndWaitForPageWithoutDateRange(CASES); + goToEditExternalConnection(); + openAddNewConnectorOption(); + addServiceNowConnector(serviceNowConnector); + + cy.wait('@createConnector') + .its('status') + .should('eql', 200); + cy.get(TOASTER).should('have.text', "Created 'New connector'"); + + selectLastConnectorCreated(); + saveChanges(); + + cy.wait('@saveConnector', { timeout: 10000 }) + .its('status') + .should('eql', 200); + cy.get(TOASTER).should('have.text', 'Saved external connection settings'); + }); +}); diff --git a/x-pack/plugins/siem/cypress/objects/case.ts b/x-pack/plugins/siem/cypress/objects/case.ts index 1c7bc34bca417..12d3f925169af 100644 --- a/x-pack/plugins/siem/cypress/objects/case.ts +++ b/x-pack/plugins/siem/cypress/objects/case.ts @@ -14,6 +14,13 @@ export interface TestCase { reporter: string; } +export interface Connector { + connectorName: string; + URL: string; + username: string; + password: string; +} + const caseTimeline: Timeline = { title: 'SIEM test', description: 'description', @@ -27,3 +34,10 @@ export const case1: TestCase = { timeline: caseTimeline, reporter: 'elastic', }; + +export const serviceNowConnector: Connector = { + connectorName: 'New connector', + URL: 'https://www.test.service-now.com', + username: 'Username Name', + password: 'password', +}; diff --git a/x-pack/plugins/siem/cypress/screens/all_cases.ts b/x-pack/plugins/siem/cypress/screens/all_cases.ts index b1e4c66515352..4fa6b69eea7c3 100644 --- a/x-pack/plugins/siem/cypress/screens/all_cases.ts +++ b/x-pack/plugins/siem/cypress/screens/all_cases.ts @@ -39,3 +39,5 @@ export const ALL_CASES_TAGS = (index: number) => { }; export const ALL_CASES_TAGS_COUNT = '[data-test-subj="options-filter-popover-button-Tags"]'; + +export const EDIT_EXTERNAL_CONNECTION = '[data-test-subj="configure-case-button"]'; diff --git a/x-pack/plugins/siem/cypress/screens/configure_cases.ts b/x-pack/plugins/siem/cypress/screens/configure_cases.ts new file mode 100644 index 0000000000000..5a1e897c43e27 --- /dev/null +++ b/x-pack/plugins/siem/cypress/screens/configure_cases.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const ADD_NEW_CONNECTOR_OPTION_LINK = + '[data-test-subj="case-configure-add-connector-button"]'; + +export const CONNECTOR = (id: string) => { + return `[data-test-subj='dropdown-connector-${id}']`; +}; + +export const CONNECTOR_NAME = '[data-test-subj="nameInput"]'; + +export const CONNECTORS_DROPDOWN = '[data-test-subj="dropdown-connectors"]'; + +export const PASSWORD = '[data-test-subj="connector-servicenow-password-form-input"]'; + +export const SAVE_BTN = '[data-test-subj="saveNewActionButton"]'; + +export const SAVE_CHANGES_BTN = '[data-test-subj="case-configure-action-bottom-bar-save-button"]'; + +export const SERVICE_NOW_CONNECTOR_CARD = '[data-test-subj=".servicenow-card"]'; + +export const TOASTER = '[data-test-subj="euiToastHeader"]'; + +export const URL = '[data-test-subj="apiUrlFromInput"]'; + +export const USERNAME = '[data-test-subj="connector-servicenow-username-form-input"]'; diff --git a/x-pack/plugins/siem/cypress/tasks/all_cases.ts b/x-pack/plugins/siem/cypress/tasks/all_cases.ts index f374532201324..8ebe35e173e59 100644 --- a/x-pack/plugins/siem/cypress/tasks/all_cases.ts +++ b/x-pack/plugins/siem/cypress/tasks/all_cases.ts @@ -4,7 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ALL_CASES_NAME, ALL_CASES_CREATE_NEW_CASE_BTN } from '../screens/all_cases'; +import { + ALL_CASES_NAME, + ALL_CASES_CREATE_NEW_CASE_BTN, + EDIT_EXTERNAL_CONNECTION, +} from '../screens/all_cases'; export const goToCreateNewCase = () => { cy.get(ALL_CASES_CREATE_NEW_CASE_BTN).click({ force: true }); @@ -13,3 +17,7 @@ export const goToCreateNewCase = () => { export const goToCaseDetails = () => { cy.get(ALL_CASES_NAME).click({ force: true }); }; + +export const goToEditExternalConnection = () => { + cy.get(EDIT_EXTERNAL_CONNECTION).click({ force: true }); +}; diff --git a/x-pack/plugins/siem/cypress/tasks/configure_cases.ts b/x-pack/plugins/siem/cypress/tasks/configure_cases.ts new file mode 100644 index 0000000000000..9172e02708ae7 --- /dev/null +++ b/x-pack/plugins/siem/cypress/tasks/configure_cases.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + ADD_NEW_CONNECTOR_OPTION_LINK, + CONNECTOR, + CONNECTOR_NAME, + CONNECTORS_DROPDOWN, + PASSWORD, + SAVE_BTN, + SAVE_CHANGES_BTN, + SERVICE_NOW_CONNECTOR_CARD, + URL, + USERNAME, +} from '../screens/configure_cases'; +import { MAIN_PAGE } from '../screens/siem_main'; + +import { Connector } from '../objects/case'; + +export const addServiceNowConnector = (connector: Connector) => { + cy.get(SERVICE_NOW_CONNECTOR_CARD).click(); + cy.get(CONNECTOR_NAME).type(connector.connectorName); + cy.get(URL).type(connector.URL); + cy.get(USERNAME).type(connector.username); + cy.get(PASSWORD).type(connector.password); + cy.get(SAVE_BTN).click({ force: true }); +}; + +export const openAddNewConnectorOption = () => { + cy.get(MAIN_PAGE).then($page => { + if ($page.find(SERVICE_NOW_CONNECTOR_CARD).length !== 1) { + cy.wait(1000); + cy.get(ADD_NEW_CONNECTOR_OPTION_LINK).click({ force: true }); + } + }); +}; + +export const saveChanges = () => { + cy.get(SAVE_CHANGES_BTN).click(); +}; + +export const selectLastConnectorCreated = () => { + cy.get(CONNECTORS_DROPDOWN).click({ force: true }); + cy.get('@createConnector') + .its('response') + .then(response => { + cy.get(CONNECTOR(response.body.id)).click(); + }); +}; diff --git a/x-pack/plugins/siem/public/pages/case/components/configure_cases/connectors_dropdown.tsx b/x-pack/plugins/siem/public/pages/case/components/configure_cases/connectors_dropdown.tsx index bfd26d3cf8e00..2f73c8c5dba05 100644 --- a/x-pack/plugins/siem/public/pages/case/components/configure_cases/connectors_dropdown.tsx +++ b/x-pack/plugins/siem/public/pages/case/components/configure_cases/connectors_dropdown.tsx @@ -65,9 +65,7 @@ const ConnectorsDropdownComponent: React.FC = ({ /> - - {connector.name} - + {connector.name} ), From 19ed83958f04374afbe9252fe08ca1065abc43ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Thu, 7 May 2020 09:00:11 +0100 Subject: [PATCH 08/23] [APM] Remove link from active page in the breadcrumb (#65473) --- .../{__test__ => }/ProvideBreadcrumbs.test.tsx | 4 ++-- .../components/app/Main/UpdateBreadcrumbs.tsx | 16 ++++++++++++---- .../UpdateBreadcrumbs.test.tsx.snap | 10 +++++----- 3 files changed, 19 insertions(+), 11 deletions(-) rename x-pack/plugins/apm/public/components/app/Main/{__test__ => }/ProvideBreadcrumbs.test.tsx (94%) diff --git a/x-pack/plugins/apm/public/components/app/Main/__test__/ProvideBreadcrumbs.test.tsx b/x-pack/plugins/apm/public/components/app/Main/ProvideBreadcrumbs.test.tsx similarity index 94% rename from x-pack/plugins/apm/public/components/app/Main/__test__/ProvideBreadcrumbs.test.tsx rename to x-pack/plugins/apm/public/components/app/Main/ProvideBreadcrumbs.test.tsx index cb983cdffa028..1e3a73acfab57 100644 --- a/x-pack/plugins/apm/public/components/app/Main/__test__/ProvideBreadcrumbs.test.tsx +++ b/x-pack/plugins/apm/public/components/app/Main/ProvideBreadcrumbs.test.tsx @@ -5,8 +5,8 @@ */ import { Location } from 'history'; -import { BreadcrumbRoute, getBreadcrumbs } from '../ProvideBreadcrumbs'; -import { RouteName } from '../route_config/route_names'; +import { BreadcrumbRoute, getBreadcrumbs } from './ProvideBreadcrumbs'; +import { RouteName } from './route_config/route_names'; describe('getBreadcrumbs', () => { const getTestRoutes = (): BreadcrumbRoute[] => [ diff --git a/x-pack/plugins/apm/public/components/app/Main/UpdateBreadcrumbs.tsx b/x-pack/plugins/apm/public/components/app/Main/UpdateBreadcrumbs.tsx index 8960af0f21fd2..b4a556c497c1b 100644 --- a/x-pack/plugins/apm/public/components/app/Main/UpdateBreadcrumbs.tsx +++ b/x-pack/plugins/apm/public/components/app/Main/UpdateBreadcrumbs.tsx @@ -30,10 +30,18 @@ function getTitleFromBreadCrumbs(breadcrumbs: Breadcrumb[]) { class UpdateBreadcrumbsComponent extends React.Component { public updateHeaderBreadcrumbs() { - const breadcrumbs = this.props.breadcrumbs.map(({ value, match }) => ({ - text: value, - href: getAPMHref(match.url, this.props.location.search) - })); + const breadcrumbs = this.props.breadcrumbs.map( + ({ value, match }, index) => { + const isLastBreadcrumbItem = + index === this.props.breadcrumbs.length - 1; + return { + text: value, + href: isLastBreadcrumbItem + ? undefined // makes the breadcrumb item not clickable + : getAPMHref(match.url, this.props.location.search) + }; + } + ); document.title = getTitleFromBreadCrumbs(this.props.breadcrumbs); this.props.core.chrome.setBreadcrumbs(breadcrumbs); diff --git a/x-pack/plugins/apm/public/components/app/Main/__snapshots__/UpdateBreadcrumbs.test.tsx.snap b/x-pack/plugins/apm/public/components/app/Main/__snapshots__/UpdateBreadcrumbs.test.tsx.snap index 51bdb63874e63..e7f6cba59318a 100644 --- a/x-pack/plugins/apm/public/components/app/Main/__snapshots__/UpdateBreadcrumbs.test.tsx.snap +++ b/x-pack/plugins/apm/public/components/app/Main/__snapshots__/UpdateBreadcrumbs.test.tsx.snap @@ -15,7 +15,7 @@ Array [ "text": "opbeans-node", }, Object { - "href": "#/services/opbeans-node/errors?rangeFrom=now-24h&rangeTo=now&refreshPaused=true&refreshInterval=0&kuery=myKuery", + "href": undefined, "text": "Errors", }, ] @@ -40,7 +40,7 @@ Array [ "text": "Errors", }, Object { - "href": "#/services/opbeans-node/errors/myGroupId?rangeFrom=now-24h&rangeTo=now&refreshPaused=true&refreshInterval=0&kuery=myKuery", + "href": undefined, "text": "myGroupId", }, ] @@ -61,7 +61,7 @@ Array [ "text": "opbeans-node", }, Object { - "href": "#/services/opbeans-node/transactions?rangeFrom=now-24h&rangeTo=now&refreshPaused=true&refreshInterval=0&kuery=myKuery", + "href": undefined, "text": "Transactions", }, ] @@ -86,7 +86,7 @@ Array [ "text": "Transactions", }, Object { - "href": "#/services/opbeans-node/transactions/view?rangeFrom=now-24h&rangeTo=now&refreshPaused=true&refreshInterval=0&kuery=myKuery", + "href": undefined, "text": "my-transaction-name", }, ] @@ -95,7 +95,7 @@ Array [ exports[`UpdateBreadcrumbs Homepage 1`] = ` Array [ Object { - "href": "#/?rangeFrom=now-24h&rangeTo=now&refreshPaused=true&refreshInterval=0&kuery=myKuery", + "href": undefined, "text": "APM", }, ] From d935600645f1ca205b7524fd640377ddd97a6ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Thu, 7 May 2020 09:00:40 +0100 Subject: [PATCH 09/23] [APM] Agent configuration: Bug makes it possible to create invalid configurations (#65508) * reset settings when navigate to choose-settings-step page * reset settings when navigate to choose-settings-step page * reset settings when navigate to choose-settings-step page --- .../AgentConfigurationCreateEdit/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/index.tsx index 3a6f94b975800..79a6370b4be46 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/index.tsx @@ -132,7 +132,10 @@ export function AgentConfigurationCreateEdit({ setPage('choose-settings-step')} + onClickNext={() => { + resetSettings(); + setPage('choose-settings-step'); + }} /> )} From be3f6ef8ed1f0aa18b633a4c4f7cf2d53bad282e Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 7 May 2020 10:30:28 +0200 Subject: [PATCH 10/23] [Uptime] Fix monitor list result runtime type, ip can be null (#65532) --- x-pack/plugins/uptime/common/runtime_types/monitor/state.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/uptime/common/runtime_types/monitor/state.ts b/x-pack/plugins/uptime/common/runtime_types/monitor/state.ts index 90aa692f89a42..b3c39e5180adf 100644 --- a/x-pack/plugins/uptime/common/runtime_types/monitor/state.ts +++ b/x-pack/plugins/uptime/common/runtime_types/monitor/state.ts @@ -9,7 +9,7 @@ import * as t from 'io-ts'; export const CheckMonitorType = t.intersection([ t.partial({ name: t.string, - ip: t.union([t.array(t.string), t.string]), + ip: t.union([t.array(t.union([t.string, t.null])), t.string, t.null]), }), t.type({ status: t.string, From 9734dafbfab4ef0673e56edba3342e2e354ecb5f Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 7 May 2020 10:31:02 +0200 Subject: [PATCH 11/23] [Uptime] Improve cert flaky test (#65458) --- x-pack/test/functional/apps/uptime/certificates.ts | 1 - x-pack/test/functional/services/uptime/navigation.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/x-pack/test/functional/apps/uptime/certificates.ts b/x-pack/test/functional/apps/uptime/certificates.ts index 05967e0f3acaf..59e9dda7b184f 100644 --- a/x-pack/test/functional/apps/uptime/certificates.ts +++ b/x-pack/test/functional/apps/uptime/certificates.ts @@ -25,7 +25,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); it('can navigate to cert page', async () => { - await uptimeService.navigation.refreshApp(); await uptimeService.cert.hasViewCertButton(); await uptimeService.navigation.goToCertificates(); }); diff --git a/x-pack/test/functional/services/uptime/navigation.ts b/x-pack/test/functional/services/uptime/navigation.ts index 13d3cc62183bd..37cc71d6865b0 100644 --- a/x-pack/test/functional/services/uptime/navigation.ts +++ b/x-pack/test/functional/services/uptime/navigation.ts @@ -65,8 +65,8 @@ export function UptimeNavigationProvider({ getService, getPageObjects }: FtrProv }, goToCertificates: async () => { - await testSubjects.click('uptimeCertificatesLink'); - return retry.tryForTime(30 * 1000, async () => { + await testSubjects.click('uptimeCertificatesLink', 10000); + return retry.tryForTime(60 * 1000, async () => { await testSubjects.existOrFail('uptimeCertificatesPage'); }); }, From 3f3d5f9666f1dd3607de0c78e4a15c54a9fea09d Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Thu, 7 May 2020 10:32:30 +0200 Subject: [PATCH 12/23] fix SavedObjectMigrationMap type (#65569) --- .../kibana-plugin-plugins-data-server.iindexpattern.md | 6 ++++++ src/core/server/saved_objects/migrations/types.ts | 2 +- src/core/server/server.api.md | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iindexpattern.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iindexpattern.md index 24b56a9b98621..a79244a24acf5 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iindexpattern.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iindexpattern.md @@ -21,3 +21,9 @@ export interface IIndexPattern | [title](./kibana-plugin-plugins-data-server.iindexpattern.title.md) | string | | | [type](./kibana-plugin-plugins-data-server.iindexpattern.type.md) | string | | +## Methods + +| Method | Description | +| --- | --- | +| [getTimeField()](./kibana-plugin-plugins-data-server.iindexpattern.gettimefield.md) | | + diff --git a/src/core/server/saved_objects/migrations/types.ts b/src/core/server/saved_objects/migrations/types.ts index 85f15b4c18b66..5e55a34193a96 100644 --- a/src/core/server/saved_objects/migrations/types.ts +++ b/src/core/server/saved_objects/migrations/types.ts @@ -88,5 +88,5 @@ export interface SavedObjectMigrationContext { * @public */ export interface SavedObjectMigrationMap { - [version: string]: SavedObjectMigrationFn; + [version: string]: SavedObjectMigrationFn; } diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 62d11ee7cf9a7..bd6046b5ec281 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1735,7 +1735,7 @@ export type SavedObjectMigrationFn; } // @public From f53b1470974257a985d28fb14bfc4901c271f411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez?= Date: Thu, 7 May 2020 11:15:47 +0200 Subject: [PATCH 13/23] [Logs UI] Disable search bar when live stream is on. (#65491) --- .../components/autocomplete_field/autocomplete_field.tsx | 3 +++ x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx | 1 + 2 files changed, 4 insertions(+) diff --git a/x-pack/plugins/infra/public/components/autocomplete_field/autocomplete_field.tsx b/x-pack/plugins/infra/public/components/autocomplete_field/autocomplete_field.tsx index 2abef7d71e65a..6bbd67ce932c6 100644 --- a/x-pack/plugins/infra/public/components/autocomplete_field/autocomplete_field.tsx +++ b/x-pack/plugins/infra/public/components/autocomplete_field/autocomplete_field.tsx @@ -26,6 +26,7 @@ interface AutocompleteFieldProps { placeholder?: string; suggestions: QuerySuggestion[]; value: string; + disabled?: boolean; autoFocus?: boolean; 'aria-label'?: string; } @@ -55,6 +56,7 @@ export class AutocompleteField extends React.Component< isValid, placeholder, value, + disabled, 'aria-label': ariaLabel, } = this.props; const { areSuggestionsVisible, selectedIndex } = this.state; @@ -64,6 +66,7 @@ export class AutocompleteField extends React.Component< { isLoadingSuggestions={isLoadingSuggestions} isValid={isFilterQueryDraftValid} loadSuggestions={loadSuggestions} + disabled={isStreaming} onChange={(expression: string) => { setSurroundingLogsId(null); setLogFilterQueryDraft(expression); From 8a8647ab951282bf61d490702b22b60a55af2309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20St=C3=BCrmer?= Date: Thu, 7 May 2020 11:33:50 +0200 Subject: [PATCH 14/23] [Logs + Metrics UI] Prevent component errors from breaking the whole UI (#65456) --- .../pages/logs/log_entry_categories/page.tsx | 14 +- .../public/pages/logs/log_entry_rate/page.tsx | 14 +- .../plugins/infra/public/pages/logs/page.tsx | 12 +- .../source_configuration_settings.tsx | 5 +- .../infra/public/pages/logs/stream/page.tsx | 15 +- .../infra/public/pages/metrics/index.tsx | 194 +++++++++--------- .../pages/metrics/inventory_view/index.tsx | 121 +++++------ .../metrics/metric_detail/page_providers.tsx | 14 +- .../pages/metrics/metrics_explorer/index.tsx | 12 +- .../infra/public/pages/metrics/settings.tsx | 13 +- 10 files changed, 218 insertions(+), 196 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page.tsx index 64e83a6eaa497..ad7893183c4df 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page.tsx @@ -4,18 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EuiErrorBoundary } from '@elastic/eui'; import React from 'react'; - import { ColumnarPage } from '../../../components/page'; import { LogEntryCategoriesPageContent } from './page_content'; import { LogEntryCategoriesPageProviders } from './page_providers'; export const LogEntryCategoriesPage = () => { return ( - - - - - + + + + + + + ); }; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page.tsx index 5ff5cd4db7168..16751fabd6e96 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page.tsx @@ -4,18 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EuiErrorBoundary } from '@elastic/eui'; import React from 'react'; - import { ColumnarPage } from '../../../components/page'; import { LogEntryRatePageContent } from './page_content'; import { LogEntryRatePageProviders } from './page_providers'; export const LogEntryRatePage = () => { return ( - - - - - + + + + + + + ); }; diff --git a/x-pack/plugins/infra/public/pages/logs/page.tsx b/x-pack/plugins/infra/public/pages/logs/page.tsx index 08049183d0a18..018f89fbb23c4 100644 --- a/x-pack/plugins/infra/public/pages/logs/page.tsx +++ b/x-pack/plugins/infra/public/pages/logs/page.tsx @@ -4,16 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EuiErrorBoundary } from '@elastic/eui'; import React from 'react'; import { RouteComponentProps } from 'react-router-dom'; - import { LogsPageContent } from './page_content'; import { LogsPageProviders } from './page_providers'; -export const LogsPage: React.FunctionComponent = ({ match }) => { +export const LogsPage: React.FunctionComponent = () => { return ( - - - + + + + + ); }; diff --git a/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx b/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx index 88b1441f0ba7c..363b1b7627104 100644 --- a/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx +++ b/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx @@ -7,6 +7,7 @@ import { EuiButton, EuiCallOut, + EuiErrorBoundary, EuiFlexGroup, EuiFlexItem, EuiPanel, @@ -74,7 +75,7 @@ export const LogsSettingsPage = () => { } return ( - <> + { - + ); }; diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page.tsx index 712d625052140..bc25d7c49b129 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page.tsx @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EuiErrorBoundary } from '@elastic/eui'; import React from 'react'; import { useTrackPageview } from '../../../../../observability/public'; import { ColumnarPage } from '../../../components/page'; @@ -15,11 +16,13 @@ export const StreamPage = () => { useTrackPageview({ app: 'infra_logs', path: 'stream' }); useTrackPageview({ app: 'infra_logs', path: 'stream', delay: 15000 }); return ( - - - - - - + + + + + + + + ); }; diff --git a/x-pack/plugins/infra/public/pages/metrics/index.tsx b/x-pack/plugins/infra/public/pages/metrics/index.tsx index dbf71665ea869..91362d9098e34 100644 --- a/x-pack/plugins/infra/public/pages/metrics/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/index.tsx @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { Route, RouteComponentProps, Switch } from 'react-router-dom'; -import { EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; +import { EuiErrorBoundary, EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; import { DocumentTitle } from '../../components/document_title'; import { HelpCenterContent } from '../../components/help_center_content'; import { RoutedTabs } from '../../components/navigation/routed_tabs'; @@ -36,103 +36,105 @@ export const InfrastructurePage = ({ match }: RouteComponentProps) => { const uiCapabilities = useKibana().services.application?.capabilities; return ( - - - - - - - - + + + + + + + -

- - - - - - - - - - - + - - - ( - - {({ configuration, createDerivedIndexPattern }) => ( - - - {configuration ? ( - - ) : ( - - )} - - )} - - )} +
- - - - - - - + + + + + + + + + + + + + + + ( + + {({ configuration, createDerivedIndexPattern }) => ( + + + {configuration ? ( + + ) : ( + + )} + + )} + + )} + /> + + + + + + + + ); }; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx index 3a2c33d1c824c..ebb8243369b3c 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiButton, EuiErrorBoundary, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useContext } from 'react'; @@ -41,65 +41,70 @@ export const SnapshotPage = () => { }); return ( - - - i18n.translate('xpack.infra.infrastructureSnapshotPage.documentTitle', { - defaultMessage: '{previousTitle} | Inventory', - values: { - previousTitle, - }, - }) - } - /> - {isLoading ? ( - - ) : metricIndicesExist ? ( - <> - - - - ) : hasFailedLoadingSource ? ( - - ) : ( - - - - {i18n.translate('xpack.infra.homePage.noMetricsIndicesInstructionsActionLabel', { - defaultMessage: 'View setup instructions', - })} - - - {uiCapabilities?.infrastructure?.configureSource ? ( + + + + i18n.translate('xpack.infra.infrastructureSnapshotPage.documentTitle', { + defaultMessage: '{previousTitle} | Inventory', + values: { + previousTitle, + }, + }) + } + /> + {isLoading ? ( + + ) : metricIndicesExist ? ( + <> + + + + ) : hasFailedLoadingSource ? ( + + ) : ( + - - {i18n.translate('xpack.infra.configureSourceActionLabel', { - defaultMessage: 'Change source configuration', - })} - + {i18n.translate( + 'xpack.infra.homePage.noMetricsIndicesInstructionsActionLabel', + { + defaultMessage: 'View setup instructions', + } + )} + - ) : null} - - } - data-test-subj="noMetricsIndicesPrompt" - /> - )} - + {uiCapabilities?.infrastructure?.configureSource ? ( + + + {i18n.translate('xpack.infra.configureSourceActionLabel', { + defaultMessage: 'Change source configuration', + })} + + + ) : null} + + } + data-test-subj="noMetricsIndicesPrompt" + /> + )} + + ); }; diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/page_providers.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/page_providers.tsx index 597977d9d2735..dcd1c1d949971 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/page_providers.tsx @@ -4,17 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EuiErrorBoundary } from '@elastic/eui'; import React from 'react'; - import { Source } from '../../../containers/source'; import { MetricsTimeProvider } from './hooks/use_metrics_time'; export const withMetricPageProviders = (Component: React.ComponentType) => ( props: T ) => ( - - - - - + + + + + + + ); diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx index a213671e9436e..8b703b1177c8c 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx @@ -4,17 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EuiErrorBoundary } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; - import React from 'react'; import { IIndexPattern } from 'src/plugins/data/public'; +import { useTrackPageview } from '../../../../../observability/public'; +import { SourceQuery } from '../../../../common/graphql/types'; import { DocumentTitle } from '../../../components/document_title'; +import { NoData } from '../../../components/empty_states'; import { MetricsExplorerCharts } from './components/charts'; import { MetricsExplorerToolbar } from './components/toolbar'; -import { SourceQuery } from '../../../../common/graphql/types'; -import { NoData } from '../../../components/empty_states'; import { useMetricsExplorerState } from './hooks/use_metric_explorer_state'; -import { useTrackPageview } from '../../../../../observability/public'; interface MetricsExplorerPageProps { source: SourceQuery.Query['source']['configuration']; @@ -45,7 +45,7 @@ export const MetricsExplorerPage = ({ source, derivedIndexPattern }: MetricsExpl useTrackPageview({ app: 'infra_metrics', path: 'metrics_explorer', delay: 15000 }); return ( - + i18n.translate('xpack.infra.infrastructureMetricsExplorerPage.documentTitle', { @@ -95,6 +95,6 @@ export const MetricsExplorerPage = ({ source, derivedIndexPattern }: MetricsExpl onTimeChange={handleTimeChange} /> )} - + ); }; diff --git a/x-pack/plugins/infra/public/pages/metrics/settings.tsx b/x-pack/plugins/infra/public/pages/metrics/settings.tsx index 9414eb7d3e564..7d4f35b19da7d 100644 --- a/x-pack/plugins/infra/public/pages/metrics/settings.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/settings.tsx @@ -4,16 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EuiErrorBoundary } from '@elastic/eui'; import React from 'react'; -import { SourceConfigurationSettings } from '../../components/source_configuration/source_configuration_settings'; import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; +import { SourceConfigurationSettings } from '../../components/source_configuration/source_configuration_settings'; export const MetricsSettingsPage = () => { const uiCapabilities = useKibana().services.application?.capabilities; return ( - + + + ); }; From 83a088cb499a90daa76162237b459c80f4fedfe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Thu, 7 May 2020 11:47:50 +0200 Subject: [PATCH 15/23] =?UTF-8?q?[Mappings=20editor]=C2=A0Add=20component?= =?UTF-8?q?=20integration=20tests=20(#63853)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__jest__/components/index_table.test.js | 9 + .../client_integration/datatypes/index.ts | 8 + .../datatypes/shape_datatype.test.tsx | 81 ++++ .../datatypes/text_datatype.test.tsx | 459 ++++++++++++++++++ .../client_integration/edit_field.test.tsx | 127 +++++ .../client_integration/helpers/index.ts | 11 +- .../helpers/mappings_editor.helpers.tsx | 228 ++++++++- .../client_integration/mapped_fields.test.tsx | 104 ++++ .../mappings_editor.test.tsx | 252 +++++++++- .../configuration_form/configuration_form.tsx | 15 +- .../dynamic_mapping_section.tsx | 2 + .../meta_field_section/meta_field_section.tsx | 1 + .../configuration_form/routing_section.tsx | 6 +- .../source_field_section.tsx | 6 +- .../field_parameters/analyzer_parameter.tsx | 16 +- .../analyzer_parameter_selects.tsx | 11 +- .../field_parameters/analyzers_parameter.tsx | 7 + .../field_parameters/index_parameter.tsx | 1 + .../advanced_parameters_section.tsx | 4 +- .../fields/edit_field/edit_field.tsx | 5 +- .../fields/edit_field/edit_field_form_row.tsx | 18 +- .../document_fields/fields/fields_list.tsx | 2 +- .../fields/fields_list_item.tsx | 22 +- .../templates_form/templates_form.tsx | 10 +- .../mappings_editor/lib/utils.test.ts | 47 +- .../components/mappings_editor/lib/utils.ts | 43 +- .../mappings_editor/mappings_editor.tsx | 22 +- .../mappings_editor/mappings_state.tsx | 42 +- .../template_form/steps/step_mappings.tsx | 4 +- x-pack/test_utils/testbed/testbed.ts | 42 +- x-pack/test_utils/testbed/types.ts | 25 +- 31 files changed, 1513 insertions(+), 117 deletions(-) create mode 100644 x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/index.ts create mode 100644 x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/shape_datatype.test.tsx create mode 100644 x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/text_datatype.test.tsx create mode 100644 x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/edit_field.test.tsx create mode 100644 x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mapped_fields.test.tsx diff --git a/x-pack/plugins/index_management/__jest__/components/index_table.test.js b/x-pack/plugins/index_management/__jest__/components/index_table.test.js index 15c3ef0b84562..84fbc04aa5a31 100644 --- a/x-pack/plugins/index_management/__jest__/components/index_table.test.js +++ b/x-pack/plugins/index_management/__jest__/components/index_table.test.js @@ -8,6 +8,15 @@ import React from 'react'; import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; import { MemoryRouter } from 'react-router-dom'; + +/** + * The below import is required to avoid a console error warn from brace package + * console.warn ../node_modules/brace/index.js:3999 + Could not load worker ReferenceError: Worker is not defined + at createWorker (//node_modules/brace/index.js:17992:5) + */ +import * as stubWebWorker from '../../../../test_utils/stub_web_worker'; // eslint-disable-line no-unused-vars + import { AppWithoutRouter } from '../../public/application/app'; import { AppContextProvider } from '../../public/application/app_context'; import { Provider } from 'react-redux'; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/index.ts new file mode 100644 index 0000000000000..eac68770d3de2 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { defaultShapeParameters } from './shape_datatype.test'; +export { defaultTextParameters } from './text_datatype.test'; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/shape_datatype.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/shape_datatype.test.tsx new file mode 100644 index 0000000000000..19bf6973472ff --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/shape_datatype.test.tsx @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { act } from 'react-dom/test-utils'; + +import { componentHelpers, MappingsEditorTestBed } from '../helpers'; + +const { setup, getMappingsEditorDataFactory } = componentHelpers.mappingsEditor; +const onChangeHandler = jest.fn(); +const getMappingsEditorData = getMappingsEditorDataFactory(onChangeHandler); + +// Parameters automatically added to the shape datatype when saved (with the default values) +export const defaultShapeParameters = { + type: 'shape', + coerce: false, + ignore_malformed: false, + ignore_z_value: true, +}; + +describe('Mappings editor: shape datatype', () => { + let testBed: MappingsEditorTestBed; + + /** + * Variable to store the mappings data forwarded to the consumer component + */ + let data: any; + + test('initial view and default parameters values', async () => { + const defaultMappings = { + _meta: {}, + _source: {}, + properties: { + myField: { + type: 'shape', + }, + }, + }; + + const updatedMappings = { ...defaultMappings }; + + await act(async () => { + testBed = await setup({ value: defaultMappings, onChange: onChangeHandler }); + }); + + const { + exists, + waitFor, + waitForFn, + actions: { startEditField, updateFieldAndCloseFlyout }, + } = testBed; + + // Open the flyout to edit the field + await act(async () => { + startEditField('myField'); + }); + + await waitFor('mappingsEditorFieldEdit'); + + // Save the field and close the flyout + await act(async () => { + await updateFieldAndCloseFlyout(); + }); + + await waitForFn( + async () => exists('mappingsEditorFieldEdit') === false, + 'Error waiting for the details flyout to close' + ); + + // It should have the default parameters values added + updatedMappings.properties.myField = { + type: 'shape', + ...defaultShapeParameters, + }; + + ({ data } = await getMappingsEditorData()); + expect(data).toEqual(updatedMappings); + }); +}); diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/text_datatype.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/text_datatype.test.tsx new file mode 100644 index 0000000000000..2bfaa884a0132 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/text_datatype.test.tsx @@ -0,0 +1,459 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { act } from 'react-dom/test-utils'; + +import { componentHelpers, MappingsEditorTestBed } from '../helpers'; +import { getFieldConfig } from '../../../lib'; + +const { setup, getMappingsEditorDataFactory } = componentHelpers.mappingsEditor; +const onChangeHandler = jest.fn(); +const getMappingsEditorData = getMappingsEditorDataFactory(onChangeHandler); + +// Parameters automatically added to the text datatype when saved (with the default values) +export const defaultTextParameters = { + type: 'text', + eager_global_ordinals: false, + fielddata: false, + index: true, + index_options: 'positions', + index_phrases: false, + norms: true, + store: false, +}; + +describe('Mappings editor: text datatype', () => { + let testBed: MappingsEditorTestBed; + + /** + * Variable to store the mappings data forwarded to the consumer component + */ + let data: any; + + afterEach(() => { + onChangeHandler.mockReset(); + }); + + test('initial view and default parameters values', async () => { + const defaultMappings = { + _meta: {}, + _source: {}, + properties: { + myField: { + type: 'text', + }, + }, + }; + + const updatedMappings = { ...defaultMappings }; + + await act(async () => { + testBed = await setup({ value: defaultMappings, onChange: onChangeHandler }); + }); + + const { + exists, + waitFor, + waitForFn, + actions: { startEditField, getToggleValue, updateFieldAndCloseFlyout }, + } = testBed; + + // Open the flyout to edit the field + await act(async () => { + startEditField('myField'); + }); + + await waitFor('mappingsEditorFieldEdit'); + + // It should have searchable ("index" param) active by default + const indexFieldConfig = getFieldConfig('index'); + expect(getToggleValue('indexParameter.formRowToggle')).toBe(indexFieldConfig.defaultValue); + + // Save the field and close the flyout + await act(async () => { + updateFieldAndCloseFlyout(); + }); + + await waitForFn( + async () => exists('mappingsEditorFieldEdit') === false, + 'Error waiting for the details flyout to close' + ); + + // It should have the default parameters values added + updatedMappings.properties.myField = { + type: 'text', + ...defaultTextParameters, + }; + + ({ data } = await getMappingsEditorData()); + expect(data).toEqual(updatedMappings); + }, 30000); + + test('analyzer parameter: default values', async () => { + const defaultMappings = { + _meta: {}, + _source: {}, + properties: { + myField: { + type: 'text', + // Should have 2 dropdown selects: + // The first one set to 'language' and the second one set to 'french + search_quote_analyzer: 'french', + }, + }, + }; + + testBed = await setup({ value: defaultMappings, onChange: onChangeHandler }); + + const { + find, + exists, + waitFor, + waitForFn, + form: { selectCheckBox, setSelectValue }, + actions: { + startEditField, + getCheckboxValue, + showAdvancedSettings, + updateFieldAndCloseFlyout, + }, + } = testBed; + const fieldToEdit = 'myField'; + + // Start edit and immediately save to have all the default values + await act(async () => { + startEditField(fieldToEdit); + }); + await waitFor('mappingsEditorFieldEdit'); + await showAdvancedSettings(); + + await act(async () => { + updateFieldAndCloseFlyout(); + }); + + await waitForFn( + async () => exists('mappingsEditorFieldEdit') === false, + 'Error waiting for the details flyout to close' + ); + + ({ data } = await getMappingsEditorData()); + + let updatedMappings: any = { + ...defaultMappings, + properties: { + myField: { + ...defaultMappings.properties.myField, + ...defaultTextParameters, + }, + }, + }; + expect(data).toEqual(updatedMappings); + + // Re-open the edit panel + await act(async () => { + startEditField('myField'); + }); + await waitFor('mappingsEditorFieldEdit'); + await showAdvancedSettings(); + + // When no analyzer is defined, defaults to "Index default" + let indexAnalyzerValue = find('indexAnalyzer.select').props().value; + expect(indexAnalyzerValue).toEqual('index_default'); + + const searchQuoteAnalyzerSelects = find('searchQuoteAnalyzer.select'); + + expect(searchQuoteAnalyzerSelects.length).toBe(2); + expect(searchQuoteAnalyzerSelects.at(0).props().value).toBe('language'); + expect(searchQuoteAnalyzerSelects.at(1).props().value).toBe( + defaultMappings.properties.myField.search_quote_analyzer + ); + + // When no "search_analyzer" is defined, the checkBox should be checked + let isUseSameAnalyzerForSearchChecked = getCheckboxValue( + 'useSameAnalyzerForSearchCheckBox.input' + ); + expect(isUseSameAnalyzerForSearchChecked).toBe(true); + + // And the search analyzer select should not exist + expect(exists('searchAnalyzer')).toBe(false); + + // Uncheck the "Use same analyzer for search" checkbox and wait for the search analyzer select + await act(async () => { + selectCheckBox('useSameAnalyzerForSearchCheckBox.input', false); + }); + + await waitFor('searchAnalyzer'); + + let searchAnalyzerValue = find('searchAnalyzer.select').props().value; + expect(searchAnalyzerValue).toEqual('index_default'); + + await act(async () => { + // Change the value of the 3 analyzers + setSelectValue('indexAnalyzer.select', 'standard'); + setSelectValue('searchAnalyzer.select', 'simple'); + setSelectValue(find('searchQuoteAnalyzer.select').at(0), 'whitespace'); + }); + + // Make sure the second dropdown select has been removed + await waitForFn( + async () => find('searchQuoteAnalyzer.select').length === 1, + 'Error waiting for the second dropdown select of search quote analyzer to be removed' + ); + + await act(async () => { + // Save & close + updateFieldAndCloseFlyout(); + }); + + await waitForFn( + async () => exists('mappingsEditorFieldEdit') === false, + 'Error waiting for the details flyout to close' + ); + + updatedMappings = { + ...updatedMappings, + properties: { + myField: { + ...updatedMappings.properties.myField, + analyzer: 'standard', + search_analyzer: 'simple', + search_quote_analyzer: 'whitespace', + }, + }, + }; + + ({ data } = await getMappingsEditorData()); + expect(data).toEqual(updatedMappings); + + // Re-open the flyout and make sure the select have the correct updated value + await act(async () => { + startEditField('myField'); + }); + await waitFor('mappingsEditorFieldEdit'); + await showAdvancedSettings(); + + isUseSameAnalyzerForSearchChecked = getCheckboxValue('useSameAnalyzerForSearchCheckBox.input'); + expect(isUseSameAnalyzerForSearchChecked).toBe(false); + + indexAnalyzerValue = find('indexAnalyzer.select').props().value; + searchAnalyzerValue = find('searchAnalyzer.select').props().value; + const searchQuoteAnalyzerValue = find('searchQuoteAnalyzer.select').props().value; + + expect(indexAnalyzerValue).toBe('standard'); + expect(searchAnalyzerValue).toBe('simple'); + expect(searchQuoteAnalyzerValue).toBe('whitespace'); + }, 30000); + + test('analyzer parameter: custom analyzer (external plugin)', async () => { + const defaultMappings = { + _meta: {}, + _source: {}, + properties: { + myField: { + type: 'text', + analyzer: 'myCustomIndexAnalyzer', + search_analyzer: 'myCustomSearchAnalyzer', + search_quote_analyzer: 'myCustomSearchQuoteAnalyzer', + }, + }, + }; + + let updatedMappings: any = { + ...defaultMappings, + properties: { + myField: { + ...defaultMappings.properties.myField, + ...defaultTextParameters, + }, + }, + }; + + await act(async () => { + testBed = await setup({ value: defaultMappings, onChange: onChangeHandler }); + }); + + const { + find, + exists, + waitFor, + waitForFn, + component, + form: { setInputValue, setSelectValue }, + actions: { startEditField, showAdvancedSettings, updateFieldAndCloseFlyout }, + } = testBed; + const fieldToEdit = 'myField'; + + await act(async () => { + startEditField(fieldToEdit); + }); + + await waitFor('mappingsEditorFieldEdit'); + await showAdvancedSettings(); + + expect(exists('indexAnalyzer-custom')).toBe(true); + expect(exists('searchAnalyzer-custom')).toBe(true); + expect(exists('searchQuoteAnalyzer-custom')).toBe(true); + + const indexAnalyzerValue = find('indexAnalyzer-custom.input').props().value; + const searchAnalyzerValue = find('searchAnalyzer-custom.input').props().value; + const searchQuoteAnalyzerValue = find('searchQuoteAnalyzer-custom.input').props().value; + + expect(indexAnalyzerValue).toBe(defaultMappings.properties.myField.analyzer); + expect(searchAnalyzerValue).toBe(defaultMappings.properties.myField.search_analyzer); + expect(searchQuoteAnalyzerValue).toBe(defaultMappings.properties.myField.search_quote_analyzer); + + const updatedIndexAnalyzer = 'newCustomIndexAnalyzer'; + const updatedSearchAnalyzer = 'whitespace'; + + await act(async () => { + // Change the index analyzer to another custom one + setInputValue('indexAnalyzer-custom.input', updatedIndexAnalyzer); + + // Change the search analyzer to a built-in analyzer + find('searchAnalyzer-toggleCustomButton').simulate('click'); + component.update(); + }); + + await waitFor('searchAnalyzer'); + + await act(async () => { + setSelectValue('searchAnalyzer.select', updatedSearchAnalyzer); + + // Change the searchQuote to use built-in analyzer + // By default it means using the "index default" + find('searchQuoteAnalyzer-toggleCustomButton').simulate('click'); + component.update(); + }); + + await waitFor('searchQuoteAnalyzer'); + + await act(async () => { + // Save & close + updateFieldAndCloseFlyout(); + }); + + await waitForFn( + async () => exists('mappingsEditorFieldEdit') === false, + 'Error waiting for the details flyout to close' + ); + + ({ data } = await getMappingsEditorData()); + + updatedMappings = { + ...updatedMappings, + properties: { + myField: { + ...updatedMappings.properties.myField, + analyzer: updatedIndexAnalyzer, + search_analyzer: updatedSearchAnalyzer, + search_quote_analyzer: undefined, // Index default means not declaring the analyzer + }, + }, + }; + + expect(data).toEqual(updatedMappings); + }, 30000); + + test('analyzer parameter: custom analyzer (from index settings)', async () => { + const indexSettings = { + analysis: { + analyzer: { + customAnalyzer_1: {}, + customAnalyzer_2: {}, + customAnalyzer_3: {}, + }, + }, + }; + + const customAnalyzers = Object.keys(indexSettings.analysis.analyzer); + + const defaultMappings = { + _meta: {}, + _source: {}, + properties: { + myField: { + type: 'text', + analyzer: customAnalyzers[0], + }, + }, + }; + + let updatedMappings: any = { + ...defaultMappings, + properties: { + myField: { + ...defaultMappings.properties.myField, + ...defaultTextParameters, + }, + }, + }; + + testBed = await setup({ + value: defaultMappings, + onChange: onChangeHandler, + indexSettings, + }); + + const { + find, + exists, + waitFor, + waitForFn, + form: { setSelectValue }, + actions: { startEditField, showAdvancedSettings, updateFieldAndCloseFlyout }, + } = testBed; + const fieldToEdit = 'myField'; + + await act(async () => { + startEditField(fieldToEdit); + }); + await waitFor('mappingsEditorFieldEdit'); + await showAdvancedSettings(); + + // It should have 2 selects + const indexAnalyzerSelects = find('indexAnalyzer.select'); + + expect(indexAnalyzerSelects.length).toBe(2); + expect(indexAnalyzerSelects.at(0).props().value).toBe('custom'); + expect(indexAnalyzerSelects.at(1).props().value).toBe( + defaultMappings.properties.myField.analyzer + ); + + // Access the list of option of the second dropdown select + const subSelectOptions = indexAnalyzerSelects + .at(1) + .find('option') + .map(wrapper => wrapper.text()); + + expect(subSelectOptions).toEqual(customAnalyzers); + + await act(async () => { + // Change the custom analyzer dropdown to another one from the index settings + setSelectValue(find('indexAnalyzer.select').at(1), customAnalyzers[2]); + + // Save & close + updateFieldAndCloseFlyout(); + }); + + await waitForFn( + async () => exists('mappingsEditorFieldEdit') === false, + 'Error waiting for the details flyout to close' + ); + + ({ data } = await getMappingsEditorData()); + + updatedMappings = { + ...updatedMappings, + properties: { + myField: { + ...updatedMappings.properties.myField, + analyzer: customAnalyzers[2], + }, + }, + }; + + expect(data).toEqual(updatedMappings); + }, 30000); +}); diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/edit_field.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/edit_field.test.tsx new file mode 100644 index 0000000000000..4af5f82d851e3 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/edit_field.test.tsx @@ -0,0 +1,127 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { act } from 'react-dom/test-utils'; + +import { componentHelpers, MappingsEditorTestBed } from './helpers'; +import { defaultTextParameters, defaultShapeParameters } from './datatypes'; +const { setup, getMappingsEditorDataFactory } = componentHelpers.mappingsEditor; +const onChangeHandler = jest.fn(); +const getMappingsEditorData = getMappingsEditorDataFactory(onChangeHandler); + +describe('Mappings editor: edit field', () => { + let testBed: MappingsEditorTestBed; + + afterEach(() => { + onChangeHandler.mockReset(); + }); + + test('should open a flyout with the correct field to edit', async () => { + const defaultMappings = { + properties: { + user: { + type: 'object', + properties: { + address: { + type: 'object', + properties: { + street: { type: 'text' }, + }, + }, + }, + }, + }, + }; + + await act(async () => { + testBed = await setup({ value: defaultMappings, onChange: onChangeHandler }); + // Make sure all the fields are expanded and present in the DOM + await testBed.actions.expandAllFieldsAndReturnMetadata(); + }); + + const { + find, + waitFor, + actions: { startEditField }, + } = testBed; + // Open the flyout to edit the field + await act(async () => { + startEditField('user.address.street'); + }); + + await waitFor('mappingsEditorFieldEdit'); + + // It should have the correct title + expect(find('mappingsEditorFieldEdit.flyoutTitle').text()).toEqual(`Edit field 'street'`); + + // It should have the correct field path + expect(find('mappingsEditorFieldEdit.fieldPath').text()).toEqual('user > address > street'); + + // The advanced settings should be hidden initially + expect(find('mappingsEditorFieldEdit.advancedSettings').props().style.display).toEqual('none'); + }); + + test('should update form parameters when changing the field datatype', async () => { + const defaultMappings = { + _meta: {}, + _source: {}, + properties: { + myField: { + ...defaultTextParameters, + }, + }, + }; + + await act(async () => { + testBed = await setup({ value: defaultMappings, onChange: onChangeHandler }); + }); + + const { + find, + exists, + waitFor, + waitForFn, + component, + actions: { startEditField, updateFieldAndCloseFlyout }, + } = testBed; + + // Open the flyout, change the field type and save it + await act(async () => { + startEditField('myField'); + }); + + await waitFor('mappingsEditorFieldEdit'); + + await act(async () => { + // Change the field type + find('mappingsEditorFieldEdit.fieldType').simulate('change', [ + { label: 'Shape', value: defaultShapeParameters.type }, + ]); + component.update(); + }); + + await act(async () => { + await updateFieldAndCloseFlyout(); + }); + + await waitForFn( + async () => exists('mappingsEditorFieldEdit') === false, + 'Error waiting for the details flyout to close' + ); + + const { data } = await getMappingsEditorData(); + + const updatedMappings = { + ...defaultMappings, + properties: { + myField: { + ...defaultShapeParameters, + }, + }, + }; + + expect(data).toEqual(updatedMappings); + }, 15000); +}); diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/index.ts index fa6bee56349e9..afdc039ae77d2 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/index.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/index.ts @@ -3,7 +3,12 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { setup as mappingsEditorSetup, MappingsEditorTestBed } from './mappings_editor.helpers'; +import { + setup as mappingsEditorSetup, + MappingsEditorTestBed, + DomFields, + getMappingsEditorDataFactory, +} from './mappings_editor.helpers'; export { nextTick, @@ -13,7 +18,7 @@ export { } from '../../../../../../../../../test_utils'; export const componentHelpers = { - mappingsEditor: { setup: mappingsEditorSetup }, + mappingsEditor: { setup: mappingsEditorSetup, getMappingsEditorDataFactory }, }; -export { MappingsEditorTestBed }; +export { MappingsEditorTestBed, DomFields }; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.tsx index c8c8ef8bfe9b3..58242ec35018c 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.tsx @@ -4,7 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; +import { act } from 'react-dom/test-utils'; +import { ReactWrapper } from 'enzyme'; + import { registerTestBed, TestBed, nextTick } from '../../../../../../../../../test_utils'; +import { getChildFieldsName } from '../../../lib'; import { MappingsEditor } from '../../../mappings_editor'; jest.mock('@elastic/eui', () => ({ @@ -14,6 +18,7 @@ jest.mock('@elastic/eui', () => ({ EuiComboBox: (props: any) => ( { props.onChange([syntheticEvent['0']]); }} @@ -29,14 +34,121 @@ jest.mock('@elastic/eui', () => ({ }} /> ), + // Mocking EuiSuperSelect to be able to easily change its value + // with a `myWrapper.simulate('change', { target: { value: 'someValue' } })` + EuiSuperSelect: (props: any) => ( + { + props.onChange(e.target.value); + }} + /> + ), })); +export interface DomFields { + [key: string]: { + type: string; + properties?: DomFields; + fields?: DomFields; + }; +} + const createActions = (testBed: TestBed) => { - const { find, waitFor, form, component } = testBed; + const { find, exists, waitFor, waitForFn, form, component } = testBed; + + const getFieldInfo = (testSubjectField: string): { name: string; type: string } => { + const name = find(`${testSubjectField}-fieldName` as TestSubjects).text(); + const type = find(`${testSubjectField}-datatype` as TestSubjects).props()['data-type-value']; + return { name, type }; + }; + + const expandField = async ( + field: ReactWrapper + ): Promise<{ hasChildren: boolean; testSubjectField: string }> => { + /** + * Field list item have 2 test subject assigned to them: + * data-test-subj="fieldsListItem " + * + * We read the second one as it is unique. + */ + const testSubjectField = (field.props() as any)['data-test-subj'] + .split(' ') + .filter((subj: string) => subj !== 'fieldsListItem')[0] as string; + + const expandButton = find(`${testSubjectField}.toggleExpandButton` as TestSubjects); + + // No expand button, so this field is not expanded + if (expandButton.length === 0) { + return { hasChildren: false, testSubjectField }; + } + + const isExpanded = (expandButton.props()['aria-label'] as string).includes('Collapse'); + + if (!isExpanded) { + expandButton.simulate('click'); + } + + // Wait for the children FieldList to be in the DOM + await waitFor(`${testSubjectField}.fieldsList` as TestSubjects); + + return { hasChildren: true, testSubjectField }; + }; + + /** + * Expand all the children of a field and return a metadata object of the fields found in the DOM. + * + * @param fieldName The field under wich we want to expand all the children. + * If no fieldName is provided, we expand all the **root** level fields. + */ + const expandAllFieldsAndReturnMetadata = async ( + fieldName?: string, + domTreeMetadata: DomFields = {} + ): Promise => { + const fields = find( + fieldName ? (`${fieldName}.fieldsList.fieldsListItem` as TestSubjects) : 'fieldsListItem' + ).map(wrapper => wrapper); // convert to Array for our for of loop below + + for (const field of fields) { + const { hasChildren, testSubjectField } = await expandField(field); + + // Read the info from the DOM about that field and add it to our domFieldMeta + const { name, type } = getFieldInfo(testSubjectField); + domTreeMetadata[name] = { + type, + }; + + if (hasChildren) { + // Update our metadata object + const childFieldName = getChildFieldsName(type as any)!; + domTreeMetadata[name][childFieldName] = {}; + + // Expand its children + await expandAllFieldsAndReturnMetadata( + testSubjectField, + domTreeMetadata[name][childFieldName] + ); + } + } + + return domTreeMetadata; + }; + + // Get a nested field in the rendered DOM tree + const getFieldAt = (path: string) => { + const testSubjectField = `${path.split('.').join('')}Field`; + return find(testSubjectField as TestSubjects); + }; const addField = async (name: string, type: string) => { const currentCount = find('fieldsListItem').length; + if (!exists('createFieldForm')) { + find('addFieldButton').simulate('click'); + await waitFor('createFieldForm'); + } + form.setInputValue('nameParameterInput', name); find('createFieldForm.fieldType').simulate('change', [ { @@ -54,6 +166,36 @@ const createActions = (testBed: TestBed) => { await waitFor('fieldsListItem', currentCount + 1); }; + const startEditField = (path: string) => { + const field = getFieldAt(path); + find('editFieldButton', field).simulate('click'); + component.update(); + }; + + const updateFieldAndCloseFlyout = () => { + find('mappingsEditorFieldEdit.editFieldUpdateButton').simulate('click'); + component.update(); + }; + + const showAdvancedSettings = async () => { + const checkIsVisible = async () => + find('mappingsEditorFieldEdit.advancedSettings').props().style.display === 'block'; + + if (await checkIsVisible()) { + // Already opened, nothing else to do + return; + } + + await act(async () => { + find('mappingsEditorFieldEdit.toggleAdvancedSetting').simulate('click'); + }); + + await waitForFn( + checkIsVisible, + 'Error waiting for the advanced settings CSS style.display to be "block"' + ); + }; + const selectTab = async (tab: 'fields' | 'templates' | 'advanced') => { const index = ['fields', 'templates', 'advanced'].indexOf(tab); const tabIdToContentMap: { [key: string]: TestSubjects } = { @@ -87,11 +229,33 @@ const createActions = (testBed: TestBed) => { return value; }; + const getComboBoxValue = (testSubject: TestSubjects) => { + const value = find(testSubject).props()['data-currentvalue']; + if (value === undefined) { + return []; + } + return value.map(({ label }: any) => label); + }; + + const getToggleValue = (testSubject: TestSubjects): boolean => + find(testSubject).props()['aria-checked']; + + const getCheckboxValue = (testSubject: TestSubjects): boolean => + find(testSubject).props().checked; + return { selectTab, + getFieldAt, addField, + expandAllFieldsAndReturnMetadata, + startEditField, + updateFieldAndCloseFlyout, + showAdvancedSettings, updateJsonEditor, getJsonEditorValue, + getComboBoxValue, + getToggleValue, + getCheckboxValue, }; }; @@ -109,6 +273,33 @@ export const setup = async (props: any = { onUpdate() {} }): Promise) => { + /** + * Helper to access the latest data sent to the onChange handler back to the consumer of the . + * Read the latest call with its argument passed and build the mappings object from it. + */ + return async () => { + const mockCalls = onChangeHandler.mock.calls; + + if (mockCalls.length === 0) { + throw new Error( + `Can't access data forwarded as the onChange() prop handler hasn't been called.` + ); + } + + const [arg] = mockCalls[mockCalls.length - 1]; + const { isValid, validate, getData } = arg; + + const isMappingsValid = isValid === undefined ? await act(validate) : isValid; + const data = getData(isMappingsValid); + + return { + isValid: isMappingsValid, + data, + }; + }; +}; + export type MappingsEditorTestBed = TestBed & { actions: ReturnType; }; @@ -116,7 +307,9 @@ export type MappingsEditorTestBed = TestBed & { export type TestSubjects = | 'formTab' | 'mappingsEditor' + | 'fieldsList' | 'fieldsListItem' + | 'fieldsListItem.fieldName' | 'fieldName' | 'mappingTypesDetectedCallout' | 'documentFields' @@ -126,7 +319,38 @@ export type TestSubjects = | 'advancedConfiguration.numericDetection.input' | 'advancedConfiguration.dynamicMappingsToggle' | 'advancedConfiguration.dynamicMappingsToggle.input' + | 'advancedConfiguration.metaField' + | 'advancedConfiguration.routingRequiredToggle.input' + | 'sourceField.includesField' + | 'sourceField.excludesField' | 'dynamicTemplatesEditor' | 'nameParameterInput' + | 'addFieldButton' + | 'editFieldButton' + | 'toggleExpandButton' + | 'createFieldForm' | 'createFieldForm.fieldType' - | 'createFieldForm.addButton'; + | 'createFieldForm.addButton' + | 'mappingsEditorFieldEdit' + | 'mappingsEditorFieldEdit.fieldType' + | 'mappingsEditorFieldEdit.editFieldUpdateButton' + | 'mappingsEditorFieldEdit.flyoutTitle' + | 'mappingsEditorFieldEdit.documentationLink' + | 'mappingsEditorFieldEdit.fieldPath' + | 'mappingsEditorFieldEdit.advancedSettings' + | 'mappingsEditorFieldEdit.toggleAdvancedSetting' + | 'indexParameter.formRowToggle' + | 'indexAnalyzer.select' + | 'searchAnalyzer' + | 'searchAnalyzer.select' + | 'searchQuoteAnalyzer' + | 'searchQuoteAnalyzer.select' + | 'indexAnalyzer-custom' + | 'indexAnalyzer-custom.input' + | 'searchAnalyzer-toggleCustomButton' + | 'searchAnalyzer-custom' + | 'searchAnalyzer-custom.input' + | 'searchQuoteAnalyzer-custom' + | 'searchQuoteAnalyzer-toggleCustomButton' + | 'searchQuoteAnalyzer-custom.input' + | 'useSameAnalyzerForSearchCheckBox.input'; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mapped_fields.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mapped_fields.test.tsx new file mode 100644 index 0000000000000..8989e85d9f188 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mapped_fields.test.tsx @@ -0,0 +1,104 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { act } from 'react-dom/test-utils'; + +import { componentHelpers, MappingsEditorTestBed, DomFields, nextTick } from './helpers'; + +const { setup } = componentHelpers.mappingsEditor; +const onChangeHandler = jest.fn(); + +describe('Mappings editor: mapped fields', () => { + afterEach(() => { + onChangeHandler.mockReset(); + }); + + describe('', () => { + let testBed: MappingsEditorTestBed; + const defaultMappings = { + properties: { + myField: { + type: 'text', + fields: { + raw: { + type: 'keyword', + }, + simpleAnalyzer: { + type: 'text', + }, + }, + }, + myObject: { + type: 'object', + properties: { + deeplyNested: { + type: 'object', + properties: { + title: { + type: 'text', + fields: { + raw: { type: 'keyword' }, + }, + }, + }, + }, + }, + }, + }, + }; + + test('should correctly represent the fields in the DOM tree', async () => { + await act(async () => { + testBed = await setup({ + value: defaultMappings, + onChange: onChangeHandler, + }); + }); + + const { + actions: { expandAllFieldsAndReturnMetadata }, + } = testBed; + + let domTreeMetadata: DomFields = {}; + await act(async () => { + domTreeMetadata = await expandAllFieldsAndReturnMetadata(); + }); + + expect(domTreeMetadata).toEqual(defaultMappings.properties); + }); + + test('should allow to be controlled by parent component and update on prop change', async () => { + await act(async () => { + testBed = await setup({ + value: defaultMappings, + onChange: onChangeHandler, + }); + }); + + const { + component, + setProps, + actions: { expandAllFieldsAndReturnMetadata }, + } = testBed; + + const newMappings = { properties: { hello: { type: 'text' } } }; + let domTreeMetadata: DomFields = {}; + + await act(async () => { + // Change the `value` prop of our + setProps({ value: newMappings }); + + // Don't ask me why but the 3 following lines are all required + component.update(); + await nextTick(); + component.update(); + + domTreeMetadata = await expandAllFieldsAndReturnMetadata(); + }); + + expect(domTreeMetadata).toEqual(newMappings.properties); + }); + }); +}); diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx index 0cf5bf3f4453f..f516dfdb372ce 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx @@ -5,15 +5,55 @@ */ import { act } from 'react-dom/test-utils'; -import { componentHelpers, MappingsEditorTestBed, nextTick, getRandomString } from './helpers'; +import { componentHelpers, MappingsEditorTestBed, nextTick } from './helpers'; -const { setup } = componentHelpers.mappingsEditor; -const mockOnUpdate = () => undefined; +const { setup, getMappingsEditorDataFactory } = componentHelpers.mappingsEditor; +const onChangeHandler = jest.fn(); +const getMappingsEditorData = getMappingsEditorDataFactory(onChangeHandler); + +describe('Mappings editor: core', () => { + /** + * Variable to store the mappings data forwarded to the consumer component + */ + let data: any; + + afterEach(() => { + onChangeHandler.mockReset(); + }); + + test('default behaviour', async () => { + const defaultMappings = { + properties: { + user: { + // No type defined for user + properties: { + name: { type: 'text' }, + }, + }, + }, + }; + + await setup({ value: defaultMappings, onChange: onChangeHandler }); + + const expectedMappings = { + _meta: {}, // Was not defined so an empty object is returned + _source: {}, // Was not defined so an empty object is returned + ...defaultMappings, + properties: { + user: { + type: 'object', // Was not defined so it defaults to "object" type + ...defaultMappings.properties.user, + }, + }, + }; + + ({ data } = await getMappingsEditorData()); + expect(data).toEqual(expectedMappings); + }); -describe('', () => { describe('multiple mappings detection', () => { test('should show a warning when multiple mappings are detected', async () => { - const defaultValue = { + const value = { type1: { properties: { name1: { @@ -29,7 +69,7 @@ describe('', () => { }, }, }; - const testBed = await setup({ onUpdate: mockOnUpdate, defaultValue }); + const testBed = await setup({ onChange: onChangeHandler, value }); const { exists } = testBed; expect(exists('mappingsEditor')).toBe(true); @@ -38,14 +78,14 @@ describe('', () => { }); test('should not show a warning when mappings a single-type', async () => { - const defaultValue = { + const value = { properties: { name1: { type: 'keyword', }, }, }; - const testBed = await setup({ onUpdate: mockOnUpdate, defaultValue }); + const testBed = await setup({ onChange: onChangeHandler, value }); const { exists } = testBed; expect(exists('mappingsEditor')).toBe(true); @@ -62,12 +102,12 @@ describe('', () => { let testBed: MappingsEditorTestBed; beforeEach(async () => { - testBed = await setup({ defaultValue: defaultMappings, onUpdate() {} }); + testBed = await setup({ value: defaultMappings, onChange: onChangeHandler }); }); test('should keep the changes when switching tabs', async () => { const { - actions: { addField, selectTab, updateJsonEditor, getJsonEditorValue }, + actions: { addField, selectTab, updateJsonEditor, getJsonEditorValue, getToggleValue }, component, find, exists, @@ -79,7 +119,7 @@ describe('', () => { // ------------------------------------- expect(find('fieldsListItem').length).toEqual(0); // Check that we start with an empty list - const newField = { name: getRandomString(), type: 'text' }; + const newField = { name: 'John', type: 'text' }; await act(async () => { await addField(newField.name, newField.type); }); @@ -101,7 +141,6 @@ describe('', () => { // Update the dynamic templates editor value const updatedValueTemplates = [{ after: 'bar' }]; - await act(async () => { await updateJsonEditor('dynamicTemplatesEditor', updatedValueTemplates); await nextTick(); @@ -118,9 +157,9 @@ describe('', () => { await selectTab('advanced'); }); - let isDynamicMappingsEnabled = find( + let isDynamicMappingsEnabled = getToggleValue( 'advancedConfiguration.dynamicMappingsToggle.input' - ).props()['aria-checked']; + ); expect(isDynamicMappingsEnabled).toBe(true); let isNumericDetectionVisible = exists('advancedConfiguration.numericDetection'); @@ -134,9 +173,9 @@ describe('', () => { await nextTick(); }); - isDynamicMappingsEnabled = find('advancedConfiguration.dynamicMappingsToggle.input').props()[ - 'aria-checked' - ]; + isDynamicMappingsEnabled = getToggleValue( + 'advancedConfiguration.dynamicMappingsToggle.input' + ); expect(isDynamicMappingsEnabled).toBe(false); isNumericDetectionVisible = exists('advancedConfiguration.numericDetection'); @@ -166,12 +205,185 @@ describe('', () => { await selectTab('advanced'); }); - isDynamicMappingsEnabled = find('advancedConfiguration.dynamicMappingsToggle.input').props()[ - 'aria-checked' - ]; + isDynamicMappingsEnabled = getToggleValue( + 'advancedConfiguration.dynamicMappingsToggle.input' + ); expect(isDynamicMappingsEnabled).toBe(false); isNumericDetectionVisible = exists('advancedConfiguration.numericDetection'); expect(isNumericDetectionVisible).toBe(false); }); }); + + describe('component props', () => { + /** + * Note: the "indexSettings" prop will be tested along with the "analyzer" parameter on a text datatype field, + * as it is the only place where it is consumed by the mappings editor. + * + * The test that covers it is text_datatype.test.tsx: "analyzer parameter: custom analyzer (from index settings)" + */ + const defaultMappings: any = { + dynamic: true, + numeric_detection: false, + date_detection: true, + properties: { + title: { type: 'text' }, + address: { + type: 'object', + properties: { + street: { type: 'text' }, + city: { type: 'text' }, + }, + }, + }, + dynamic_templates: [{ initial: 'value' }], + _source: { + enabled: true, + includes: ['field1', 'field2'], + excludes: ['field3'], + }, + _meta: { + some: 'metaData', + }, + _routing: { + required: false, + }, + }; + + let testBed: MappingsEditorTestBed; + + beforeEach(async () => { + testBed = await setup({ value: defaultMappings, onChange: onChangeHandler }); + }); + + test('props.value => should prepopulate the editor data', async () => { + const { + actions: { selectTab, getJsonEditorValue, getComboBoxValue, getToggleValue }, + find, + } = testBed; + + /** + * Mapped fields + */ + // Test that root-level mappings "properties" are rendered as root-level "DOM tree items" + const fields = find('fieldsListItem.fieldName').map(item => item.text()); + expect(fields).toEqual(Object.keys(defaultMappings.properties).sort()); + + /** + * Dynamic templates + */ + await act(async () => { + await selectTab('templates'); + }); + + // Test that dynamic templates JSON is rendered in the templates editor + const templatesValue = getJsonEditorValue('dynamicTemplatesEditor'); + expect(templatesValue).toEqual(defaultMappings.dynamic_templates); + + /** + * Advanced settings + */ + await act(async () => { + await selectTab('advanced'); + }); + + const isDynamicMappingsEnabled = getToggleValue( + 'advancedConfiguration.dynamicMappingsToggle.input' + ); + expect(isDynamicMappingsEnabled).toBe(defaultMappings.dynamic); + + const isNumericDetectionEnabled = getToggleValue( + 'advancedConfiguration.numericDetection.input' + ); + expect(isNumericDetectionEnabled).toBe(defaultMappings.numeric_detection); + + expect(getComboBoxValue('sourceField.includesField')).toEqual( + defaultMappings._source.includes + ); + expect(getComboBoxValue('sourceField.excludesField')).toEqual( + defaultMappings._source.excludes + ); + + const metaFieldValue = getJsonEditorValue('advancedConfiguration.metaField'); + expect(metaFieldValue).toEqual(defaultMappings._meta); + + const isRoutingRequired = getToggleValue('advancedConfiguration.routingRequiredToggle.input'); + expect(isRoutingRequired).toBe(defaultMappings._routing.required); + }); + + test('props.onChange() => should forward the changes to the consumer component', async () => { + let updatedMappings = { ...defaultMappings }; + + const { + actions: { addField, selectTab, updateJsonEditor }, + component, + form, + } = testBed; + + /** + * Mapped fields + */ + const newField = { name: 'someNewField', type: 'text' }; + updatedMappings = { + ...updatedMappings, + properties: { + ...updatedMappings.properties, + [newField.name]: { type: 'text' }, + }, + }; + + await act(async () => { + await addField(newField.name, newField.type); + }); + + ({ data } = await getMappingsEditorData()); + expect(data).toEqual(updatedMappings); + + /** + * Dynamic templates + */ + await act(async () => { + await selectTab('templates'); + }); + + const updatedTemplatesValue = [{ someTemplateProp: 'updated' }]; + updatedMappings = { + ...updatedMappings, + dynamic_templates: updatedTemplatesValue, + }; + + await act(async () => { + await updateJsonEditor('dynamicTemplatesEditor', updatedTemplatesValue); + await nextTick(); + component.update(); + }); + + ({ data } = await getMappingsEditorData()); + expect(data).toEqual(updatedMappings); + + /** + * Advanced settings + */ + await act(async () => { + await selectTab('advanced'); + }); + + // Disbable dynamic mappings + await act(async () => { + form.toggleEuiSwitch('advancedConfiguration.dynamicMappingsToggle.input'); + }); + + ({ data } = await getMappingsEditorData()); + + // When we disable dynamic mappings, we set it to "false" and remove date and numeric detections + updatedMappings = { + ...updatedMappings, + dynamic: false, + date_detection: undefined, + dynamic_date_formats: undefined, + numeric_detection: undefined, + }; + + expect(data).toEqual(updatedMappings); + }); + }); }); diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx index 6b33d4450c3ae..c84756cab8e88 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx @@ -7,6 +7,7 @@ import React, { useEffect, useRef } from 'react'; import { EuiSpacer } from '@elastic/eui'; import { useForm, Form, SerializerFunc } from '../../shared_imports'; +import { GenericObject } from '../../types'; import { Types, useDispatch } from '../../mappings_state'; import { DynamicMappingSection } from './dynamic_mapping_section'; import { SourceFieldSection } from './source_field_section'; @@ -17,10 +18,10 @@ import { configurationFormSchema } from './configuration_form_schema'; type MappingsConfiguration = Types['MappingsConfiguration']; interface Props { - defaultValue?: MappingsConfiguration; + value?: MappingsConfiguration; } -const stringifyJson = (json: { [key: string]: any }) => +const stringifyJson = (json: GenericObject) => Object.keys(json).length ? JSON.stringify(json, null, 2) : '{\n\n}'; const formSerializer: SerializerFunc = formData => { @@ -57,7 +58,7 @@ const formSerializer: SerializerFunc = formData => { }; }; -const formDeserializer = (formData: { [key: string]: any }) => { +const formDeserializer = (formData: GenericObject) => { const { dynamic, numeric_detection, @@ -86,14 +87,14 @@ const formDeserializer = (formData: { [key: string]: any }) => { }; }; -export const ConfigurationForm = React.memo(({ defaultValue }: Props) => { +export const ConfigurationForm = React.memo(({ value }: Props) => { const didMountRef = useRef(false); const { form } = useForm({ schema: configurationFormSchema, serializer: formSerializer, deserializer: formDeserializer, - defaultValue, + defaultValue: value, }); const dispatch = useDispatch(); @@ -114,14 +115,14 @@ export const ConfigurationForm = React.memo(({ defaultValue }: Props) => { useEffect(() => { if (didMountRef.current) { - // If the defaultValue has changed (it probably means that we have loaded a new JSON) + // If the value has changed (it probably means that we have loaded a new JSON) // we need to reset the form to update the fields values. form.reset({ resetValues: true }); } else { // Avoid reseting the form on component mount. didMountRef.current = true; } - }, [defaultValue]); // eslint-disable-line react-hooks/exhaustive-deps + }, [value]); // eslint-disable-line react-hooks/exhaustive-deps useEffect(() => { return () => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx index cb9b464d270ce..c1a2b195a3f57 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx @@ -67,6 +67,7 @@ export const DynamicMappingSection = () => ( return ( <> @@ -87,6 +88,7 @@ export const DynamicMappingSection = () => ( } else { return ( diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/meta_field_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/meta_field_section.tsx index 68b76a1203ad5..7185016029e00 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/meta_field_section.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/meta_field_section.tsx @@ -46,6 +46,7 @@ export const MetaFieldSection = () => ( 'aria-label': i18n.translate('xpack.idxMgmt.mappingsEditor.metaFieldEditorAriaLabel', { defaultMessage: '_meta field data editor', }), + 'data-test-subj': 'metaField', }, }} /> diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/routing_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/routing_section.tsx index 7f434d6f834b2..f06b292bc33c8 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/routing_section.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/routing_section.tsx @@ -35,7 +35,11 @@ export const RoutingSection = () => { /> } > - + ); }; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/source_field_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/source_field_section.tsx index f79741d9a1a9f..4278598dfc7c1 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/source_field_section.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/source_field_section.tsx @@ -65,7 +65,7 @@ export const SourceFieldSection = () => { ); const renderFormFields = () => ( - <> +
{({ label, helpText, value, setValue }) => ( @@ -89,6 +89,7 @@ export const SourceFieldSection = () => { setValue([...(value as ComboBoxOption[]), newOption]); }} fullWidth + data-test-subj="includesField" /> )} @@ -119,11 +120,12 @@ export const SourceFieldSection = () => { setValue([...(value as ComboBoxOption[]), newOption]); }} fullWidth + data-test-subj="excludesField" /> )} - +
); return ( diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter.tsx index a97e3b227311c..569af5d21cdb0 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter.tsx @@ -25,6 +25,7 @@ interface Props { label?: string; config?: FieldConfig; allowsIndexDefaultOption?: boolean; + 'data-test-subj'?: string; } const ANALYZER_OPTIONS = PARAMETERS_OPTIONS.analyzer!; @@ -68,6 +69,7 @@ export const AnalyzerParameter = ({ label, config, allowsIndexDefaultOption = true, + 'data-test-subj': dataTestSubj, }: Props) => { const indexSettings = useIndexSettings(); const customAnalyzers = getCustomAnalyzers(indexSettings); @@ -131,6 +133,11 @@ export const AnalyzerParameter = ({ !isDefaultValueInOptions && !isDefaultValueInSubOptions ); + const [selectsDefaultValue, setSelectsDefaultValue] = useState({ + main: mainValue, + sub: subValue, + }); + const fieldConfig = config ? config : getFieldConfig('analyzer'); const fieldConfigWithLabel = label !== undefined ? { ...fieldConfig, label } : fieldConfig; @@ -142,6 +149,7 @@ export const AnalyzerParameter = ({ } field.reset({ resetValue: false }); + setSelectsDefaultValue({ main: undefined, sub: undefined }); setIsCustom(!isCustom); }; @@ -154,6 +162,7 @@ export const AnalyzerParameter = ({ size="xs" onClick={toggleCustom(field)} className="mappingsEditor__selectWithCustom__button" + data-test-subj={`${dataTestSubj}-toggleCustomButton`} > {isCustom ? i18n.translate('xpack.idxMgmt.mappingsEditor.predefinedButtonLabel', { @@ -169,17 +178,18 @@ export const AnalyzerParameter = ({ // around the field. - + ) : ( )} diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter_selects.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter_selects.tsx index a91231352c168..a44fd2257f52b 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter_selects.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter_selects.tsx @@ -36,6 +36,7 @@ interface Props { config: FieldConfig; options: Options; mapOptionsToSubOptions: MapOptionsToSubOptions; + 'data-test-subj'?: string; } export const AnalyzerParameterSelects = ({ @@ -45,6 +46,7 @@ export const AnalyzerParameterSelects = ({ config, options, mapOptionsToSubOptions, + 'data-test-subj': dataTestSubj, }: Props) => { const { form } = useForm({ defaultValue: { main: mainDefaultValue, sub: subDefaultValue } }); @@ -76,11 +78,16 @@ export const AnalyzerParameterSelects = ({ const isSuperSelect = areOptionsSuperSelect(opts); return isSuperSelect ? ( - + ) : ( ); }; @@ -102,9 +109,9 @@ export const AnalyzerParameterSelects = ({ diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzers_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzers_parameter.tsx index 0cf22946bf60a..f99aa4d1eca9a 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzers_parameter.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzers_parameter.tsx @@ -34,6 +34,7 @@ export const AnalyzersParameter = ({ field, withSearchQuoteAnalyzer = false }: P href: documentationService.getAnalyzerLink(), }} withToggle={false} + data-test-subj="analyzerParameters" > {({ useSameAnalyzerForSearch }) => { @@ -50,6 +51,7 @@ export const AnalyzersParameter = ({ field, withSearchQuoteAnalyzer = false }: P path="analyzer" label={label} defaultValue={field.source.analyzer as string} + data-test-subj="indexAnalyzer" /> ); }} @@ -60,6 +62,9 @@ export const AnalyzersParameter = ({ field, withSearchQuoteAnalyzer = false }: P @@ -94,6 +100,7 @@ export const AnalyzersParameter = ({ field, withSearchQuoteAnalyzer = false }: P path="search_quote_analyzer" defaultValue={field.source.search_quote_analyzer as string} config={getFieldConfig('search_quote_analyzer')} + data-test-subj="searchQuoteAnalyzer" /> )} diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index_parameter.tsx index fec8e49a1991c..3e91e97eef618 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index_parameter.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index_parameter.tsx @@ -39,6 +39,7 @@ export const IndexParameter = ({ href: documentationService.getIndexLink(), }} formFieldPath="index" + data-test-subj="indexParameter" > {/* index_options */} {hasIndexOptions ? ( diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/advanced_parameters_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/advanced_parameters_section.tsx index 03c774227924e..2046675881c29 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/advanced_parameters_section.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/advanced_parameters_section.tsx @@ -23,7 +23,7 @@ export const AdvancedParametersSection = ({ children }: Props) => {
- + {isVisible ? i18n.translate('xpack.idxMgmt.mappingsEditor.advancedSettings.hideButtonLabel', { defaultMessage: 'Hide advanced settings', @@ -33,7 +33,7 @@ export const AdvancedParametersSection = ({ children }: Props) => { })} -
+
{/* We ned to wrap the children inside a "div" to have our css :first-child rule */}
{children}
diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx index 489424a07e04d..854270f313e59 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx @@ -96,7 +96,7 @@ export const EditField = React.memo(({ form, field, allFields, exitEdit }: Props
{/* Title */} -

+

{isMultiField ? i18n.translate( 'xpack.idxMgmt.mappingsEditor.editMultiFieldTitle', @@ -127,6 +127,7 @@ export const EditField = React.memo(({ form, field, allFields, exitEdit }: Props href={linkDocumentation} target="_blank" iconType="help" + data-test-subj="documentationLink" > {i18n.translate( 'xpack.idxMgmt.mappingsEditor.editField.typeDocumentation', @@ -146,7 +147,7 @@ export const EditField = React.memo(({ form, field, allFields, exitEdit }: Props {/* Field path */} - + {field.path.join(' > ')} diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_form_row.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_form_row.tsx index 97a7d205c1355..1c079c8d5cf87 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_form_row.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_form_row.tsx @@ -42,6 +42,7 @@ interface Props { children?: React.ReactNode | ChildrenFunc; withToggle?: boolean; configPath?: ParameterName; + 'data-test-subj'?: string; } export const EditFieldFormRow = React.memo( @@ -54,6 +55,7 @@ export const EditFieldFormRow = React.memo( children, withToggle = true, configPath, + 'data-test-subj': dataTestSubj, }: Props) => { const form = useFormContext(); @@ -87,7 +89,7 @@ export const EditFieldFormRow = React.memo( label={title} checked={isContentVisible} onChange={onToggle} - data-test-subj="input" + data-test-subj="formRowToggle" showLabel={false} /> ) : ( @@ -99,7 +101,17 @@ export const EditFieldFormRow = React.memo( }} > {field => { - return ; + return ( + + ); }} ); @@ -165,7 +177,7 @@ export const EditFieldFormRow = React.memo( ); return ( - + {toggle} diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list.tsx index 6df86d561a532..c0d922e0d1d37 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list.tsx @@ -18,7 +18,7 @@ export const FieldsList = React.memo(function FieldsListComponent({ fields, tree return null; } return ( -
    +
      {fields.map((field, index) => (
      {source.name} - + {isMultiField ? i18n.translate('xpack.idxMgmt.mappingsEditor.multiFieldBadgeLabel', { defaultMessage: '{dataType} multi-field', values: { - dataType: TYPE_DEFINITION[source.type].label, + dataType: getTypeLabelFromType(source.type), }, }) : getTypeLabelFromType(source.type)} diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx index 3c4d6b08ebe44..f4aa17bf6fed9 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx @@ -16,7 +16,7 @@ import { documentationService } from '../../../../services/documentation'; type MappingsTemplates = Types['MappingsTemplates']; interface Props { - defaultValue?: MappingsTemplates; + value?: MappingsTemplates; } const stringifyJson = (json: { [key: string]: any }) => @@ -50,14 +50,14 @@ const formDeserializer = (formData: { [key: string]: any }) => { }; }; -export const TemplatesForm = React.memo(({ defaultValue }: Props) => { +export const TemplatesForm = React.memo(({ value }: Props) => { const didMountRef = useRef(false); const { form } = useForm({ schema: templatesFormSchema, serializer: formSerializer, deserializer: formDeserializer, - defaultValue, + defaultValue: value, }); const dispatch = useDispatch(); @@ -73,14 +73,14 @@ export const TemplatesForm = React.memo(({ defaultValue }: Props) => { useEffect(() => { if (didMountRef.current) { - // If the defaultValue has changed (it probably means that we have loaded a new JSON) + // If the value has changed (it probably means that we have loaded a new JSON) // we need to reset the form to update the fields values. form.reset({ resetValues: true }); } else { // Avoid reseting the form on component mount. didMountRef.current = true; } - }, [defaultValue]); // eslint-disable-line react-hooks/exhaustive-deps + }, [value]); // eslint-disable-line react-hooks/exhaustive-deps useEffect(() => { return () => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/utils.test.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/utils.test.ts index 0431ea472643b..4b610ff0b401d 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/utils.test.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/utils.test.ts @@ -6,7 +6,7 @@ jest.mock('../constants', () => ({ MAIN_DATA_TYPE_DEFINITION: {} })); -import { isStateValid } from './utils'; +import { isStateValid, stripUndefinedValues } from './utils'; describe('utils', () => { describe('isStateValid()', () => { @@ -62,4 +62,49 @@ describe('utils', () => { expect(isStateValid(components)).toBe(false); }); }); + + describe('stripUndefinedValues()', () => { + test('should remove all undefined value recursively', () => { + const myDate = new Date(); + + const dataIN = { + someString: 'world', + someNumber: 123, + someBoolean: true, + someArray: [1, 2, 3], + someEmptyObject: {}, + someDate: myDate, + falsey1: 0, + falsey2: '', + stripThis: undefined, + nested: { + value: 'bar', + stripThis: undefined, + deepNested: { + value: 'baz', + stripThis: undefined, + }, + }, + }; + + const dataOUT = { + someString: 'world', + someNumber: 123, + someBoolean: true, + someArray: [1, 2, 3], + someEmptyObject: {}, + someDate: myDate, + falsey1: 0, + falsey2: '', + nested: { + value: 'bar', + deepNested: { + value: 'baz', + }, + }, + }; + + expect(stripUndefinedValues(dataIN)).toEqual(dataOUT); + }); + }); }); diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/utils.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/utils.ts index cece26618ced8..306e0448df379 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/utils.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/utils.ts @@ -17,6 +17,7 @@ import { ChildFieldName, ParameterName, ComboBoxOption, + GenericObject, } from '../types'; import { @@ -32,11 +33,9 @@ import { State } from '../reducer'; import { FieldConfig } from '../shared_imports'; import { TreeItem } from '../components/tree'; -export const getUniqueId = () => { - return uuid.v4(); -}; +export const getUniqueId = () => uuid.v4(); -const getChildFieldsName = (dataType: DataType): ChildFieldName | undefined => { +export const getChildFieldsName = (dataType: DataType): ChildFieldName | undefined => { if (dataType === 'text' || dataType === 'keyword') { return 'fields'; } else if (dataType === 'object' || dataType === 'nested') { @@ -508,3 +507,39 @@ export const isStateValid = (state: State): boolean | undefined => return isValid && value.isValid; }, true as undefined | boolean); + +/** + * This helper removes all the keys on an object with an "undefined" value. + * To avoid sending updates from the mappings editor with this type of object: + * + *``` + * { + * "dyamic": undefined, + * "date_detection": undefined, + * "dynamic": undefined, + * "dynamic_date_formats": undefined, + * "dynamic_templates": undefined, + * "numeric_detection": undefined, + * "properties": { + * "title": { "type": "text" } + * } + * } + *``` + * + * @param obj The object to retrieve the undefined values from + * @param recursive A flag to strip recursively into children objects + */ +export const stripUndefinedValues = (obj: GenericObject, recursive = true): T => + Object.entries(obj).reduce((acc, [key, value]) => { + if (value === undefined) { + return acc; + } + + if (Array.isArray(value) || value instanceof Date || value === null) { + return { ...acc, [key]: value }; + } + + return recursive && typeof value === 'object' + ? { ...acc, [key]: stripUndefinedValues(value, recursive) } + : { ...acc, [key]: value }; + }, {} as T); diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx index 316fee55526a3..46dc1176f62b4 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx @@ -21,18 +21,18 @@ import { MappingsState, Props as MappingsStateProps, Types } from './mappings_st import { IndexSettingsProvider } from './index_settings_context'; interface Props { - onUpdate: MappingsStateProps['onUpdate']; - defaultValue?: { [key: string]: any }; + onChange: MappingsStateProps['onChange']; + value?: { [key: string]: any }; indexSettings?: IndexSettings; } type TabName = 'fields' | 'advanced' | 'templates'; -export const MappingsEditor = React.memo(({ onUpdate, defaultValue, indexSettings }: Props) => { +export const MappingsEditor = React.memo(({ onChange, value, indexSettings }: Props) => { const [selectedTab, selectTab] = useState('fields'); const { parsedDefaultValue, multipleMappingsDeclared } = useMemo(() => { - const mappingsDefinition = extractMappingsDefinition(defaultValue); + const mappingsDefinition = extractMappingsDefinition(value); if (mappingsDefinition === null) { return { multipleMappingsDeclared: true }; @@ -67,18 +67,18 @@ export const MappingsEditor = React.memo(({ onUpdate, defaultValue, indexSetting }; return { parsedDefaultValue: parsed, multipleMappingsDeclared: false }; - }, [defaultValue]); + }, [value]); useEffect(() => { if (multipleMappingsDeclared) { // We set the data getter here as the user won't be able to make any changes - onUpdate({ - getData: () => defaultValue! as Types['Mappings'], + onChange({ + getData: () => value! as Types['Mappings'], validate: () => Promise.resolve(true), isValid: true, }); } - }, [multipleMappingsDeclared, onUpdate, defaultValue]); + }, [multipleMappingsDeclared, onChange, value]); const changeTab = async (tab: TabName, state: State) => { if (selectedTab === 'advanced') { @@ -108,12 +108,12 @@ export const MappingsEditor = React.memo(({ onUpdate, defaultValue, indexSetting ) : ( - + {({ state }) => { const tabToContentMap = { fields: , - templates: , - advanced: , + templates: , + advanced: , }; return ( diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_state.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_state.tsx index a9d26b953b96e..280ea5c3dd28c 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_state.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_state.tsx @@ -16,7 +16,7 @@ import { Dispatch, } from './reducer'; import { Field } from './types'; -import { normalize, deNormalize } from './lib'; +import { normalize, deNormalize, stripUndefinedValues } from './lib'; type Mappings = MappingsTemplates & MappingsConfiguration & { @@ -43,36 +43,34 @@ const DispatchContext = createContext(undefined); export interface Props { children: (params: { state: State }) => React.ReactNode; - defaultValue: { + value: { templates: MappingsTemplates; configuration: MappingsConfiguration; fields: { [key: string]: Field }; }; - onUpdate: OnUpdateHandler; + onChange: OnUpdateHandler; } -export const MappingsState = React.memo(({ children, onUpdate, defaultValue }: Props) => { +export const MappingsState = React.memo(({ children, onChange, value }: Props) => { const didMountRef = useRef(false); - const parsedFieldsDefaultValue = useMemo(() => normalize(defaultValue.fields), [ - defaultValue.fields, - ]); + const parsedFieldsDefaultValue = useMemo(() => normalize(value.fields), [value.fields]); const initialState: State = { isValid: undefined, configuration: { - defaultValue: defaultValue.configuration, + defaultValue: value.configuration, data: { - raw: defaultValue.configuration, - format: () => defaultValue.configuration, + raw: value.configuration, + format: () => value.configuration, }, validate: () => Promise.resolve(true), }, templates: { - defaultValue: defaultValue.templates, + defaultValue: value.templates, data: { - raw: defaultValue.templates, - format: () => defaultValue.templates, + raw: value.templates, + format: () => value.templates, }, validate: () => Promise.resolve(true), }, @@ -105,7 +103,7 @@ export const MappingsState = React.memo(({ children, onUpdate, defaultValue }: P const bypassFieldFormValidation = state.documentFields.status === 'creatingField' && emptyNameValue; - onUpdate({ + onChange({ // Output a mappings object from the user's input. getData: (isValid: boolean) => { let nextState = state; @@ -135,8 +133,10 @@ export const MappingsState = React.memo(({ children, onUpdate, defaultValue }: P const templatesData = nextState.templates.data.format(); return { - ...configurationData, - ...templatesData, + ...stripUndefinedValues({ + ...configurationData, + ...templatesData, + }), properties: fields, }; }, @@ -169,26 +169,26 @@ export const MappingsState = React.memo(({ children, onUpdate, defaultValue }: P }, isValid: state.isValid, }); - }, [state, onUpdate]); + }, [state, onChange]); useEffect(() => { /** - * If the defaultValue has changed that probably means that we have loaded + * If the value has changed that probably means that we have loaded * new data from JSON. We need to update our state with the new mappings. */ if (didMountRef.current) { dispatch({ type: 'editor.replaceMappings', value: { - configuration: defaultValue.configuration, - templates: defaultValue.templates, + configuration: value.configuration, + templates: value.templates, fields: parsedFieldsDefaultValue, }, }); } else { didMountRef.current = true; } - }, [defaultValue, parsedFieldsDefaultValue]); + }, [value, parsedFieldsDefaultValue]); return ( diff --git a/x-pack/plugins/index_management/public/application/components/template_form/steps/step_mappings.tsx b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_mappings.tsx index cf9b57dcbcb14..d74dd435ecdae 100644 --- a/x-pack/plugins/index_management/public/application/components/template_form/steps/step_mappings.tsx +++ b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_mappings.tsx @@ -101,8 +101,8 @@ export const StepMappings: React.FunctionComponent = ({ {/* Mappings code editor */} diff --git a/x-pack/test_utils/testbed/testbed.ts b/x-pack/test_utils/testbed/testbed.ts index 9bf07f953595c..b6ec0f8997e1c 100644 --- a/x-pack/test_utils/testbed/testbed.ts +++ b/x-pack/test_utils/testbed/testbed.ts @@ -5,6 +5,7 @@ */ import { ComponentType, ReactWrapper } from 'enzyme'; + import { findTestSubject } from '../find_test_subject'; import { reactRouterMock } from '../router_helpers'; import { @@ -138,33 +139,23 @@ export const registerTestBed = ( }); }; - const waitFor: TestBed['waitFor'] = async (testSubject: T, count = 1) => { + const waitForFn: TestBed['waitForFn'] = async (predicate, errMessage) => { const triggeredAt = Date.now(); - /** - * The way jest run tests in parallel + the not deterministic DOM update from React "hooks" - * add flakiness to the tests. This is especially true for component integration tests that - * make many update to the DOM. - * - * For this reason, when we _know_ that an element should be there after we updated some state, - * we will give it 30 seconds to appear in the DOM, checking every 100 ms for its presence. - */ const MAX_WAIT_TIME = 30000; - const WAIT_INTERVAL = 100; + const WAIT_INTERVAL = 50; const process = async (): Promise => { - const elemFound = exists(testSubject, count); + const isOK = await predicate(); - if (elemFound) { + if (isOK) { // Great! nothing else to do here. return; } const timeElapsed = Date.now() - triggeredAt; if (timeElapsed > MAX_WAIT_TIME) { - throw new Error( - `I waited patiently for the "${testSubject}" test subject to appear with no luck. It is nowhere to be found!` - ); + throw new Error(errMessage); } return new Promise(resolve => setTimeout(resolve, WAIT_INTERVAL)).then(() => { @@ -176,6 +167,13 @@ export const registerTestBed = ( return process(); }; + const waitFor: TestBed['waitFor'] = (testSubject: T, count = 1) => { + return waitForFn( + () => Promise.resolve(exists(testSubject, count)), + `I waited patiently for the "${testSubject}" test subject to appear with no luck. It is nowhere to be found!` + ); + }; + /** * ---------------------------------------------------------------- * Forms @@ -201,6 +199,18 @@ export const registerTestBed = ( return new Promise(resolve => setTimeout(resolve)); }; + const setSelectValue: TestBed['form']['setSelectValue'] = (select, value) => { + const formSelect = typeof select === 'string' ? find(select) : (select as ReactWrapper); + + if (!formSelect.length) { + throw new Error(`Select "${select}" was not found.`); + } + + formSelect.simulate('change', { target: { value } }); + + component.update(); + }; + const selectCheckBox: TestBed['form']['selectCheckBox'] = ( testSubject, isChecked = true @@ -293,11 +303,13 @@ export const registerTestBed = ( find, setProps, waitFor, + waitForFn, table: { getMetaData, }, form: { setInputValue, + setSelectValue, selectCheckBox, toggleEuiSwitch, setComboBoxValue, diff --git a/x-pack/test_utils/testbed/types.ts b/x-pack/test_utils/testbed/types.ts index f3704bb463ecf..4cc7deac60156 100644 --- a/x-pack/test_utils/testbed/types.ts +++ b/x-pack/test_utils/testbed/types.ts @@ -41,7 +41,7 @@ export interface TestBed { * * @example * - ```ts + ```typescript find('nameInput'); // or more specific, // "nameInput" is a child of "myForm" @@ -61,6 +61,7 @@ export interface TestBed { * and we need to wait for the data to be fetched (and bypass any "loading" state). */ waitFor: (testSubject: T, count?: number) => Promise; + waitForFn: (predicate: () => Promise, errMessage: string) => Promise; form: { /** * Set the value of a form text input. @@ -79,6 +80,28 @@ export interface TestBed { value: string, isAsync?: boolean ) => Promise | void; + /** + * Set the value of a or a mocked + * For the you need to mock it like this + * + ```typescript + jest.mock('@elastic/eui', () => ({ + ...jest.requireActual('@elastic/eui'), + EuiSuperSelect: (props: any) => ( + { + props.onChange(e.target.value); + }} + /> + ), + })); + ``` + * @param select The form select. Can either be a data-test-subj or a reactWrapper (can be a nested path. e.g. "myForm.myInput"). + * @param value The value to set + */ + setSelectValue: (select: T | ReactWrapper, value: string) => void; /** * Select or unselect a form checkbox. * From dddeec51b72bb9cd49e3b8eccfc7004ba983da0d Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Thu, 7 May 2020 11:52:28 +0200 Subject: [PATCH 16/23] [ML] Fix the limit control on the Anomaly explorer page (#65459) * [ML] persist limit control value * [ML] remove console statement * [ML] fix default value --- .../plugins/ml/public/application/explorer/explorer.js | 9 ++------- .../explorer/select_limit/select_limit.test.tsx | 2 -- .../application/explorer/select_limit/select_limit.tsx | 6 +++--- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/ml/public/application/explorer/explorer.js b/x-pack/plugins/ml/public/application/explorer/explorer.js index 86d16776b68e2..36dac05add557 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer.js @@ -14,7 +14,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import DragSelect from 'dragselect/dist/ds.min.js'; import { Subject } from 'rxjs'; -import { map, takeUntil } from 'rxjs/operators'; +import { takeUntil } from 'rxjs/operators'; import { EuiFlexGroup, @@ -169,12 +169,7 @@ export class Explorer extends React.Component { }; componentDidMount() { - limit$ - .pipe( - takeUntil(this._unsubscribeAll), - map(d => d.val) - ) - .subscribe(explorerService.setSwimlaneLimit); + limit$.pipe(takeUntil(this._unsubscribeAll)).subscribe(explorerService.setSwimlaneLimit); // Required to redraw the time series chart when the container is resized. this.resizeChecker = new ResizeChecker(this.resizeRef.current); diff --git a/x-pack/plugins/ml/public/application/explorer/select_limit/select_limit.test.tsx b/x-pack/plugins/ml/public/application/explorer/select_limit/select_limit.test.tsx index 657f1c6c7af2e..cf65419e4bd80 100644 --- a/x-pack/plugins/ml/public/application/explorer/select_limit/select_limit.test.tsx +++ b/x-pack/plugins/ml/public/application/explorer/select_limit/select_limit.test.tsx @@ -9,8 +9,6 @@ import { act } from 'react-dom/test-utils'; import { shallow } from 'enzyme'; import { SelectLimit } from './select_limit'; -jest.useFakeTimers(); - describe('SelectLimit', () => { test('creates correct initial selected value', () => { const wrapper = shallow(); diff --git a/x-pack/plugins/ml/public/application/explorer/select_limit/select_limit.tsx b/x-pack/plugins/ml/public/application/explorer/select_limit/select_limit.tsx index 383d07eb7a9f6..03e3273b80832 100644 --- a/x-pack/plugins/ml/public/application/explorer/select_limit/select_limit.tsx +++ b/x-pack/plugins/ml/public/application/explorer/select_limit/select_limit.tsx @@ -9,7 +9,7 @@ */ import React from 'react'; import useObservable from 'react-use/lib/useObservable'; -import { Subject } from 'rxjs'; +import { BehaviorSubject } from 'rxjs'; import { EuiSelect } from '@elastic/eui'; @@ -20,13 +20,13 @@ const euiOptions = limitOptions.map(limit => ({ text: `${limit}`, })); -export const limit$ = new Subject(); export const defaultLimit = limitOptions[1]; +export const limit$ = new BehaviorSubject(defaultLimit); export const useSwimlaneLimit = (): [number, (newLimit: number) => void] => { const limit = useObservable(limit$, defaultLimit); - return [limit, (newLimit: number) => limit$.next(newLimit)]; + return [limit!, (newLimit: number) => limit$.next(newLimit)]; }; export const SelectLimit = () => { From ab5943c71d2f52d73f15562251389a4597cefdb1 Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Thu, 7 May 2020 12:10:15 +0200 Subject: [PATCH 17/23] [ML] Hide selector helper in Anomaly Explorer swimlane (#65522) --- x-pack/plugins/ml/public/application/explorer/_explorer.scss | 4 ++++ x-pack/plugins/ml/public/application/explorer/explorer.js | 1 + 2 files changed, 5 insertions(+) diff --git a/x-pack/plugins/ml/public/application/explorer/_explorer.scss b/x-pack/plugins/ml/public/application/explorer/_explorer.scss index cfcba081983c2..a46f35cbd4d20 100644 --- a/x-pack/plugins/ml/public/application/explorer/_explorer.scss +++ b/x-pack/plugins/ml/public/application/explorer/_explorer.scss @@ -1,3 +1,7 @@ +.ml-swimlane-selector { + visibility: hidden; +} + .ml-explorer { width: 100%; display: inline-block; diff --git a/x-pack/plugins/ml/public/application/explorer/explorer.js b/x-pack/plugins/ml/public/application/explorer/explorer.js index 36dac05add557..8fd2479817807 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer.js @@ -120,6 +120,7 @@ export class Explorer extends React.Component { disableDragSelectOnMouseLeave = true; dragSelect = new DragSelect({ + selectorClass: 'ml-swimlane-selector', selectables: document.getElementsByClassName('sl-cell'), callback(elements) { if (elements.length > 1 && !ALLOW_CELL_RANGE_SELECTION) { From 8b862fea069566a03b4bc23902cf5c6db6741aa3 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 7 May 2020 13:21:47 +0300 Subject: [PATCH 18/23] Change the copy and the id from blacklist to block list for consistency (#65419) Co-authored-by: Elastic Machine --- x-pack/plugins/graph/public/angular/templates/index.html | 4 ++-- x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/graph/public/angular/templates/index.html b/x-pack/plugins/graph/public/angular/templates/index.html index 8555658596179..939d92518e271 100644 --- a/x-pack/plugins/graph/public/angular/templates/index.html +++ b/x-pack/plugins/graph/public/angular/templates/index.html @@ -122,8 +122,8 @@ diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1adc77267c44f..0d050f7bf9842 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -6589,7 +6589,6 @@ "xpack.graph.sidebar.selectionsTitle": "選択項目", "xpack.graph.sidebar.styleVerticesTitle": "スタイルが選択された頂点", "xpack.graph.sidebar.topMenu.addLinksButtonTooltip": "既存の用語の間にリンクを追加します", - "xpack.graph.sidebar.topMenu.blacklistButtonTooltip": "選択項目がワークスペースに戻らないようブラックリストに追加します", "xpack.graph.sidebar.topMenu.customStyleButtonTooltip": "選択された頂点のカスタムスタイル", "xpack.graph.sidebar.topMenu.drillDownButtonTooltip": "ドリルダウン", "xpack.graph.sidebar.topMenu.expandSelectionButtonTooltip": "選択項目を拡張", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index a57b517123e77..21113d55b4641 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -6594,7 +6594,6 @@ "xpack.graph.sidebar.selectionsTitle": "选择的内容", "xpack.graph.sidebar.styleVerticesTitle": "样式选择的顶点", "xpack.graph.sidebar.topMenu.addLinksButtonTooltip": "在现有字词之间添加链接", - "xpack.graph.sidebar.topMenu.blacklistButtonTooltip": "返回工作空间时选择的黑名单", "xpack.graph.sidebar.topMenu.customStyleButtonTooltip": "定制样式选择的顶点", "xpack.graph.sidebar.topMenu.drillDownButtonTooltip": "向下钻取", "xpack.graph.sidebar.topMenu.expandSelectionButtonTooltip": "展开选择内容", From e723a8f9169b34109913728d7157efeedeba9b8b Mon Sep 17 00:00:00 2001 From: Diana Derevyankina <54894989+DziyanaDzeraviankina@users.noreply.github.com> Date: Thu, 7 May 2020 13:34:07 +0300 Subject: [PATCH 19/23] Move remaining home assets to the new platform (#65053) * Migrate tutorial resources Closes #55710 * Added type to context in apm plugin index * Removed context parameter from ApmPlugin * Generated apm plugin by generate_plugin script * Removed getGreeting declaration * Remove unused assets and comment previewImagePaths * Removed unnecessary types file * Move assets and sample_data_resources, update snapshot Co-authored-by: Elastic Machine --- .../dashboard_empty_screen.test.tsx.snap | 8 ++++---- .../public/application/dashboard_empty_screen.tsx | 4 ++-- .../application/components/sample_data/index.tsx | 2 +- .../public}/assets/illustration_elastic_heart.png | Bin .../sample_data_resources/ecommerce/dashboard.png | Bin .../ecommerce/dashboard_dark.png | Bin .../sample_data_resources/flights/dashboard.png | Bin .../flights/dashboard_dark.png | Bin .../sample_data_resources/logs/dashboard.png | Bin .../sample_data_resources/logs/dashboard_dark.png | Bin .../home/public}/assets/welcome_graphic_dark_2x.png | Bin .../public}/assets/welcome_graphic_light_2x.png | Bin .../sample_data/data_sets/ecommerce/index.ts | 4 ++-- .../services/sample_data/data_sets/flights/index.ts | 4 ++-- .../services/sample_data/data_sets/logs/index.ts | 4 ++-- 15 files changed, 13 insertions(+), 13 deletions(-) rename src/{legacy/core_plugins/kibana/public/home => plugins/home/public}/assets/illustration_elastic_heart.png (100%) rename src/{legacy/core_plugins/kibana/public/home => plugins/home/public/assets}/sample_data_resources/ecommerce/dashboard.png (100%) rename src/{legacy/core_plugins/kibana/public/home => plugins/home/public/assets}/sample_data_resources/ecommerce/dashboard_dark.png (100%) rename src/{legacy/core_plugins/kibana/public/home => plugins/home/public/assets}/sample_data_resources/flights/dashboard.png (100%) rename src/{legacy/core_plugins/kibana/public/home => plugins/home/public/assets}/sample_data_resources/flights/dashboard_dark.png (100%) rename src/{legacy/core_plugins/kibana/public/home => plugins/home/public/assets}/sample_data_resources/logs/dashboard.png (100%) rename src/{legacy/core_plugins/kibana/public/home => plugins/home/public/assets}/sample_data_resources/logs/dashboard_dark.png (100%) rename src/{legacy/core_plugins/kibana/public/home => plugins/home/public}/assets/welcome_graphic_dark_2x.png (100%) rename src/{legacy/core_plugins/kibana/public/home => plugins/home/public}/assets/welcome_graphic_light_2x.png (100%) diff --git a/src/plugins/dashboard/public/application/__snapshots__/dashboard_empty_screen.test.tsx.snap b/src/plugins/dashboard/public/application/__snapshots__/dashboard_empty_screen.test.tsx.snap index 1bc85fa110ca0..698c124d2d805 100644 --- a/src/plugins/dashboard/public/application/__snapshots__/dashboard_empty_screen.test.tsx.snap +++ b/src/plugins/dashboard/public/application/__snapshots__/dashboard_empty_screen.test.tsx.snap @@ -301,7 +301,7 @@ exports[`DashboardEmptyScreen renders correctly with readonly mode 1`] = ` >
      @@ -995,7 +995,7 @@ exports[`DashboardEmptyScreen renders correctly without visualize paragraph 1`] >
      diff --git a/src/plugins/dashboard/public/application/dashboard_empty_screen.tsx b/src/plugins/dashboard/public/application/dashboard_empty_screen.tsx index 8bf205b8cb507..955d5244ce190 100644 --- a/src/plugins/dashboard/public/application/dashboard_empty_screen.tsx +++ b/src/plugins/dashboard/public/application/dashboard_empty_screen.tsx @@ -50,8 +50,8 @@ export function DashboardEmptyScreen({ }: DashboardEmptyScreenProps) { const IS_DARK_THEME = uiSettings.get('theme:darkMode'); const emptyStateGraphicURL = IS_DARK_THEME - ? '/plugins/kibana/home/assets/welcome_graphic_dark_2x.png' - : '/plugins/kibana/home/assets/welcome_graphic_light_2x.png'; + ? '/plugins/home/assets/welcome_graphic_dark_2x.png' + : '/plugins/home/assets/welcome_graphic_light_2x.png'; const linkToVisualizeParagraph = (

      } description={ diff --git a/src/legacy/core_plugins/kibana/public/home/assets/illustration_elastic_heart.png b/src/plugins/home/public/assets/illustration_elastic_heart.png similarity index 100% rename from src/legacy/core_plugins/kibana/public/home/assets/illustration_elastic_heart.png rename to src/plugins/home/public/assets/illustration_elastic_heart.png diff --git a/src/legacy/core_plugins/kibana/public/home/sample_data_resources/ecommerce/dashboard.png b/src/plugins/home/public/assets/sample_data_resources/ecommerce/dashboard.png similarity index 100% rename from src/legacy/core_plugins/kibana/public/home/sample_data_resources/ecommerce/dashboard.png rename to src/plugins/home/public/assets/sample_data_resources/ecommerce/dashboard.png diff --git a/src/legacy/core_plugins/kibana/public/home/sample_data_resources/ecommerce/dashboard_dark.png b/src/plugins/home/public/assets/sample_data_resources/ecommerce/dashboard_dark.png similarity index 100% rename from src/legacy/core_plugins/kibana/public/home/sample_data_resources/ecommerce/dashboard_dark.png rename to src/plugins/home/public/assets/sample_data_resources/ecommerce/dashboard_dark.png diff --git a/src/legacy/core_plugins/kibana/public/home/sample_data_resources/flights/dashboard.png b/src/plugins/home/public/assets/sample_data_resources/flights/dashboard.png similarity index 100% rename from src/legacy/core_plugins/kibana/public/home/sample_data_resources/flights/dashboard.png rename to src/plugins/home/public/assets/sample_data_resources/flights/dashboard.png diff --git a/src/legacy/core_plugins/kibana/public/home/sample_data_resources/flights/dashboard_dark.png b/src/plugins/home/public/assets/sample_data_resources/flights/dashboard_dark.png similarity index 100% rename from src/legacy/core_plugins/kibana/public/home/sample_data_resources/flights/dashboard_dark.png rename to src/plugins/home/public/assets/sample_data_resources/flights/dashboard_dark.png diff --git a/src/legacy/core_plugins/kibana/public/home/sample_data_resources/logs/dashboard.png b/src/plugins/home/public/assets/sample_data_resources/logs/dashboard.png similarity index 100% rename from src/legacy/core_plugins/kibana/public/home/sample_data_resources/logs/dashboard.png rename to src/plugins/home/public/assets/sample_data_resources/logs/dashboard.png diff --git a/src/legacy/core_plugins/kibana/public/home/sample_data_resources/logs/dashboard_dark.png b/src/plugins/home/public/assets/sample_data_resources/logs/dashboard_dark.png similarity index 100% rename from src/legacy/core_plugins/kibana/public/home/sample_data_resources/logs/dashboard_dark.png rename to src/plugins/home/public/assets/sample_data_resources/logs/dashboard_dark.png diff --git a/src/legacy/core_plugins/kibana/public/home/assets/welcome_graphic_dark_2x.png b/src/plugins/home/public/assets/welcome_graphic_dark_2x.png similarity index 100% rename from src/legacy/core_plugins/kibana/public/home/assets/welcome_graphic_dark_2x.png rename to src/plugins/home/public/assets/welcome_graphic_dark_2x.png diff --git a/src/legacy/core_plugins/kibana/public/home/assets/welcome_graphic_light_2x.png b/src/plugins/home/public/assets/welcome_graphic_light_2x.png similarity index 100% rename from src/legacy/core_plugins/kibana/public/home/assets/welcome_graphic_light_2x.png rename to src/plugins/home/public/assets/welcome_graphic_light_2x.png diff --git a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/index.ts b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/index.ts index 3e16187c44343..b0cc2e2db3cc9 100644 --- a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/index.ts +++ b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/index.ts @@ -36,8 +36,8 @@ export const ecommerceSpecProvider = function(): SampleDatasetSchema { id: 'ecommerce', name: ecommerceName, description: ecommerceDescription, - previewImagePath: '/plugins/kibana/home/sample_data_resources/ecommerce/dashboard.png', - darkPreviewImagePath: '/plugins/kibana/home/sample_data_resources/ecommerce/dashboard_dark.png', + previewImagePath: '/plugins/home/assets/sample_data_resources/ecommerce/dashboard.png', + darkPreviewImagePath: '/plugins/home/assets/sample_data_resources/ecommerce/dashboard_dark.png', overviewDashboard: '722b74f0-b882-11e8-a6d9-e546fe2bba5f', appLinks: initialAppLinks, defaultIndex: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', diff --git a/src/plugins/home/server/services/sample_data/data_sets/flights/index.ts b/src/plugins/home/server/services/sample_data/data_sets/flights/index.ts index d63ea8f7fb493..fc3cb6094b5ea 100644 --- a/src/plugins/home/server/services/sample_data/data_sets/flights/index.ts +++ b/src/plugins/home/server/services/sample_data/data_sets/flights/index.ts @@ -36,8 +36,8 @@ export const flightsSpecProvider = function(): SampleDatasetSchema { id: 'flights', name: flightsName, description: flightsDescription, - previewImagePath: '/plugins/kibana/home/sample_data_resources/flights/dashboard.png', - darkPreviewImagePath: '/plugins/kibana/home/sample_data_resources/flights/dashboard_dark.png', + previewImagePath: '/plugins/home/assets/sample_data_resources/flights/dashboard.png', + darkPreviewImagePath: '/plugins/home/assets/sample_data_resources/flights/dashboard_dark.png', overviewDashboard: '7adfa750-4c81-11e8-b3d7-01146121b73d', appLinks: initialAppLinks, defaultIndex: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', diff --git a/src/plugins/home/server/services/sample_data/data_sets/logs/index.ts b/src/plugins/home/server/services/sample_data/data_sets/logs/index.ts index bb6e2982f59a0..d8f205dff24e8 100644 --- a/src/plugins/home/server/services/sample_data/data_sets/logs/index.ts +++ b/src/plugins/home/server/services/sample_data/data_sets/logs/index.ts @@ -36,8 +36,8 @@ export const logsSpecProvider = function(): SampleDatasetSchema { id: 'logs', name: logsName, description: logsDescription, - previewImagePath: '/plugins/kibana/home/sample_data_resources/logs/dashboard.png', - darkPreviewImagePath: '/plugins/kibana/home/sample_data_resources/logs/dashboard_dark.png', + previewImagePath: '/plugins/home/assets/sample_data_resources/logs/dashboard.png', + darkPreviewImagePath: '/plugins/home/assets/sample_data_resources/logs/dashboard_dark.png', overviewDashboard: 'edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b', appLinks: initialAppLinks, defaultIndex: '90943e30-9a47-11e8-b64d-95841ca0b247', From 6ef45e17d4908f8129f0ce9f1aee9a818938a281 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Thu, 7 May 2020 14:15:37 +0300 Subject: [PATCH 20/23] =?UTF-8?q?Migrate=20test=20plugins=20=E2=87=92=20NP?= =?UTF-8?q?=20(kbn=5Ftp=5Fembeddable=5Fexplorer)=20(#64756)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Migrated kbn_tp_embeddable_explorer to the new platform. * Added discover as a dependency * fixed types * Updated typescript task * revert previous commit Co-authored-by: Elastic Machine --- .../kbn_tp_embeddable_explorer/index.ts | 39 -------- .../kbn_tp_embeddable_explorer/kibana.json | 16 +++ .../public/{np_ready/public => }/app/app.tsx | 0 .../app/dashboard_container_example.tsx | 2 +- .../public => }/app/dashboard_input.ts | 2 +- .../public/{np_ready/public => }/app/index.ts | 0 .../{np_ready/public => }/embeddable_api.ts | 9 +- .../public/{np_ready/public => }/index.ts | 0 .../public/initialize.ts | 20 ---- .../public/np_ready/kibana.json | 10 -- .../public/np_ready/public/index.html | 3 - .../public/np_ready/public/legacy.ts | 90 ----------------- .../public/np_ready/public/plugin.tsx | 84 ---------------- .../public/plugin.tsx | 98 +++++++++++++++++++ 14 files changed, 122 insertions(+), 251 deletions(-) delete mode 100644 test/plugin_functional/plugins/kbn_tp_embeddable_explorer/index.ts create mode 100644 test/plugin_functional/plugins/kbn_tp_embeddable_explorer/kibana.json rename test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/{np_ready/public => }/app/app.tsx (100%) rename test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/{np_ready/public => }/app/dashboard_container_example.tsx (98%) rename test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/{np_ready/public => }/app/dashboard_input.ts (96%) rename test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/{np_ready/public => }/app/index.ts (100%) rename test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/{np_ready/public => }/embeddable_api.ts (74%) rename test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/{np_ready/public => }/index.ts (100%) delete mode 100644 test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/initialize.ts delete mode 100644 test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/kibana.json delete mode 100644 test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/index.html delete mode 100644 test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/legacy.ts delete mode 100644 test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/plugin.tsx create mode 100644 test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/plugin.tsx diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/index.ts b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/index.ts deleted file mode 100644 index 99f54277be5d2..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { Legacy } from 'kibana'; - -// eslint-disable-next-line import/no-default-export -export default function(kibana: any) { - return new kibana.Plugin({ - require: ['kibana'], - uiExports: { - app: { - title: 'Embeddable Explorer', - order: 1, - main: 'plugins/kbn_tp_embeddable_explorer/np_ready/public/legacy', - }, - }, - init(server: Legacy.Server) { - server.injectUiAppVars('kbn_tp_embeddable_explorer', async () => - server.getInjectedUiAppVars('kibana') - ); - }, - }); -} diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/kibana.json b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/kibana.json new file mode 100644 index 0000000000000..6c8d51ccb8651 --- /dev/null +++ b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/kibana.json @@ -0,0 +1,16 @@ +{ + "id": "kbn_tp_embeddable_explorer", + "version": "0.0.1", + "kibanaVersion": "kibana", + "requiredPlugins": [ + "visTypeMarkdown", + "visTypeVislib", + "data", + "embeddable", + "uiActions", + "inspector", + "discover" + ], + "server": false, + "ui": true +} diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/app.tsx b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/app.tsx similarity index 100% rename from test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/app.tsx rename to test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/app.tsx diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/dashboard_container_example.tsx b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/dashboard_container_example.tsx similarity index 98% rename from test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/dashboard_container_example.tsx rename to test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/dashboard_container_example.tsx index 16c2840d6a32e..e56b82378ddf7 100644 --- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/dashboard_container_example.tsx +++ b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/dashboard_container_example.tsx @@ -24,7 +24,7 @@ import { DASHBOARD_CONTAINER_TYPE, DashboardContainer, DashboardContainerInput, -} from '../../../../../../../../src/plugins/dashboard/public'; +} from '../../../../../../src/plugins/dashboard/public'; import { dashboardInput } from './dashboard_input'; diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/dashboard_input.ts b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/dashboard_input.ts similarity index 96% rename from test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/dashboard_input.ts rename to test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/dashboard_input.ts index 37ef8cad948cb..6f4e1f052f5e0 100644 --- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/dashboard_input.ts +++ b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/dashboard_input.ts @@ -18,7 +18,7 @@ */ import { ViewMode, CONTACT_CARD_EMBEDDABLE, HELLO_WORLD_EMBEDDABLE } from '../embeddable_api'; -import { DashboardContainerInput } from '../../../../../../../../src/plugins/dashboard/public'; +import { DashboardContainerInput } from '../../../../../../src/plugins/dashboard/public'; export const dashboardInput: DashboardContainerInput = { panels: { diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/index.ts b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/index.ts similarity index 100% rename from test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/app/index.ts rename to test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/index.ts diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/embeddable_api.ts b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/embeddable_api.ts similarity index 74% rename from test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/embeddable_api.ts rename to test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/embeddable_api.ts index dd25bebf89920..9f6597fefa1e4 100644 --- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/embeddable_api.ts +++ b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/embeddable_api.ts @@ -17,6 +17,9 @@ * under the License. */ -export * from '../../../../../../../src/plugins/embeddable/public'; -export * from '../../../../../../../src/plugins/embeddable/public/lib/test_samples'; -export { HELLO_WORLD_EMBEDDABLE } from '../../../../../../../examples/embeddable_examples/public'; +export * from '../../../../../src/plugins/embeddable/public'; +export * from '../../../../../src/plugins/embeddable/public/lib/test_samples'; +export { + HELLO_WORLD_EMBEDDABLE, + HelloWorldEmbeddableFactory, +} from '../../../../../examples/embeddable_examples/public'; diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/index.ts b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/index.ts similarity index 100% rename from test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/index.ts rename to test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/index.ts diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/initialize.ts b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/initialize.ts deleted file mode 100644 index a4bc3cf17026c..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/initialize.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import './np_ready/public/legacy'; diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/kibana.json b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/kibana.json deleted file mode 100644 index d0d0784eae8d3..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/kibana.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "id": "kbn_tp_embeddable_explorer", - "version": "kibana", - "requiredPlugins": [ - "embeddable", - "inspector" - ], - "server": false, - "ui": true -} diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/index.html b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/index.html deleted file mode 100644 index a242631e1638f..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/index.html +++ /dev/null @@ -1,3 +0,0 @@ - -

      ANGULAR STUFF!
      - diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/legacy.ts b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/legacy.ts deleted file mode 100644 index 6d125bc3002e0..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/legacy.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ -import 'ui/autoload/all'; - -import 'uiExports/interpreter'; -import 'uiExports/embeddableFactories'; -import 'uiExports/embeddableActions'; -import 'uiExports/contextMenuActions'; -import 'uiExports/devTools'; -import 'uiExports/docViews'; -import 'uiExports/embeddableActions'; -import 'uiExports/fieldFormatEditors'; -import 'uiExports/fieldFormats'; -import 'uiExports/home'; -import 'uiExports/indexManagement'; -import 'uiExports/inspectorViews'; -import 'uiExports/savedObjectTypes'; -import 'uiExports/search'; -import 'uiExports/shareContextMenuExtensions'; -import 'uiExports/visTypes'; -import 'uiExports/visualize'; - -import { npSetup, npStart } from 'ui/new_platform'; -import { ExitFullScreenButton } from 'ui/exit_full_screen'; -import uiRoutes from 'ui/routes'; -// @ts-ignore -import { uiModules } from 'ui/modules'; -/* eslint-enable @kbn/eslint/no-restricted-paths */ - -import template from './index.html'; - -import { plugin } from '.'; - -const pluginInstance = plugin({} as any); - -export const setup = pluginInstance.setup(npSetup.core, { - embeddable: npSetup.plugins.embeddable, - inspector: npSetup.plugins.inspector, - __LEGACY: { - ExitFullScreenButton, - }, -}); - -let rendered = false; -const onRenderCompleteListeners: Array<() => void> = []; - -uiRoutes.enable(); -uiRoutes.defaults(/\embeddable_explorer/, {}); -uiRoutes.when('/', { - template, - controller($scope) { - $scope.$$postDigest(() => { - rendered = true; - onRenderCompleteListeners.forEach(listener => listener()); - }); - }, -}); - -export const start = pluginInstance.start(npStart.core, { - embeddable: npStart.plugins.embeddable, - inspector: npStart.plugins.inspector, - uiActions: npStart.plugins.uiActions, - __LEGACY: { - ExitFullScreenButton, - onRenderComplete: (renderCompleteListener: () => void) => { - if (rendered) { - renderCompleteListener(); - } else { - onRenderCompleteListeners.push(renderCompleteListener); - } - }, - }, -}); diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/plugin.tsx b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/plugin.tsx deleted file mode 100644 index b47e84216dd16..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/plugin.tsx +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import React from 'react'; -import ReactDOM from 'react-dom'; -import { CoreSetup, CoreStart, Plugin } from 'src/core/public'; -import { UiActionsStart } from '../../../../../../../src/plugins/ui_actions/public'; -import { createHelloWorldAction } from '../../../../../../../src/plugins/ui_actions/public/tests/test_samples'; - -import { - Start as InspectorStartContract, - Setup as InspectorSetupContract, -} from '../../../../../../../src/plugins/inspector/public'; - -import { CONTEXT_MENU_TRIGGER } from './embeddable_api'; - -const REACT_ROOT_ID = 'embeddableExplorerRoot'; - -import { SayHelloAction, createSendMessageAction } from './embeddable_api'; -import { App } from './app'; -import { - EmbeddableStart, - EmbeddableSetup, -} from '.../../../../../../../src/plugins/embeddable/public'; - -export interface SetupDependencies { - embeddable: EmbeddableSetup; - inspector: InspectorSetupContract; - __LEGACY: { - ExitFullScreenButton: React.ComponentType; - }; -} - -interface StartDependencies { - embeddable: EmbeddableStart; - uiActions: UiActionsStart; - inspector: InspectorStartContract; - __LEGACY: { - ExitFullScreenButton: React.ComponentType; - onRenderComplete: (onRenderComplete: () => void) => void; - }; -} - -export type EmbeddableExplorerSetup = void; -export type EmbeddableExplorerStart = void; - -export class EmbeddableExplorerPublicPlugin - implements - Plugin { - public setup(core: CoreSetup, setupDeps: SetupDependencies): EmbeddableExplorerSetup {} - - public start(core: CoreStart, plugins: StartDependencies): EmbeddableExplorerStart { - const helloWorldAction = createHelloWorldAction(core.overlays); - const sayHelloAction = new SayHelloAction(alert); - const sendMessageAction = createSendMessageAction(core.overlays); - - plugins.uiActions.registerAction(sayHelloAction); - plugins.uiActions.registerAction(sendMessageAction); - - plugins.uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, helloWorldAction); - - plugins.__LEGACY.onRenderComplete(() => { - const root = document.getElementById(REACT_ROOT_ID); - ReactDOM.render(, root); - }); - } - - public stop() {} -} diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/plugin.tsx b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/plugin.tsx new file mode 100644 index 0000000000000..f99d89ca630bb --- /dev/null +++ b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/plugin.tsx @@ -0,0 +1,98 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; +import { CoreSetup, Plugin, AppMountParameters } from 'kibana/public'; +import { UiActionsStart, UiActionsSetup } from '../../../../../src/plugins/ui_actions/public'; +import { createHelloWorldAction } from '../../../../../src/plugins/ui_actions/public/tests/test_samples'; + +import { + Start as InspectorStartContract, + Setup as InspectorSetupContract, +} from '../../../../../src/plugins/inspector/public'; + +import { App } from './app'; +import { + CONTEXT_MENU_TRIGGER, + CONTACT_CARD_EMBEDDABLE, + HELLO_WORLD_EMBEDDABLE, + HelloWorldEmbeddableFactory, + ContactCardEmbeddableFactory, + SayHelloAction, + createSendMessageAction, +} from './embeddable_api'; +import { + EmbeddableStart, + EmbeddableSetup, +} from '.../../../../../../../src/plugins/embeddable/public'; + +export interface SetupDependencies { + embeddable: EmbeddableSetup; + inspector: InspectorSetupContract; + uiActions: UiActionsSetup; +} + +interface StartDependencies { + embeddable: EmbeddableStart; + uiActions: UiActionsStart; + inspector: InspectorStartContract; +} + +export type EmbeddableExplorerSetup = void; +export type EmbeddableExplorerStart = void; + +export class EmbeddableExplorerPublicPlugin + implements + Plugin { + public setup(core: CoreSetup, setupDeps: SetupDependencies): EmbeddableExplorerSetup { + const helloWorldAction = createHelloWorldAction({} as any); + const sayHelloAction = new SayHelloAction(alert); + const sendMessageAction = createSendMessageAction({} as any); + + setupDeps.uiActions.registerAction(helloWorldAction); + setupDeps.uiActions.registerAction(sayHelloAction); + setupDeps.uiActions.registerAction(sendMessageAction); + + setupDeps.uiActions.attachAction(CONTEXT_MENU_TRIGGER, helloWorldAction.id); + + setupDeps.embeddable.registerEmbeddableFactory( + HELLO_WORLD_EMBEDDABLE, + new HelloWorldEmbeddableFactory() + ); + + setupDeps.embeddable.registerEmbeddableFactory( + CONTACT_CARD_EMBEDDABLE, + new ContactCardEmbeddableFactory((() => null) as any, {} as any) + ); + + core.application.register({ + id: 'EmbeddableExplorer', + title: 'Embeddable Explorer', + async mount(params: AppMountParameters) { + const startPlugins = (await core.getStartServices())[1] as StartDependencies; + render(, params.element); + + return () => unmountComponentAtNode(params.element); + }, + }); + } + + public start() {} + public stop() {} +} From 3604f5d21ae4ea5d72873196afe62056a2f0496c Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Thu, 7 May 2020 13:18:56 +0200 Subject: [PATCH 21/23] [Drilldowns] Preserve state when selecting different action factory (#65074) Co-authored-by: Elastic Machine --- .../action_wizard/action_wizard.tsx | 6 +- .../components/action_wizard/test_data.tsx | 2 +- ...onnected_flyout_manage_drilldowns.test.tsx | 36 ++++++ .../flyout_drilldown_wizard.tsx | 103 ++++++++++++------ .../form_drilldown_wizard.tsx | 2 +- 5 files changed, 112 insertions(+), 37 deletions(-) diff --git a/x-pack/plugins/advanced_ui_actions/public/components/action_wizard/action_wizard.tsx b/x-pack/plugins/advanced_ui_actions/public/components/action_wizard/action_wizard.tsx index 867ead688d23d..4d14226777a0b 100644 --- a/x-pack/plugins/advanced_ui_actions/public/components/action_wizard/action_wizard.tsx +++ b/x-pack/plugins/advanced_ui_actions/public/components/action_wizard/action_wizard.tsx @@ -32,9 +32,9 @@ export interface ActionWizardProps { /** * Action factory selected changed - * null - means user click "change" and removed action factory selection + * empty - means user click "change" and removed action factory selection */ - onActionFactoryChange: (actionFactory: ActionFactory | null) => void; + onActionFactoryChange: (actionFactory?: ActionFactory) => void; /** * current config for currently selected action factory @@ -71,7 +71,7 @@ export const ActionWizard: React.FC = ({ actionFactory={currentActionFactory} showDeselect={actionFactories.length > 1} onDeselect={() => { - onActionFactoryChange(null); + onActionFactoryChange(undefined); }} context={context} config={config} diff --git a/x-pack/plugins/advanced_ui_actions/public/components/action_wizard/test_data.tsx b/x-pack/plugins/advanced_ui_actions/public/components/action_wizard/test_data.tsx index c3e749f163c94..692e86b53f09d 100644 --- a/x-pack/plugins/advanced_ui_actions/public/components/action_wizard/test_data.tsx +++ b/x-pack/plugins/advanced_ui_actions/public/components/action_wizard/test_data.tsx @@ -167,7 +167,7 @@ export function Demo({ actionFactories }: { actionFactories: Array({}); - function changeActionFactory(newActionFactory: ActionFactory | null) { + function changeActionFactory(newActionFactory?: ActionFactory) { if (!newActionFactory) { // removing action factory return setState({}); diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx index 6749b41e81fc7..52c53f32ff09b 100644 --- a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx +++ b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx @@ -173,6 +173,42 @@ test('Create only mode', async () => { expect(await mockDynamicActionManager.state.get().events.length).toBe(1); }); +test('After switching between action factories state is restored', async () => { + const screen = render( + + ); + // wait for initial render. It is async because resolving compatible action factories is async + await wait(() => expect(screen.getAllByText(/Create/i).length).toBeGreaterThan(0)); + fireEvent.change(screen.getByLabelText(/name/i), { + target: { value: 'test' }, + }); + fireEvent.click(screen.getByText(/Go to URL/i)); + fireEvent.change(screen.getByLabelText(/url/i), { + target: { value: 'https://elastic.co' }, + }); + + // change to dashboard + fireEvent.click(screen.getByText(/change/i)); + fireEvent.click(screen.getByText(/Go to Dashboard/i)); + + // change back to url + fireEvent.click(screen.getByText(/change/i)); + fireEvent.click(screen.getByText(/Go to URL/i)); + + expect(screen.getByLabelText(/url/i)).toHaveValue('https://elastic.co'); + expect(screen.getByLabelText(/name/i)).toHaveValue('test'); + + fireEvent.click(screen.getAllByText(/Create Drilldown/i)[1]); + await wait(() => expect(notifications.toasts.addSuccess).toBeCalled()); + expect(await (mockDynamicActionManager.state.get().events[0].action.config as any).url).toBe( + 'https://elastic.co' + ); +}); + test.todo("Error when can't fetch drilldown list"); test("Error when can't save drilldown changes", async () => { diff --git a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx b/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx index 8541aae06ff0c..1f775a5ff103f 100644 --- a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx +++ b/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx @@ -41,6 +41,72 @@ export interface FlyoutDrilldownWizardProps void; + setActionConfig: (actionConfig: object) => void; + setActionFactory: (actionFactory?: ActionFactory) => void; + } +] { + const [wizardConfig, setWizardConfig] = useState( + () => + initialDrilldownWizardConfig ?? { + name: '', + } + ); + const [actionConfigCache, setActionConfigCache] = useState>( + initialDrilldownWizardConfig?.actionFactory + ? { + [initialDrilldownWizardConfig.actionFactory + .id]: initialDrilldownWizardConfig.actionConfig!, + } + : {} + ); + + return [ + wizardConfig, + { + setName: (name: string) => { + setWizardConfig({ + ...wizardConfig, + name, + }); + }, + setActionConfig: (actionConfig: object) => { + setWizardConfig({ + ...wizardConfig, + actionConfig, + }); + }, + setActionFactory: (actionFactory?: ActionFactory) => { + if (actionFactory) { + setWizardConfig({ + ...wizardConfig, + actionFactory, + actionConfig: actionConfigCache[actionFactory.id] ?? actionFactory.createConfig(), + }); + } else { + if (wizardConfig.actionFactory?.id) { + setActionConfigCache({ + ...actionConfigCache, + [wizardConfig.actionFactory.id]: wizardConfig.actionConfig!, + }); + } + + setWizardConfig({ + ...wizardConfig, + actionFactory: undefined, + actionConfig: undefined, + }); + } + }, + }, + ]; +} + export function FlyoutDrilldownWizard({ onClose, onBack, @@ -53,11 +119,8 @@ export function FlyoutDrilldownWizard) { - const [wizardConfig, setWizardConfig] = useState( - () => - initialDrilldownWizardConfig ?? { - name: '', - } + const [wizardConfig, { setActionFactory, setActionConfig, setName }] = useWizardConfigState( + initialDrilldownWizardConfig ); const isActionValid = ( @@ -95,35 +158,11 @@ export function FlyoutDrilldownWizard { - setWizardConfig({ - ...wizardConfig, - name: newName, - }); - }} + onNameChange={setName} actionConfig={wizardConfig.actionConfig} - onActionConfigChange={newActionConfig => { - setWizardConfig({ - ...wizardConfig, - actionConfig: newActionConfig, - }); - }} + onActionConfigChange={setActionConfig} currentActionFactory={wizardConfig.actionFactory} - onActionFactoryChange={actionFactory => { - if (!actionFactory) { - setWizardConfig({ - ...wizardConfig, - actionFactory: undefined, - actionConfig: undefined, - }); - } else { - setWizardConfig({ - ...wizardConfig, - actionFactory, - actionConfig: actionFactory.createConfig(), - }); - } - }} + onActionFactoryChange={setActionFactory} actionFactories={drilldownActionFactories} actionFactoryContext={actionFactoryContext!} /> diff --git a/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.tsx b/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.tsx index 93b3710bf6cc6..3bed81a971921 100644 --- a/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.tsx +++ b/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.tsx @@ -19,7 +19,7 @@ export interface FormDrilldownWizardProps { onNameChange?: (name: string) => void; currentActionFactory?: ActionFactory; - onActionFactoryChange?: (actionFactory: ActionFactory | null) => void; + onActionFactoryChange?: (actionFactory?: ActionFactory) => void; actionFactoryContext: object; actionConfig?: object; From 55e4c7f9a78d81ae213471b68c8b4c2075e1616d Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Thu, 7 May 2020 12:23:42 +0100 Subject: [PATCH 22/23] [ML] Consolidating shared types and util functions (#65247) * [ML] Consolidating shared types and util functions * including formatter * adding missing includes * removing unused export * ignoring numeral type error Co-authored-by: Elastic Machine --- .../field_type_icon/field_type_icon.js | 2 -- .../message_call_out/message_call_out.js | 2 -- .../validate_job/validate_job_view.js | 2 -- .../file_based/components/utils/utils.ts | 1 + .../explorer_chart_distribution.js | 2 -- .../explorer_chart_single_metric.js | 2 -- .../explorer/explorer_swimlane.tsx | 2 -- .../forecasting_modal/forecasting_modal.js | 2 -- .../forecasting_modal/run_controls.js | 2 -- x-pack/plugins/ml/public/index.ts | 4 ++-- x-pack/plugins/ml/public/shared.ts | 22 +++++++++++++++++++ x-pack/plugins/ml/server/index.ts | 1 + x-pack/plugins/ml/server/shared.ts | 7 ++++++ .../public/components/ml_popover/types.ts | 2 +- .../siem/server/lib/machine_learning/index.ts | 2 +- .../public/__mocks__/shared_imports.ts | 6 ++--- .../public/app/common/aggregations.ts | 2 +- .../transform/public/shared_imports.ts | 7 +++--- .../common/charts/duration_line_bar_list.tsx | 4 ++-- .../components/monitor/ml/ml_integeration.tsx | 2 +- .../monitor_duration_container.tsx | 2 +- .../uptime/public/state/actions/ml_anomaly.ts | 8 ++++--- .../uptime/public/state/api/ml_anomaly.ts | 8 ++++--- .../public/state/reducers/ml_anomaly.ts | 3 +-- 24 files changed, 57 insertions(+), 40 deletions(-) create mode 100644 x-pack/plugins/ml/public/shared.ts create mode 100644 x-pack/plugins/ml/server/shared.ts diff --git a/x-pack/plugins/ml/public/application/components/field_type_icon/field_type_icon.js b/x-pack/plugins/ml/public/application/components/field_type_icon/field_type_icon.js index a3c60a87636f9..1853c3d629c3e 100644 --- a/x-pack/plugins/ml/public/application/components/field_type_icon/field_type_icon.js +++ b/x-pack/plugins/ml/public/application/components/field_type_icon/field_type_icon.js @@ -9,8 +9,6 @@ import React from 'react'; import { EuiToolTip } from '@elastic/eui'; -// don't use something like plugins/ml/../common -// because it won't work with the jest tests import { getMLJobTypeAriaLabel } from '../../util/field_types_utils'; import { ML_JOB_FIELD_TYPES } from '../../../../common/constants/field_types'; import { i18n } from '@kbn/i18n'; diff --git a/x-pack/plugins/ml/public/application/components/message_call_out/message_call_out.js b/x-pack/plugins/ml/public/application/components/message_call_out/message_call_out.js index 9a122a0eea700..9a1260ecfdd45 100644 --- a/x-pack/plugins/ml/public/application/components/message_call_out/message_call_out.js +++ b/x-pack/plugins/ml/public/application/components/message_call_out/message_call_out.js @@ -14,8 +14,6 @@ import PropTypes from 'prop-types'; import { EuiCallOut } from '@elastic/eui'; -// don't use something like plugins/ml/../common -// because it won't work with the jest tests import { MESSAGE_LEVEL } from '../../../../common/constants/message_levels'; function getCallOutAttributes(message, status) { diff --git a/x-pack/plugins/ml/public/application/components/validate_job/validate_job_view.js b/x-pack/plugins/ml/public/application/components/validate_job/validate_job_view.js index 98e027ec4f365..6001d7cbf6f61 100644 --- a/x-pack/plugins/ml/public/application/components/validate_job/validate_job_view.js +++ b/x-pack/plugins/ml/public/application/components/validate_job/validate_job_view.js @@ -30,8 +30,6 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { getDocLinks } from '../../util/dependency_cache'; -// don't use something like plugins/ml/../common -// because it won't work with the jest tests import { VALIDATION_STATUS } from '../../../../common/constants/validation'; import { getMostSevereMessageStatus } from '../../../../common/util/validation_utils'; diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/utils.ts b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/utils.ts index 7d966949624c1..3b82a34b889b7 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/utils.ts +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/utils.ts @@ -5,6 +5,7 @@ */ import { isEqual } from 'lodash'; +// @ts-ignore import numeral from '@elastic/numeral'; import { ml } from '../../../../services/ml_api_service'; import { AnalysisResult, InputOverrides } from '../../../../../../common/types/file_datavisualizer'; diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js index 03426869b0ccf..2b577c978eb13 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js @@ -17,8 +17,6 @@ import d3 from 'd3'; import $ from 'jquery'; import moment from 'moment'; -// don't use something like plugins/ml/../common -// because it won't work with the jest tests import { formatHumanReadableDateTime } from '../../util/date_utils'; import { formatValue } from '../../formatters/format_value'; import { getSeverityColor, getSeverityWithLow } from '../../../../common/util/anomaly_utils'; diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js index 82041af39ca15..531a24493c961 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js @@ -17,8 +17,6 @@ import d3 from 'd3'; import $ from 'jquery'; import moment from 'moment'; -// don't use something like plugins/ml/../common -// because it won't work with the jest tests import { formatHumanReadableDateTime } from '../../util/date_utils'; import { formatValue } from '../../formatters/format_value'; import { diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_swimlane.tsx b/x-pack/plugins/ml/public/application/explorer/explorer_swimlane.tsx index bf1a3b424edb9..8a8a826e1831f 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_swimlane.tsx +++ b/x-pack/plugins/ml/public/application/explorer/explorer_swimlane.tsx @@ -14,8 +14,6 @@ import _ from 'lodash'; import d3 from 'd3'; import moment from 'moment'; -// don't use something like plugins/ml/../common -// because it won't work with the jest tests import { i18n } from '@kbn/i18n'; import { Subscription } from 'rxjs'; import { TooltipValue } from '@elastic/charts'; diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecasting_modal.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecasting_modal.js index 64f2066793118..eded8460d2205 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecasting_modal.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecasting_modal.js @@ -15,8 +15,6 @@ import React, { Component } from 'react'; import { EuiButton, EuiToolTip } from '@elastic/eui'; -// don't use something like plugins/ml/../common -// because it won't work with the jest tests import { FORECAST_REQUEST_STATE, JOB_STATE } from '../../../../../common/constants/states'; import { MESSAGE_LEVEL } from '../../../../../common/constants/message_levels'; import { isJobVersionGte } from '../../../../../common/util/job_utils'; diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/run_controls.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/run_controls.js index 7dd06268f7f8d..3208697073b8e 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/run_controls.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/run_controls.js @@ -23,8 +23,6 @@ import { EuiToolTip, } from '@elastic/eui'; -// don't use something like plugins/ml/../common -// because it won't work with the jest tests import { JOB_STATE } from '../../../../../common/constants/states'; import { FORECAST_DURATION_MAX_DAYS } from './forecasting_modal'; import { ForecastProgress } from './forecast_progress'; diff --git a/x-pack/plugins/ml/public/index.ts b/x-pack/plugins/ml/public/index.ts index c23d042822816..a9ffb1a5bf579 100755 --- a/x-pack/plugins/ml/public/index.ts +++ b/x-pack/plugins/ml/public/index.ts @@ -13,7 +13,6 @@ import { MlSetupDependencies, MlStartDependencies, } from './plugin'; -import { getMetricChangeDescription } from './application/formatters/metric_change_description'; export const plugin: PluginInitializer< MlPluginSetup, @@ -22,4 +21,5 @@ export const plugin: PluginInitializer< MlStartDependencies > = () => new MlPlugin(); -export { MlPluginSetup, MlPluginStart, getMetricChangeDescription }; +export { MlPluginSetup, MlPluginStart }; +export * from './shared'; diff --git a/x-pack/plugins/ml/public/shared.ts b/x-pack/plugins/ml/public/shared.ts new file mode 100644 index 0000000000000..6821cb7ef0f94 --- /dev/null +++ b/x-pack/plugins/ml/public/shared.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from '../common/constants/anomalies'; + +export * from '../common/types/data_recognizer'; +export * from '../common/types/capabilities'; +export * from '../common/types/anomalies'; +export * from '../common/types/modules'; +export * from '../common/types/audit_message'; + +export * from '../common/util/anomaly_utils'; +export * from '../common/util/errors'; +export * from '../common/util/validators'; + +export * from './application/formatters/metric_change_description'; + +export * from './application/components/data_grid'; +export * from './application/data_frame_analytics/common'; diff --git a/x-pack/plugins/ml/server/index.ts b/x-pack/plugins/ml/server/index.ts index 175c20bf49c94..4c27854ec719b 100644 --- a/x-pack/plugins/ml/server/index.ts +++ b/x-pack/plugins/ml/server/index.ts @@ -7,5 +7,6 @@ import { PluginInitializerContext } from 'kibana/server'; import { MlServerPlugin } from './plugin'; export { MlPluginSetup, MlPluginStart } from './plugin'; +export * from './shared'; export const plugin = (ctx: PluginInitializerContext) => new MlServerPlugin(ctx); diff --git a/x-pack/plugins/ml/server/shared.ts b/x-pack/plugins/ml/server/shared.ts new file mode 100644 index 0000000000000..1e50950bc3bce --- /dev/null +++ b/x-pack/plugins/ml/server/shared.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from '../common/types/anomalies'; diff --git a/x-pack/plugins/siem/public/components/ml_popover/types.ts b/x-pack/plugins/siem/public/components/ml_popover/types.ts index 58d40c298b329..005f93650a8eb 100644 --- a/x-pack/plugins/siem/public/components/ml_popover/types.ts +++ b/x-pack/plugins/siem/public/components/ml_popover/types.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AuditMessageBase } from '../../../../ml/common/types/audit_message'; +import { AuditMessageBase } from '../../../../ml/public'; import { MlError } from '../ml/types'; export interface Group { diff --git a/x-pack/plugins/siem/server/lib/machine_learning/index.ts b/x-pack/plugins/siem/server/lib/machine_learning/index.ts index eb09fdde3cce3..865a3cf51604d 100644 --- a/x-pack/plugins/siem/server/lib/machine_learning/index.ts +++ b/x-pack/plugins/siem/server/lib/machine_learning/index.ts @@ -6,7 +6,7 @@ import { SearchResponse, SearchParams } from 'elasticsearch'; -import { AnomalyRecordDoc as Anomaly } from '../../../../ml/common/types/anomalies'; +import { AnomalyRecordDoc as Anomaly } from '../../../../ml/server'; export { Anomaly }; export type AnomalyResults = SearchResponse; diff --git a/x-pack/plugins/transform/public/__mocks__/shared_imports.ts b/x-pack/plugins/transform/public/__mocks__/shared_imports.ts index 9d8106a1366d6..e115e086f45b5 100644 --- a/x-pack/plugins/transform/public/__mocks__/shared_imports.ts +++ b/x-pack/plugins/transform/public/__mocks__/shared_imports.ts @@ -14,8 +14,8 @@ export const useRequest = jest.fn(() => ({ })); // just passing through the reimports -export { getErrorMessage } from '../../../ml/common/util/errors'; export { + getErrorMessage, getDataGridSchemaFromKibanaFieldType, getFieldsFromKibanaIndexPattern, multiColumnSortFactory, @@ -27,5 +27,5 @@ export { SearchResponse7, UseDataGridReturnType, UseIndexDataReturnType, -} from '../../../ml/public/application/components/data_grid'; -export { INDEX_STATUS } from '../../../ml/public/application/data_frame_analytics/common'; + INDEX_STATUS, +} from '../../../ml/public'; diff --git a/x-pack/plugins/transform/public/app/common/aggregations.ts b/x-pack/plugins/transform/public/app/common/aggregations.ts index 038d68ff37d87..397a58006f1d1 100644 --- a/x-pack/plugins/transform/public/app/common/aggregations.ts +++ b/x-pack/plugins/transform/public/app/common/aggregations.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { composeValidators, patternValidator } from '../../../../ml/common/util/validators'; +import { composeValidators, patternValidator } from '../../../../ml/public'; export type AggName = string; diff --git a/x-pack/plugins/transform/public/shared_imports.ts b/x-pack/plugins/transform/public/shared_imports.ts index bcd8e53e3d191..3737377de2d5e 100644 --- a/x-pack/plugins/transform/public/shared_imports.ts +++ b/x-pack/plugins/transform/public/shared_imports.ts @@ -16,9 +16,8 @@ export { useRequest, } from '../../../../src/plugins/es_ui_shared/public/request/np_ready_request'; -export { getErrorMessage } from '../../ml/common/util/errors'; - export { + getErrorMessage, getDataGridSchemaFromKibanaFieldType, getFieldsFromKibanaIndexPattern, multiColumnSortFactory, @@ -30,5 +29,5 @@ export { SearchResponse7, UseDataGridReturnType, UseIndexDataReturnType, -} from '../../ml/public/application/components/data_grid'; -export { INDEX_STATUS } from '../../ml/public/application/data_frame_analytics/common'; + INDEX_STATUS, +} from '../../ml/public'; diff --git a/x-pack/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx b/x-pack/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx index ceb1e700f293e..5e41c4b74fd5d 100644 --- a/x-pack/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx +++ b/x-pack/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx @@ -9,11 +9,11 @@ import moment from 'moment'; import { AnnotationTooltipFormatter, RectAnnotation } from '@elastic/charts'; import { RectAnnotationDatum } from '@elastic/charts/dist/chart_types/xy_chart/utils/specs'; import { AnnotationTooltip } from './annotation_tooltip'; -import { ANOMALY_SEVERITY } from '../../../../../../plugins/ml/common/constants/anomalies'; import { + ANOMALY_SEVERITY, getSeverityColor, getSeverityType, -} from '../../../../../../plugins/ml/common/util/anomaly_utils'; +} from '../../../../../../plugins/ml/public'; interface Props { anomalies: any; diff --git a/x-pack/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx index 5330ac6e12e98..e66808f76d24a 100644 --- a/x-pack/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx @@ -20,7 +20,7 @@ import { getMLJobId } from '../../../state/api/ml_anomaly'; import * as labels from './translations'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; import { ManageMLJobComponent } from './manage_ml_job'; -import { JobStat } from '../../../../../../plugins/ml/common/types/data_recognizer'; +import { JobStat } from '../../../../../../plugins/ml/public'; import { useMonitorId } from '../../../hooks'; export const MLIntegrationComponent = () => { diff --git a/x-pack/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx index 52d4f620f84b3..b586c1241290b 100644 --- a/x-pack/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx @@ -20,7 +20,7 @@ import { } from '../../../state/selectors'; import { UptimeRefreshContext } from '../../../contexts'; import { getMLJobId } from '../../../state/api/ml_anomaly'; -import { JobStat } from '../../../../../ml/common/types/data_recognizer'; +import { JobStat } from '../../../../../ml/public'; import { MonitorDurationComponent } from './monitor_duration'; import { MonitorIdParam } from '../../../../common/types'; diff --git a/x-pack/plugins/uptime/public/state/actions/ml_anomaly.ts b/x-pack/plugins/uptime/public/state/actions/ml_anomaly.ts index 441a3cefdf204..6b564ba0e83e4 100644 --- a/x-pack/plugins/uptime/public/state/actions/ml_anomaly.ts +++ b/x-pack/plugins/uptime/public/state/actions/ml_anomaly.ts @@ -6,15 +6,17 @@ import { createAction } from 'redux-actions'; import { createAsyncAction } from './utils'; -import { MlCapabilitiesResponse } from '../../../../../plugins/ml/common/types/capabilities'; -import { AnomaliesTableRecord } from '../../../../../plugins/ml/common/types/anomalies'; +import { + MlCapabilitiesResponse, + AnomaliesTableRecord, + JobExistResult, +} from '../../../../../plugins/ml/public'; import { CreateMLJobSuccess, DeleteJobResults, MonitorIdParam, HeartbeatIndicesParam, } from './types'; -import { JobExistResult } from '../../../../../plugins/ml/common/types/data_recognizer'; export const resetMLState = createAction('RESET_ML_STATE'); diff --git a/x-pack/plugins/uptime/public/state/api/ml_anomaly.ts b/x-pack/plugins/uptime/public/state/api/ml_anomaly.ts index ff2ad8ba0745f..158d7b631a8b8 100644 --- a/x-pack/plugins/uptime/public/state/api/ml_anomaly.ts +++ b/x-pack/plugins/uptime/public/state/api/ml_anomaly.ts @@ -8,15 +8,17 @@ import moment from 'moment'; import { apiService } from './utils'; import { AnomalyRecords, AnomalyRecordsParams } from '../actions'; import { API_URLS, ML_JOB_ID, ML_MODULE_ID } from '../../../common/constants'; -import { MlCapabilitiesResponse } from '../../../../../plugins/ml/common/types/capabilities'; +import { + MlCapabilitiesResponse, + DataRecognizerConfigResponse, + JobExistResult, +} from '../../../../../plugins/ml/public'; import { CreateMLJobSuccess, DeleteJobResults, MonitorIdParam, HeartbeatIndicesParam, } from '../actions/types'; -import { DataRecognizerConfigResponse } from '../../../../../plugins/ml/common/types/modules'; -import { JobExistResult } from '../../../../../plugins/ml/common/types/data_recognizer'; const getJobPrefix = (monitorId: string) => { // ML App doesn't support upper case characters in job name diff --git a/x-pack/plugins/uptime/public/state/reducers/ml_anomaly.ts b/x-pack/plugins/uptime/public/state/reducers/ml_anomaly.ts index 9a4a949ac4ede..9f2da19d24208 100644 --- a/x-pack/plugins/uptime/public/state/reducers/ml_anomaly.ts +++ b/x-pack/plugins/uptime/public/state/reducers/ml_anomaly.ts @@ -16,9 +16,8 @@ import { } from '../actions'; import { getAsyncInitialState, handleAsyncAction } from './utils'; import { AsyncInitialState } from './types'; -import { MlCapabilitiesResponse } from '../../../../../plugins/ml/common/types/capabilities'; +import { MlCapabilitiesResponse, JobExistResult } from '../../../../../plugins/ml/public'; import { CreateMLJobSuccess, DeleteJobResults } from '../actions/types'; -import { JobExistResult } from '../../../../../plugins/ml/common/types/data_recognizer'; export interface MLJobState { mlJob: AsyncInitialState; From 8373247da026c9c14f9ca0d864c9e0f8a21d0ae3 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Thu, 7 May 2020 14:36:35 +0200 Subject: [PATCH 23/23] reduce uptime plugin initial bundle size (#65257) --- x-pack/plugins/uptime/public/apps/plugin.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/uptime/public/apps/plugin.ts b/x-pack/plugins/uptime/public/apps/plugin.ts index c64ca7c3d4843..c6a7eb261d8fd 100644 --- a/x-pack/plugins/uptime/public/apps/plugin.ts +++ b/x-pack/plugins/uptime/public/apps/plugin.ts @@ -12,7 +12,6 @@ import { import { UMFrontendLibs } from '../lib/lib'; import { PLUGIN } from '../../common/constants'; import { FeatureCatalogueCategory } from '../../../../../src/plugins/home/public'; -import { getKibanaFrameworkAdapter } from '../lib/adapters/framework/new_platform_adapter'; import { HomePublicPluginSetup } from '../../../../../src/plugins/home/public'; import { EmbeddableStart } from '../../../../../src/plugins/embeddable/public'; import { TriggersAndActionsUIPublicPluginSetup } from '../../../triggers_actions_ui/public'; @@ -61,6 +60,10 @@ export class UptimePlugin implements Plugin