Skip to content

Commit

Permalink
[ML] Fixing ML's watcher integration (#55439) (#55548)
Browse files Browse the repository at this point in the history
  • Loading branch information
jgowdyelastic committed Jan 22, 2020
1 parent 10571fb commit 6edf08b
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { FormattedMessage, injectI18n } from '@kbn/i18n/react';

import { parseInterval } from '../../../../../../common/util/parse_interval';
import { ml } from '../../../../services/ml_api_service';
import { SelectSeverity } from '../../../../components/controls/select_severity/select_severity';
import { SelectSeverity } from './select_severity';
import { mlCreateWatchService } from './create_watch_service';
const STATUS = mlCreateWatchService.STATUS;

Expand Down Expand Up @@ -111,20 +111,6 @@ export const CreateWatch = injectI18n(

render() {
const { intl } = this.props;
const mlSelectSeverityService = {
state: {
set: (name, threshold) => {
// eslint-disable-line no-unused-vars
this.onThresholdChange(threshold);
return {
changed: () => {},
};
},
get: () => {
return this.config.threshold;
},
},
};
const { status } = this.state;

if (status === null || status === STATUS.SAVING || status === STATUS.SAVE_FAILED) {
Expand Down Expand Up @@ -165,10 +151,7 @@ export const CreateWatch = injectI18n(
</label>
</div>
<div className="dropdown-group">
<SelectSeverity
id="selectSeverity"
mlSelectSeverityService={mlSelectSeverityService}
/>
<SelectSeverity onChange={this.onThresholdChange} />
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

/*
* React component for rendering a select element with threshold levels.
* This is basically a copy of SelectSeverity in public/application/components/controls/select_severity
* but which stores its state internally rather than in the appState
*/
import React, { Fragment, FC, useState } from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';

import { EuiHealth, EuiSpacer, EuiSuperSelect, EuiText } from '@elastic/eui';

import { getSeverityColor } from '../../../../../../common/util/anomaly_utils';

const warningLabel = i18n.translate('xpack.ml.controls.selectSeverity.warningLabel', {
defaultMessage: 'warning',
});
const minorLabel = i18n.translate('xpack.ml.controls.selectSeverity.minorLabel', {
defaultMessage: 'minor',
});
const majorLabel = i18n.translate('xpack.ml.controls.selectSeverity.majorLabel', {
defaultMessage: 'major',
});
const criticalLabel = i18n.translate('xpack.ml.controls.selectSeverity.criticalLabel', {
defaultMessage: 'critical',
});

const optionsMap = {
[warningLabel]: 0,
[minorLabel]: 25,
[majorLabel]: 50,
[criticalLabel]: 75,
};

interface TableSeverity {
val: number;
display: string;
color: string;
}

export const SEVERITY_OPTIONS: TableSeverity[] = [
{
val: 0,
display: warningLabel,
color: getSeverityColor(0),
},
{
val: 25,
display: minorLabel,
color: getSeverityColor(25),
},
{
val: 50,
display: majorLabel,
color: getSeverityColor(50),
},
{
val: 75,
display: criticalLabel,
color: getSeverityColor(75),
},
];

function optionValueToThreshold(value: number) {
// Get corresponding threshold object with required display and val properties from the specified value.
let threshold = SEVERITY_OPTIONS.find(opt => opt.val === value);

// Default to warning if supplied value doesn't map to one of the options.
if (threshold === undefined) {
threshold = SEVERITY_OPTIONS[0];
}

return threshold;
}

const TABLE_SEVERITY_DEFAULT = SEVERITY_OPTIONS[0];

const getSeverityOptions = () =>
SEVERITY_OPTIONS.map(({ color, display, val }) => ({
value: display,
inputDisplay: (
<Fragment>
<EuiHealth color={color} style={{ lineHeight: 'inherit' }}>
{display}
</EuiHealth>
</Fragment>
),
dropdownDisplay: (
<Fragment>
<EuiHealth color={color} style={{ lineHeight: 'inherit' }}>
{display}
</EuiHealth>
<EuiSpacer size="xs" />
<EuiText size="xs" color="subdued">
<p className="euiTextColor--subdued">
<FormattedMessage
id="xpack.ml.controls.selectSeverity.scoreDetailsDescription"
defaultMessage="score {value} and above"
values={{ value: val }}
/>
</p>
</EuiText>
</Fragment>
),
}));

interface Props {
onChange: (sev: TableSeverity) => void;
}

export const SelectSeverity: FC<Props> = ({ onChange }) => {
const [severity, setSeverity] = useState(TABLE_SEVERITY_DEFAULT);

const onSeverityChange = (valueDisplay: string) => {
const option = optionValueToThreshold(optionsMap[valueDisplay]);
setSeverity(option);
onChange(option);
};

return (
<EuiSuperSelect
hasDividers
options={getSeverityOptions()}
valueOfSelected={severity.display}
onChange={onSeverityChange}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ export function http(options: any) {

fetch(url, payload)
.then(resp => {
resp.json().then(resp.ok === true ? resolve : reject);
resp
.json()
.then(resp.ok === true ? resolve : reject)
.catch(resp.ok === true ? resolve : reject);
})
.catch(resp => {
reject(resp);
Expand Down

0 comments on commit 6edf08b

Please sign in to comment.