Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Address feedback and add feature required state
Browse files Browse the repository at this point in the history
  • Loading branch information
ohltyler committed Apr 27, 2020
1 parent 76b5459 commit fd4441e
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const ListControls = (props: ListControlsProps) => (
? props.selectedDetectorStates.map(index => ({ label: index }))
: []
}
fullWidth={true}
/>
</EuiFlexItem>
<EuiFlexItem>
Expand All @@ -78,6 +79,7 @@ export const ListControls = (props: ListControlsProps) => (
? props.selectedIndices.map(index => ({ label: index }))
: []
}
fullWidth={true}
/>
</EuiFlexItem>
{props.pageCount > 1 ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ exports[`<ListControls /> spec Empty results renders component with empty messag
<div
aria-expanded="false"
aria-haspopup="listbox"
class="euiComboBox"
class="euiComboBox euiComboBox--fullWidth"
role="combobox"
>
<div
class="euiFormControlLayout"
class="euiFormControlLayout euiFormControlLayout--fullWidth"
>
<div
class="euiFormControlLayout__childrenWrapper"
>
<div
class="euiComboBox__inputWrap euiComboBox__inputWrap-isClearable"
class="euiComboBox__inputWrap euiComboBox__inputWrap--fullWidth euiComboBox__inputWrap-isClearable"
data-test-subj="comboBoxInput"
tabindex="-1"
>
Expand Down Expand Up @@ -112,17 +112,17 @@ exports[`<ListControls /> spec Empty results renders component with empty messag
<div
aria-expanded="false"
aria-haspopup="listbox"
class="euiComboBox"
class="euiComboBox euiComboBox--fullWidth"
role="combobox"
>
<div
class="euiFormControlLayout"
class="euiFormControlLayout euiFormControlLayout--fullWidth"
>
<div
class="euiFormControlLayout__childrenWrapper"
>
<div
class="euiComboBox__inputWrap euiComboBox__inputWrap-isClearable"
class="euiComboBox__inputWrap euiComboBox__inputWrap--fullWidth euiComboBox__inputWrap-isClearable"
data-test-subj="comboBoxInput"
tabindex="-1"
>
Expand Down
39 changes: 18 additions & 21 deletions public/pages/DetectorsList/List/__tests__/List.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ describe('<ListControls /> spec', () => {
name: `detector_name_${index}`,
indices: [`index_${index}`],
curState: DETECTOR_STATE.DISABLED,
featureAttributes: [`feature_${index}`],
totalAnomalies: index,
lastActiveAnomaly: moment('2020-04-15T09:00:00')
.add(index, 'minutes')
Expand All @@ -160,12 +161,7 @@ describe('<ListControls /> spec', () => {
},
});

const {
getByText,
getAllByTestId,
queryByText,
getAllByText,
} = renderWithRouter({
const { getByText, getAllByTestId, queryByText } = renderWithRouter({
...initialDetectorsState,
requesting: true,
});
Expand All @@ -191,13 +187,14 @@ describe('<ListControls /> spec', () => {
expect(queryByText('index_0')).toBeNull();

// Sort by detector state (enum sorting)
// NOTE: this is assuming DETECTOR_STATE.RUNNING is higher alphabetically ('running')
// than DETECTOR_STATE.DISABLED ('stopped')
userEvent.click(getAllByTestId('tableHeaderSortButton')[2]);
await wait();
getAllByText(DETECTOR_STATE.DISABLED);
expect(queryByText(DETECTOR_STATE.RUNNING)).toBeNull();
expect(queryByText(DETECTOR_STATE.RUNNING)).not.toBeNull();
userEvent.click(getAllByTestId('tableHeaderSortButton')[2]);
await wait();
expect(queryByText(DETECTOR_STATE.RUNNING)).not.toBeNull();
expect(queryByText(DETECTOR_STATE.RUNNING)).toBeNull();

// Sort by totalAnomalies (numeric sorting)
userEvent.click(getAllByTestId('tableHeaderSortButton')[3]);
Expand All @@ -216,22 +213,22 @@ describe('<ListControls /> spec', () => {
// Sort by last anomaly occurrence (date sorting)
userEvent.click(getAllByTestId('tableHeaderSortButton')[4]);
await wait();
getByText('04/15/2020 9:00 am');
expect(queryByText('04/15/2020 9:30 am')).toBeNull();
getByText('04/15/2020 9:00 AM');
expect(queryByText('04/15/2020 9:30 AM')).toBeNull();
userEvent.click(getAllByTestId('tableHeaderSortButton')[4]);
await wait();
getByText('04/15/2020 9:30 am');
expect(queryByText('04/15/2020 9:00 am')).toBeNull();
getByText('04/15/2020 9:30 AM');
expect(queryByText('04/15/2020 9:00 AM')).toBeNull();

// Sort by last updated (date sorting)
userEvent.click(getAllByTestId('tableHeaderSortButton')[5]);
await wait();
getByText('04/15/2020 7:00 am');
expect(queryByText('04/15/2020 7:30 am')).toBeNull();
getByText('04/15/2020 7:00 AM');
expect(queryByText('04/15/2020 7:30 AM')).toBeNull();
userEvent.click(getAllByTestId('tableHeaderSortButton')[5]);
await wait();
getByText('04/15/2020 7:30 am');
expect(queryByText('04/15/2020 7:00 am')).toBeNull();
getByText('04/15/2020 7:30 AM');
expect(queryByText('04/15/2020 7:00 AM')).toBeNull();
});
test('should be able to search', async () => {
const randomDetectors = new Array(40).fill(null).map((_, index) => {
Expand Down Expand Up @@ -328,15 +325,15 @@ describe('<ListControls /> spec', () => {
getByText(randomDetectors[0].indices[0]);
getByText(randomDetectors[0].curState);
getByText(randomDetectors[0].totalAnomalies.toString());
getByText('10/19/2019 9:00 am');
getByText('10/19/2019 7:00 am');
getByText('10/19/2019 9:00 AM');
getByText('10/19/2019 7:00 AM');
//Test3 Detector
getByText(randomDetectors[2].name);
getByText(randomDetectors[2].indices[0]);
getByText(randomDetectors[2].curState);
getByText(randomDetectors[2].totalAnomalies.toString());
getByText('10/19/2019 9:30 am');
getByText('10/19/2019 7:30 am');
getByText('10/19/2019 9:30 AM');
getByText('10/19/2019 7:30 AM');
});
});
});
10 changes: 7 additions & 3 deletions public/pages/DetectorsList/utils/tableUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { EuiIcon, EuiLink, EuiToolTip, EuiHealth } from '@elastic/eui';
import moment from 'moment';
import get from 'lodash/get';
import React from 'react';
import { Detector } from '../../../../server/models/types';
import { Detector } from '../../../models/interfaces';
import { PLUGIN_NAME, DETECTOR_STATE } from '../../../utils/constants';
import { stateToColorMap } from '../../utils/constants';
import { darkModeEnabled } from '../../../utils/kibanaUtils';
Expand All @@ -29,15 +29,15 @@ const hintColor = darkModeEnabled() ? '#98A2B3' : '#535966';
const renderTime = (time: number) => {
const momentTime = moment(time);
if (time && momentTime.isValid())
return momentTime.format('MM/DD/YYYY h:mm a');
return momentTime.format('MM/DD/YYYY h:mm A');
return DEFAULT_EMPTY_DATA;
};

const renderIndices = (indices: string[]) => {
return get(indices, '0', DEFAULT_EMPTY_DATA);
};

const renderState = (state: DETECTOR_STATE) => {
const renderState = (state: DETECTOR_STATE, detector: Detector) => {
return (
//@ts-ignore
<EuiHealth color={stateToColorMap.get(state)}>{state}</EuiHealth>
Expand All @@ -64,6 +64,7 @@ export const staticColumn = [
truncateText: true,
textOnly: true,
align: 'left',
width: '15%',
render: (name: string, detector: Detector) => (
<EuiLink href={`${PLUGIN_NAME}#/detectors/${detector.id}`}>
{name}
Expand All @@ -89,6 +90,7 @@ export const staticColumn = [
truncateText: true,
textOnly: true,
align: 'left',
width: '15%',
render: renderIndices,
},
{
Expand Down Expand Up @@ -153,6 +155,7 @@ export const staticColumn = [
dataType: 'date',
truncateText: false,
align: 'left',
width: '16%',
render: renderTime,
},
{
Expand All @@ -174,6 +177,7 @@ export const staticColumn = [
dataType: 'date',
truncateText: false,
align: 'left',
width: '16%',
render: renderTime,
},
];
2 changes: 2 additions & 0 deletions public/pages/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export enum DETECTOR_STATE_COLOR {
DISABLED = 'subdued',
INIT = '#0000cc',
RUNNING = 'success',
FEATURE_REQUIRED = 'subdued',
INIT_FAILURE = 'danger',
UNEXPECTED_FAILURE = 'danger',
}
Expand All @@ -28,6 +29,7 @@ export const stateToColorMap = new Map<DETECTOR_STATE, DETECTOR_STATE_COLOR>()
.set(DETECTOR_STATE.DISABLED, DETECTOR_STATE_COLOR.DISABLED)
.set(DETECTOR_STATE.INIT, DETECTOR_STATE_COLOR.INIT)
.set(DETECTOR_STATE.RUNNING, DETECTOR_STATE_COLOR.RUNNING)
.set(DETECTOR_STATE.FEATURE_REQUIRED, DETECTOR_STATE_COLOR.FEATURE_REQUIRED)
.set(DETECTOR_STATE.INIT_FAILURE, DETECTOR_STATE_COLOR.INIT_FAILURE)
.set(
DETECTOR_STATE.UNEXPECTED_FAILURE,
Expand Down
1 change: 1 addition & 0 deletions public/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export enum DETECTOR_STATE {
DISABLED = 'Stopped',
INIT = 'Initializing',
RUNNING = 'Running',
FEATURE_REQUIRED = 'Feature required',
INIT_FAILURE = 'Initialization failure',
UNEXPECTED_FAILURE = 'Unexpected failure',
}
15 changes: 12 additions & 3 deletions server/routes/ad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,6 @@ const getDetectors = async (
description: get(detector, '_source.description', ''),
indices: get(detector, '_source.indices', []),
lastUpdateTime: get(detector, '_source.last_update_time', 0),
// TODO: get the state of the detector once possible (enabled/disabled for now)
...convertDetectorKeysToCamelCase(get(detector, '_source', {})),
},
}),
Expand Down Expand Up @@ -445,8 +444,8 @@ const getDetectors = async (
detectorState.state = DETECTOR_STATE[detectorState.state];
});

// check if there was any failures
detectorStates.forEach(detectorState => {
// check if there was any failures / detectors that are unable to start
detectorStates.forEach((detectorState, i) => {
/*
If the error starts with 'Stopped detector', then an EndRunException was thrown.
All EndRunExceptions are related to initialization failures except for the
Expand All @@ -461,6 +460,16 @@ const getDetectors = async (
? DETECTOR_STATE.UNEXPECTED_FAILURE
: DETECTOR_STATE.INIT_FAILURE;
}

/*
If a detector has no features, set to a feature required state
*/
if (
detectorState.state === DETECTOR_STATE.DISABLED &&
finalDetectors[i].featureAttributes.length === 0
) {
detectorState.state = DETECTOR_STATE.FEATURE_REQUIRED;
}
});

// update the final detectors to include the detector state
Expand Down

0 comments on commit fd4441e

Please sign in to comment.