Skip to content

Commit

Permalink
[ML] Consolidate view by swimlane naming. Fix view by dropdown select…
Browse files Browse the repository at this point in the history
…ion on load.
  • Loading branch information
walterra committed Nov 25, 2019
1 parent db0364f commit fb2e326
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export function jobSelectionActionCreator(
noJobsFound,
selectedCells,
selectedJobs,
swimlaneViewByFieldName: appState.mlExplorerSwimlane.viewByFieldName,
viewBySwimlaneFieldName: appState.mlExplorerSwimlane.viewByFieldName,
filterData,
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export function loadOverallDataActionCreator(
swimlaneBucketInterval: TimeBucketsInterval,
bounds: TimeRangeBounds,
showOverallLoadingIndicator = true,
viewBySwimlaneOptions: any,
viewBySwimlaneFieldName: string,
viewBySwimlaneOptions: string[],
influencersFilterQuery: any,
timerange: any,
swimlaneLimit: number,
Expand All @@ -66,7 +67,7 @@ export function loadOverallDataActionCreator(
timerange.earliestMs,
timerange.latestMs,
selectedJobs,
viewBySwimlaneOptions.swimlaneViewByFieldName,
viewBySwimlaneFieldName,
swimlaneLimit,
noInfluencersConfigured
)
Expand All @@ -92,7 +93,7 @@ export function loadOverallDataActionCreator(
latest: overallState.overallSwimlaneData.latest,
},
selectedJobs,
viewBySwimlaneOptions.swimlaneViewByFieldName,
viewBySwimlaneFieldName,
swimlaneLimit,
influencersFilterQuery,
noInfluencersConfigured
Expand All @@ -107,7 +108,8 @@ export function loadOverallDataActionCreator(
...overallState,
...viewBySwimlaneState,
viewByLoadedForTimeFormatted: formatHumanReadableDateTime(timerange.earliestMs),
...viewBySwimlaneOptions,
viewBySwimlaneFieldName,
viewBySwimlaneOptions,
},
};
} else {
Expand All @@ -116,7 +118,8 @@ export function loadOverallDataActionCreator(
payload: {
...overallState,
...viewBySwimlaneState,
...viewBySwimlaneOptions,
viewBySwimlaneFieldName,
viewBySwimlaneOptions,
},
};
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,30 @@ import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiEmptyPrompt } from '@elastic/eui';

