Skip to content

Commit 0288a85

Browse files
authored
[Alerting UI] Disable "Save" button for Alerts with broken Connectors (#80579) (#80816)
* Adding check for broken connectors in action form * Adding check for broken connectors in action form * Adding unit test * PR fixes
1 parent c229cc9 commit 0288a85

File tree

4 files changed

+58
-12
lines changed

4 files changed

+58
-12
lines changed

x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ describe('action_form', () => {
114114
describe('action_form in alert', () => {
115115
let wrapper: ReactWrapper<any>;
116116

117-
async function setup() {
117+
async function setup(customActions?: AlertAction[]) {
118118
const { loadAllActions } = jest.requireMock('../../lib/action_connector_api');
119119
loadAllActions.mockResolvedValueOnce([
120120
{
@@ -177,6 +177,7 @@ describe('action_form', () => {
177177
show: true,
178178
},
179179
},
180+
setHasActionsWithBrokenConnector: jest.fn(),
180181
actionTypeRegistry: actionTypeRegistry as any,
181182
docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' },
182183
};
@@ -198,16 +199,18 @@ describe('action_form', () => {
198199
schedule: {
199200
interval: '1m',
200201
},
201-
actions: [
202-
{
203-
group: 'default',
204-
id: 'test',
205-
actionTypeId: actionType.id,
206-
params: {
207-
message: '',
208-
},
209-
},
210-
],
202+
actions: customActions
203+
? customActions
204+
: [
205+
{
206+
group: 'default',
207+
id: 'test',
208+
actionTypeId: actionType.id,
209+
params: {
210+
message: '',
211+
},
212+
},
213+
],
211214
tags: [],
212215
muteAll: false,
213216
enabled: false,
@@ -229,6 +232,7 @@ describe('action_form', () => {
229232
setActionParamsProperty={(key: string, value: any, index: number) =>
230233
(initialAlert.actions[index] = { ...initialAlert.actions[index], [key]: value })
231234
}
235+
setHasActionsWithBrokenConnector={deps!.setHasActionsWithBrokenConnector}
232236
http={deps!.http}
233237
actionTypeRegistry={deps!.actionTypeRegistry}
234238
defaultActionMessage={'Alert [{{ctx.metadata.name}}] has exceeded the threshold'}
@@ -306,6 +310,7 @@ describe('action_form', () => {
306310
.find(`EuiToolTip [data-test-subj="${actionType.id}-ActionTypeSelectOption"]`)
307311
.exists()
308312
).toBeFalsy();
313+
expect(deps.setHasActionsWithBrokenConnector).toHaveBeenLastCalledWith(false);
309314
});
310315

311316
it('does not render action types disabled by config', async () => {
@@ -392,5 +397,27 @@ describe('action_form', () => {
392397
);
393398
expect(actionOption.exists()).toBeFalsy();
394399
});
400+
401+
it('recognizes actions with broken connectors', async () => {
402+
await setup([
403+
{
404+
group: 'default',
405+
id: 'test',
406+
actionTypeId: actionType.id,
407+
params: {
408+
message: '',
409+
},
410+
},
411+
{
412+
group: 'default',
413+
id: 'connector-doesnt-exist',
414+
actionTypeId: actionType.id,
415+
params: {
416+
message: 'broken',
417+
},
418+
},
419+
]);
420+
expect(deps.setHasActionsWithBrokenConnector).toHaveBeenLastCalledWith(true);
421+
});
395422
});
396423
});

x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ interface ActionAccordionFormProps {
6262
messageVariables?: ActionVariable[];
6363
defaultActionMessage?: string;
6464
setHasActionsDisabled?: (value: boolean) => void;
65+
setHasActionsWithBrokenConnector?: (value: boolean) => void;
6566
capabilities: ApplicationStart['capabilities'];
6667
}
6768

@@ -83,6 +84,7 @@ export const ActionForm = ({
8384
defaultActionMessage,
8485
toastNotifications,
8586
setHasActionsDisabled,
87+
setHasActionsWithBrokenConnector,
8688
capabilities,
8789
docLinks,
8890
}: ActionAccordionFormProps) => {
@@ -171,6 +173,16 @@ export const ActionForm = ({
171173
// eslint-disable-next-line react-hooks/exhaustive-deps
172174
}, [connectors, actionTypesIndex]);
173175

176+
useEffect(() => {
177+
const hasActionWithBrokenConnector = actions.some(
178+
(action) => !connectors.find((connector) => connector.id === action.id)
179+
);
180+
if (setHasActionsWithBrokenConnector) {
181+
setHasActionsWithBrokenConnector(hasActionWithBrokenConnector);
182+
}
183+
// eslint-disable-next-line react-hooks/exhaustive-deps
184+
}, [actions, connectors]);
185+
174186
const preconfiguredMessage = i18n.translate(
175187
'xpack.triggersActionsUI.sections.actionForm.preconfiguredTitleMessage',
176188
{

x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ export const AlertEdit = ({ initialAlert, onClose }: AlertEditProps) => {
3838
const [{ alert }, dispatch] = useReducer(alertReducer, { alert: initialAlert });
3939
const [isSaving, setIsSaving] = useState<boolean>(false);
4040
const [hasActionsDisabled, setHasActionsDisabled] = useState<boolean>(false);
41+
const [hasActionsWithBrokenConnector, setHasActionsWithBrokenConnector] = useState<boolean>(
42+
false
43+
);
4144
const setAlert = (key: string, value: any) => {
4245
dispatch({ command: { type: 'setAlert' }, payload: { key, value } });
4346
};
@@ -155,6 +158,7 @@ export const AlertEdit = ({ initialAlert, onClose }: AlertEditProps) => {
155158
errors={errors}
156159
canChangeTrigger={false}
157160
setHasActionsDisabled={setHasActionsDisabled}
161+
setHasActionsWithBrokenConnector={setHasActionsWithBrokenConnector}
158162
operation="i18n.translate('xpack.triggersActionsUI.sections.alertEdit.operationName', {
159163
defaultMessage: 'edit',
160164
})"
@@ -176,7 +180,7 @@ export const AlertEdit = ({ initialAlert, onClose }: AlertEditProps) => {
176180
data-test-subj="saveEditedAlertButton"
177181
type="submit"
178182
iconType="check"
179-
isDisabled={hasErrors || hasActionErrors}
183+
isDisabled={hasErrors || hasActionErrors || hasActionsWithBrokenConnector}
180184
isLoading={isSaving}
181185
onClick={async () => {
182186
setIsSaving(true);

x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ interface AlertFormProps {
8181
errors: IErrorObject;
8282
canChangeTrigger?: boolean; // to hide Change trigger button
8383
setHasActionsDisabled?: (value: boolean) => void;
84+
setHasActionsWithBrokenConnector?: (value: boolean) => void;
8485
operation: string;
8586
}
8687

@@ -90,6 +91,7 @@ export const AlertForm = ({
9091
dispatch,
9192
errors,
9293
setHasActionsDisabled,
94+
setHasActionsWithBrokenConnector,
9395
operation,
9496
}: AlertFormProps) => {
9597
const alertsContext = useAlertsContext();
@@ -260,6 +262,7 @@ export const AlertForm = ({
260262
<ActionForm
261263
actions={alert.actions}
262264
setHasActionsDisabled={setHasActionsDisabled}
265+
setHasActionsWithBrokenConnector={setHasActionsWithBrokenConnector}
263266
messageVariables={
264267
alertTypesIndex && alertTypesIndex.has(alert.alertTypeId)
265268
? actionVariablesFromAlertType(alertTypesIndex.get(alert.alertTypeId)!).sort((a, b) =>

0 commit comments

Comments
 (0)