diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_validator/job_validator.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_validator/job_validator.ts index 669dc4d231aeb..5939da0d64abf 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_validator/job_validator.ts +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_validator/job_validator.ts @@ -37,7 +37,7 @@ export class JobValidator { private _jobCreator: JobCreatorType; private _validationSummary: ValidationSummary; private _lastJobConfig: string; - private _validateTimeout: NodeJS.Timeout; + private _validateTimeout: ReturnType | null = null; private _existingJobsAndGroups: ExistingJobsAndGroups; private _basicValidations: BasicValidations = { jobId: { valid: true }, @@ -46,6 +46,7 @@ export class JobValidator { bucketSpan: { valid: true }, duplicateDetectors: { valid: true }, }; + private _validating: boolean = false; constructor(jobCreator: JobCreatorType, existingJobsAndGroups: ExistingJobsAndGroups) { this._jobCreator = jobCreator; @@ -54,25 +55,30 @@ export class JobValidator { basic: false, advanced: false, }; - this._validateTimeout = setTimeout(() => {}, 0); this._existingJobsAndGroups = existingJobsAndGroups; } - public validate() { + public validate(callback: () => void) { + this._validating = true; const formattedJobConfig = this._jobCreator.formattedJobJson; - return new Promise((resolve: () => void) => { - // only validate if the config has changed - if (formattedJobConfig !== this._lastJobConfig) { + // only validate if the config has changed + if (formattedJobConfig !== this._lastJobConfig) { + if (this._validateTimeout !== null) { + // clear any previous on going validation timeouts clearTimeout(this._validateTimeout); - this._lastJobConfig = formattedJobConfig; - this._validateTimeout = setTimeout(() => { - this._runBasicValidation(); - resolve(); - }, VALIDATION_DELAY_MS); - } else { - resolve(); } - }); + this._lastJobConfig = formattedJobConfig; + this._validateTimeout = setTimeout(() => { + this._runBasicValidation(); + this._validating = false; + this._validateTimeout = null; + callback(); + }, VALIDATION_DELAY_MS); + } else { + // _validating is still true if there is a previous validation timeout on going. + this._validating = this._validateTimeout !== null; + } + callback(); } private _resetBasicValidations() { @@ -135,4 +141,8 @@ export class JobValidator { public set advancedValid(valid: boolean) { this._validationSummary.advanced = valid; } + + public get validating(): boolean { + return this._validating; + } } diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/job_details.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/job_details.tsx index 244608f400f55..6fafadf6c29b9 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/job_details.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/job_details.tsx @@ -37,7 +37,8 @@ export const JobDetailsStep: FC = ({ const active = jobValidator.jobId.valid && jobValidator.modelMemoryLimit.valid && - jobValidator.groupIds.valid; + jobValidator.groupIds.valid && + jobValidator.validating === false; setNextActive(active); }, [jobValidatorUpdated]); diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/pick_fields.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/pick_fields.tsx index 712d49159b542..ca46b88f1bc2c 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/pick_fields.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/pick_fields.tsx @@ -30,7 +30,8 @@ export const PickFieldsStep: FC = ({ setCurrentStep, isCurrentStep }) const active = jobCreator.detectors.length > 0 && jobValidator.bucketSpan.valid && - jobValidator.duplicateDetectors.valid; + jobValidator.duplicateDetectors.valid && + jobValidator.validating === false; setNextActive(active); }, [jobValidatorUpdated]); diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/new_job/wizard.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/new_job/wizard.tsx index a6ce188ddbad9..fcd1c4808a30a 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/new_job/wizard.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/new_job/wizard.tsx @@ -86,11 +86,9 @@ export const Wizard: FC = ({ ); useEffect(() => { - // IIFE to run the validation. the useEffect callback can't be async - (async () => { - await jobValidator.validate(); + jobValidator.validate(() => { setJobValidatorUpdate(jobValidatorUpdated); - })(); + }); // if the job config has changed, reset the highestStep // compare a stringified config to ensure the configs have actually changed