export const ExplorerNoInfluencersFound = ({ swimlaneViewByFieldName, showFilterMessage = false }) => (
export const ExplorerNoInfluencersFound = ({ viewBySwimlaneFieldName, showFilterMessage = false }) => (
<EuiEmptyPrompt
titleSize="xs"
title={
<h2>
{showFilterMessage === false && (
<FormattedMessage
id="xpack.ml.explorer.noInfluencersFoundTitle"
defaultMessage="No {swimlaneViewByFieldName} influencers found"
values={{ swimlaneViewByFieldName }}
defaultMessage="No {viewBySwimlaneFieldName} influencers found"
values={{ viewBySwimlaneFieldName }}
/>
)}
{showFilterMessage === true && (
<FormattedMessage
id="xpack.ml.explorer.noInfluencersFoundTitleFilterMessage"
defaultMessage="No {swimlaneViewByFieldName} influencers found for specified filter"
values={{ swimlaneViewByFieldName }}
defaultMessage="No {viewBySwimlaneFieldName} influencers found for specified filter"
values={{ viewBySwimlaneFieldName }}
/>
)}
</h2>
}
/>);

ExplorerNoInfluencersFound.propTypes = {
swimlaneViewByFieldName: PropTypes.string.isRequired,
viewBySwimlaneFieldName: PropTypes.string.isRequired,
showFilterMessage: PropTypes.bool
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ExplorerNoInfluencersFound } from './explorer_no_influencers_found';
describe('ExplorerNoInfluencersFound', () => {

test('snapshot', () => {
const wrapper = shallow(<ExplorerNoInfluencersFound swimlaneViewByFieldName="field_name" />);
const wrapper = shallow(<ExplorerNoInfluencersFound viewBySwimlaneFieldName="field_name" />);
expect(wrapper).toMatchSnapshot();
});

Expand Down
83 changes: 33 additions & 50 deletions x-pack/legacy/plugins/ml/public/application/explorer/explorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,12 @@ export const Explorer = injectI18n(injectObservablesAsProps(
const { type, payload } = this.props.explorer;

if (type === EXPLORER_ACTION.INITIALIZE) {
const { noJobsFound, selectedCells, selectedJobs, swimlaneViewByFieldName, filterData } = payload;
const { noJobsFound, selectedCells, selectedJobs, viewBySwimlaneFieldName, filterData } = payload;
let currentSelectedCells = this.state.selectedCells;
let currentSwimlaneViewByFieldName = this.state.swimlaneViewByFieldName;
let currentviewBySwimlaneFieldName = this.props.explorerState.viewBySwimlaneFieldName;

if (swimlaneViewByFieldName !== undefined) {
currentSwimlaneViewByFieldName = swimlaneViewByFieldName;
if (viewBySwimlaneFieldName !== undefined) {
currentviewBySwimlaneFieldName = viewBySwimlaneFieldName;
}

if (selectedCells !== undefined && currentSelectedCells === null) {
Expand All @@ -305,7 +305,7 @@ export const Explorer = injectI18n(injectObservablesAsProps(
noJobsFound,
selectedCells: currentSelectedCells,
selectedJobs,
swimlaneViewByFieldName: currentSwimlaneViewByFieldName
viewBySwimlaneFieldName: currentviewBySwimlaneFieldName
};

if (filterData.influencersFilterQuery !== undefined) {
Expand Down Expand Up @@ -351,15 +351,9 @@ export const Explorer = injectI18n(injectObservablesAsProps(
}

if (selectedJobs.length > 1) {
explorerAction$.next({
type: EXPLORER_ACTION.APP_STATE_SAVE_SWIMLANE_VIEW_BY_FIELD_NAME,
payload: { swimlaneViewByFieldName: VIEW_BY_JOB_LABEL }
});
stateUpdate.swimlaneViewByFieldName = VIEW_BY_JOB_LABEL;
// enforce a state update for swimlaneViewByFieldName
this.setState({ swimlaneViewByFieldName: VIEW_BY_JOB_LABEL }, () => {
this.updateExplorer(stateUpdate, true);
});
stateUpdate.viewBySwimlaneFieldName = VIEW_BY_JOB_LABEL;
this.updateExplorer(stateUpdate, true);
explorerAction$.next({ type: EXPLORER_ACTION.IDLE });
return;
}
this.updateExplorer(stateUpdate, true);
Expand Down Expand Up @@ -419,12 +413,12 @@ export const Explorer = injectI18n(injectObservablesAsProps(

topFieldsPreviousArgs = null;
topFieldsPreviousData = null;
loadViewByTopFieldValuesForSelectedTime(earliestMs, latestMs, selectedJobs, swimlaneViewByFieldName) {
loadViewByTopFieldValuesForSelectedTime(earliestMs, latestMs, selectedJobs, viewBySwimlaneFieldName) {
const selectedJobIds = selectedJobs.map(d => d.id);
const { swimlaneLimit } = this.props;

const compareArgs = {
earliestMs, latestMs, selectedJobIds, swimlaneLimit, swimlaneViewByFieldName,
earliestMs, latestMs, selectedJobIds, swimlaneLimit, viewBySwimlaneFieldName,
interval: getSwimlaneBucketInterval(selectedJobs, getSwimlaneContainerWidth(this.state.noInfluencersConfigured)).asSeconds()
};

Expand All @@ -437,20 +431,20 @@ export const Explorer = injectI18n(injectObservablesAsProps(
}
this.topFieldsPreviousArgs = compareArgs;

if (swimlaneViewByFieldName !== VIEW_BY_JOB_LABEL) {
if (viewBySwimlaneFieldName !== VIEW_BY_JOB_LABEL) {
mlResultsService.getTopInfluencers(
selectedJobIds,
earliestMs,
latestMs,
swimlaneLimit
).then((resp) => {
if (resp.influencers[swimlaneViewByFieldName] === undefined) {
if (resp.influencers[viewBySwimlaneFieldName] === undefined) {
this.topFieldsPreviousData = [];
resolve([]);
}

const topFieldValues = [];
const topInfluencers = resp.influencers[swimlaneViewByFieldName];
const topInfluencers = resp.influencers[viewBySwimlaneFieldName];
topInfluencers.forEach((influencerData) => {
if (influencerData.maxAnomalyScore > 0) {
topFieldValues.push(influencerData.influencerFieldValue);
Expand Down Expand Up @@ -489,7 +483,7 @@ export const Explorer = injectI18n(injectObservablesAsProps(
noJobsFound,
selectedCells,
selectedJobs,
swimlaneViewByFieldName,
viewBySwimlaneFieldName: currentviewBySwimlaneFieldName,
} = {
...this.state,
...stateUpdate
Expand All @@ -511,8 +505,8 @@ export const Explorer = injectI18n(injectObservablesAsProps(
bounds,
);

const viewBySwimlaneOptions = getViewBySwimlaneOptions({
currentSwimlaneViewByFieldName: swimlaneViewByFieldName,
const { viewBySwimlaneFieldName, viewBySwimlaneOptions } = getViewBySwimlaneOptions({
currentviewBySwimlaneFieldName,
filterActive,
filteredFields,
isAndOperator,
Expand All @@ -528,6 +522,7 @@ export const Explorer = injectI18n(injectObservablesAsProps(
getSwimlaneBucketInterval(selectedJobs, getSwimlaneContainerWidth(this.state.noInfluencersConfigured)),
bounds,
showOverallLoadingIndicator,
viewBySwimlaneFieldName,
viewBySwimlaneOptions,
influencersFilterQuery,
timerange,
Expand Down Expand Up @@ -556,7 +551,7 @@ export const Explorer = injectI18n(injectObservablesAsProps(
);
}

const selectionInfluencers = getSelectionInfluencers(selectedCells, viewBySwimlaneOptions.swimlaneViewByFieldName);
const selectionInfluencers = getSelectionInfluencers(selectedCells, viewBySwimlaneFieldName);

if (selectionInfluencers.length === 0) {
stateUpdate.influencers = await loadTopInfluencers(jobIds, timerange.earliestMs, timerange.latestMs, noInfluencersConfigured);
Expand Down Expand Up @@ -622,7 +617,7 @@ export const Explorer = injectI18n(injectObservablesAsProps(
interval: getSwimlaneBucketInterval(selectedJobs, getSwimlaneContainerWidth(this.state.noInfluencersConfigured)).asSeconds(),
boundsMin: bounds.min.valueOf(),
boundsMax: bounds.max.valueOf(),
swimlaneViewByFieldName: viewBySwimlaneOptions.swimlaneViewByFieldName,
viewBySwimlaneFieldName,
tableInterval,
tableSeverity,
influencersFilterQuery
Expand All @@ -638,7 +633,7 @@ export const Explorer = injectI18n(injectObservablesAsProps(
dateFormatTz,
getSwimlaneBucketInterval(selectedJobs, getSwimlaneContainerWidth(this.state.noInfluencersConfigured)).asSeconds(),
bounds,
viewBySwimlaneOptions.swimlaneViewByFieldName,
viewBySwimlaneFieldName,
tableInterval,
tableSeverity,
influencersFilterQuery
Expand All @@ -648,22 +643,18 @@ export const Explorer = injectI18n(injectObservablesAsProps(
}

viewByChangeHandler = e => this.setSwimlaneViewBy(e.target.value);
setSwimlaneViewBy = (swimlaneViewByFieldName) => {
setSwimlaneViewBy = (viewBySwimlaneFieldName) => {
let maskAll = false;

if (this.state.influencersFilterQuery !== undefined) {
maskAll = (swimlaneViewByFieldName === VIEW_BY_JOB_LABEL ||
this.state.filteredFields.includes(swimlaneViewByFieldName) === false);
maskAll = (viewBySwimlaneFieldName === VIEW_BY_JOB_LABEL ||
this.state.filteredFields.includes(viewBySwimlaneFieldName) === false);
}

explorerAction$.next({ type: EXPLORER_ACTION.APP_STATE_CLEAR_SELECTION });
explorerAction$.next({
type: EXPLORER_ACTION.APP_STATE_SAVE_SWIMLANE_VIEW_BY_FIELD_NAME,
payload: { swimlaneViewByFieldName }
});
this.setState({ swimlaneViewByFieldName, maskAll }, () => {
this.setState({ viewBySwimlaneFieldName, maskAll }, () => {
this.updateExplorer({
swimlaneViewByFieldName,
viewBySwimlaneFieldName,
...getClearedSelectedAnomaliesState(),
}, false);
});
Expand Down Expand Up @@ -758,8 +749,8 @@ export const Explorer = injectI18n(injectObservablesAsProps(
queryString,
tableQueryString }) => {
const { viewBySwimlaneOptions } = this.props.explorerState;
const { selectedCells, swimlaneViewByFieldName } = this.state;
let selectedViewByFieldName = swimlaneViewByFieldName;
const { selectedCells, viewBySwimlaneFieldName } = this.state;
let selectedViewByFieldName = viewBySwimlaneFieldName;

if (influencersFilterQuery.match_all && Object.keys(influencersFilterQuery.match_all).length === 0) {
explorerAction$.next({ type: EXPLORER_ACTION.APP_STATE_CLEAR_INFLUENCER_FILTER_SETTINGS });
Expand All @@ -780,21 +771,13 @@ export const Explorer = injectI18n(injectObservablesAsProps(
// if it's an AND filter set view by swimlane to job ID as the others will have no results
if (isAndOperator && selectedCells === null) {
selectedViewByFieldName = VIEW_BY_JOB_LABEL;
explorerAction$.next({
type: EXPLORER_ACTION.APP_STATE_SAVE_SWIMLANE_VIEW_BY_FIELD_NAME,
payload: { swimlaneViewByFieldName: selectedViewByFieldName },
});
} else {
// Set View by dropdown to first relevant fieldName based on incoming filter if there's no cell selection already
// or if selected cell is from overall swimlane as this won't include an additional influencer filter
for (let i = 0; i < filteredFields.length; i++) {
if (viewBySwimlaneOptions.includes(filteredFields[i]) &&
((selectedCells === null || (selectedCells && selectedCells.type === 'overall')))) {
selectedViewByFieldName = filteredFields[i];
explorerAction$.next({
type: EXPLORER_ACTION.APP_STATE_SAVE_SWIMLANE_VIEW_BY_FIELD_NAME,
payload: { swimlaneViewByFieldName: selectedViewByFieldName },
});
break;
}
}
Expand All @@ -814,7 +797,7 @@ export const Explorer = injectI18n(injectObservablesAsProps(
tableQueryString,
maskAll: (selectedViewByFieldName === VIEW_BY_JOB_LABEL ||
filteredFields.includes(selectedViewByFieldName) === false),
swimlaneViewByFieldName: selectedViewByFieldName
viewBySwimlaneFieldName: selectedViewByFieldName
}, false);
}
}
Expand All @@ -839,7 +822,6 @@ export const Explorer = injectI18n(injectObservablesAsProps(
noJobsFound,
queryString,
selectedCells,
swimlaneViewByFieldName,
tableData,
tableQueryString,
} = this.state;
Expand All @@ -850,6 +832,7 @@ export const Explorer = injectI18n(injectObservablesAsProps(
viewByLoadedForTimeFormatted,
viewBySwimlaneData,
viewBySwimlaneDataLoading,
viewBySwimlaneFieldName,
viewBySwimlaneOptions,
} = this.props.explorerState;

Expand Down Expand Up @@ -990,7 +973,7 @@ export const Explorer = injectI18n(injectObservablesAsProps(
<EuiSelect
id="selectViewBy"
options={mapSwimlaneOptionsToEuiOptions(viewBySwimlaneOptions)}
value={swimlaneViewByFieldName}
value={viewBySwimlaneFieldName}
onChange={this.viewByChangeHandler}
/>
</EuiFormRow>
Expand Down Expand Up @@ -1022,7 +1005,7 @@ export const Explorer = injectI18n(injectObservablesAsProps(
/>
)}
{filterActive === true &&
swimlaneViewByFieldName === 'job ID' && (
viewBySwimlaneFieldName === VIEW_BY_JOB_LABEL && (
<FormattedMessage
id="xpack.ml.explorer.jobScoreAcrossAllInfluencersLabel"
defaultMessage="(Job score across all influencers)"
Expand Down Expand Up @@ -1061,9 +1044,9 @@ export const Explorer = injectI18n(injectObservablesAsProps(
<LoadingIndicator/>
)}

{!showViewBySwimlane && !viewBySwimlaneDataLoading && swimlaneViewByFieldName !== null && (
{!showViewBySwimlane && !viewBySwimlaneDataLoading && viewBySwimlaneFieldName !== null && (
<ExplorerNoInfluencersFound
swimlaneViewByFieldName={swimlaneViewByFieldName}
viewBySwimlaneFieldName={viewBySwimlaneFieldName}
showFilterMessage={(filterActive === true)}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const EXPLORER_ACTION = {
APP_STATE_CLEAR_INFLUENCER_FILTER_SETTINGS: 'appStateClearInfluencerFilterSettings',
APP_STATE_CLEAR_SELECTION: 'appStateClearSelection',
APP_STATE_SAVE_SELECTION: 'appStateSaveSelection',
APP_STATE_SAVE_SWIMLANE_VIEW_BY_FIELD_NAME: 'appStateSaveSwimlaneViewByFieldName',
APP_STATE_SAVE_VIEW_BY_SWIMLANE_FIELD_NAME: 'appStateSaveViewBySwimlaneFieldName',
APP_STATE_SAVE_INFLUENCER_FILTER_SETTINGS: 'appStateSaveInfluencerFilterSettings',
IDLE: 'idle',
INITIALIZE: 'initialize',
Expand All @@ -37,14 +37,6 @@ export const FILTER_ACTION = {
REMOVE: '-',
};

export const APP_STATE_ACTION = {
CLEAR_INFLUENCER_FILTER_SETTINGS: 'clearInfluencerFilterSettings',
CLEAR_SELECTION: 'clearSelection',
SAVE_SELECTION: 'saveSelection',
SAVE_SWIMLANE_VIEW_BY_FIELD_NAME: 'saveSwimlaneViewByFieldName',
SAVE_INFLUENCER_FILTER_SETTINGS: 'saveInfluencerFilterSettings',
};

export const SWIMLANE_TYPE = {
OVERALL: 'overall',
VIEW_BY: 'viewBy',
Expand Down
Loading

0 comments on commit fb2e326

Please sign in to comment.