From 5a36bf69b848315cc3c3999d97abd9173c1eb457 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Tue, 19 Mar 2019 15:32:47 -0400 Subject: [PATCH] [ML] Anomaly explorer clear filter when switching to jobs with no influencers (#33512) (#33529) * Remove race condition: trigger reload if job selection not in progress * clear filter on job change when no influencers * remove commented code * update indexPattern comment for clarity --- x-pack/plugins/ml/public/explorer/explorer.js | 65 ++++++++++++------- .../ml/public/explorer/explorer_controller.js | 16 ++++- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/ml/public/explorer/explorer.js b/x-pack/plugins/ml/public/explorer/explorer.js index 9fc8ebec88ad0..4b18b16aea756 100644 --- a/x-pack/plugins/ml/public/explorer/explorer.js +++ b/x-pack/plugins/ml/public/explorer/explorer.js @@ -246,32 +246,49 @@ export const Explorer = injectI18n(injectObservablesAsProps( // Listen for changes to job selection. if (action === EXPLORER_ACTION.JOB_SELECTION_CHANGE) { - const { selectedJobs } = payload; - const stateUpdate = { - noInfluencersConfigured: (getInfluencers(selectedJobs).length === 0), - selectedJobs, - }; - - const indexPattern = await this.getIndexPattern(selectedJobs); - stateUpdate.indexPattern = indexPattern; - - this.props.appStateHandler(APP_STATE_ACTION.CLEAR_SELECTION); - Object.assign(stateUpdate, getClearedSelectedAnomaliesState()); + this.setState(...getExplorerDefaultState(), async () => { + const { selectedJobs } = payload; + const stateUpdate = { + noInfluencersConfigured: (getInfluencers(selectedJobs).length === 0), + selectedJobs, + }; + + this.props.appStateHandler(APP_STATE_ACTION.CLEAR_SELECTION); + Object.assign(stateUpdate, getClearedSelectedAnomaliesState()); + // clear filter if selected jobs have no influencers + if (stateUpdate.noInfluencersConfigured === true) { + this.props.appStateHandler(APP_STATE_ACTION.CLEAR_INFLUENCER_FILTER_SETTINGS); + const noFilterState = { + filterActive: false, + filteredFields: [], + influencersFilterQuery: undefined, + maskAll: false, + queryString: undefined + }; + + Object.assign(stateUpdate, noFilterState); + } else { + // indexPattern will not be used if there are no influencers so set up can be skipped + // indexPattern is passed to KqlFilterBar which is only shown if (noInfluencersConfigured === false) + const indexPattern = await this.getIndexPattern(selectedJobs); + stateUpdate.indexPattern = indexPattern; + } - if (selectedJobs.length > 1) { - this.props.appStateHandler( - APP_STATE_ACTION.SAVE_SWIMLANE_VIEW_BY_FIELD_NAME, - { 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); - }); - return; - } + if (selectedJobs.length > 1) { + this.props.appStateHandler( + APP_STATE_ACTION.SAVE_SWIMLANE_VIEW_BY_FIELD_NAME, + { 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); + }); + return; + } - this.updateExplorer(stateUpdate, true); + this.updateExplorer(stateUpdate, true); + }); } // RELOAD reloads full Anomaly Explorer and clears the selection. diff --git a/x-pack/plugins/ml/public/explorer/explorer_controller.js b/x-pack/plugins/ml/public/explorer/explorer_controller.js index 8d3c051eed98e..bb7e86a429aec 100644 --- a/x-pack/plugins/ml/public/explorer/explorer_controller.js +++ b/x-pack/plugins/ml/public/explorer/explorer_controller.js @@ -116,6 +116,8 @@ module.controller('MlExplorerController', function ( filterData } }); + $scope.jobSelectionUpdateInProgress = false; + $scope.$applyAsync(); } // Populate the map of jobs / detectors / field formatters for the selected IDs. @@ -196,19 +198,25 @@ module.controller('MlExplorerController', function ( const explorerSubscriber = explorer$.subscribe(loadJobsListener); // Listen for changes to job selection. + $scope.jobSelectionUpdateInProgress = false; $scope.mlJobSelectService.listenJobSelectionChange($scope, (event, selectedJobIds) => { + $scope.jobSelectionUpdateInProgress = true; jobSelectionUpdate(EXPLORER_ACTION.JOB_SELECTION_CHANGE, { fullJobs: mlJobService.jobs, selectedJobIds }); }); // Refresh all the data when the time range is altered. $scope.$listenAndDigestAsync(timefilter, 'fetch', () => { - explorer$.next({ action: EXPLORER_ACTION.RELOAD }); + if ($scope.jobSelectionUpdateInProgress === false) { + explorer$.next({ action: EXPLORER_ACTION.RELOAD }); + } }); // Add a watcher for auto-refresh of the time filter to refresh all the data. const refreshWatcher = Private(refreshIntervalWatcher); refreshWatcher.init(async () => { - explorer$.next({ action: EXPLORER_ACTION.RELOAD }); + if ($scope.jobSelectionUpdateInProgress === false) { + explorer$.next({ action: EXPLORER_ACTION.RELOAD }); + } }); // Redraw the swimlane when the window resizes or the global nav is toggled. @@ -230,7 +238,9 @@ module.controller('MlExplorerController', function ( }); function redrawOnResize() { - explorer$.next({ action: EXPLORER_ACTION.REDRAW }); + if ($scope.jobSelectionUpdateInProgress === false) { + explorer$.next({ action: EXPLORER_ACTION.REDRAW }); + } } $scope.appStateHandler = ((action, payload) => {