Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand All @@ -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"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ interface Duration {
end: string;
}

interface RefreshInterval {
pause: boolean;
value: number;
}

function getRecentlyUsedRangesFactory(timeHistory: TimeHistory) {
return function(): Duration[] {
return (
Expand All @@ -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(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/

import React, { Component } from 'react';
import { timefilter } from 'ui/timefilter';
import { FormattedMessage } from '@kbn/i18n/react';
import {
EuiFlexGroup,
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -90,59 +75,18 @@ export class JobsListView extends Component {
}
}

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);
componentDidUpdate(prevProps) {
if (prevProps.lastRefresh !== this.props.lastRefresh) {
this.refreshJobSummaryList();
}
// 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);
componentWillUnmount() {
if (this.props.isManagementTable === undefined) {
deletingJobsRefreshTimeout = null;
}
}

clearRefreshInterval() {
this.blockRefresh = true;
clearInterval(jobsRefreshInterval);
}

openAutoStartDatafeedModal() {
const job = checkForAutoStartDatafeed();
if (job !== undefined) {
Expand Down Expand Up @@ -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 });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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>
);
};