Adds a Reason indicator to the onClose handler in AddAlert and EditAlert (#92149)
Adds a `AlertFlyoutCloseReason` on the `onClose` handlers of `AlertAdd` and `AlertEdit` indicating the reason for the handler being called.
This commit is contained in:
parent
678f848919
commit
c9ca111035
|
@ -5,16 +5,19 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import uuid from 'uuid';
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { mountWithIntl, nextTick } from '@kbn/test/jest';
|
||||
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, { AlertAddProps } from './alert_add';
|
||||
import { createAlert } from '../../lib/alert_api';
|
||||
import { actionTypeRegistryMock } from '../../action_type_registry.mock';
|
||||
import {
|
||||
Alert,
|
||||
AlertFlyoutCloseReason,
|
||||
ConnectorValidationResult,
|
||||
GenericValidationResult,
|
||||
ValidationResult,
|
||||
|
@ -23,10 +26,12 @@ import { alertTypeRegistryMock } from '../../alert_type_registry.mock';
|
|||
import { ReactWrapper } from 'enzyme';
|
||||
import { ALERTS_FEATURE_ID } from '../../../../../alerts/common';
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
|
||||
jest.mock('../../../common/lib/kibana');
|
||||
|
||||
jest.mock('../../lib/alert_api', () => ({
|
||||
loadAlertTypes: jest.fn(),
|
||||
createAlert: jest.fn(),
|
||||
alertingFrameworkHealth: jest.fn(() => ({
|
||||
isSufficientlySecure: true,
|
||||
hasPermanentEncryptionKey: true,
|
||||
|
@ -41,7 +46,12 @@ const actionTypeRegistry = actionTypeRegistryMock.create();
|
|||
const alertTypeRegistry = alertTypeRegistryMock.create();
|
||||
const useKibanaMock = useKibana as jest.Mocked<typeof useKibana>;
|
||||
|
||||
export const TestExpression: React.FunctionComponent<any> = () => {
|
||||
const delay = (wait: number = 1000) =>
|
||||
new Promise((resolve) => {
|
||||
setTimeout(resolve, wait);
|
||||
});
|
||||
|
||||
export const TestExpression: FunctionComponent<any> = () => {
|
||||
return (
|
||||
<EuiFormLabel>
|
||||
<FormattedMessage
|
||||
|
@ -56,7 +66,10 @@ export const TestExpression: React.FunctionComponent<any> = () => {
|
|||
describe('alert_add', () => {
|
||||
let wrapper: ReactWrapper<any>;
|
||||
|
||||
async function setup(initialValues?: Partial<Alert>) {
|
||||
async function setup(
|
||||
initialValues?: Partial<Alert>,
|
||||
onClose: AlertAddProps['onClose'] = jest.fn()
|
||||
) {
|
||||
const mocks = coreMock.createSetup();
|
||||
const { loadAlertTypes } = jest.requireMock('../../lib/alert_api');
|
||||
const alertTypes = [
|
||||
|
@ -141,7 +154,7 @@ describe('alert_add', () => {
|
|||
wrapper = mountWithIntl(
|
||||
<AlertAdd
|
||||
consumer={ALERTS_FEATURE_ID}
|
||||
onClose={() => {}}
|
||||
onClose={onClose}
|
||||
initialValues={initialValues}
|
||||
reloadAlerts={() => {
|
||||
return new Promise<void>(() => {});
|
||||
|
@ -160,11 +173,9 @@ describe('alert_add', () => {
|
|||
}
|
||||
|
||||
it('renders alert add flyout', async () => {
|
||||
await setup();
|
||||
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 1000);
|
||||
});
|
||||
const onClose = jest.fn();
|
||||
await setup({}, onClose);
|
||||
await delay(1000);
|
||||
|
||||
expect(wrapper.find('[data-test-subj="addAlertFlyoutTitle"]').exists()).toBeTruthy();
|
||||
expect(wrapper.find('[data-test-subj="saveAlertButton"]').exists()).toBeTruthy();
|
||||
|
@ -176,20 +187,25 @@ describe('alert_add', () => {
|
|||
expect(wrapper.find('[data-test-subj="tagsComboBox"]').first().text()).toBe('');
|
||||
|
||||
expect(wrapper.find('.euiSelect').first().props().value).toBe('m');
|
||||
|
||||
wrapper.find('[data-test-subj="cancelSaveAlertButton"]').first().simulate('click');
|
||||
expect(onClose).toHaveBeenCalledWith(AlertFlyoutCloseReason.CANCELED);
|
||||
});
|
||||
|
||||
it('renders alert add flyout with initial values', async () => {
|
||||
await setup({
|
||||
name: 'Simple status alert',
|
||||
tags: ['uptime', 'logs'],
|
||||
schedule: {
|
||||
interval: '1h',
|
||||
const onClose = jest.fn();
|
||||
await setup(
|
||||
{
|
||||
name: 'Simple status alert',
|
||||
tags: ['uptime', 'logs'],
|
||||
schedule: {
|
||||
interval: '1h',
|
||||
},
|
||||
},
|
||||
});
|
||||
onClose
|
||||
);
|
||||
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 1000);
|
||||
});
|
||||
await delay(1000);
|
||||
|
||||
expect(wrapper.find('input#alertName').props().value).toBe('Simple status alert');
|
||||
|
||||
|
@ -197,4 +213,61 @@ describe('alert_add', () => {
|
|||
|
||||
expect(wrapper.find('.euiSelect').first().props().value).toBe('h');
|
||||
});
|
||||
|
||||
it('emit an onClose event when the alert is saved', async () => {
|
||||
const onClose = jest.fn();
|
||||
const alert = mockAlert();
|
||||
|
||||
(createAlert as jest.MockedFunction<typeof createAlert>).mockResolvedValue(alert);
|
||||
|
||||
await setup(
|
||||
{
|
||||
name: 'Simple status alert',
|
||||
alertTypeId: 'my-alert-type',
|
||||
tags: ['uptime', 'logs'],
|
||||
schedule: {
|
||||
interval: '1h',
|
||||
},
|
||||
},
|
||||
onClose
|
||||
);
|
||||
|
||||
wrapper.find('[data-test-subj="saveAlertButton"]').first().simulate('click');
|
||||
|
||||
// Wait for handlers to fire
|
||||
await act(async () => {
|
||||
await nextTick();
|
||||
wrapper.update();
|
||||
});
|
||||
|
||||
expect(onClose).toHaveBeenCalledWith(AlertFlyoutCloseReason.SAVED);
|
||||
});
|
||||
});
|
||||
|
||||
function mockAlert(overloads: Partial<Alert> = {}): Alert {
|
||||
return {
|
||||
id: uuid.v4(),
|
||||
enabled: true,
|
||||
name: `alert-${uuid.v4()}`,
|
||||
tags: [],
|
||||
alertTypeId: '.noop',
|
||||
consumer: 'consumer',
|
||||
schedule: { interval: '1m' },
|
||||
actions: [],
|
||||
params: {},
|
||||
createdBy: null,
|
||||
updatedBy: null,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
apiKeyOwner: null,
|
||||
throttle: null,
|
||||
notifyWhen: null,
|
||||
muteAll: false,
|
||||
mutedInstanceIds: [],
|
||||
executionStatus: {
|
||||
status: 'unknown',
|
||||
lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
|
||||
},
|
||||
...overloads,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
AlertTypeRegistryContract,
|
||||
AlertTypeParams,
|
||||
AlertUpdates,
|
||||
AlertFlyoutCloseReason,
|
||||
} from '../../../types';
|
||||
import { AlertForm, getAlertErrors, isValidAlert } from './alert_form';
|
||||
import { alertReducer, InitialAlert, InitialAlertReducer } from './alert_reducer';
|
||||
|
@ -34,7 +35,7 @@ export interface AlertAddProps<MetaData = Record<string, any>> {
|
|||
consumer: string;
|
||||
alertTypeRegistry: AlertTypeRegistryContract;
|
||||
actionTypeRegistry: ActionTypeRegistryContract;
|
||||
onClose: () => void;
|
||||
onClose: (reason: AlertFlyoutCloseReason) => void;
|
||||
alertTypeId?: string;
|
||||
canChangeTrigger?: boolean;
|
||||
initialValues?: Partial<Alert>;
|
||||
|
@ -119,7 +120,7 @@ const AlertAdd = ({
|
|||
) {
|
||||
setIsConfirmAlertCloseModalOpen(true);
|
||||
} else {
|
||||
onClose();
|
||||
onClose(AlertFlyoutCloseReason.CANCELED);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -127,7 +128,7 @@ const AlertAdd = ({
|
|||
const savedAlert = await onSaveAlert();
|
||||
setIsSaving(false);
|
||||
if (savedAlert) {
|
||||
onClose();
|
||||
onClose(AlertFlyoutCloseReason.SAVED);
|
||||
if (reloadAlerts) {
|
||||
reloadAlerts();
|
||||
}
|
||||
|
@ -245,7 +246,7 @@ const AlertAdd = ({
|
|||
<ConfirmAlertClose
|
||||
onConfirm={() => {
|
||||
setIsConfirmAlertCloseModalOpen(false);
|
||||
onClose();
|
||||
onClose(AlertFlyoutCloseReason.CANCELED);
|
||||
}}
|
||||
onCancel={() => {
|
||||
setIsConfirmAlertCloseModalOpen(false);
|
||||
|
|
|
@ -23,7 +23,12 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ActionTypeRegistryContract, Alert, AlertTypeRegistryContract } from '../../../types';
|
||||
import {
|
||||
ActionTypeRegistryContract,
|
||||
Alert,
|
||||
AlertFlyoutCloseReason,
|
||||
AlertTypeRegistryContract,
|
||||
} from '../../../types';
|
||||
import { AlertForm, getAlertErrors, isValidAlert } from './alert_form';
|
||||
import { alertReducer, ConcreteAlertReducer } from './alert_reducer';
|
||||
import { updateAlert } from '../../lib/alert_api';
|
||||
|
@ -38,7 +43,7 @@ export interface AlertEditProps<MetaData = Record<string, any>> {
|
|||
initialAlert: Alert;
|
||||
alertTypeRegistry: AlertTypeRegistryContract;
|
||||
actionTypeRegistry: ActionTypeRegistryContract;
|
||||
onClose(): void;
|
||||
onClose: (reason: AlertFlyoutCloseReason) => void;
|
||||
reloadAlerts?: () => Promise<void>;
|
||||
metadata?: MetaData;
|
||||
}
|
||||
|
@ -81,7 +86,7 @@ export const AlertEdit = ({
|
|||
if (hasAlertChanged(alert, initialAlert, true)) {
|
||||
setIsConfirmAlertCloseModalOpen(true);
|
||||
} else {
|
||||
onClose();
|
||||
onClose(AlertFlyoutCloseReason.CANCELED);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -197,7 +202,7 @@ export const AlertEdit = ({
|
|||
const savedAlert = await onSaveAlert();
|
||||
setIsSaving(false);
|
||||
if (savedAlert) {
|
||||
onClose();
|
||||
onClose(AlertFlyoutCloseReason.SAVED);
|
||||
if (reloadAlerts) {
|
||||
reloadAlerts();
|
||||
}
|
||||
|
@ -218,7 +223,7 @@ export const AlertEdit = ({
|
|||
<ConfirmAlertClose
|
||||
onConfirm={() => {
|
||||
setIsConfirmAlertCloseModalOpen(false);
|
||||
onClose();
|
||||
onClose(AlertFlyoutCloseReason.CANCELED);
|
||||
}}
|
||||
onCancel={() => {
|
||||
setIsConfirmAlertCloseModalOpen(false);
|
||||
|
|
|
@ -28,6 +28,7 @@ export {
|
|||
ActionVariables,
|
||||
ActionConnector,
|
||||
IErrorObject,
|
||||
AlertFlyoutCloseReason,
|
||||
} from './types';
|
||||
export {
|
||||
ConnectorAddFlyout,
|
||||
|
|
|
@ -63,6 +63,11 @@ export interface ActionConnectorFieldsProps<TActionConnector> {
|
|||
consumer?: string;
|
||||
}
|
||||
|
||||
export enum AlertFlyoutCloseReason {
|
||||
SAVED,
|
||||
CANCELED,
|
||||
}
|
||||
|
||||
export interface ActionParamsProps<TParams> {
|
||||
actionParams: Partial<TParams>;
|
||||
index: number;
|
||||
|
|
Loading…
Reference in a new issue