mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[ML] Anomaly Detection: Fix jobs list default refresh. (#57086)
* [ML] Fix anomaly detection jobs list default refresh. * [ML] Fix initial load of jobs list. * [ML] Fix blockRefresh check. * [ML] Fix blockRefresh check. * [ML] Fix passing globalState between main tabs and retain custom refreshInterval when loading jobs list.
This commit is contained in:
parent
d7c2552944
commit
c654018122
5 changed files with 63 additions and 71 deletions
|
@ -5,8 +5,13 @@
|
|||
*/
|
||||
|
||||
import React, { FC, useState } from 'react';
|
||||
import { encode } from 'rison-node';
|
||||
|
||||
import { EuiTabs, EuiTab, EuiLink } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { useUrlState } from '../../util/url_state';
|
||||
|
||||
import { TabId } from './navigation_menu';
|
||||
|
||||
export interface Tab {
|
||||
|
@ -65,6 +70,7 @@ const TAB_DATA: Record<TabId, TabData> = {
|
|||
};
|
||||
|
||||
export const MainTabs: FC<Props> = ({ tabId, disableLinks }) => {
|
||||
const [globalState] = useUrlState('_g');
|
||||
const [selectedTabId, setSelectedTabId] = useState(tabId);
|
||||
function onSelectedTabChanged(id: string) {
|
||||
setSelectedTabId(id);
|
||||
|
@ -78,10 +84,13 @@ export const MainTabs: FC<Props> = ({ tabId, disableLinks }) => {
|
|||
const id = tab.id;
|
||||
const testSubject = TAB_DATA[id].testSubject;
|
||||
const defaultPathId = TAB_DATA[id].pathId || id;
|
||||
// globalState (e.g. selected jobs and time range) should be retained when changing pages.
|
||||
// appState will not be considered.
|
||||
const fullGlobalStateString = globalState !== undefined ? `?_g=${encode(globalState)}` : '';
|
||||
return (
|
||||
<EuiLink
|
||||
data-test-subj={testSubject + (id === selectedTabId ? ' selected' : '')}
|
||||
href={`#/${defaultPathId}`}
|
||||
href={`#/${defaultPathId}${fullGlobalStateString}`}
|
||||
key={`${id}-key`}
|
||||
color="text"
|
||||
>
|
||||
|
|
|
@ -22,6 +22,11 @@ interface Duration {
|
|||
end: string;
|
||||
}
|
||||
|
||||
interface RefreshInterval {
|
||||
pause: boolean;
|
||||
value: number;
|
||||
}
|
||||
|
||||
function getRecentlyUsedRangesFactory(timeHistory: TimeHistory) {
|
||||
return function(): Duration[] {
|
||||
return (
|
||||
|
@ -44,7 +49,7 @@ export const TopNav: FC = () => {
|
|||
const [globalState, setGlobalState] = useUrlState('_g');
|
||||
const getRecentlyUsedRanges = getRecentlyUsedRangesFactory(timeHistory);
|
||||
|
||||
const [refreshInterval, setRefreshInterval] = useState(
|
||||
const [refreshInterval, setRefreshInterval] = useState<RefreshInterval>(
|
||||
globalState?.refreshInterval ?? timefilter.getRefreshInterval()
|
||||
);
|
||||
useEffect(() => {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
|
@ -35,13 +34,8 @@ import { UpgradeWarning } from '../../../../components/upgrade';
|
|||
import { RefreshJobsListButton } from '../refresh_jobs_list_button';
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import {
|
||||
DEFAULT_REFRESH_INTERVAL_MS,
|
||||
DELETING_JOBS_REFRESH_INTERVAL_MS,
|
||||
MINIMUM_REFRESH_INTERVAL_MS,
|
||||
} from '../../../../../../common/constants/jobs_list';
|
||||
import { DELETING_JOBS_REFRESH_INTERVAL_MS } from '../../../../../../common/constants/jobs_list';
|
||||
|
||||
let jobsRefreshInterval = null;
|
||||
let deletingJobsRefreshTimeout = null;
|
||||
|
||||
// 'isManagementTable' bool prop to determine when to configure table for use in Kibana management page
|
||||
|
@ -67,21 +61,12 @@ export class JobsListView extends Component {
|
|||
this.showDeleteJobModal = () => {};
|
||||
this.showStartDatafeedModal = () => {};
|
||||
this.showCreateWatchFlyout = () => {};
|
||||
|
||||
this.blockRefresh = false;
|
||||
this.refreshIntervalSubscription = null;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.isManagementTable === true) {
|
||||
this.refreshJobSummaryList(true);
|
||||
} else {
|
||||
timefilter.disableTimeRangeSelector();
|
||||
timefilter.enableAutoRefreshSelector();
|
||||
|
||||
this.initAutoRefresh();
|
||||
this.initAutoRefreshUpdate();
|
||||
this.refreshJobSummaryList(true);
|
||||
|
||||
if (this.props.isManagementTable !== true) {
|
||||
// check to see if we need to open the start datafeed modal
|
||||
// after the page has rendered. This will happen if the user
|
||||
// has just created a job in the advanced wizard and selected to
|
||||
|
@ -90,59 +75,18 @@ export class JobsListView extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.lastRefresh !== this.props.lastRefresh) {
|
||||
this.refreshJobSummaryList();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.props.isManagementTable === undefined) {
|
||||
if (this.refreshIntervalSubscription) this.refreshIntervalSubscription.unsubscribe();
|
||||
deletingJobsRefreshTimeout = null;
|
||||
this.clearRefreshInterval();
|
||||
}
|
||||
}
|
||||
|
||||
initAutoRefresh() {
|
||||
const { value } = timefilter.getRefreshInterval();
|
||||
if (value === 0) {
|
||||
// the auto refresher starts in an off state
|
||||
// so switch it on and set the interval to 30s
|
||||
timefilter.setRefreshInterval({
|
||||
pause: false,
|
||||
value: DEFAULT_REFRESH_INTERVAL_MS,
|
||||
});
|
||||
}
|
||||
|
||||
this.setAutoRefresh();
|
||||
}
|
||||
|
||||
initAutoRefreshUpdate() {
|
||||
// update the interval if it changes
|
||||
this.refreshIntervalSubscription = timefilter.getRefreshIntervalUpdate$().subscribe({
|
||||
next: () => this.setAutoRefresh(),
|
||||
});
|
||||
}
|
||||
|
||||
setAutoRefresh() {
|
||||
const { value, pause } = timefilter.getRefreshInterval();
|
||||
if (pause) {
|
||||
this.clearRefreshInterval();
|
||||
} else {
|
||||
this.setRefreshInterval(value);
|
||||
}
|
||||
// force load the jobs list when the refresh interval changes
|
||||
this.refreshJobSummaryList(true);
|
||||
}
|
||||
|
||||
setRefreshInterval(interval) {
|
||||
this.clearRefreshInterval();
|
||||
if (interval >= MINIMUM_REFRESH_INTERVAL_MS) {
|
||||
this.blockRefresh = false;
|
||||
jobsRefreshInterval = setInterval(() => this.refreshJobSummaryList(), interval);
|
||||
}
|
||||
}
|
||||
|
||||
clearRefreshInterval() {
|
||||
this.blockRefresh = true;
|
||||
clearInterval(jobsRefreshInterval);
|
||||
}
|
||||
|
||||
openAutoStartDatafeedModal() {
|
||||
const job = checkForAutoStartDatafeed();
|
||||
if (job !== undefined) {
|
||||
|
@ -281,7 +225,7 @@ export class JobsListView extends Component {
|
|||
};
|
||||
|
||||
async refreshJobSummaryList(forceRefresh = false) {
|
||||
if (forceRefresh === true || this.blockRefresh === false) {
|
||||
if (forceRefresh === true || this.props.blockRefresh !== true) {
|
||||
// Set loading to true for jobs_list table for initial job loading
|
||||
if (this.state.loading === null) {
|
||||
this.setState({ loading: true });
|
||||
|
|
|
@ -11,7 +11,14 @@ import { NavigationMenu } from '../../components/navigation_menu';
|
|||
// @ts-ignore
|
||||
import { JobsListView } from './components/jobs_list_view';
|
||||
|
||||
export const JobsPage: FC<{ props?: any }> = props => {
|
||||
interface JobsPageProps {
|
||||
blockRefresh?: boolean;
|
||||
isManagementTable?: boolean;
|
||||
isMlEnabledInSpace?: boolean;
|
||||
lastRefresh?: number;
|
||||
}
|
||||
|
||||
export const JobsPage: FC<JobsPageProps> = props => {
|
||||
return (
|
||||
<div data-test-subj="mlPageJobManagement">
|
||||
<NavigationMenu tabId="jobs" />
|
||||
|
|
|
@ -4,8 +4,13 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { FC } from 'react';
|
||||
import React, { useEffect, FC } from 'react';
|
||||
import { useObservable } from 'react-use';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { DEFAULT_REFRESH_INTERVAL_MS } from '../../../../common/constants/jobs_list';
|
||||
import { mlTimefilterRefresh$ } from '../../services/timefilter_refresh_service';
|
||||
import { useUrlState } from '../../util/url_state';
|
||||
import { MlRoute, PageLoader, PageProps } from '../router';
|
||||
import { useResolver } from '../use_resolver';
|
||||
import { basicResolvers } from '../resolvers';
|
||||
|
@ -32,9 +37,31 @@ export const jobListRoute: MlRoute = {
|
|||
const PageWrapper: FC<PageProps> = ({ config, deps }) => {
|
||||
const { context } = useResolver(undefined, undefined, config, basicResolvers(deps));
|
||||
|
||||
const [globalState, setGlobalState] = useUrlState('_g');
|
||||
|
||||
const mlTimefilterRefresh = useObservable(mlTimefilterRefresh$);
|
||||
const lastRefresh = mlTimefilterRefresh?.lastRefresh ?? 0;
|
||||
const refreshValue = globalState?.refreshInterval?.value ?? 0;
|
||||
const refreshPause = globalState?.refreshInterval?.pause ?? true;
|
||||
const blockRefresh = refreshValue === 0 || refreshPause === true;
|
||||
|
||||
useEffect(() => {
|
||||
timefilter.disableTimeRangeSelector();
|
||||
timefilter.enableAutoRefreshSelector();
|
||||
|
||||
// If the refreshInterval defaults to 0s/pause=true, set it to 30s/pause=false,
|
||||
// otherwise pass on the globalState's settings to the date picker.
|
||||
const refreshInterval =
|
||||
refreshValue === 0 && refreshPause === true
|
||||
? { pause: false, value: DEFAULT_REFRESH_INTERVAL_MS }
|
||||
: { pause: refreshPause, value: refreshValue };
|
||||
setGlobalState({ refreshInterval });
|
||||
timefilter.setRefreshInterval(refreshInterval);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<PageLoader context={context}>
|
||||
<JobsPage />
|
||||
<JobsPage blockRefresh={blockRefresh} lastRefresh={lastRefresh} />
|
||||
</PageLoader>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue