Skip to content

Commit

Permalink
[Alerting UI] Disable "Save" button for Alerts with broken Connectors (
Browse files Browse the repository at this point in the history
…#80579)

* Adding check for broken connectors in action form

* Adding check for broken connectors in action form

* Adding unit test

* PR fixes
  • Loading branch information
ymao1 authored Oct 16, 2020
1 parent 51ac14b commit a377204
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ describe('action_form', () => {
describe('action_form in alert', () => {
let wrapper: ReactWrapper<any>;

async function setup() {
async function setup(customActions?: AlertAction[]) {
const { loadAllActions } = jest.requireMock('../../lib/action_connector_api');
loadAllActions.mockResolvedValueOnce([
{
Expand Down Expand Up @@ -177,6 +177,7 @@ describe('action_form', () => {
show: true,
},
},
setHasActionsWithBrokenConnector: jest.fn(),
actionTypeRegistry: actionTypeRegistry as any,
docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' },
};
Expand All @@ -198,16 +199,18 @@ describe('action_form', () => {
schedule: {
interval: '1m',
},
actions: [
{
group: 'default',
id: 'test',
actionTypeId: actionType.id,
params: {
message: '',
},
},
],
actions: customActions
? customActions
: [
{
group: 'default',
id: 'test',
actionTypeId: actionType.id,
params: {
message: '',
},
},
],
tags: [],
muteAll: false,
enabled: false,
Expand All @@ -229,6 +232,7 @@ describe('action_form', () => {
setActionParamsProperty={(key: string, value: any, index: number) =>
(initialAlert.actions[index] = { ...initialAlert.actions[index], [key]: value })
}
setHasActionsWithBrokenConnector={deps!.setHasActionsWithBrokenConnector}
http={deps!.http}
actionTypeRegistry={deps!.actionTypeRegistry}
defaultActionMessage={'Alert [{{ctx.metadata.name}}] has exceeded the threshold'}
Expand Down Expand Up @@ -306,6 +310,7 @@ describe('action_form', () => {
.find(`EuiToolTip [data-test-subj="${actionType.id}-ActionTypeSelectOption"]`)
.exists()
).toBeFalsy();
expect(deps.setHasActionsWithBrokenConnector).toHaveBeenLastCalledWith(false);
});

it('does not render action types disabled by config', async () => {
Expand Down Expand Up @@ -392,5 +397,27 @@ describe('action_form', () => {
);
expect(actionOption.exists()).toBeFalsy();
});

it('recognizes actions with broken connectors', async () => {
await setup([
{
group: 'default',
id: 'test',
actionTypeId: actionType.id,
params: {
message: '',
},
},
{
group: 'default',
id: 'connector-doesnt-exist',
actionTypeId: actionType.id,
params: {
message: 'broken',
},
},
]);
expect(deps.setHasActionsWithBrokenConnector).toHaveBeenLastCalledWith(true);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ interface ActionAccordionFormProps {
messageVariables?: ActionVariable[];
defaultActionMessage?: string;
setHasActionsDisabled?: (value: boolean) => void;
setHasActionsWithBrokenConnector?: (value: boolean) => void;
capabilities: ApplicationStart['capabilities'];
}

Expand All @@ -83,6 +84,7 @@ export const ActionForm = ({
defaultActionMessage,
toastNotifications,
setHasActionsDisabled,
setHasActionsWithBrokenConnector,
capabilities,
docLinks,
}: ActionAccordionFormProps) => {
Expand Down Expand Up @@ -171,6 +173,16 @@ export const ActionForm = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [connectors, actionTypesIndex]);

useEffect(() => {
const hasActionWithBrokenConnector = actions.some(
(action) => !connectors.find((connector) => connector.id === action.id)
);
if (setHasActionsWithBrokenConnector) {
setHasActionsWithBrokenConnector(hasActionWithBrokenConnector);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [actions, connectors]);

const preconfiguredMessage = i18n.translate(
'xpack.triggersActionsUI.sections.actionForm.preconfiguredTitleMessage',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ export const AlertEdit = ({ initialAlert, onClose }: AlertEditProps) => {
const [{ alert }, dispatch] = useReducer(alertReducer, { alert: initialAlert });
const [isSaving, setIsSaving] = useState<boolean>(false);
const [hasActionsDisabled, setHasActionsDisabled] = useState<boolean>(false);
const [hasActionsWithBrokenConnector, setHasActionsWithBrokenConnector] = useState<boolean>(
false
);
const setAlert = (key: string, value: any) => {
dispatch({ command: { type: 'setAlert' }, payload: { key, value } });
};
Expand Down Expand Up @@ -155,6 +158,7 @@ export const AlertEdit = ({ initialAlert, onClose }: AlertEditProps) => {
errors={errors}
canChangeTrigger={false}
setHasActionsDisabled={setHasActionsDisabled}
setHasActionsWithBrokenConnector={setHasActionsWithBrokenConnector}
operation="i18n.translate('xpack.triggersActionsUI.sections.alertEdit.operationName', {
defaultMessage: 'edit',
})"
Expand All @@ -176,7 +180,7 @@ export const AlertEdit = ({ initialAlert, onClose }: AlertEditProps) => {
data-test-subj="saveEditedAlertButton"
type="submit"
iconType="check"
isDisabled={hasErrors || hasActionErrors}
isDisabled={hasErrors || hasActionErrors || hasActionsWithBrokenConnector}
isLoading={isSaving}
onClick={async () => {
setIsSaving(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ interface AlertFormProps {
errors: IErrorObject;
canChangeTrigger?: boolean; // to hide Change trigger button
setHasActionsDisabled?: (value: boolean) => void;
setHasActionsWithBrokenConnector?: (value: boolean) => void;
operation: string;
}

Expand All @@ -90,6 +91,7 @@ export const AlertForm = ({
dispatch,
errors,
setHasActionsDisabled,
setHasActionsWithBrokenConnector,
operation,
}: AlertFormProps) => {
const alertsContext = useAlertsContext();
Expand Down Expand Up @@ -260,6 +262,7 @@ export const AlertForm = ({
<ActionForm
actions={alert.actions}
setHasActionsDisabled={setHasActionsDisabled}
setHasActionsWithBrokenConnector={setHasActionsWithBrokenConnector}
messageVariables={
alertTypesIndex && alertTypesIndex.has(alert.alertTypeId)
? actionVariablesFromAlertType(alertTypesIndex.get(alert.alertTypeId)!).sort((a, b) =>
Expand Down

0 comments on commit a377204

Please sign in to comment.