diff --git a/x-pack/plugins/ml/common/types/storage.ts b/x-pack/plugins/ml/common/types/storage.ts index f8ffc4aec122e..2750acf981ca8 100644 --- a/x-pack/plugins/ml/common/types/storage.ts +++ b/x-pack/plugins/ml/common/types/storage.ts @@ -9,6 +9,8 @@ import { EntityFieldType } from './anomalies'; export const ML_ENTITY_FIELDS_CONFIG = 'ml.singleMetricViewer.partitionFields'; +export const ML_APPLY_TIME_RANGE_CONFIG = 'ml.jobSelectorFlyout.applyTimeRange'; + export type PartitionFieldConfig = | { /** @@ -34,6 +36,9 @@ export type PartitionFieldsConfig = | Partial> | undefined; +export type ApplyTimeRangeConfig = boolean | undefined; + export type MlStorage = Partial<{ [ML_ENTITY_FIELDS_CONFIG]: PartitionFieldsConfig; + [ML_APPLY_TIME_RANGE_CONFIG]: ApplyTimeRangeConfig; }> | null; diff --git a/x-pack/plugins/ml/public/application/components/job_selector/job_selector.tsx b/x-pack/plugins/ml/public/application/components/job_selector/job_selector.tsx index 3758fb6c42081..f67a9df4a4a85 100644 --- a/x-pack/plugins/ml/public/application/components/job_selector/job_selector.tsx +++ b/x-pack/plugins/ml/public/application/components/job_selector/job_selector.tsx @@ -20,6 +20,8 @@ import { JobSelectorFlyoutProps, } from './job_selector_flyout'; import { MlJobWithTimeRange } from '../../../../common/types/anomaly_detection_jobs'; +import { useStorage } from '../../contexts/ml/use_storage'; +import { ApplyTimeRangeConfig, ML_APPLY_TIME_RANGE_CONFIG } from '../../../../common/types/storage'; interface GroupObj { groupId: string; @@ -79,6 +81,10 @@ export interface JobSelectionMaps { export function JobSelector({ dateFormatTz, singleSelection, timeseriesOnly }: JobSelectorProps) { const [globalState, setGlobalState] = useUrlState('_g'); + const [applyTimeRangeConfig, setApplyTimeRangeConfig] = useStorage( + ML_APPLY_TIME_RANGE_CONFIG, + true + ); const selectedJobIds = globalState?.ml?.jobIds ?? []; const selectedGroups = globalState?.ml?.groups ?? []; @@ -180,6 +186,8 @@ export function JobSelector({ dateFormatTz, singleSelection, timeseriesOnly }: J onJobsFetched={setMaps} onFlyoutClose={closeFlyout} maps={maps} + applyTimeRangeConfig={applyTimeRangeConfig} + onTimeRangeConfigChange={setApplyTimeRangeConfig} /> ); diff --git a/x-pack/plugins/ml/public/application/components/job_selector/job_selector_flyout.tsx b/x-pack/plugins/ml/public/application/components/job_selector/job_selector_flyout.tsx index 31f2714259aa0..d64e85e70f2eb 100644 --- a/x-pack/plugins/ml/public/application/components/job_selector/job_selector_flyout.tsx +++ b/x-pack/plugins/ml/public/application/components/job_selector/job_selector_flyout.tsx @@ -51,6 +51,8 @@ export interface JobSelectorFlyoutProps { timeseriesOnly: boolean; maps: JobSelectionMaps; withTimeRangeSelector?: boolean; + applyTimeRangeConfig?: boolean; + onTimeRangeConfigChange?: (v: boolean) => void; } export const JobSelectorFlyoutContent: FC = ({ @@ -62,6 +64,8 @@ export const JobSelectorFlyoutContent: FC = ({ onSelectionConfirmed, onFlyoutClose, maps, + applyTimeRangeConfig, + onTimeRangeConfigChange, withTimeRangeSelector = true, }) => { const { @@ -75,7 +79,6 @@ export const JobSelectorFlyoutContent: FC = ({ const [isLoading, setIsLoading] = useState(true); const [showAllBadges, setShowAllBadges] = useState(false); - const [applyTimeRange, setApplyTimeRange] = useState(true); const [jobs, setJobs] = useState([]); const [groups, setGroups] = useState([]); const [ganttBarWidth, setGanttBarWidth] = useState(DEFAULT_GANTT_BAR_WIDTH); @@ -101,7 +104,7 @@ export const JobSelectorFlyoutContent: FC = ({ // create a Set to remove duplicate values const allNewSelectionUnique = Array.from(new Set(allNewSelection)); - const time = applyTimeRange + const time = applyTimeRangeConfig ? getTimeRangeFromSelection(jobs, allNewSelectionUnique) : undefined; @@ -111,14 +114,16 @@ export const JobSelectorFlyoutContent: FC = ({ groups: groupSelection, time, }); - }, [onSelectionConfirmed, newSelection, jobGroupsMaps, applyTimeRange]); + }, [onSelectionConfirmed, newSelection, jobGroupsMaps, applyTimeRangeConfig]); function removeId(id: string) { setNewSelection(newSelection.filter((item) => item !== id)); } function toggleTimerangeSwitch() { - setApplyTimeRange(!applyTimeRange); + if (onTimeRangeConfigChange) { + onTimeRangeConfigChange(!applyTimeRangeConfig); + } } function clearSelection() { @@ -233,7 +238,7 @@ export const JobSelectorFlyoutContent: FC = ({ )} - {withTimeRangeSelector && ( + {withTimeRangeSelector && applyTimeRangeConfig !== undefined && ( = ({ defaultMessage: 'Apply time range', } )} - checked={applyTimeRange} + checked={applyTimeRangeConfig} onChange={toggleTimerangeSwitch} data-test-subj="mlFlyoutJobSelectorSwitchApplyTimeRange" /> diff --git a/x-pack/plugins/ml/public/embeddables/common/components/job_selector_flyout.tsx b/x-pack/plugins/ml/public/embeddables/common/components/job_selector_flyout.tsx new file mode 100644 index 0000000000000..23c057e6b7f33 --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/common/components/job_selector_flyout.tsx @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC, useState } from 'react'; +import { + JobSelectorFlyoutContent, + JobSelectorFlyoutProps, +} from '../../../application/components/job_selector/job_selector_flyout'; + +export const JobSelectorFlyout: FC = ({ + selectedIds, + withTimeRangeSelector, + dateFormatTz, + singleSelection, + timeseriesOnly, + onFlyoutClose, + onSelectionConfirmed, + maps, +}) => { + const [applyTimeRangeState, setApplyTimeRangeState] = useState(true); + + return ( + + ); +}; diff --git a/x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx b/x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx index 8499ab624f790..1833883447859 100644 --- a/x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx +++ b/x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx @@ -4,7 +4,6 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - import { CoreStart } from 'kibana/public'; import moment from 'moment'; import { takeUntil } from 'rxjs/operators'; @@ -16,9 +15,9 @@ import { toMountPoint, } from '../../../../../../src/plugins/kibana_react/public'; import { getMlGlobalServices } from '../../application/app'; -import { JobSelectorFlyoutContent } from '../../application/components/job_selector/job_selector_flyout'; import { DashboardConstants } from '../../../../../../src/plugins/dashboard/public'; import { JobId } from '../../../common/types/anomaly_detection_jobs'; +import { JobSelectorFlyout } from './components/job_selector_flyout'; /** * Handles Anomaly detection jobs selection by a user. @@ -47,23 +46,32 @@ export async function resolveJobSelection( const tzConfig = uiSettings.get('dateFormat:tz'); const dateFormatTz = tzConfig !== 'Browser' ? tzConfig : moment.tz.guess(); + const onFlyoutClose = () => { + flyoutSession.close(); + reject(); + }; + + const onSelectionConfirmed = async ({ + jobIds, + groups, + }: { + jobIds: string[]; + groups: Array<{ groupId: string; jobIds: string[] }>; + }) => { + await flyoutSession.close(); + resolve({ jobIds, groups }); + }; const flyoutSession = coreStart.overlays.openFlyout( toMountPoint( - { - flyoutSession.close(); - reject(); - }} - onSelectionConfirmed={async ({ jobIds, groups }) => { - await flyoutSession.close(); - resolve({ jobIds, groups }); - }} + onFlyoutClose={onFlyoutClose} + onSelectionConfirmed={onSelectionConfirmed} maps={maps} />