diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_creator/configs/job.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_creator/configs/job.ts index 194cc84adb6c3..cf9407e0c9511 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_creator/configs/job.ts +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_creator/configs/job.ts @@ -16,6 +16,7 @@ export interface Job { data_description: DataDescription; description: string; groups: string[]; + calendars?: string[]; model_plot_config?: ModelPlotConfig; model_snapshot_retention_days?: number; renormalization_window_days?: number; diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_creator/job_creator.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_creator/job_creator.ts index cffc91e6a37fb..aaabaf44f9bfc 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_creator/job_creator.ts +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_creator/job_creator.ts @@ -143,12 +143,6 @@ export class JobCreator { return this._job_config.description; } - public addGroup(group: string) { - if (this._job_config.groups.includes(group) === false) { - this._job_config.groups.push(group); - } - } - public get groups(): string[] { return this._job_config.groups; } @@ -157,6 +151,14 @@ export class JobCreator { this._job_config.groups = groups; } + public get calendars(): string[] { + return this._job_config.calendars || []; + } + + public set calendars(calendars: string[]) { + this._job_config.calendars = calendars; + } + public set modelPlot(enable: boolean) { if (enable) { this._job_config.model_plot_config = { diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/additional_section.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/additional_section.tsx new file mode 100644 index 0000000000000..0aa87925eb61b --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/additional_section.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiAccordion, EuiSpacer } from '@elastic/eui'; +import { CalendarsSelection } from './components/calendars'; + +const ButtonContent = Additional settings; + +interface Props { + additionalExpanded: boolean; + setAdditionalExpanded: (a: boolean) => void; +} + +export const AdditionalSection: FC = ({ additionalExpanded, setAdditionalExpanded }) => { + return null; // disable this section until custom URLs component is ready + return ( + + + + + + + + + + ); +}; diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/components/calendars/calendars_selection.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/components/calendars/calendars_selection.tsx new file mode 100644 index 0000000000000..f749d78508a2e --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/components/calendars/calendars_selection.tsx @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, useState, useContext, useEffect } from 'react'; +import { EuiComboBox, EuiComboBoxOptionProps } from '@elastic/eui'; +import { JobCreatorContext } from '../../../../../job_creator_context'; +import { Description } from './description'; +import { ml } from '../../../../../../../../../services/ml_api_service'; + +export const CalendarsSelection: FC = () => { + const { jobCreator, jobCreatorUpdate } = useContext(JobCreatorContext); + const [selectedCalendars, setSelectedCalendars] = useState(jobCreator.calendars); + const [selectedOptions, setSelectedOptions] = useState([]); + const [options, setOptions] = useState([]); + const [isLoading, setIsLoading] = useState(false); + + async function loadCalendars() { + setIsLoading(true); + const calendars = await ml.calendars(); + setOptions(calendars.map(c => ({ label: c.calendar_id }))); + setSelectedOptions(selectedCalendars.map(c => ({ label: c }))); + setIsLoading(false); + } + + useEffect(() => { + loadCalendars(); + }, []); + + function onChange(optionsIn: EuiComboBoxOptionProps[]) { + setSelectedOptions(optionsIn); + setSelectedCalendars(optionsIn.map(o => o.label)); + } + + useEffect(() => { + jobCreator.calendars = selectedCalendars; + jobCreatorUpdate(); + }, [selectedCalendars.join()]); + + return ( + + + + ); +}; diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/components/calendars/description.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/components/calendars/description.tsx new file mode 100644 index 0000000000000..339a4c14530e8 --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/components/calendars/description.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { Fragment, memo, FC } from 'react'; +import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; + +interface Props { + children: JSX.Element; +} + +export const Description: FC = memo(({ children }) => { + const title = 'Calendars'; + return ( + {title}} + description={ + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt + ut labore et dolore magna aliqua. Ut enim ad minim veniam. + + } + > + + {children} + + + ); +}); diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/components/calendars/index.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/components/calendars/index.ts new file mode 100644 index 0000000000000..54fd45c6f40e4 --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/components/calendars/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { CalendarsSelection } from './calendars_selection'; diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/index.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/index.ts new file mode 100644 index 0000000000000..ba62f0cdc6983 --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/job_details_step/components/additional_section/index.ts @@ -0,0 +1,6 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +export { AdditionalSection } from './additional_section'; 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 830b502bc3614..ad31ad15e160a 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 @@ -6,17 +6,20 @@ import React, { Fragment, FC, useContext, useEffect, useState } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; -import { WizardNav } from '../../../../../data_frame/pages/data_frame_new_pivot/components/wizard_nav'; +import { WizardNav } from '../wizard_nav'; import { JobIdInput } from './components/job_id'; import { JobDescriptionInput } from './components/job_description'; import { GroupsInput } from './components/groups'; import { WIZARD_STEPS, StepProps } from '../step_types'; import { JobCreatorContext } from '../job_creator_context'; import { AdvancedSection } from './components/advanced_section'; +import { AdditionalSection } from './components/additional_section'; interface Props extends StepProps { advancedExpanded: boolean; setAdvancedExpanded: (a: boolean) => void; + additionalExpanded: boolean; + setAdditionalExpanded: (a: boolean) => void; } export const JobDetailsStep: FC = ({ @@ -24,6 +27,8 @@ export const JobDetailsStep: FC = ({ isCurrentStep, advancedExpanded, setAdvancedExpanded, + additionalExpanded, + setAdditionalExpanded, }) => { const { jobCreator, jobCreatorUpdated } = useContext(JobCreatorContext); const [nextActive, setNextActive] = useState(false); @@ -46,10 +51,17 @@ export const JobDetailsStep: FC = ({ + + + + setCurrentStep(WIZARD_STEPS.PICK_FIELDS)} next={() => setCurrentStep(WIZARD_STEPS.SUMMARY)} 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 3dca90695e693..b1b9c7628472d 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 @@ -7,7 +7,7 @@ import React, { Fragment, FC, useContext, useEffect, useState } from 'react'; import { JobCreatorContext } from '../job_creator_context'; -import { WizardNav } from '../../../../../data_frame/pages/data_frame_new_pivot/components/wizard_nav'; +import { WizardNav } from '../wizard_nav'; import { WIZARD_STEPS, StepProps } from '../step_types'; import { JOB_TYPE } from '../../../common/job_creator/util/constants'; import { SingleMetricView } from './components/single_metric_view'; diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/summary_step/summary.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/summary_step/summary.tsx index 0536537c4d2df..88bf3751f45de 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/summary_step/summary.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/summary_step/summary.tsx @@ -6,7 +6,7 @@ import React, { Fragment, FC, useContext, useState, useEffect } from 'react'; import { EuiButton, EuiButtonEmpty, EuiHorizontalRule } from '@elastic/eui'; -import { WizardNav } from '../../../../../data_frame/pages/data_frame_new_pivot/components/wizard_nav'; +import { WizardNav } from '../wizard_nav'; import { WIZARD_STEPS, StepProps } from '../step_types'; import { JobCreatorContext } from '../job_creator_context'; import { KibanaContext, isKibanaContext } from '../../../../../data_frame/common/kibana_context'; diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/time_range_step/time_range.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/time_range_step/time_range.tsx index b3337583bfaf4..deb36b214875b 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/time_range_step/time_range.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/time_range_step/time_range.tsx @@ -7,7 +7,7 @@ import React, { Fragment, FC, useContext, useState, useEffect } from 'react'; import { timefilter } from 'ui/timefilter'; import moment from 'moment'; -import { WizardNav } from '../../../../../data_frame/pages/data_frame_new_pivot/components/wizard_nav'; +import { WizardNav } from '../wizard_nav'; import { WIZARD_STEPS, StepProps } from '../step_types'; import { JobCreatorContext } from '../job_creator_context'; import { KibanaContext, isKibanaContext } from '../../../../../data_frame/common/kibana_context'; diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/wizard_nav/index.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/wizard_nav/index.ts new file mode 100644 index 0000000000000..5d9db25730fce --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/wizard_nav/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { WizardNav } from './wizard_nav'; diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/wizard_nav/wizard_nav.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/wizard_nav/wizard_nav.tsx new file mode 100644 index 0000000000000..d1629e03f36d9 --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/wizard_nav/wizard_nav.tsx @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC } from 'react'; + +import { i18n } from '@kbn/i18n'; + +import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; + +interface StepsNavProps { + previousActive?: boolean; + nextActive?: boolean; + previous?(): void; + next?(): void; +} + +export const WizardNav: FC = ({ + previous, + previousActive = true, + next, + nextActive = true, +}) => ( + + + {previous && ( + + + {i18n.translate('xpack.ml.newJob.wizard.previousStepButton', { + defaultMessage: 'Previous', + })} + + + )} + {next && ( + + + {i18n.translate('xpack.ml.newJob.wizard.nextStepButton', { + defaultMessage: 'Next', + })} + + + )} + +); 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 cca4a34117818..0cffa4ee579fe 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 @@ -70,6 +70,7 @@ export const Wizard: FC = ({ }; const [advancedExpanded, setAdvancedExpanded] = useState(false); + const [additionalExpanded, setAdditionalExpanded] = useState(false); const [currentStep, setCurrentStep] = useState(WIZARD_STEPS.TIME_RANGE); @@ -109,6 +110,8 @@ export const Wizard: FC = ({ setCurrentStep={setCurrentStep} advancedExpanded={advancedExpanded} setAdvancedExpanded={setAdvancedExpanded} + additionalExpanded={additionalExpanded} + setAdditionalExpanded={setAdditionalExpanded} /> ), status: currentStep >= WIZARD_STEPS.JOB_DETAILS ? undefined : ('incomplete' as EuiStepStatus), diff --git a/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts b/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts index 20983f67415e7..31c262096154b 100644 --- a/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts +++ b/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts @@ -47,6 +47,14 @@ declare interface Ml { getTimeFieldRange(obj: object): Promise; calculateModelMemoryLimit(obj: object): Promise<{ modelMemoryLimit: string }>; + calendars(): Promise< + Array<{ + calendar_id: string; + description: string; + events: any[]; + job_ids: string[]; + }> + >; jobs: { jobsSummary(jobIds: string[]): Promise;