Skip to content

Commit c716d02

Browse files
[7.x] [Uptime] Ml anomaly alert edit (#76909) (#78749)
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
1 parent 5516dc6 commit c716d02

File tree

8 files changed

+100
-24
lines changed

8 files changed

+100
-24
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import React from 'react';
8+
import { Alert, AlertEdit } from '../../../../../../plugins/triggers_actions_ui/public';
9+
10+
interface Props {
11+
alertFlyoutVisible: boolean;
12+
initialAlert: Alert;
13+
setAlertFlyoutVisibility: React.Dispatch<React.SetStateAction<boolean>>;
14+
}
15+
16+
export const UptimeEditAlertFlyoutComponent = ({
17+
alertFlyoutVisible,
18+
initialAlert,
19+
setAlertFlyoutVisibility,
20+
}: Props) => {
21+
const onClose = () => {
22+
setAlertFlyoutVisibility(false);
23+
};
24+
return alertFlyoutVisible ? <AlertEdit initialAlert={initialAlert} onClose={onClose} /> : null;
25+
};

x-pack/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ import { useMonitorId } from '../../../hooks';
2222
import { setAlertFlyoutType, setAlertFlyoutVisible } from '../../../state/actions';
2323
import { useAnomalyAlert } from './use_anomaly_alert';
2424
import { ConfirmAlertDeletion } from './confirm_alert_delete';
25-
import { deleteAnomalyAlertAction } from '../../../state/alerts/alerts';
25+
import {
26+
deleteAnomalyAlertAction,
27+
getAnomalyAlertAction,
28+
isAnomalyAlertDeleting,
29+
} from '../../../state/alerts/alerts';
30+
import { UptimeEditAlertFlyoutComponent } from '../../common/alerts/uptime_edit_alert_flyout';
2631

2732
interface Props {
2833
hasMLJob: boolean;
@@ -33,11 +38,14 @@ interface Props {
3338
export const ManageMLJobComponent = ({ hasMLJob, onEnableJob, onJobDelete }: Props) => {
3439
const [isPopOverOpen, setIsPopOverOpen] = useState(false);
3540

41+
const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
42+
3643
const { basePath } = useContext(UptimeSettingsContext);
3744

3845
const canDeleteMLJob = useSelector(canDeleteMLJobSelector);
3946

4047
const isMLJobCreating = useSelector(isMLJobCreatingSelector);
48+
const isAlertDeleting = useSelector(isAnomalyAlertDeleting);
4149

4250
const { loading: isMLJobLoading } = useSelector(hasMLJobSelector);
4351

@@ -54,7 +62,7 @@ export const ManageMLJobComponent = ({ hasMLJob, onEnableJob, onJobDelete }: Pro
5462
const deleteAnomalyAlert = () =>
5563
dispatch(deleteAnomalyAlertAction.get({ alertId: anomalyAlert?.id as string }));
5664

57-
const showLoading = isMLJobCreating || isMLJobLoading;
65+
const showLoading = isMLJobCreating || isMLJobLoading || isAlertDeleting;
5866

5967
const btnText = hasMLJob ? labels.ANOMALY_DETECTION : labels.ENABLE_ANOMALY_DETECTION;
6068

@@ -63,7 +71,7 @@ export const ManageMLJobComponent = ({ hasMLJob, onEnableJob, onJobDelete }: Pro
6371
data-test-subj={hasMLJob ? 'uptimeManageMLJobBtn' : 'uptimeEnableAnomalyBtn'}
6472
onClick={hasMLJob ? () => setIsPopOverOpen(true) : onEnableJob}
6573
disabled={hasMLJob && !canDeleteMLJob}
66-
isLoading={isMLJobCreating || isMLJobLoading}
74+
isLoading={showLoading}
6775
size="s"
6876
aria-label={labels.ENABLE_MANAGE_JOB}
6977
>
@@ -85,21 +93,27 @@ export const ManageMLJobComponent = ({ hasMLJob, onEnableJob, onJobDelete }: Pro
8593
dateRange: { from: dateRangeStart, to: dateRangeEnd },
8694
}),
8795
},
88-
{
89-
name: anomalyAlert ? labels.DISABLE_ANOMALY_ALERT : labels.ENABLE_ANOMALY_ALERT,
90-
'data-test-subj': anomalyAlert
91-
? 'uptimeDisableAnomalyAlertBtn'
92-
: 'uptimeEnableAnomalyAlertBtn',
93-
icon: <EuiIcon type={anomalyAlert ? 'bellSlash' : 'bell'} size="m" />,
94-
onClick: () => {
95-
if (anomalyAlert) {
96-
setIsConfirmAlertDeleteOpen(true);
97-
} else {
98-
dispatch(setAlertFlyoutType(CLIENT_ALERT_TYPES.DURATION_ANOMALY));
99-
dispatch(setAlertFlyoutVisible(true));
100-
}
101-
},
102-
},
96+
...(anomalyAlert
97+
? [
98+
{
99+
name: 'Anomaly alert',
100+
icon: 'bell',
101+
'data-test-subj': 'uptimeManageAnomalyAlertBtn',
102+
panel: 1,
103+
},
104+
]
105+
: [
106+
{
107+
name: labels.ENABLE_ANOMALY_ALERT,
108+
'data-test-subj': 'uptimeEnableAnomalyAlertBtn',
109+
icon: 'bell',
110+
onClick: () => {
111+
dispatch(setAlertFlyoutType(CLIENT_ALERT_TYPES.DURATION_ANOMALY));
112+
dispatch(setAlertFlyoutVisible(true));
113+
setIsPopOverOpen(false);
114+
},
115+
},
116+
]),
103117
{
104118
name: labels.DISABLE_ANOMALY_DETECTION,
105119
'data-test-subj': 'uptimeDeleteMLJobBtn',
@@ -111,6 +125,27 @@ export const ManageMLJobComponent = ({ hasMLJob, onEnableJob, onJobDelete }: Pro
111125
},
112126
],
113127
},
128+
{
129+
id: 1,
130+
title: 'Anomaly alert',
131+
items: [
132+
{
133+
name: 'Edit',
134+
'data-test-subj': 'uptimeEditAnomalyAlertBtn',
135+
onClick: () => {
136+
setIsFlyoutOpen(true);
137+
setIsPopOverOpen(false);
138+
},
139+
},
140+
{
141+
name: 'Disable',
142+
'data-test-subj': 'uptimeDisableAnomalyAlertBtn',
143+
onClick: () => {
144+
setIsConfirmAlertDeleteOpen(true);
145+
},
146+
},
147+
],
148+
},
114149
];
115150

116151
return (
@@ -138,6 +173,14 @@ export const ManageMLJobComponent = ({ hasMLJob, onEnableJob, onJobDelete }: Pro
138173
}}
139174
/>
140175
)}
176+
<UptimeEditAlertFlyoutComponent
177+
initialAlert={anomalyAlert!}
178+
alertFlyoutVisible={isFlyoutOpen}
179+
setAlertFlyoutVisibility={() => {
180+
setIsFlyoutOpen(false);
181+
dispatch(getAnomalyAlertAction.get({ monitorId }));
182+
}}
183+
/>
141184
</>
142185
);
143186
};

