mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* [ML] Fix job wizard when converting to different wizard type
* using url constants
* fix validation issue and the MML check
* fix dependencies in react hooks
Co-authored-by: Dima Arnautov <dmitrii.arnautov@elastic.co>
(cherry picked from commit b5cb3f6a22
)
Co-authored-by: James Gowdy <jgowdy@elastic.co>
This commit is contained in:
parent
d4118a4ae0
commit
8a9da5065d
12 changed files with 68 additions and 48 deletions
|
@ -37,12 +37,16 @@ export const ML_PAGES = {
|
|||
* Open index data visualizer viewer page
|
||||
*/
|
||||
DATA_VISUALIZER_INDEX_VIEWER: 'jobs/new_job/datavisualizer',
|
||||
ANOMALY_DETECTION_CREATE_JOB: `jobs/new_job`,
|
||||
ANOMALY_DETECTION_CREATE_JOB_RECOGNIZER: `jobs/new_job/recognize`,
|
||||
ANOMALY_DETECTION_CREATE_JOB_ADVANCED: `jobs/new_job/advanced`,
|
||||
ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE: `jobs/new_job/step/job_type`,
|
||||
ANOMALY_DETECTION_CREATE_JOB_SELECT_INDEX: `jobs/new_job/step/index_or_search`,
|
||||
ANOMALY_DETECTION_CREATE_JOB_FROM_LENS: `jobs/new_job/from_lens`,
|
||||
ANOMALY_DETECTION_CREATE_JOB: 'jobs/new_job',
|
||||
ANOMALY_DETECTION_CREATE_JOB_RECOGNIZER: 'jobs/new_job/recognize',
|
||||
ANOMALY_DETECTION_CREATE_JOB_SINGLE_METRIC: 'jobs/new_job/single_metric',
|
||||
ANOMALY_DETECTION_CREATE_JOB_MULTI_METRIC: 'jobs/new_job/multi_metric',
|
||||
ANOMALY_DETECTION_CREATE_JOB_CONVERT_TO_MULTI_METRIC: 'jobs/new_job/convert_to_multi_metric',
|
||||
ANOMALY_DETECTION_CREATE_JOB_ADVANCED: 'jobs/new_job/advanced',
|
||||
ANOMALY_DETECTION_CREATE_JOB_CONVERT_TO_ADVANCED: 'jobs/new_job/convert_to_advanced',
|
||||
ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE: 'jobs/new_job/step/job_type',
|
||||
ANOMALY_DETECTION_CREATE_JOB_SELECT_INDEX: 'jobs/new_job/step/index_or_search',
|
||||
ANOMALY_DETECTION_CREATE_JOB_FROM_LENS: 'jobs/new_job/from_lens',
|
||||
SETTINGS: 'settings',
|
||||
CALENDARS_MANAGE: 'settings/calendars_list',
|
||||
CALENDARS_NEW: 'settings/calendars_list/new_calendar',
|
||||
|
|
|
@ -46,8 +46,7 @@ export const TimeRangePicker: FC<Props> = ({ setTimeRange, timeRange }) => {
|
|||
end: endMoment.valueOf(),
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [startMoment, endMoment]);
|
||||
}, [startMoment, endMoment, setTimeRange]);
|
||||
|
||||
// update our local start and end moment objects if
|
||||
// the parent start and end updates.
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
DOC_COUNT,
|
||||
_DOC_COUNT,
|
||||
} from '../../../../../../../common/constants/field_types';
|
||||
import { ML_PAGES } from '../../../../../../../common/constants/locator';
|
||||
import {
|
||||
EVENT_RATE_FIELD_ID,
|
||||
Field,
|
||||
|
@ -261,25 +262,25 @@ export function convertToMultiMetricJob(
|
|||
jobCreator.createdBy = CREATED_BY_LABEL.MULTI_METRIC;
|
||||
jobCreator.modelPlot = false;
|
||||
stashJobForCloning(jobCreator, true, true);
|
||||
navigateToPath(`jobs/new_job/${JOB_TYPE.MULTI_METRIC}`, true);
|
||||
navigateToPath(ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_CONVERT_TO_MULTI_METRIC, true);
|
||||
}
|
||||
|
||||
export function convertToAdvancedJob(jobCreator: JobCreatorType, navigateToPath: NavigateToPath) {
|
||||
jobCreator.createdBy = null;
|
||||
stashJobForCloning(jobCreator, true, true);
|
||||
navigateToPath(`jobs/new_job/${JOB_TYPE.ADVANCED}`, true);
|
||||
navigateToPath(ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_CONVERT_TO_ADVANCED, true);
|
||||
}
|
||||
|
||||
export function resetAdvancedJob(jobCreator: JobCreatorType, navigateToPath: NavigateToPath) {
|
||||
jobCreator.createdBy = null;
|
||||
stashJobForCloning(jobCreator, true, false);
|
||||
navigateToPath('/jobs/new_job');
|
||||
navigateToPath(ML_PAGES.ANOMALY_DETECTION_CREATE_JOB);
|
||||
}
|
||||
|
||||
export function resetJob(jobCreator: JobCreatorType, navigateToPath: NavigateToPath) {
|
||||
jobCreator.jobId = '';
|
||||
stashJobForCloning(jobCreator, true, true);
|
||||
navigateToPath('/jobs/new_job');
|
||||
navigateToPath(ML_PAGES.ANOMALY_DETECTION_CREATE_JOB);
|
||||
}
|
||||
|
||||
export function advancedStartDatafeed(
|
||||
|
|
|
@ -92,8 +92,7 @@ export const useModelMemoryEstimator = (
|
|||
// Initialize model memory estimator only once
|
||||
const modelMemoryEstimator = useMemo<ModelMemoryEstimator>(
|
||||
() => modelMemoryEstimatorProvider(jobCreator, jobValidator),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[]
|
||||
[jobCreator, jobValidator]
|
||||
);
|
||||
|
||||
// Listen for estimation results and errors
|
||||
|
@ -131,7 +130,7 @@ export const useModelMemoryEstimator = (
|
|||
subscription.unsubscribe();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [modelMemoryEstimator]);
|
||||
|
||||
// Update model memory estimation payload on the job creator updates
|
||||
useEffect(() => {
|
||||
|
@ -145,5 +144,5 @@ export const useModelMemoryEstimator = (
|
|||
latestMs: jobCreator.end,
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [jobCreatorUpdated]);
|
||||
}, [jobCreator, jobCreatorUpdated]);
|
||||
};
|
||||
|
|
|
@ -59,8 +59,7 @@ export const MultiMetricDetectorsSummary: FC = () => {
|
|||
return () => {
|
||||
subscription.unsubscribe();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [chartLoader, resultsLoader, jobCreator]);
|
||||
|
||||
useEffect(() => {
|
||||
if (allDataReady()) {
|
||||
|
|
|
@ -68,7 +68,7 @@ export const SingleMetricDetectors: FC<Props> = ({ setIsValid }) => {
|
|||
setIsValid(aggFieldPair !== null);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [aggFieldPair]);
|
||||
}, [jobCreator, aggFieldPair]);
|
||||
|
||||
useEffect(() => {
|
||||
if (jobCreator.start !== start || jobCreator.end !== end) {
|
||||
|
@ -82,7 +82,7 @@ export const SingleMetricDetectors: FC<Props> = ({ setIsValid }) => {
|
|||
loadChart();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [jobCreatorUpdated]);
|
||||
}, [jobCreator, jobCreatorUpdated]);
|
||||
|
||||
async function loadChart() {
|
||||
if (aggFieldPair !== null) {
|
||||
|
|
|
@ -49,7 +49,7 @@ export const SingleMetricDetectorsSummary: FC = () => {
|
|||
subscription.unsubscribe();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [resultsLoader]);
|
||||
|
||||
async function loadChart() {
|
||||
if (jobCreator.aggFieldPair !== null) {
|
||||
|
|
|
@ -33,8 +33,7 @@ export const PickFieldsStep: FC<StepProps> = ({ setCurrentStep, isCurrentStep })
|
|||
|
||||
useEffect(() => {
|
||||
setNextActive(selectionValid && jobValidator.isPickFieldsStepValid);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [jobValidatorUpdated, selectionValid]);
|
||||
}, [jobValidator, jobValidatorUpdated, selectionValid]);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
|
|
@ -70,15 +70,21 @@ export const TimeRangeStep: FC<StepProps> = ({ setCurrentStep, isCurrentStep })
|
|||
jobCreatorUpdate();
|
||||
loadChart();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [JSON.stringify(timeRange)]);
|
||||
}, [
|
||||
jobCreator,
|
||||
chartInterval,
|
||||
timeRange.start,
|
||||
timeRange.end,
|
||||
jobCreatorUpdate,
|
||||
services.data.query.timefilter,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
setTimeRange({
|
||||
start: jobCreator.start,
|
||||
end: jobCreator.end,
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [jobCreatorUpdated]);
|
||||
}, [jobCreator, jobCreatorUpdated]);
|
||||
|
||||
function fullTimeRangeCallback(range: GetTimeFieldRangeResponse) {
|
||||
if (range.start !== null && range.end !== null) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { useTimeBuckets } from '../../../../components/custom_hooks/use_time_buckets';
|
||||
import { Wizard } from './wizard';
|
||||
import { WIZARD_STEPS } from '../components/step_types';
|
||||
import { getJobCreatorTitle } from '../../common/job_creator/util/general';
|
||||
|
@ -31,7 +32,6 @@ import { ResultsLoader } from '../../common/results_loader';
|
|||
import { JobValidator } from '../../common/job_validator';
|
||||
import { useMlContext } from '../../../../contexts/ml';
|
||||
import { getTimeFilterRange } from '../../../../components/full_time_range_selector';
|
||||
import { getTimeBucketsFromCache } from '../../../../util/time_buckets';
|
||||
import { ExistingJobsAndGroups, mlJobService } from '../../../../services/job_service';
|
||||
import { newJobCapsService } from '../../../../services/new_job_capabilities/new_job_capabilities_service';
|
||||
import { EVENT_RATE_FIELD_ID } from '../../../../../../common/types/fields';
|
||||
|
@ -50,6 +50,9 @@ export interface PageProps {
|
|||
|
||||
export const Page: FC<PageProps> = ({ existingJobsAndGroups, jobType }) => {
|
||||
const mlContext = useMlContext();
|
||||
|
||||
const chartInterval = useTimeBuckets();
|
||||
|
||||
const jobCreator = useMemo(
|
||||
() =>
|
||||
jobCreatorFactory(jobType)(
|
||||
|
@ -61,6 +64,8 @@ export const Page: FC<PageProps> = ({ existingJobsAndGroups, jobType }) => {
|
|||
[jobType]
|
||||
);
|
||||
|
||||
const jobValidator = useMemo(() => new JobValidator(jobCreator), [jobCreator]);
|
||||
|
||||
const { displayErrorToast } = useToastNotificationService();
|
||||
|
||||
const { from, to } = getTimeFilterRange();
|
||||
|
@ -182,23 +187,18 @@ export const Page: FC<PageProps> = ({ existingJobsAndGroups, jobType }) => {
|
|||
}
|
||||
}
|
||||
|
||||
const chartInterval = getTimeBucketsFromCache();
|
||||
chartInterval.setBarTarget(BAR_TARGET);
|
||||
chartInterval.setMaxBars(MAX_BARS);
|
||||
chartInterval.setInterval('auto');
|
||||
|
||||
const chartLoader = useMemo(
|
||||
() => new ChartLoader(mlContext.currentDataView, jobCreator.query),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[]
|
||||
[mlContext.currentDataView, jobCreator.query]
|
||||
);
|
||||
|
||||
const jobValidator = useMemo(() => new JobValidator(jobCreator), [jobCreator]);
|
||||
|
||||
const resultsLoader = useMemo(
|
||||
() => new ResultsLoader(jobCreator, chartInterval, chartLoader),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[]
|
||||
[jobCreator, chartInterval, chartLoader]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { FC, useReducer, useState, useEffect } from 'react';
|
||||
import React, { FC, useState, useEffect, useCallback } from 'react';
|
||||
import { useModelMemoryEstimator } from '../../common/job_creator/util/model_memory_estimator';
|
||||
|
||||
import { WIZARD_STEPS } from '../components/step_types';
|
||||
|
||||
import { TimeBuckets } from '../../../../util/time_buckets';
|
||||
|
@ -43,15 +42,15 @@ export const Wizard: FC<Props> = ({
|
|||
existingJobsAndGroups,
|
||||
firstWizardStep = WIZARD_STEPS.TIME_RANGE,
|
||||
}) => {
|
||||
const [jobCreatorUpdated, setJobCreatorUpdate] = useReducer<(s: number, action: any) => number>(
|
||||
(s) => s + 1,
|
||||
0
|
||||
);
|
||||
const jobCreatorUpdate = () => setJobCreatorUpdate(jobCreatorUpdated);
|
||||
const [jobCreatorUpdated, setJobCreatorUpdate] = useState(0);
|
||||
const jobCreatorUpdate = useCallback(() => {
|
||||
setJobCreatorUpdate((prev) => prev + 1);
|
||||
}, []);
|
||||
|
||||
const [jobValidatorUpdated, setJobValidatorUpdate] = useReducer<
|
||||
(s: number, action: any) => number
|
||||
>((s) => s + 1, 0);
|
||||
const [jobValidatorUpdated, setJobValidatorUpdate] = useState(0);
|
||||
const jobValidatorUpdate = useCallback(() => {
|
||||
setJobValidatorUpdate((prev) => prev + 1);
|
||||
}, []);
|
||||
|
||||
const jobCreatorContext: JobCreatorContextValue = {
|
||||
jobCreatorUpdated,
|
||||
|
@ -82,18 +81,18 @@ export const Wizard: FC<Props> = ({
|
|||
|
||||
useEffect(() => {
|
||||
const subscription = jobValidator.validationResult$.subscribe(() => {
|
||||
setJobValidatorUpdate(jobValidatorUpdated);
|
||||
jobValidatorUpdate();
|
||||
});
|
||||
|
||||
return () => {
|
||||
return subscription.unsubscribe();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [jobValidator]);
|
||||
|
||||
useEffect(() => {
|
||||
jobValidator.validate(() => {
|
||||
setJobValidatorUpdate(jobValidatorUpdated);
|
||||
jobValidatorUpdate();
|
||||
});
|
||||
|
||||
// if the job config has changed, reset the highestStep
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { parse } from 'query-string';
|
||||
import React, { FC } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import { NavigateToPath } from '../../../contexts/kibana';
|
||||
|
||||
import { basicResolvers } from '../../resolvers';
|
||||
|
@ -114,6 +114,13 @@ export const multiMetricRouteFactory = (
|
|||
breadcrumbs: getMultiMetricBreadcrumbs(navigateToPath, basePath),
|
||||
});
|
||||
|
||||
// redirect route to reset the job wizard when converting to multi metric job
|
||||
export const multiMetricRouteFactoryRedirect = (): MlRoute => ({
|
||||
path: '/jobs/new_job/convert_to_multi_metric',
|
||||
render: (props) => <Redirect to={`/jobs/new_job/multi_metric${props.location.search}`} />,
|
||||
breadcrumbs: [],
|
||||
});
|
||||
|
||||
export const populationRouteFactory = (
|
||||
navigateToPath: NavigateToPath,
|
||||
basePath: string
|
||||
|
@ -132,6 +139,13 @@ export const advancedRouteFactory = (
|
|||
breadcrumbs: getAdvancedBreadcrumbs(navigateToPath, basePath),
|
||||
});
|
||||
|
||||
// redirect route to reset the job wizard when converting to advanced job
|
||||
export const advancedRouteFactoryRedirect = (): MlRoute => ({
|
||||
path: '/jobs/new_job/convert_to_advanced',
|
||||
render: (props) => <Redirect to={`/jobs/new_job/advanced${props.location.search}`} />,
|
||||
breadcrumbs: [],
|
||||
});
|
||||
|
||||
export const categorizationRouteFactory = (
|
||||
navigateToPath: NavigateToPath,
|
||||
basePath: string
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue