Skip to content

Commit

Permalink
[ML] Change to pass 'invalid' to url to retain the original full rang…
Browse files Browse the repository at this point in the history
…e + update field values
  • Loading branch information
qn895 committed Sep 1, 2020
1 parent 0176c59 commit 4155201
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 52 deletions.
4 changes: 2 additions & 2 deletions x-pack/plugins/ml/common/constants/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
*/

export const FILE_DATA_VISUALIZER_MAX_FILE_SIZE = 'ml:fileDataVisualizerMaxFileSize';
export const ANOMALY_DETECTION_ENABLE_TIME_RANGE = 'ml:anomalyDetectionDefaultTimeRangeEnable';
export const ANOMALY_DETECTION_DEFAULT_TIME_RANGE = 'ml:anomalyDetectionDefaultTimeRangeSet';
export const ANOMALY_DETECTION_ENABLE_TIME_RANGE = 'ml:anomalyDetectionTimeDefaultsEnable';
export const ANOMALY_DETECTION_DEFAULT_TIME_RANGE = 'ml:anomalyDetectionTimeDefaults';
11 changes: 10 additions & 1 deletion x-pack/plugins/ml/public/application/explorer/explorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import { ExplorerChartsContainer } from './explorer_charts/explorer_charts_conta
import { AnomaliesTable } from '../components/anomalies_table/anomalies_table';

import { getTimefilter, getToastNotifications } from '../util/dependency_cache';
import { ANOMALY_DETECTION_DEFAULT_TIME_RANGE } from '../../../common/constants/settings';

const ExplorerPage = ({
children,
Expand Down Expand Up @@ -149,7 +150,15 @@ export class Explorer extends React.Component {
const { invalidTimeRangeError } = this.props;
if (invalidTimeRangeError) {
const toastNotifications = getToastNotifications();
toastNotifications.addWarning(invalidTimeRangeError);
toastNotifications.addWarning(
i18n.translate('xpack.ml.explorer.invalidTimeRangeInUrlCallout', {
defaultMessage:
'The time filter changed to the full range for this job due to invalid default time filter. Please check the advanced settings for {field}.',
values: {
field: ANOMALY_DETECTION_DEFAULT_TIME_RANGE,
},
})
);
}
}

Expand Down
26 changes: 8 additions & 18 deletions x-pack/plugins/ml/public/application/routing/routes/explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { getBreadcrumbWithUrlForApp } from '../breadcrumbs';
import { useTimefilter } from '../../contexts/kibana';
import { isViewBySwimLaneData } from '../../explorer/swimlane_container';
import { JOB_ID } from '../../../../common/constants/anomalies';
import { validateTimeRange } from '../../util/date_utils';

export const explorerRouteFactory = (navigateToPath: NavigateToPath): MlRoute => ({
path: '/explorer',
render: (props, deps) => <PageWrapper {...props} deps={deps} />,
Expand Down Expand Up @@ -72,7 +72,7 @@ const ExplorerUrlStateManager: FC<ExplorerUrlStateManagerProps> = ({ jobsWithTim
const [globalState, setGlobalState] = useUrlState('_g');
const [lastRefresh, setLastRefresh] = useState(0);
const [stoppedPartitions, setStoppedPartitions] = useState<string[] | undefined>();
const [invalidTimeRangeError, setInValidTimeRangeError] = useState<string | undefined>();
const [invalidTimeRangeError, setInValidTimeRangeError] = useState<boolean>(false);
const timefilter = useTimefilter({ timeRangeSelector: true, autoRefreshSelector: true });

const { jobIds } = useJobSelection(jobsWithTimeRange);
Expand All @@ -98,23 +98,13 @@ const ExplorerUrlStateManager: FC<ExplorerUrlStateManagerProps> = ({ jobsWithTim
// `timefilter.getBounds()` to update `bounds` in this component's state.
useEffect(() => {
if (globalState?.time !== undefined) {
if (!validateTimeRange(globalState.time)) {
setInValidTimeRangeError(
i18n.translate('xpack.ml.explorer.invalidTimeRangeInUrlCallout', {
defaultMessage:
"The time filter changed to the full range for this job due to invalid default time filter from '{from}' to '{to}'. Please check the advanced settings.",
values: {
from: globalState.time.from,
to: globalState.time.to,
},
})
);
} else {
timefilter.setTime({
from: globalState.time.from,
to: globalState.time.to,
});
if (globalState.time.mode === 'invalid') {
setInValidTimeRangeError(true);
}
timefilter.setTime({
from: globalState.time.from,
to: globalState.time.to,
});

const timefilterBounds = timefilter.getBounds();
// Only if both min/max bounds are valid moment times set the bounds.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import { useResolver } from '../use_resolver';
import { basicResolvers } from '../resolvers';
import { getBreadcrumbWithUrlForApp } from '../breadcrumbs';
import { useTimefilter } from '../../contexts/kibana';
import { validateTimeRange } from '../../..';

export const timeSeriesExplorerRouteFactory = (navigateToPath: NavigateToPath): MlRoute => ({
path: '/timeseriesexplorer',
Expand Down Expand Up @@ -92,7 +91,7 @@ export const TimeSeriesExplorerUrlStateManager: FC<TimeSeriesExplorerUrlStateMan
const previousRefresh = usePrevious(lastRefresh);
const [selectedJobId, setSelectedJobId] = useState<string>();
const timefilter = useTimefilter({ timeRangeSelector: true, autoRefreshSelector: true });
const [invalidTimeRangeError, setInValidTimeRangeError] = useState<string | undefined>();
const [invalidTimeRangeError, setInValidTimeRangeError] = useState<boolean>(false);

const refresh = useRefresh();
useEffect(() => {
Expand All @@ -116,23 +115,13 @@ export const TimeSeriesExplorerUrlStateManager: FC<TimeSeriesExplorerUrlStateMan
const [bounds, setBounds] = useState<TimeRangeBounds | undefined>(undefined);
useEffect(() => {
if (globalState?.time !== undefined) {
if (!validateTimeRange(globalState.time)) {
setInValidTimeRangeError(
i18n.translate('xpack.ml.timeSeriesExplorer.invalidTimeRangeInUrlCallout', {
defaultMessage:
"The time filter changed to the full range for this job due to invalid default time filter from '{from}' to '{to}'. Please check the advanced settings.",
values: {
from: globalState.time.from,
to: globalState.time.to,
},
})
);
} else {
timefilter.setTime({
from: globalState.time.from,
to: globalState.time.to,
});
if (globalState.time.mode === 'invalid') {
setInValidTimeRangeError(true);
}
timefilter.setTime({
from: globalState.time.from,
to: globalState.time.to,
});

const timefilterBounds = timefilter.getBounds();
// Only if both min/max bounds are valid moment times set the bounds.
Expand Down
26 changes: 18 additions & 8 deletions x-pack/plugins/ml/public/application/services/job_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { ML_DATA_PREVIEW_COUNT } from '../../../common/util/job_utils';
import { TIME_FORMAT } from '../../../common/constants/time_format';
import { parseInterval } from '../../../common/util/parse_interval';
import { toastNotificationServiceProvider } from '../services/toast_notification_service';

import { validateTimeRange } from '../util/date_utils';
const msgs = mlMessageBarService;
let jobs = [];
let datafeedIds = {};
Expand Down Expand Up @@ -935,22 +935,29 @@ function createJobStats(jobsList, jobStats) {
function createResultsUrlForJobs(jobsList, resultsPage, userTimeRange) {
let from = undefined;
let to = undefined;
let mode = 'absolute';
const jobIds = jobsList.map((j) => j.id);

// if user input is a valid time range object
if (userTimeRange) {
// if the custom default time filter is set and enabled in advanced settings
// if time is either absolute date or proper datemath format
if (validateTimeRange(userTimeRange)) {
from = userTimeRange.from;
to = userTimeRange.to;
// if both pass datemath's checks but are not technically absolute dates, use 'quick'
// e.g. "now-15m" "now+1d"
const fromFieldAValidDate = moment(userTimeRange.from).isValid();
const toFieldAValidDate = moment(userTimeRange.to).isValid();
// if both are not a valid date, use 'quick'
// e.g. "now-15m" "now+1d"
if (!fromFieldAValidDate && !toFieldAValidDate) {
return createResultsUrl(jobIds, from, to, resultsPage, 'quick');
}
// if both fields are absolute date
// continue to createResultsUrl with from and to converted as normal
} else {
// if time range is specified but with incorrect format
// change back to the default time range but alert the user
// that the advanced setting config is invalid
if (userTimeRange) {
mode = 'invalid';
}

if (jobsList.length === 1) {
from = jobsList[0].earliestTimestampMs;
to = jobsList[0].latestResultsTimestampMs; // Will be max(latest source data, latest bucket results)
Expand All @@ -966,7 +973,7 @@ function createResultsUrlForJobs(jobsList, resultsPage, userTimeRange) {
const fromString = moment(from).format(TIME_FORMAT); // Defaults to 'now' if 'from' is undefined
const toString = moment(to).format(TIME_FORMAT); // Defaults to 'now' if 'to' is undefined

return createResultsUrl(jobIds, fromString, toString, resultsPage);
return createResultsUrl(jobIds, fromString, toString, resultsPage, mode);
}

function createResultsUrl(jobIds, start, end, resultsPage, mode = 'absolute') {
Expand All @@ -991,6 +998,9 @@ function createResultsUrl(jobIds, start, end, resultsPage, mode = 'absolute') {
path += `?_g=(ml:(jobIds:!(${idString}))`;
path += `,refreshInterval:(display:Off,pause:!f,value:0),time:(from:'${from}'`;
path += `,to:'${to}'`;
if (mode === 'invalid') {
path += `,mode:invalid`;
}
path += "))&_a=(query:(query_string:(analyze_wildcard:!t,query:'*')))";

return path;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ import {
getFocusData,
} from './timeseriesexplorer_utils';
import { EMPTY_FIELD_VALUE_LABEL } from './components/entity_control/entity_control';
import { ANOMALY_DETECTION_DEFAULT_TIME_RANGE } from '../../../common/constants/settings';

// Used to indicate the chart is being plotted across
// all partition field values, where the cardinality of the field cannot be
Expand Down Expand Up @@ -838,7 +839,15 @@ export class TimeSeriesExplorer extends React.Component {
const { invalidTimeRangeError } = this.props;
if (invalidTimeRangeError) {
const toastNotifications = getToastNotifications();
toastNotifications.addWarning(invalidTimeRangeError);
toastNotifications.addWarning(
i18n.translate('xpack.ml.timeSeriesExplorer.invalidTimeRangeInUrlCallout', {
defaultMessage:
'The time filter changed to the full range for this job due to invalid default time filter. Please check the advanced settings for {field}.',
values: {
field: ANOMALY_DETECTION_DEFAULT_TIME_RANGE,
},
})
);
}

// Required to redraw the time series chart when the container is resized.
Expand Down
8 changes: 4 additions & 4 deletions x-pack/plugins/ml/server/lib/register_settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ export function registerKibanaSettings(coreSetup: CoreSetup) {
},
[ANOMALY_DETECTION_ENABLE_TIME_RANGE]: {
name: i18n.translate('xpack.ml.advancedSettings.enableAnomalyDetectionDefaultTimeRangeName', {
defaultMessage: 'Enable default time range for anomaly detection jobs.',
defaultMessage: 'Enable default time range for anomaly detection jobs',
}),
value: false,
schema: schema.boolean(),
description: i18n.translate(
'xpack.ml.advancedSettings.anomalyDetectionDefaultTimeRangeDesc',
'xpack.ml.advancedSettings.enableAnomalyDetectionDefaultTimeRangeDesc',
{
defaultMessage: 'Use a default time range to view anomaly detection jobs.',
defaultMessage: 'Use a default time filter to view anomaly detection jobs.',
}
),
category: ['Machine Learning'],
Expand All @@ -60,7 +60,7 @@ export function registerKibanaSettings(coreSetup: CoreSetup) {
description: i18n.translate(
'xpack.ml.advancedSettings.anomalyDetectionDefaultTimeRangeDesc',
{
defaultMessage: 'The default time range to view anomaly detection jobs.',
defaultMessage: 'The default time filter to view anomaly detection jobs.',
}
),
schema: schema.object({
Expand Down

0 comments on commit 4155201

Please sign in to comment.