From eef9ecefe0bc06392e607d27860f8eb473e43500 Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Tue, 12 May 2020 17:05:46 +0100 Subject: [PATCH] [Alerting] Adds lazy loading to AlertType and Flyout components (#65678) This PR: 1. Adds support for lazy loading AlertType components and migrates the built-in IndexThreshold components to lazy load. 2. Adds lazy loading of the components contained in the flyout so that only the wrapper component is imported by other plugins and the internal components are loaded when needed. --- x-pack/plugins/triggers_actions_ui/README.md | 23 +++++++++----- .../public/application/app.tsx | 31 +++++-------------- .../threshold/expression.tsx | 25 +++++---------- .../builtin_alert_types/threshold/index.ts | 13 +++++--- .../lib/suspended_component_with_props.tsx | 27 ++++++++++++++++ .../action_form.test.tsx | 2 +- .../action_connector_form/action_form.tsx | 3 ++ .../connector_add_flyout.test.tsx | 2 +- .../connector_add_flyout.tsx | 3 ++ .../connector_edit_flyout.test.tsx | 2 +- .../connector_edit_flyout.tsx | 3 ++ .../sections/action_connector_form/index.ts | 13 ++++++-- .../actions_connectors_list.test.tsx | 5 +-- .../components/actions_connectors_list.tsx | 4 ++- .../sections/alert_form/alert_add.test.tsx | 2 +- .../sections/alert_form/alert_add.tsx | 3 ++ .../sections/alert_form/alert_edit.test.tsx | 2 +- .../sections/alert_form/alert_edit.tsx | 3 ++ .../sections/alert_form/alert_form.tsx | 31 +++++++++++++------ .../application/sections/alert_form/index.ts | 8 ----- .../application/sections/alert_form/index.tsx | 10 ++++++ .../public/application/sections/index.tsx | 21 +++++++++++++ .../common/expression_items/for_the_last.tsx | 3 +- .../common/expression_items/group_by_over.tsx | 3 +- .../triggers_actions_ui/public/index.ts | 8 ++++- .../triggers_actions_ui/public/types.ts | 22 +++++++++++-- .../public/lib/alert_types/monitor_status.tsx | 4 ++- 27 files changed, 188 insertions(+), 88 deletions(-) create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/lib/suspended_component_with_props.tsx delete mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/index.ts create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/index.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/index.tsx diff --git a/x-pack/plugins/triggers_actions_ui/README.md b/x-pack/plugins/triggers_actions_ui/README.md index c5f02863ba8a..0ed6917854dc 100644 --- a/x-pack/plugins/triggers_actions_ui/README.md +++ b/x-pack/plugins/triggers_actions_ui/README.md @@ -69,13 +69,13 @@ export function getAlertType(): AlertTypeModel { id: '.index-threshold', name: 'Index threshold', iconClass: 'alert', - alertParamsExpression: IndexThresholdAlertTypeExpression, + alertParamsExpression: lazy(() => import('./index_threshold_expression')), validate: validateAlertType, }; } ``` -alertParamsExpression form represented as an expression using `EuiExpression` components: +alertParamsExpression should be a lazy loaded React component extending an expression using `EuiExpression` components: ![Index Threshold Alert expression form](https://i.imgur.com/Ysk1ljY.png) ``` @@ -171,6 +171,7 @@ export const alertReducer = (state: any, action: AlertReducerAction) => { ``` +The Expression component should be lazy loaded which means it'll have to be the default export in `index_threshold_expression.ts`: ``` export const IndexThresholdAlertTypeExpression: React.FunctionComponent = ({ @@ -224,6 +225,9 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent ); }; + +// Export as default in order to support lazy loading +export {IndexThresholdAlertTypeExpression as default}; ``` Index Threshold Alert form with validation: @@ -237,7 +241,9 @@ Each alert type should be defined as `AlertTypeModel` object with the these prop name: string; iconClass: string; validate: (alertParams: any) => ValidationResult; - alertParamsExpression: React.FunctionComponent; + alertParamsExpression: React.LazyExoticComponent< + ComponentType> + >; defaultActionMessage?: string; ``` |Property|Description| @@ -246,7 +252,7 @@ Each alert type should be defined as `AlertTypeModel` object with the these prop |name|Name of the alert type that will be displayed on the select card in the UI.| |iconClass|Icon of the alert type that will be displayed on the select card in the UI.| |validate|Validation function for the alert params.| -|alertParamsExpression|React functional component for building UI of the current alert type params.| +|alertParamsExpression| A lazy loaded React component for building UI of the current alert type params.| |defaultActionMessage|Optional property for providing default message for all added actions with `message` property.| IMPORTANT: The current UI supports a single action group only. @@ -295,8 +301,8 @@ Below is a list of steps that should be done to build and register a new alert t 1. At any suitable place in Kibana, create a file, which will expose an object implementing interface [AlertTypeModel](https://github.com/elastic/kibana/blob/55b7905fb5265b73806006e7265739545d7521d0/x-pack/legacy/plugins/triggers_actions_ui/np_ready/public/types.ts#L83). Example: ``` +import { lazy } from 'react'; import { AlertTypeModel } from '../../../../types'; -import { ExampleExpression } from './expression'; import { validateExampleAlertType } from './validation'; export function getAlertType(): AlertTypeModel { @@ -304,7 +310,7 @@ export function getAlertType(): AlertTypeModel { id: 'example', name: 'Example Alert Type', iconClass: 'bell', - alertParamsExpression: ExampleExpression, + alertParamsExpression: lazy(() => import('./expression')), validate: validateExampleAlertType, defaultActionMessage: 'Alert [{{ctx.metadata.name}}] has exceeded the threshold', }; @@ -361,6 +367,9 @@ export const ExampleExpression: React.FunctionComponent = ({ ); }; +// Export as default in order to support lazy loading +export {ExampleExpression as default}; + ``` This alert type form becomes available, when the card of `Example Alert Type` is selected. Each expression word here is `EuiExpression` component and implements the basic aggregation, grouping and comparison methods. @@ -1017,7 +1026,7 @@ Below is a list of steps that should be done to build and register a new action 1. At any suitable place in Kibana, create a file, which will expose an object implementing interface [ActionTypeModel]: ``` -import React, { Fragment } from 'react'; +import React, { Fragment, lazy } from 'react'; import { i18n } from '@kbn/i18n'; import { ActionTypeModel, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/app.tsx b/x-pack/plugins/triggers_actions_ui/public/application/app.tsx index 63860e062c8d..ebd9294ce1e6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/app.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/app.tsx @@ -3,8 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React, { lazy, Suspense } from 'react'; -import { Switch, Route, Redirect, HashRouter, RouteComponentProps } from 'react-router-dom'; +import React, { lazy } from 'react'; +import { Switch, Route, Redirect, HashRouter } from 'react-router-dom'; import { ChromeStart, DocLinksStart, @@ -15,7 +15,6 @@ import { ChromeBreadcrumb, CoreStart, } from 'kibana/public'; -import { EuiLoadingSpinner, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { BASE_PATH, Section, routeToAlertDetails } from './constants'; import { AppContextProvider, useAppDependencies } from './app_context'; import { hasShowAlertsCapability } from './lib/capabilities'; @@ -24,6 +23,7 @@ import { TypeRegistry } from './type_registry'; import { ChartsPluginStart } from '../../../../../src/plugins/charts/public'; import { DataPublicPluginStart } from '../../../../../src/plugins/data/public'; import { PluginStartContract as AlertingStart } from '../../../alerting/public'; +import { suspendedComponentWithProps } from './lib/suspended_component_with_props'; const TriggersActionsUIHome = lazy(async () => import('./home')); const AlertDetailsRoute = lazy(() => @@ -68,30 +68,15 @@ export const AppWithoutRouter = ({ sectionsRegex }: { sectionsRegex: string }) = {canShowAlerts && ( - + )} ); }; - -function suspendedRouteComponent( - RouteComponent: React.ComponentType> -) { - return (props: RouteComponentProps) => ( - - - - - - } - > - - - ); -} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx index 43955db97f29..7803ed1ac3a7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx @@ -42,6 +42,7 @@ import { } from '../../../../common'; import { builtInAggregationTypes } from '../../../../common/constants'; import { IndexThresholdAlertParams } from './types'; +import { AlertTypeParamsExpressionProps } from '../../../../types'; import { AlertsContextValue } from '../../../context/alerts_context'; import './expression.scss'; @@ -66,23 +67,10 @@ const expressionFieldsWithValidation = [ 'timeWindowSize', ]; -interface IndexThresholdProps { - alertParams: IndexThresholdAlertParams; - alertInterval: string; - setAlertParams: (property: string, value: any) => void; - setAlertProperty: (key: string, value: any) => void; - errors: { [key: string]: string[] }; - alertsContext: AlertsContextValue; -} - -export const IndexThresholdAlertTypeExpression: React.FunctionComponent = ({ - alertParams, - alertInterval, - setAlertParams, - setAlertProperty, - errors, - alertsContext, -}) => { +export const IndexThresholdAlertTypeExpression: React.FunctionComponent> = ({ alertParams, alertInterval, setAlertParams, setAlertProperty, errors, alertsContext }) => { const { index, timeField, @@ -476,3 +464,6 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent ); }; + +// eslint-disable-next-line import/no-default-export +export { IndexThresholdAlertTypeExpression as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/index.ts index 983f759214b6..42747b9e85e2 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/index.ts @@ -3,16 +3,19 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { AlertTypeModel } from '../../../../types'; -import { IndexThresholdAlertTypeExpression } from './expression'; -import { validateExpression } from './validation'; +import { lazy } from 'react'; -export function getAlertType(): AlertTypeModel { +import { AlertTypeModel } from '../../../../types'; +import { validateExpression } from './validation'; +import { IndexThresholdAlertParams } from './types'; +import { AlertsContextValue } from '../../../context/alerts_context'; + +export function getAlertType(): AlertTypeModel { return { id: '.index-threshold', name: 'Index threshold', iconClass: 'alert', - alertParamsExpression: IndexThresholdAlertTypeExpression, + alertParamsExpression: lazy(() => import('./expression')), validate: validateExpression, }; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/suspended_component_with_props.tsx b/x-pack/plugins/triggers_actions_ui/public/application/lib/suspended_component_with_props.tsx new file mode 100644 index 000000000000..563353793f99 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/suspended_component_with_props.tsx @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React, { Suspense } from 'react'; +import { EuiLoadingSpinner, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiLoadingSpinnerSize } from '@elastic/eui/src/components/loading/loading_spinner'; + +export function suspendedComponentWithProps( + ComponentToSuspend: React.ComponentType, + size?: EuiLoadingSpinnerSize +) { + return (props: T) => ( + + + + + + } + > + + + ); +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index cdc187bc6f3b..931fde430c60 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -10,7 +10,7 @@ import { ReactWrapper } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { actionTypeRegistryMock } from '../../action_type_registry.mock'; import { ValidationResult, Alert, AlertAction } from '../../../types'; -import { ActionForm } from './action_form'; +import ActionForm from './action_form'; jest.mock('../../lib/action_connector_api', () => ({ loadAllActions: jest.fn(), loadActionTypes: jest.fn(), diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index f3e955c97330..5af56f410ad5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -713,3 +713,6 @@ export const ActionForm = ({ ); }; + +// eslint-disable-next-line import/no-default-export +export { ActionForm as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.test.tsx index ac6c0e274977..4f5007949f8b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.test.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; import { coreMock } from '../../../../../../../src/core/public/mocks'; -import { ConnectorAddFlyout } from './connector_add_flyout'; +import ConnectorAddFlyout from './connector_add_flyout'; import { ActionsConnectorsContextProvider } from '../../context/actions_connectors_context'; import { actionTypeRegistryMock } from '../../action_type_registry.mock'; import { ValidationResult } from '../../../types'; 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 c9844f4e1086..adee2e09a56f 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 @@ -319,3 +319,6 @@ const UpgradeYourLicenseCallOut = ({ http }: { http: HttpSetup }) => ( ); + +// eslint-disable-next-line import/no-default-export +export { ConnectorAddFlyout as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx index 976ec146181c..e4a9e6e74173 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx @@ -9,7 +9,7 @@ import { coreMock } from '../../../../../../../src/core/public/mocks'; import { ActionsConnectorsContextProvider } from '../../context/actions_connectors_context'; import { actionTypeRegistryMock } from '../../action_type_registry.mock'; import { ValidationResult } from '../../../types'; -import { ConnectorEditFlyout } from './connector_edit_flyout'; +import ConnectorEditFlyout from './connector_edit_flyout'; import { AppContextProvider } from '../../app_context'; const actionTypeRegistry = actionTypeRegistryMock.create(); 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 4a0effcbd682..6ea78f60c52e 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 @@ -254,3 +254,6 @@ export const ConnectorEditFlyout = ({ ); }; + +// eslint-disable-next-line import/no-default-export +export { ConnectorEditFlyout as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/index.ts index 52ee1efbdaf9..e0065c143a1a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/index.ts @@ -4,6 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -export { ConnectorAddFlyout } from './connector_add_flyout'; -export { ConnectorEditFlyout } from './connector_edit_flyout'; -export { ActionForm } from './action_form'; +import { lazy } from 'react'; +import { suspendedComponentWithProps } from '../../lib/suspended_component_with_props'; + +export const ConnectorAddFlyout = suspendedComponentWithProps( + lazy(() => import('./connector_add_flyout')) +); +export const ConnectorEditFlyout = suspendedComponentWithProps( + lazy(() => import('./connector_edit_flyout')) +); +export const ActionForm = suspendedComponentWithProps(lazy(() => import('./action_form'))); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx index 01d21e954bbf..12b6f9931959 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx @@ -202,11 +202,12 @@ describe('actions_connectors_list component with items', () => { expect(wrapper.find('[data-test-subj="preConfiguredTitleMessage"]')).toHaveLength(2); }); - test('if select item for edit should render ConnectorEditFlyout', () => { - wrapper + test('if select item for edit should render ConnectorEditFlyout', async () => { + await wrapper .find('[data-test-subj="edit1"]') .first() .simulate('click'); + expect(wrapper.find('ConnectorEditFlyout')).toHaveLength(1); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx index 9267a154efaa..64a7aa9ffa8b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx @@ -22,7 +22,9 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { useAppDependencies } from '../../../app_context'; import { loadAllActions, loadActionTypes, deleteActions } from '../../../lib/action_connector_api'; -import { ConnectorAddFlyout, ConnectorEditFlyout } from '../../action_connector_form'; +import ConnectorAddFlyout from '../../action_connector_form/connector_add_flyout'; +import ConnectorEditFlyout from '../../action_connector_form/connector_edit_flyout'; + import { hasDeleteActionsCapability, hasSaveActionsCapability } from '../../../lib/capabilities'; import { DeleteModalConfirmation } from '../../../components/delete_modal_confirmation'; import { ActionsConnectorsContextProvider } from '../../../context/actions_connectors_context'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.test.tsx index 3d6493a5131e..bebbcdda10a0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.test.tsx @@ -9,7 +9,7 @@ import { act } from 'react-dom/test-utils'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFormLabel } from '@elastic/eui'; import { coreMock } from '../../../../../../../src/core/public/mocks'; -import { AlertAdd } from './alert_add'; +import AlertAdd from './alert_add'; import { actionTypeRegistryMock } from '../../action_type_registry.mock'; import { ValidationResult } from '../../../types'; import { AlertsContextProvider, useAlertsContext } from '../../context/alerts_context'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx index 651f2cdba34a..004ad97083fe 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx @@ -219,3 +219,6 @@ const parseErrors: (errors: IErrorObject) => boolean = errors => if (isObject(errorList)) return parseErrors(errorList as IErrorObject); return errorList.length >= 1; }); + +// eslint-disable-next-line import/no-default-export +export { AlertAdd as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.test.tsx index 4d8801d8b748..39112a150958 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.test.tsx @@ -12,7 +12,7 @@ import { ValidationResult } from '../../../types'; import { AlertsContextProvider } from '../../context/alerts_context'; import { alertTypeRegistryMock } from '../../alert_type_registry.mock'; import { ReactWrapper } from 'enzyme'; -import { AlertEdit } from './alert_edit'; +import AlertEdit from './alert_edit'; import { AppContextProvider } from '../../app_context'; const actionTypeRegistry = actionTypeRegistryMock.create(); const alertTypeRegistry = alertTypeRegistryMock.create(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx index 747464d2212f..fc1a3778bc5b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx @@ -201,3 +201,6 @@ export const AlertEdit = ({ initialAlert, onClose }: AlertEditProps) => { ); }; + +// eslint-disable-next-line import/no-default-export +export { AlertEdit as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx index 3b7283e69e01..e956c8ecc4f3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx @@ -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 React, { Fragment, useState, useEffect } from 'react'; +import React, { Fragment, useState, useEffect, Suspense } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { @@ -23,6 +23,7 @@ import { EuiIconTip, EuiButtonIcon, EuiHorizontalRule, + EuiLoadingSpinner, } from '@elastic/eui'; import { some, filter, map, fold } from 'fp-ts/lib/Option'; import { pipe } from 'fp-ts/lib/pipeable'; @@ -36,7 +37,7 @@ import { AlertReducerAction } from './alert_reducer'; import { AlertTypeModel, Alert, IErrorObject, AlertAction, AlertTypeIndex } from '../../../types'; import { getTimeOptions } from '../../../common/lib/get_time_options'; import { useAlertsContext } from '../../context/alerts_context'; -import { ActionForm } from '../action_connector_form/action_form'; +import { ActionForm } from '../action_connector_form'; export function validateBaseProperties(alertObject: Alert) { const validationResult = { errors: {} }; @@ -222,14 +223,24 @@ export const AlertForm = ({ ) : null} {AlertParamsExpressionComponent ? ( - + + + + + + } + > + + ) : null} {defaultActionGroupId ? ( import('./alert_add'))); +export const AlertEdit = suspendedComponentWithProps(lazy(() => import('./alert_edit'))); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/index.tsx new file mode 100644 index 000000000000..677ee139271c --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/index.tsx @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { lazy } from 'react'; +import { suspendedComponentWithProps } from '../lib/suspended_component_with_props'; + +export const AlertAdd = suspendedComponentWithProps(lazy(() => import('./alert_form/alert_add'))); +export const AlertEdit = suspendedComponentWithProps(lazy(() => import('./alert_form/alert_edit'))); + +export const ConnectorAddFlyout = suspendedComponentWithProps( + lazy(() => import('./action_connector_form/connector_add_flyout')) +); +export const ConnectorEditFlyout = suspendedComponentWithProps( + lazy(() => import('./action_connector_form/connector_edit_flyout')) +); +export const ActionForm = suspendedComponentWithProps( + lazy(() => import('./action_connector_form/action_form')) +); diff --git a/x-pack/plugins/triggers_actions_ui/public/common/expression_items/for_the_last.tsx b/x-pack/plugins/triggers_actions_ui/public/common/expression_items/for_the_last.tsx index defad2b80171..5405d96bb1dc 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/expression_items/for_the_last.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/common/expression_items/for_the_last.tsx @@ -20,11 +20,12 @@ import { getTimeUnitLabel } from '../lib/get_time_unit_label'; import { TIME_UNITS } from '../../application/constants'; import { getTimeOptions } from '../lib/get_time_options'; import { ClosablePopoverTitle } from './components'; +import { IErrorObject } from '../../types'; interface ForLastExpressionProps { timeWindowSize?: number; timeWindowUnit?: string; - errors: { [key: string]: string[] }; + errors: IErrorObject; onChangeWindowSize: (selectedWindowSize: number | undefined) => void; onChangeWindowUnit: (selectedWindowUnit: string) => void; popupPosition?: diff --git a/x-pack/plugins/triggers_actions_ui/public/common/expression_items/group_by_over.tsx b/x-pack/plugins/triggers_actions_ui/public/common/expression_items/group_by_over.tsx index 619d85d99719..33ca98de4c08 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/expression_items/group_by_over.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/common/expression_items/group_by_over.tsx @@ -19,10 +19,11 @@ import { import { builtInGroupByTypes } from '../constants'; import { GroupByType } from '../types'; import { ClosablePopoverTitle } from './components'; +import { IErrorObject } from '../../types'; interface GroupByExpressionProps { groupBy: string; - errors: { [key: string]: string[] }; + errors: IErrorObject; onChangeSelectedTermSize: (selectedTermSize?: number) => void; onChangeSelectedTermField: (selectedTermField?: string) => void; onChangeSelectedGroupBy: (selectedGroupBy?: string) => void; diff --git a/x-pack/plugins/triggers_actions_ui/public/index.ts b/x-pack/plugins/triggers_actions_ui/public/index.ts index 96645e856e41..a72d8815c95b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/index.ts @@ -11,7 +11,13 @@ export { AlertsContextProvider } from './application/context/alerts_context'; export { ActionsConnectorsContextProvider } from './application/context/actions_connectors_context'; export { AlertAdd } from './application/sections/alert_form'; export { ActionForm } from './application/sections/action_connector_form'; -export { AlertAction, Alert, AlertTypeModel, ActionType } from './types'; +export { + AlertAction, + Alert, + AlertTypeModel, + AlertTypeParamsExpressionProps, + ActionType, +} from './types'; export { ConnectorAddFlyout, ConnectorEditFlyout, diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index cc511434267c..e9cfd5b33db2 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -110,12 +110,28 @@ export interface AlertTableItem extends Alert { tagsText: string; } -export interface AlertTypeModel { +export interface AlertTypeParamsExpressionProps< + AlertParamsType = unknown, + AlertsContextValue = unknown +> { + alertParams: AlertParamsType; + alertInterval: string; + setAlertParams: (property: string, value: any) => void; + setAlertProperty: (key: string, value: any) => void; + errors: IErrorObject; + alertsContext: AlertsContextValue; +} + +export interface AlertTypeModel { id: string; name: string | JSX.Element; iconClass: string; - validate: (alertParams: any) => ValidationResult; - alertParamsExpression: React.FunctionComponent; + validate: (alertParams: AlertParamsType) => ValidationResult; + alertParamsExpression: + | React.FunctionComponent + | React.LazyExoticComponent< + ComponentType> + >; defaultActionMessage?: string; } diff --git a/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx b/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx index 66e61fbf73b6..65827867da5e 100644 --- a/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx +++ b/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx @@ -63,7 +63,9 @@ export const initMonitorStatusAlertType: AlertTypeInitializer = ({ id: CLIENT_ALERT_TYPES.MONITOR_STATUS, name: , iconClass: 'uptimeApp', - alertParamsExpression: params => , + alertParamsExpression: (params: any) => ( + + ), validate, defaultActionMessage, });