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
This commit is contained in:
Yuliia Naumenko 2020-05-06 16:06:40 -07:00 committed by GitHub
parent c03bdccce1
commit bb9eaf78a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 64 additions and 162 deletions

View file

@ -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(
<ActionsConnectorsContextProvider
value={{
http: deps!.http,
actionTypeRegistry: deps!.actionTypeRegistry,
capabilities: deps!.capabilities,
toastNotifications: deps!.toastNotifications,
reloadConnectors: () => {
return new Promise<void>(() => {});
},
docLinks: deps!.docLinks,
}}
>
<ConnectorFields
action={actionConnector}
errors={{ index: [] }}
editActionConfig={() => {}}
editActionSecrets={() => {}}
/>
</ActionsConnectorsContextProvider>
<ConnectorFields
action={actionConnector}
errors={{ index: [] }}
editActionConfig={() => {}}
editActionSecrets={() => {}}
http={deps!.http}
/>
);
await act(async () => {

View file

@ -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<ActionConnectorFieldsProps<
EsIndexActionConnector
>> = ({ action, editActionConfig, errors }) => {
const { http } = useActionsConnectorsContext();
>> = ({ action, editActionConfig, errors, http }) => {
const { index, refresh, executionTimeField } = action.config;
const [hasTimeFieldCheckbox, setTimeFieldCheckboxState] = useState<boolean>(
executionTimeField != null

View file

@ -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(
<ActionsConnectorsContextProvider
value={{
http: deps!.http,
actionTypeRegistry: deps!.actionTypeRegistry,
capabilities: deps!.capabilities,
toastNotifications: deps!.toastNotifications,
reloadConnectors: () => {
return new Promise<void>(() => {});
},
docLinks: deps!.docLinks,
}}
>
<ConnectorFields
action={actionConnector}
errors={{ index: [], routingKey: [] }}
editActionConfig={() => {}}
editActionSecrets={() => {}}
/>
</ActionsConnectorsContextProvider>
<ConnectorFields
action={actionConnector}
errors={{ index: [], routingKey: [] }}
editActionConfig={() => {}}
editActionSecrets={() => {}}
docLinks={deps!.docLinks}
/>
);
await act(async () => {

View file

@ -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<ActionConnectorFieldsProps<
PagerDutyActionConnector
>> = ({ errors, action, editActionConfig, editActionSecrets }) => {
const { docLinks } = useActionsConnectorsContext();
>> = ({ errors, action, editActionConfig, editActionSecrets, docLinks }) => {
const { apiUrl } = action.config;
const { routingKey } = action.secrets;
return (

View file

@ -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(
<ActionsConnectorsContextProvider
value={{
http: deps!.http,
actionTypeRegistry: deps!.actionTypeRegistry,
capabilities: deps!.capabilities,
toastNotifications: deps!.toastNotifications,
reloadConnectors: () => {
return new Promise<void>(() => {});
},
docLinks: deps!.docLinks,
}}
>
<ConnectorFields
action={actionConnector}
errors={{ index: [], webhookUrl: [] }}
editActionConfig={() => {}}
editActionSecrets={() => {}}
/>
</ActionsConnectorsContextProvider>
<ConnectorFields
action={actionConnector}
errors={{ index: [], webhookUrl: [] }}
editActionConfig={() => {}}
editActionSecrets={() => {}}
docLinks={deps!.docLinks}
/>
);
await act(async () => {

View file

@ -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<ActionConnectorFieldsProps<
SlackActionConnector
>> = ({ action, editActionSecrets, errors }) => {
const { docLinks } = useActionsConnectorsContext();
>> = ({ action, editActionSecrets, errors, docLinks }) => {
const { webhookUrl } = action.secrets;
return (

View file

@ -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;
};

View file

@ -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(
<ActionsConnectorsContextProvider
value={{
http: deps!.http,
actionTypeRegistry: deps!.actionTypeRegistry,
capabilities: deps!.capabilities,
toastNotifications: deps!.toastNotifications,
reloadConnectors: () => {
return new Promise<void>(() => {});
},
docLinks: deps!.docLinks,
}}
>
<ActionConnectorForm
actionTypeName={'my-action-type-name'}
connector={initialConnector}
dispatch={() => {}}
errors={{ name: [] }}
/>
</ActionsConnectorsContextProvider>
<ActionConnectorForm
actionTypeName={'my-action-type-name'}
connector={initialConnector}
dispatch={() => {}}
errors={{ name: [] }}
http={deps!.http}
actionTypeRegistry={deps!.actionTypeRegistry}
docLinks={deps!.docLinks}
/>
);
}
const connectorNameField = wrapper?.find('[data-test-subj="nameInput"]');

View file

@ -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<ActionTypeModel>;
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}
</EuiForm>

View file

@ -52,6 +52,7 @@ export const ConnectorAddFlyout = ({
capabilities,
actionTypeRegistry,
reloadConnectors,
docLinks,
} = useActionsConnectorsContext();
const [actionType, setActionType] = useState<ActionType | undefined>(undefined);
const [hasActionsUpgradeableByTrial, setHasActionsUpgradeableByTrial] = useState<boolean>(false);
@ -114,6 +115,9 @@ export const ConnectorAddFlyout = ({
connector={connector}
dispatch={dispatch}
errors={errors}
actionTypeRegistry={actionTypeRegistry}
http={http}
docLinks={docLinks}
/>
);
}

View file

@ -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 = ({
</EuiModalHeader>
<EuiModalBody>
<ActionsConnectorsContextProvider
value={{
actionTypeRegistry,
http,
capabilities,
toastNotifications,
docLinks,
}}
>
<ActionConnectorForm
connector={connector}
actionTypeName={actionType.name}
dispatch={dispatch}
serverError={serverError}
errors={errors}
/>
</ActionsConnectorsContextProvider>
<ActionConnectorForm
connector={connector}
actionTypeName={actionType.name}
dispatch={dispatch}
serverError={serverError}
errors={errors}
actionTypeRegistry={actionTypeRegistry}
docLinks={docLinks}
http={http}
/>
</EuiModalBody>
<EuiModalFooter>
<EuiButtonEmpty onClick={closeModal}>

View file

@ -182,6 +182,9 @@ export const ConnectorEditFlyout = ({
errors={errors}
actionTypeName={connector.actionType}
dispatch={dispatch}
actionTypeRegistry={actionTypeRegistry}
http={http}
docLinks={docLinks}
/>
) : (
<Fragment>

View file

@ -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<TActionConnector> {
editActionConfig: (property: string, value: any) => void;
editActionSecrets: (property: string, value: any) => void;
errors: { [key: string]: string[] };
docLinks: DocLinksStart;
http?: HttpSetup;
}