From ac818fee2bbc8d933e35727e9f9eff3a2d7f0cf5 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Sun, 18 Apr 2021 12:29:05 -0500 Subject: [PATCH 1/3] [ML] Persist apply time range --- x-pack/plugins/ml/common/types/storage.ts | 5 +++++ .../components/job_selector/job_selector_flyout.tsx | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/ml/common/types/storage.ts b/x-pack/plugins/ml/common/types/storage.ts index f8ffc4aec122e..af1cdb30da0cd 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; + 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_flyout.tsx b/x-pack/plugins/ml/public/application/components/job_selector/job_selector_flyout.tsx index 31f2714259aa0..3f3ef7bda81f0 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 @@ -31,6 +31,8 @@ import { import { MlJobWithTimeRange } from '../../../../common/types/anomaly_detection_jobs'; import { useMlKibana } from '../../contexts/kibana'; import { JobSelectionMaps } from './job_selector'; +import { useStorage } from '../../contexts/ml/use_storage'; +import { ApplyTimeRangeConfig, ML_APPLY_TIME_RANGE_CONFIG } from '../../../../common/types/storage'; export const BADGE_LIMIT = 10; export const DEFAULT_GANTT_BAR_WIDTH = 299; // pixels @@ -71,11 +73,15 @@ export const JobSelectorFlyoutContent: FC = ({ }, } = useMlKibana(); + const [applyTimeRangeConfig, setApplyTimeRange] = useStorage( + ML_APPLY_TIME_RANGE_CONFIG + ); + + const applyTimeRange = applyTimeRangeConfig ?? true; const [newSelection, setNewSelection] = useState(selectedIds); 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); From 0adf8ae220b2482322e380b66817059f2800fb73 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Sun, 18 Apr 2021 12:39:21 -0500 Subject: [PATCH 2/3] [ML] Fix support for dashboard --- .../components/job_selector/job_selector.tsx | 7 +++++++ .../job_selector/job_selector_flyout.tsx | 16 +++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) 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..50e2fa5e0202e 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,9 @@ export interface JobSelectionMaps { export function JobSelector({ dateFormatTz, singleSelection, timeseriesOnly }: JobSelectorProps) { const [globalState, setGlobalState] = useUrlState('_g'); + const [applyTimeRangeConfig, setApplyTimeRangeConfig] = useStorage( + ML_APPLY_TIME_RANGE_CONFIG + ); const selectedJobIds = globalState?.ml?.jobIds ?? []; const selectedGroups = globalState?.ml?.groups ?? []; @@ -180,6 +185,8 @@ export function JobSelector({ dateFormatTz, singleSelection, timeseriesOnly }: J onJobsFetched={setMaps} onFlyoutClose={closeFlyout} maps={maps} + applyTimeRangeConfig={applyTimeRangeConfig} + setApplyTimeRangeConfig={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 3f3ef7bda81f0..81082334a8346 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 @@ -31,8 +31,6 @@ import { import { MlJobWithTimeRange } from '../../../../common/types/anomaly_detection_jobs'; import { useMlKibana } from '../../contexts/kibana'; import { JobSelectionMaps } from './job_selector'; -import { useStorage } from '../../contexts/ml/use_storage'; -import { ApplyTimeRangeConfig, ML_APPLY_TIME_RANGE_CONFIG } from '../../../../common/types/storage'; export const BADGE_LIMIT = 10; export const DEFAULT_GANTT_BAR_WIDTH = 299; // pixels @@ -53,6 +51,8 @@ export interface JobSelectorFlyoutProps { timeseriesOnly: boolean; maps: JobSelectionMaps; withTimeRangeSelector?: boolean; + applyTimeRangeConfig?: boolean; + setApplyTimeRangeConfig?: (v: boolean) => void; } export const JobSelectorFlyoutContent: FC = ({ @@ -64,6 +64,8 @@ export const JobSelectorFlyoutContent: FC = ({ onSelectionConfirmed, onFlyoutClose, maps, + applyTimeRangeConfig, + setApplyTimeRangeConfig, withTimeRangeSelector = true, }) => { const { @@ -73,11 +75,11 @@ export const JobSelectorFlyoutContent: FC = ({ }, } = useMlKibana(); - const [applyTimeRangeConfig, setApplyTimeRange] = useStorage( - ML_APPLY_TIME_RANGE_CONFIG - ); + const [applyTimeRangeState, setApplyTimeRangeState] = useState(true); + + const handleToggleApplyTimeRange = setApplyTimeRangeConfig ?? setApplyTimeRangeState; + const applyTimeRange = applyTimeRangeConfig ?? applyTimeRangeState; - const applyTimeRange = applyTimeRangeConfig ?? true; const [newSelection, setNewSelection] = useState(selectedIds); const [isLoading, setIsLoading] = useState(true); @@ -124,7 +126,7 @@ export const JobSelectorFlyoutContent: FC = ({ } function toggleTimerangeSwitch() { - setApplyTimeRange(!applyTimeRange); + handleToggleApplyTimeRange(!applyTimeRange); } function clearSelection() { From 82b3c330d69d78c0386ca7164db80736b36ffe0b Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Tue, 20 Apr 2021 09:13:30 -0500 Subject: [PATCH 3/3] [ML] Move onTimeRangeConfigChange and applyTimeRangeConfig up to parent level --- x-pack/plugins/ml/common/types/storage.ts | 2 +- .../components/job_selector/job_selector.tsx | 5 ++- .../job_selector/job_selector_flyout.tsx | 21 +++++----- .../common/components/job_selector_flyout.tsx | 40 +++++++++++++++++++ .../common/resolve_job_selection.tsx | 30 +++++++++----- 5 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 x-pack/plugins/ml/public/embeddables/common/components/job_selector_flyout.tsx diff --git a/x-pack/plugins/ml/common/types/storage.ts b/x-pack/plugins/ml/common/types/storage.ts index af1cdb30da0cd..2750acf981ca8 100644 --- a/x-pack/plugins/ml/common/types/storage.ts +++ b/x-pack/plugins/ml/common/types/storage.ts @@ -36,7 +36,7 @@ export type PartitionFieldsConfig = | Partial> | undefined; -export type ApplyTimeRangeConfig = boolean; +export type ApplyTimeRangeConfig = boolean | undefined; export type MlStorage = Partial<{ [ML_ENTITY_FIELDS_CONFIG]: PartitionFieldsConfig; 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 50e2fa5e0202e..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 @@ -82,7 +82,8 @@ export interface JobSelectionMaps { export function JobSelector({ dateFormatTz, singleSelection, timeseriesOnly }: JobSelectorProps) { const [globalState, setGlobalState] = useUrlState('_g'); const [applyTimeRangeConfig, setApplyTimeRangeConfig] = useStorage( - ML_APPLY_TIME_RANGE_CONFIG + ML_APPLY_TIME_RANGE_CONFIG, + true ); const selectedJobIds = globalState?.ml?.jobIds ?? []; @@ -186,7 +187,7 @@ export function JobSelector({ dateFormatTz, singleSelection, timeseriesOnly }: J onFlyoutClose={closeFlyout} maps={maps} applyTimeRangeConfig={applyTimeRangeConfig} - setApplyTimeRangeConfig={setApplyTimeRangeConfig} + 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 81082334a8346..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 @@ -52,7 +52,7 @@ export interface JobSelectorFlyoutProps { maps: JobSelectionMaps; withTimeRangeSelector?: boolean; applyTimeRangeConfig?: boolean; - setApplyTimeRangeConfig?: (v: boolean) => void; + onTimeRangeConfigChange?: (v: boolean) => void; } export const JobSelectorFlyoutContent: FC = ({ @@ -65,7 +65,7 @@ export const JobSelectorFlyoutContent: FC = ({ onFlyoutClose, maps, applyTimeRangeConfig, - setApplyTimeRangeConfig, + onTimeRangeConfigChange, withTimeRangeSelector = true, }) => { const { @@ -75,11 +75,6 @@ export const JobSelectorFlyoutContent: FC = ({ }, } = useMlKibana(); - const [applyTimeRangeState, setApplyTimeRangeState] = useState(true); - - const handleToggleApplyTimeRange = setApplyTimeRangeConfig ?? setApplyTimeRangeState; - const applyTimeRange = applyTimeRangeConfig ?? applyTimeRangeState; - const [newSelection, setNewSelection] = useState(selectedIds); const [isLoading, setIsLoading] = useState(true); @@ -109,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; @@ -119,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() { - handleToggleApplyTimeRange(!applyTimeRange); + if (onTimeRangeConfigChange) { + onTimeRangeConfigChange(!applyTimeRangeConfig); + } } function clearSelection() { @@ -241,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} />