Skip to content

Commit 2f8801e

Browse files
[ML] Fixing ML's watcher integration (#55439) (#55547)
1 parent a92684b commit 2f8801e

File tree

3 files changed

+139
-20
lines changed

3 files changed

+139
-20
lines changed

x-pack/legacy/plugins/ml/public/application/jobs/jobs_list/components/create_watch_flyout/create_watch_view.js

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
2121

2222
import { parseInterval } from '../../../../../../common/util/parse_interval';
2323
import { ml } from '../../../../services/ml_api_service';
24-
import { SelectSeverity } from '../../../../components/controls/select_severity/select_severity';
24+
import { SelectSeverity } from './select_severity';
2525
import { mlCreateWatchService } from './create_watch_service';
2626
const STATUS = mlCreateWatchService.STATUS;
2727

@@ -111,20 +111,6 @@ export const CreateWatch = injectI18n(
111111

112112
render() {
113113
const { intl } = this.props;
114-
const mlSelectSeverityService = {
115-
state: {
116-
set: (name, threshold) => {
117-
// eslint-disable-line no-unused-vars
118-
this.onThresholdChange(threshold);
119-
return {
120-
changed: () => {},
121-
};
122-
},
123-
get: () => {
124-
return this.config.threshold;
125-
},
126-
},
127-
};
128114
const { status } = this.state;
129115

130116
if (status === null || status === STATUS.SAVING || status === STATUS.SAVE_FAILED) {
@@ -165,10 +151,7 @@ export const CreateWatch = injectI18n(
165151
</label>
166152
</div>
167153
<div className="dropdown-group">
168-
<SelectSeverity
169-
id="selectSeverity"
170-
mlSelectSeverityService={mlSelectSeverityService}
171-
/>
154+
<SelectSeverity onChange={this.onThresholdChange} />
172155
</div>
173156
</div>
174157
</div>
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
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+
/*
8+
* React component for rendering a select element with threshold levels.
9+
* This is basically a copy of SelectSeverity in public/application/components/controls/select_severity
10+
* but which stores its state internally rather than in the appState
11+
*/
12+
import React, { Fragment, FC, useState } from 'react';
13+
import { i18n } from '@kbn/i18n';
14+
import { FormattedMessage } from '@kbn/i18n/react';
15+
16+
import { EuiHealth, EuiSpacer, EuiSuperSelect, EuiText } from '@elastic/eui';
17+
18+
import { getSeverityColor } from '../../../../../../common/util/anomaly_utils';
19+
20+
const warningLabel = i18n.translate('xpack.ml.controls.selectSeverity.warningLabel', {
21+
defaultMessage: 'warning',
22+
});
23+
const minorLabel = i18n.translate('xpack.ml.controls.selectSeverity.minorLabel', {
24+
defaultMessage: 'minor',
25+
});
26+
const majorLabel = i18n.translate('xpack.ml.controls.selectSeverity.majorLabel', {
27+
defaultMessage: 'major',
28+
});
29+
const criticalLabel = i18n.translate('xpack.ml.controls.selectSeverity.criticalLabel', {
30+
defaultMessage: 'critical',
31+
});
32+
33+
const optionsMap = {
34+
[warningLabel]: 0,
35+
[minorLabel]: 25,
36+
[majorLabel]: 50,
37+
[criticalLabel]: 75,
38+
};
39+
40+
interface TableSeverity {
41+
val: number;
42+
display: string;
43+
color: string;
44+
}
45+
46+
export const SEVERITY_OPTIONS: TableSeverity[] = [
47+
{
48+
val: 0,
49+
display: warningLabel,
50+
color: getSeverityColor(0),
51+
},
52+
{
53+
val: 25,
54+
display: minorLabel,
55+
color: getSeverityColor(25),
56+
},
57+
{
58+
val: 50,
59+
display: majorLabel,
60+
color: getSeverityColor(50),
61+
},
62+
{
63+
val: 75,
64+
display: criticalLabel,
65+
color: getSeverityColor(75),
66+
},
67+
];
68+
69+
function optionValueToThreshold(value: number) {
70+
// Get corresponding threshold object with required display and val properties from the specified value.
71+
let threshold = SEVERITY_OPTIONS.find(opt => opt.val === value);
72+
73+
// Default to warning if supplied value doesn't map to one of the options.
74+
if (threshold === undefined) {
75+
threshold = SEVERITY_OPTIONS[0];
76+
}
77+
78+
return threshold;
79+
}
80+
81+
const TABLE_SEVERITY_DEFAULT = SEVERITY_OPTIONS[0];
82+
83+
const getSeverityOptions = () =>
84+
SEVERITY_OPTIONS.map(({ color, display, val }) => ({
85+
value: display,
86+
inputDisplay: (
87+
<Fragment>
88+
<EuiHealth color={color} style={{ lineHeight: 'inherit' }}>
89+
{display}
90+
</EuiHealth>
91+
</Fragment>
92+
),
93+
dropdownDisplay: (
94+
<Fragment>
95+
<EuiHealth color={color} style={{ lineHeight: 'inherit' }}>
96+
{display}
97+
</EuiHealth>
98+
<EuiSpacer size="xs" />
99+
<EuiText size="xs" color="subdued">
100+
<p className="euiTextColor--subdued">
101+
<FormattedMessage
102+
id="xpack.ml.controls.selectSeverity.scoreDetailsDescription"
103+
defaultMessage="score {value} and above"
104+
values={{ value: val }}
105+
/>
106+
</p>
107+
</EuiText>
108+
</Fragment>
109+
),
110+
}));
111+
112+
interface Props {
113+
onChange: (sev: TableSeverity) => void;
114+
}
115+
116+
export const SelectSeverity: FC<Props> = ({ onChange }) => {
117+
const [severity, setSeverity] = useState(TABLE_SEVERITY_DEFAULT);
118+
119+
const onSeverityChange = (valueDisplay: string) => {
120+
const option = optionValueToThreshold(optionsMap[valueDisplay]);
121+
setSeverity(option);
122+
onChange(option);
123+
};
124+
125+
return (
126+
<EuiSuperSelect
127+
hasDividers
128+
options={getSeverityOptions()}
129+
valueOfSelected={severity.display}
130+
onChange={onSeverityChange}
131+
/>
132+
);
133+
};

x-pack/legacy/plugins/ml/public/application/services/http_service.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ export function http(options: any) {
5353

5454
fetch(url, payload)
5555
.then(resp => {
56-
resp.json().then(resp.ok === true ? resolve : reject);
56+
resp
57+
.json()
58+
.then(resp.ok === true ? resolve : reject)
59+
.catch(resp.ok === true ? resolve : reject);
5760
})
5861
.catch(resp => {
5962
reject(resp);

0 commit comments

Comments
 (0)