x-pack/plugins/uptime/public/components/overview/alerts/anomaly_alert/anomaly_alert.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { useSelector } from 'react-redux';
1616
import React, { useEffect, useState } from 'react';
1717
import { AnomalyTranslations } from './translations';
1818
import { AlertExpressionPopover } from '../alert_expression_popover';
19-
import { DEFAULT_SEVERITY, SelectSeverity } from './select_severity';
19+
import { DEFAULT_SEVERITY, SelectSeverity, SEVERITY_OPTIONS } from './select_severity';
2020
import { monitorIdSelector } from '../../../../state/selectors';
2121
import { getSeverityColor, getSeverityType } from '../../../../../../ml/public';
2222

@@ -40,6 +40,14 @@ export function AnomalyAlertComponent({ setAlertParams, alertParams }: Props) {
4040
setAlertParams('severity', severity.val);
4141
}, [severity, setAlertParams]);
4242

43+
useEffect(() => {
44+
if (alertParams.severity !== undefined) {
45+
setSeverity(SEVERITY_OPTIONS.find(({ val }) => val === alertParams.severity)!);
46+
}
47+
48+
// eslint-disable-next-line react-hooks/exhaustive-deps
49+
}, []);
50+
4351
return (
4452
<>
4553
<EuiSpacer size="l" />

x-pack/plugins/uptime/public/lib/alert_types/duration_anomaly.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ export const initDurationAnomalyAlertType: AlertTypeInitializer = ({
2525
name,
2626
validate: () => ({ errors: {} }),
2727
defaultActionMessage,
28-
requiresAppContext: false,
28+
requiresAppContext: true,
2929
});

x-pack/plugins/uptime/public/state/alerts/alerts.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,4 @@ export const alertsSelector = ({ alerts }: AppState) => alerts.alerts;
163163
export const isAlertDeletedSelector = ({ alerts }: AppState) => alerts.alertDeletion;
164164

165165
export const anomalyAlertSelector = ({ alerts }: AppState) => alerts.anomalyAlert;
166+
export const isAnomalyAlertDeleting = ({ alerts }: AppState) => alerts.anomalyAlertDeletion.loading;

x-pack/test/functional/apps/uptime/ml_anomaly.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ export default ({ getService }: FtrProviderContext) => {
4040

4141
it('can create job successfully', async () => {
4242
await uptime.ml.createMLJob();
43-
// await uptime.navigation.refreshApp();
4443
});
4544

4645
it('can open ML Manage Menu', async () => {

x-pack/test/functional/services/uptime/ml_anomaly.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ export function UptimeMLAnomalyProvider({ getService }: FtrProviderContext) {
6666
return await testSubjects.click('uptimeEnableAnomalyAlertBtn');
6767
},
6868

69-
async disableAnomalyAlertIsVisible() {
70-
return await testSubjects.exists('uptimeDisableAnomalyAlertBtn');
69+
async manageAnomalyAlertIsVisible() {
70+
return await testSubjects.exists('uptimeManageAnomalyAlertBtn');
7171
},
7272

7373
async changeAlertThreshold(level: string) {

x-pack/test/functional_with_es_ssl/apps/uptime/anomaly_alert.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
111111

112112
it('change button to disable anomaly alert', async () => {
113113
await uptime.ml.openMLManageMenu();
114-
expect(uptime.ml.disableAnomalyAlertIsVisible()).to.eql(true);
114+
expect(uptime.ml.manageAnomalyAlertIsVisible()).to.eql(true);
115115
});
116116

117117
it('can delete job successfully', async () => {

0 commit comments

Comments
 (0)