From 5efa8cd7dd019dc685b23848bf211c9caf1c8ac6 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Thu, 13 Aug 2020 13:23:47 -0500 Subject: [PATCH 01/29] [ML] Extend MlUrlGenerator to support other pages --- .../data/common/query/timefilter/types.ts | 1 + .../application/contexts/kibana/index.ts | 1 + .../contexts/kibana/use_create_url.ts | 20 ++ .../contexts/kibana/use_navigate_to_path.ts | 25 +- .../back_to_list_panel/back_to_list_panel.tsx | 12 +- .../view_results_panel/view_results_panel.tsx | 11 +- .../explorer/explorer_dashboard_service.ts | 1 + .../ml/public/application/routing/router.tsx | 1 - .../plugins/ml/public/url_generator.test.ts | 180 ++++++++++- x-pack/plugins/ml/public/url_generator.ts | 304 +++++++++++++++++- 10 files changed, 514 insertions(+), 42 deletions(-) create mode 100644 x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts diff --git a/src/plugins/data/common/query/timefilter/types.ts b/src/plugins/data/common/query/timefilter/types.ts index 60008ce6054e1b..ca741e24d11f4b 100644 --- a/src/plugins/data/common/query/timefilter/types.ts +++ b/src/plugins/data/common/query/timefilter/types.ts @@ -20,6 +20,7 @@ import { Moment } from 'moment'; export interface RefreshInterval { + display?: string; pause: boolean; value: number; } diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/index.ts b/x-pack/plugins/ml/public/application/contexts/kibana/index.ts index 8a43ae12deb21c..44979a1b9c60ae 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/index.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/index.ts @@ -9,3 +9,4 @@ export { useNavigateToPath, NavigateToPath } from './use_navigate_to_path'; export { useUiSettings } from './use_ui_settings_context'; export { useTimefilter } from './use_timefilter'; export { useNotifications } from './use_notifications_context'; +export { useMlUrlGenerator } from './use_create_url'; diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts b/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts new file mode 100644 index 00000000000000..1b8f0d1d64bbb5 --- /dev/null +++ b/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts @@ -0,0 +1,20 @@ +/* + * 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 { useMlKibana } from './kibana_context'; +import { ML_APP_URL_GENERATOR } from '../../../url_generator'; + +export const useMlUrlGenerator = () => { + const { + services: { + share: { + urlGenerators: { getUrlGenerator }, + }, + }, + } = useMlKibana(); + + return getUrlGenerator(ML_APP_URL_GENERATOR); +}; diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/use_navigate_to_path.ts b/x-pack/plugins/ml/public/application/contexts/kibana/use_navigate_to_path.ts index f2db970bf5057e..b5ad6e168086b5 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/use_navigate_to_path.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/use_navigate_to_path.ts @@ -21,14 +21,19 @@ export const useNavigateToPath = () => { const location = useLocation(); - return useMemo( - () => (path: string | undefined, preserveSearch = false) => { - navigateToUrl( - getUrlForApp(PLUGIN_ID, { - path: `${path}${preserveSearch === true ? location.search : ''}`, - }) - ); - }, - [location] - ); + return useMemo(() => { + return (path: string | undefined, preserveSearch = false) => { + if (path === undefined) return; + const modifiedPath = `${path}${preserveSearch === true ? location.search : ''}`; + /** + * Handle urls generated by MlUrlGenerator where '/app/ml' is automatically prepended + */ + const url = modifiedPath.startsWith('/app/ml') + ? modifiedPath + : getUrlForApp(PLUGIN_ID, { + path: modifiedPath, + }); + navigateToUrl(url); + }; + }, [location]); }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx index babb5571052702..f4adfe0f2a18cf 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx @@ -7,13 +7,19 @@ import React, { FC, Fragment } from 'react'; import { EuiCard, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useNavigateToPath } from '../../../../../contexts/kibana'; +import { useMlKibana, useMlUrlGenerator } from '../../../../../contexts/kibana'; export const BackToListPanel: FC = () => { - const navigateToPath = useNavigateToPath(); + const urlGenerator = useMlUrlGenerator(); + const { + services: { + application: { navigateToUrl }, + }, + } = useMlKibana(); const redirectToAnalyticsManagementPage = async () => { - await navigateToPath('/data_frame_analytics'); + const url = await urlGenerator.createUrl({ page: 'data_frame_analytics' }); + await navigateToUrl(url); }; return ( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx index 23a16ba84ef923..e1b1f80122da30 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx @@ -7,9 +7,9 @@ import React, { FC, Fragment } from 'react'; import { EuiCard, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useNavigateToPath } from '../../../../../contexts/kibana'; -import { getResultsUrl } from '../../../analytics_management/components/analytics_list/common'; +import { useMlUrlGenerator } from '../../../../../contexts/kibana'; import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics'; +import { useNavigateToPath } from '../../../../../contexts/kibana'; interface Props { jobId: string; @@ -17,10 +17,15 @@ interface Props { } export const ViewResultsPanel: FC = ({ jobId, analysisType }) => { + const urlGenerator = useMlUrlGenerator(); const navigateToPath = useNavigateToPath(); const redirectToAnalyticsManagementPage = async () => { - const path = getResultsUrl(jobId, analysisType); + const path = await urlGenerator.createUrl({ + page: 'data_frame_analytics/exploration', + jobId, + analysisType, + }); await navigateToPath(path); }; diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_dashboard_service.ts b/x-pack/plugins/ml/public/application/explorer/explorer_dashboard_service.ts index 4d697bcda1a065..12ec394c668eaa 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_dashboard_service.ts +++ b/x-pack/plugins/ml/public/application/explorer/explorer_dashboard_service.ts @@ -65,6 +65,7 @@ export interface ExplorerAppState { filteredFields?: string[]; queryString?: string; }; + query?: any; } const explorerAppState$: Observable = explorerState$.pipe( diff --git a/x-pack/plugins/ml/public/application/routing/router.tsx b/x-pack/plugins/ml/public/application/routing/router.tsx index 56c9a19723fba1..22a17c4ea089a9 100644 --- a/x-pack/plugins/ml/public/application/routing/router.tsx +++ b/x-pack/plugins/ml/public/application/routing/router.tsx @@ -75,7 +75,6 @@ const MlRoutes: FC<{ pageDeps: PageDependencies; }> = ({ pageDeps }) => { const navigateToPath = useNavigateToPath(); - return ( <> {Object.entries(routes).map(([name, routeFactory]) => { diff --git a/x-pack/plugins/ml/public/url_generator.test.ts b/x-pack/plugins/ml/public/url_generator.test.ts index 21dde124049577..b486706e2784d7 100644 --- a/x-pack/plugins/ml/public/url_generator.test.ts +++ b/x-pack/plugins/ml/public/url_generator.test.ts @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { MlUrlGenerator } from './url_generator'; +import { MlUrlGenerator, ML_TABS } from './url_generator'; +import { ANALYSIS_CONFIG_TYPE } from './application/data_frame_analytics/common'; describe('MlUrlGenerator', () => { const urlGenerator = new MlUrlGenerator({ @@ -12,15 +13,176 @@ describe('MlUrlGenerator', () => { useHash: false, }); - it('should generate valid URL for the Anomaly Explorer page', async () => { - const url = await urlGenerator.createUrl({ - page: 'explorer', - jobIds: ['test-job'], - mlExplorerSwimlane: { viewByFromPage: 2, viewByPerPage: 20 }, + describe('AnomalyDetection', () => { + describe('Job Management Page', () => { + it('should generate valid URL for the Anomaly Detection job management page', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.ANOMALY_DETECTION, + }); + expect(url).toBe('/app/ml/jobs'); + }); + + it('should generate valid URL for the Anomaly Detection job management page for job', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.ANOMALY_DETECTION, + jobId: 'fq_single_1', + }); + expect(url).toBe('/app/ml/jobs?mlManagement=(jobId:fq_single_1)'); + }); + + it('should generate valid URL for the Anomaly Detection job management page for groupIds', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.ANOMALY_DETECTION, + groupIds: ['farequote', 'categorization'], + }); + expect(url).toBe('/app/ml/jobs?mlManagement=(groupIds:!(farequote,categorization))'); + }); + }); + + describe('Anomaly Explorer Page', () => { + it('should generate valid URL for the Anomaly Explorer page', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.ANOMALY_EXPLORER, + jobIds: ['fq_single_1'], + mlExplorerSwimlane: { viewByFromPage: 2, viewByPerPage: 20 }, + refreshInterval: { + display: 'Off', + pause: false, + value: 0, + }, + timeRange: { + from: '2019-02-07T00:00:00.000Z', + to: '2020-08-13T17:15:00.000Z', + mode: 'absolute', + }, + query: { + analyze_wildcard: true, + query: '*', + }, + }); + expect(url).toBe( + "/app/ml/explorer?_g=(ml:(jobIds:!(fq_single_1)),refreshInterval:(display:Off,pause:!f,value:0),time:(from:'2019-02-07T00:00:00.000Z',mode:absolute,to:'2020-08-13T17:15:00.000Z'))&_a=(mlExplorerFilter:(),mlExplorerSwimlane:(viewByFromPage:2,viewByPerPage:20),query:(analyze_wildcard:!t,query:'*'))" + ); + }); + it('should generate valid URL for the Anomaly Explorer page for multiple jobIds', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.ANOMALY_EXPLORER, + jobIds: ['fq_single_1', 'logs_categorization_1'], + timeRange: { + from: '2019-02-07T00:00:00.000Z', + to: '2020-08-13T17:15:00.000Z', + mode: 'absolute', + }, + }); + expect(url).toBe( + "/app/ml/explorer?_g=(ml:(jobIds:!(fq_single_1,logs_categorization_1)),time:(from:'2019-02-07T00:00:00.000Z',mode:absolute,to:'2020-08-13T17:15:00.000Z'))&_a=(mlExplorerFilter:(),mlExplorerSwimlane:())" + ); + }); + }); + + describe('Single Metric Viewer Page', () => { + it('should generate valid URL for the Single Metric Viewer page', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.TIME_SERIES_EXPLORER, + jobIds: ['logs_categorization_1'], + refreshInterval: { + display: 'Off', + pause: false, + value: 0, + }, + timeRange: { + from: '2020-07-12T00:39:02.912Z', + to: '2020-07-22T15:52:18.613Z', + mode: 'absolute', + }, + query: { + analyze_wildcard: true, + query: '*', + }, + }); + expect(url).toBe( + "/app/ml/timeseriesexplorer?_g=(ml:(jobIds:!(logs_categorization_1)),refreshInterval:(display:Off,pause:!f,value:0),time:(from:'2020-07-12T00:39:02.912Z',mode:absolute,to:'2020-07-22T15:52:18.613Z'))&_a=(mlTimeSeriesExplorer:(),query:(query_string:(analyze_wildcard:!t,query:'*')))" + ); + }); + + it('should generate valid URL for the Single Metric Viewer page with extra settings', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.TIME_SERIES_EXPLORER, + jobIds: ['logs_categorization_1'], + detectorIndex: 0, + entities: { mlcategory: '2' }, + refreshInterval: { + display: 'Off', + pause: false, + value: 0, + }, + timeRange: { + from: '2020-07-12T00:39:02.912Z', + to: '2020-07-22T15:52:18.613Z', + mode: 'absolute', + }, + zoom: { + from: '2020-07-20T23:58:29.367Z', + to: '2020-07-21T11:00:13.173Z', + }, + query: { + analyze_wildcard: true, + query: '*', + }, + }); + expect(url).toBe( + "/app/ml/timeseriesexplorer?_g=(ml:(jobIds:!(logs_categorization_1)),refreshInterval:(display:Off,pause:!f,value:0),time:(from:'2020-07-12T00:39:02.912Z',mode:absolute,to:'2020-07-22T15:52:18.613Z'))&_a=(mlTimeSeriesExplorer:(detectorIndex:0,entities:(mlcategory:'2')),query:(query_string:(analyze_wildcard:!t,query:'*')),zoom:(from:'2020-07-20T23:58:29.367Z',to:'2020-07-21T11:00:13.173Z'))" + ); + }); + }); + }); + + describe('DataFrameAnalytics', () => { + describe('JobManagement Page', () => { + it('should generate valid URL for the Data Frame Analytics job management page', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.DATA_FRAME_ANALYTICS, + }); + expect(url).toBe('/app/ml/data_frame_analytics'); + }); + it('should generate valid URL for the Data Frame Analytics job management page with jobId', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.DATA_FRAME_ANALYTICS, + jobId: 'grid_regression_1', + }); + expect(url).toBe('/app/ml/data_frame_analytics?mlManagement=(jobId:grid_regression_1)'); + }); + + it('should generate valid URL for the Data Frame Analytics job management page with groupIds', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.DATA_FRAME_ANALYTICS, + groupIds: ['group_1', 'group_2'], + }); + expect(url).toBe('/app/ml/data_frame_analytics?mlManagement=(groupIds:!(group_1,group_2))'); + }); + }); + + describe('ExplorationPage', () => { + it('should generate valid URL for the Data Frame Analytics exploration page for job', async () => { + const url = await urlGenerator.createUrl({ + page: 'data_frame_analytics/exploration', + jobId: 'grid_regression_1', + analysisType: ANALYSIS_CONFIG_TYPE.REGRESSION, + }); + expect(url).toBe( + '/app/ml/data_frame_analytics/exploration?_g=(ml:(analysisType:regression,jobId:grid_regression_1))' + ); + }); + }); + }); + + describe('DataVisualizer', () => { + it('should generate valid URL for the Data Visualizer page', async () => { + const url = await urlGenerator.createUrl({ + page: 'datavisualizer', + }); + expect(url).toBe('/app/ml/datavisualizer'); }); - expect(url).toBe( - '/app/ml/explorer#?_g=(ml:(jobIds:!(test-job)))&_a=(mlExplorerFilter:(),mlExplorerSwimlane:(viewByFromPage:2,viewByPerPage:20))' - ); }); it('should throw an error in case the page is not provided', async () => { diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index 4e08c57c0b2e0b..25040dee2ecf8e 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -5,16 +5,18 @@ */ import { CoreSetup } from 'kibana/public'; +import isEmpty from 'lodash/isEmpty'; import { SharePluginSetup, UrlGeneratorsDefinition, UrlGeneratorState, } from '../../../../src/plugins/share/public'; -import { TimeRange } from '../../../../src/plugins/data/public'; +import { TimeRange, RefreshInterval } from '../../../../src/plugins/data/public'; import { setStateToKbnUrl } from '../../../../src/plugins/kibana_utils/public'; import { JobId } from '../../reporting/common/types'; import { ExplorerAppState } from './application/explorer/explorer_dashboard_service'; import { MlStartDependencies } from './plugin'; +import { ANALYSIS_CONFIG_TYPE } from './application/data_frame_analytics/common'; declare module '../../../../src/plugins/share/public' { export interface UrlGeneratorStateMapping { @@ -24,11 +26,39 @@ declare module '../../../../src/plugins/share/public' { export const ML_APP_URL_GENERATOR = 'ML_APP_URL_GENERATOR'; +export const ML_TABS = { + ANOMALY_DETECTION: 'jobs', + ANOMALY_EXPLORER: 'explorer', + TIME_SERIES_EXPLORER: 'timeseriesexplorer', + DATA_FRAME_ANALYTICS: 'data_frame_analytics', + DATA_FRAME_ANALYTICS_EXPLORATION: 'data_frame_analytics/exploration', + DATA_VISUALIZER: 'datavisualizer', + SETTINGS: 'settings', + CALENDARS: 'settings/calendars_list', + FILTERS: 'settings/filter_lists', +} as const; + +export interface AnomalyDetectionQueryState { + jobId?: JobId; + groupIds?: string[]; +} + +export interface AnomalyDetectionUrlState { + page: typeof ML_TABS.ANOMALY_DETECTION; + jobId?: JobId; + groupIds?: string[]; +} +export interface ExplorerGlobalState { + ml: { jobIds: JobId[] }; + time?: TimeRange; + refreshInterval?: RefreshInterval; +} + export interface ExplorerUrlState { /** * ML App Page */ - page: 'explorer'; + page: typeof ML_TABS.ANOMALY_EXPLORER; /** * Job IDs */ @@ -37,6 +67,14 @@ export interface ExplorerUrlState { * Optionally set the time range in the time picker. */ timeRange?: TimeRange; + /** + * Optionally set the refresh interval. + */ + refreshInterval?: RefreshInterval; + /** + * Optionally set the query. + */ + query?: any; /** * Optional state for the swim lane */ @@ -44,15 +82,75 @@ export interface ExplorerUrlState { mlExplorerFilter?: ExplorerAppState['mlExplorerFilter']; } +export interface TimeSeriesExplorerGlobalState { + ml: { + jobIds: JobId[]; + }; + time?: TimeRange; + refreshInterval?: RefreshInterval; +} + +export interface TimeSeriesExplorerAppState { + zoom?: { + from?: string; + to?: string; + }; + mlTimeSeriesExplorer?: { + detectorIndex?: number; + entities?: Record; + }; + query?: any; +} + +export interface TimeSeriesExplorerUrlState + extends Pick, + Pick { + /** + * ML App Page + */ + page: typeof ML_TABS.TIME_SERIES_EXPLORER; + jobIds: JobId[]; + timeRange?: TimeRange; + detectorIndex?: number; + entities?: Record; +} + +export interface DataFrameAnalyticsQueryState { + jobId?: JobId | JobId[]; + groupIds?: string[]; +} + +export interface DataFrameAnalyticsUrlState extends DataFrameAnalyticsQueryState { + page: typeof ML_TABS.DATA_FRAME_ANALYTICS; +} + +export interface DataVisualizerUrlState { + page: typeof ML_TABS.DATA_VISUALIZER; +} + +export interface DataFrameAnalyticsExplorationQueryState { + ml: { + jobId: JobId; + analysisType: ANALYSIS_CONFIG_TYPE; + }; +} + +export interface DataFrameAnalyticsExplorationUrlState { + page: typeof ML_TABS.DATA_FRAME_ANALYTICS_EXPLORATION; + jobId: JobId; + analysisType: ANALYSIS_CONFIG_TYPE; +} + /** * Union type of ML URL state based on page */ -export type MlUrlGeneratorState = ExplorerUrlState; - -export interface ExplorerQueryState { - ml: { jobIds: JobId[] }; - time?: TimeRange; -} +export type MlUrlGeneratorState = + | AnomalyDetectionUrlState + | ExplorerUrlState + | TimeSeriesExplorerUrlState + | DataFrameAnalyticsUrlState + | DataFrameAnalyticsExplorationUrlState + | DataVisualizerUrlState; interface Params { appBasePath: string; @@ -65,40 +163,214 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition => { - if (page === 'explorer') { - return this.createExplorerUrl(params); + if (page === ML_TABS.ANOMALY_DETECTION) { + return this.createAnomalyDetectionJobManagementUrl( + params as Omit + ); + } + if (page === ML_TABS.ANOMALY_EXPLORER) { + return this.createExplorerUrl(params as Omit); + } + if (page === ML_TABS.TIME_SERIES_EXPLORER) { + return this.createSingleMetricViewerUrl(params as Omit); + } + if (page === ML_TABS.DATA_FRAME_ANALYTICS) { + return this.createDataframeAnalyticsUrl(params as Omit); + } + if (page === ML_TABS.DATA_FRAME_ANALYTICS_EXPLORATION) { + return this.createDataframeAnalyticsExplorationUrl( + params as Omit + ); + } + if (page === ML_TABS.DATA_VISUALIZER) { + return this.createDataVisualizerUrl(params as Omit); } + throw new Error('Page type is not provided or unknown'); }; + /** + * Creates URL to the Anomaly Detection Job management page + */ + private createAnomalyDetectionJobManagementUrl( + params: Omit + ): string { + let url = `${this.params.appBasePath}/${ML_TABS.ANOMALY_DETECTION}`; + if (isEmpty(params)) { + return url; + } + const { jobId, groupIds } = params; + const queryState: AnomalyDetectionQueryState = { + jobId, + groupIds, + }; + + url = setStateToKbnUrl( + 'mlManagement', + queryState, + { useHash: false, storeInHashQuery: false }, + url + ); + return url; + } + /** * Creates URL to the Anomaly Explorer page */ private createExplorerUrl({ + refreshInterval, timeRange, jobIds, + query, mlExplorerSwimlane = {}, mlExplorerFilter = {}, }: Omit): string { - const appState: ExplorerAppState = { + let url = `${this.params.appBasePath}/${ML_TABS.ANOMALY_EXPLORER}`; + + const appState: Partial = { mlExplorerSwimlane, mlExplorerFilter, }; + if (query) appState.query = query; + + if (jobIds) { + const queryState: Partial = { + ml: { + jobIds, + }, + }; + + if (timeRange) queryState.time = timeRange; + if (refreshInterval) queryState.refreshInterval = refreshInterval; - const queryState: ExplorerQueryState = { + url = setStateToKbnUrl>( + '_g', + queryState, + { useHash: false, storeInHashQuery: false }, + url + ); + url = setStateToKbnUrl>( + '_a', + appState, + { useHash: false, storeInHashQuery: false }, + url + ); + } + + return url; + } + + /** + * Creates URL to the SingleMetricViewer page + */ + private createSingleMetricViewerUrl({ + timeRange, + jobIds, + refreshInterval, + zoom, + query, + detectorIndex, + entities, + }: Omit): string { + let url = `${this.params.appBasePath}/${ML_TABS.TIME_SERIES_EXPLORER}`; + const queryState: TimeSeriesExplorerGlobalState = { ml: { jobIds, }, + refreshInterval, + time: timeRange, }; - if (timeRange) queryState.time = timeRange; + const appState: Partial = {}; + const mlTimeSeriesExplorer: Partial = {}; + + if (detectorIndex !== undefined) { + mlTimeSeriesExplorer.detectorIndex = detectorIndex; + } + if (entities !== undefined) { + mlTimeSeriesExplorer.entities = entities; + } + appState.mlTimeSeriesExplorer = mlTimeSeriesExplorer; + + if (zoom) appState.zoom = zoom; + if (query) + appState.query = { + query_string: query, + }; + url = setStateToKbnUrl( + '_g', + queryState, + { useHash: false, storeInHashQuery: false }, + url + ); + url = setStateToKbnUrl( + '_a', + appState, + { useHash: false, storeInHashQuery: false }, + url + ); + + return url; + } + + /** + * Creates URL to the DataFrameAnalytics Exploration page + */ + private createDataframeAnalyticsExplorationUrl( + params: Omit + ): string { + let url = `${this.params.appBasePath}/${ML_TABS.DATA_FRAME_ANALYTICS_EXPLORATION}`; + + if (!isEmpty(params)) { + const { jobId, analysisType } = params; + const queryState: DataFrameAnalyticsExplorationQueryState = { + ml: { + jobId, + analysisType, + }, + }; - let url = `${this.params.appBasePath}/explorer`; - url = setStateToKbnUrl('_g', queryState, { useHash: false }, url); - url = setStateToKbnUrl('_a', appState, { useHash: false }, url); + url = setStateToKbnUrl( + '_g', + queryState, + { useHash: false, storeInHashQuery: false }, + url + ); + } return url; } + + /** + * Creates URL to the DataFrameAnalytics page + */ + private createDataframeAnalyticsUrl(params: Omit): string { + let url = `${this.params.appBasePath}/${ML_TABS.DATA_FRAME_ANALYTICS}`; + + if (!isEmpty(params)) { + const { jobId, groupIds } = params; + const queryState: Partial = { + jobId, + groupIds, + }; + + url = setStateToKbnUrl>( + 'mlManagement', + queryState, + { useHash: false, storeInHashQuery: false }, + url + ); + } + + return url; + } + + /** + * Creates URL to the Data Visualizer page + */ + private createDataVisualizerUrl({}: Omit): string { + return `${this.params.appBasePath}/${ML_TABS.DATA_VISUALIZER}`; + } } /** From 9faedfd6ed31dca929ae6d0be39a5f00bf8cfcbf Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Fri, 21 Aug 2020 10:21:05 -0500 Subject: [PATCH 02/29] [ML] Change destructuring & index based ml generator --- .../plugins/ml/public/url_generator.test.ts | 52 +++++- x-pack/plugins/ml/public/url_generator.ts | 161 ++++++++++++++---- 2 files changed, 178 insertions(+), 35 deletions(-) diff --git a/x-pack/plugins/ml/public/url_generator.test.ts b/x-pack/plugins/ml/public/url_generator.test.ts index b486706e2784d7..dd7098517c3b0a 100644 --- a/x-pack/plugins/ml/public/url_generator.test.ts +++ b/x-pack/plugins/ml/public/url_generator.test.ts @@ -37,6 +37,23 @@ describe('MlUrlGenerator', () => { }); expect(url).toBe('/app/ml/jobs?mlManagement=(groupIds:!(farequote,categorization))'); }); + + it('should generate valid URL for the Data Visualizer Viewer page', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.DATA_VISUALIZER_NEW_JOB, + index: `3da93760-e0af-11ea-9ad3-3bcfc330e42a`, + globalState: { + time: { + from: 'now-30m', + to: 'now', + mode: 'quick', + }, + }, + }); + expect(url).toBe( + '/app/ml/jobs/new_job/step/job_type?index=3da93760-e0af-11ea-9ad3-3bcfc330e42a&_g=(time:(from:now-30m,mode:quick,to:now))' + ); + }); }); describe('Anomaly Explorer Page', () => { @@ -165,7 +182,7 @@ describe('MlUrlGenerator', () => { describe('ExplorationPage', () => { it('should generate valid URL for the Data Frame Analytics exploration page for job', async () => { const url = await urlGenerator.createUrl({ - page: 'data_frame_analytics/exploration', + page: ML_TABS.DATA_FRAME_ANALYTICS_EXPLORATION, jobId: 'grid_regression_1', analysisType: ANALYSIS_CONFIG_TYPE.REGRESSION, }); @@ -179,10 +196,41 @@ describe('MlUrlGenerator', () => { describe('DataVisualizer', () => { it('should generate valid URL for the Data Visualizer page', async () => { const url = await urlGenerator.createUrl({ - page: 'datavisualizer', + page: ML_TABS.DATA_VISUALIZER, }); expect(url).toBe('/app/ml/datavisualizer'); }); + + it('should generate valid URL for the Data Visualizer import file page', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.DATA_VISUALIZER_FILE, + }); + expect(url).toBe('/app/ml/filedatavisualizer'); + }); + + it('should generate valid URL for the Data Visualizer import by index page', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.DATA_VISUALIZER_INDEX_SELECT, + }); + expect(url).toBe('/app/ml/datavisualizer_index_select'); + }); + + it('should generate valid URL for the Data Visualizer Viewer page', async () => { + const url = await urlGenerator.createUrl({ + page: ML_TABS.DATA_VISUALIZER_VIEWER, + index: '3da93760-e0af-11ea-9ad3-3bcfc330e42a', + globalState: { + time: { + from: 'now-30m', + to: 'now', + mode: 'quick', + }, + }, + }); + expect(url).toBe( + '/app/ml/jobs/new_job/datavisualizer?index=3da93760-e0af-11ea-9ad3-3bcfc330e42a&_g=(time:(from:now-30m,mode:quick,to:now))' + ); + }); }); it('should throw an error in case the page is not provided', async () => { diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index 25040dee2ecf8e..d5f7bfb54972e0 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -32,12 +32,55 @@ export const ML_TABS = { TIME_SERIES_EXPLORER: 'timeseriesexplorer', DATA_FRAME_ANALYTICS: 'data_frame_analytics', DATA_FRAME_ANALYTICS_EXPLORATION: 'data_frame_analytics/exploration', + /** + * Page: Data Visualizer + */ DATA_VISUALIZER: 'datavisualizer', + /** + * Page: Data Visualizer + * Create data visualizer by selecting an existing Elasticsearch index + */ + DATA_VISUALIZER_INDEX_SELECT: 'datavisualizer_index_select', + /** + * Page: Data Visualizer + * Create data visualizer by importing log data + */ + DATA_VISUALIZER_FILE: 'filedatavisualizer', + /** + * Page: Data Visualizer + * Create a job from the index pattern + */ + get DATA_VISUALIZER_VIEWER() { + return `${this.ANOMALY_DETECTION}/new_job/${this.DATA_VISUALIZER}`; + }, + get DATA_VISUALIZER_NEW_JOB() { + return `${this.ANOMALY_DETECTION}/new_job/step/job_type`; + }, + SETTINGS: 'settings', CALENDARS: 'settings/calendars_list', FILTERS: 'settings/filter_lists', } as const; +export interface MlCommonGlobalState { + time?: TimeRange; +} +export interface MlCommonAppState { + [key: string]: any; +} + +export interface MlIndexBasedSearchState { + index?: string; + savedSearchId?: string; +} + +export interface MlGenericUrlState extends MlIndexBasedSearchState { + page: typeof ML_TABS.DATA_VISUALIZER_VIEWER | typeof ML_TABS.DATA_VISUALIZER_NEW_JOB; + globalState?: MlCommonGlobalState; + appState?: MlCommonAppState; + [key: string]: any; +} + export interface AnomalyDetectionQueryState { jobId?: JobId; groupIds?: string[]; @@ -125,7 +168,10 @@ export interface DataFrameAnalyticsUrlState extends DataFrameAnalyticsQueryState } export interface DataVisualizerUrlState { - page: typeof ML_TABS.DATA_VISUALIZER; + page: + | typeof ML_TABS.DATA_VISUALIZER + | typeof ML_TABS.DATA_VISUALIZER_FILE + | typeof ML_TABS.DATA_VISUALIZER_INDEX_SELECT; } export interface DataFrameAnalyticsExplorationQueryState { @@ -150,7 +196,8 @@ export type MlUrlGeneratorState = | TimeSeriesExplorerUrlState | DataFrameAnalyticsUrlState | DataFrameAnalyticsExplorationUrlState - | DataVisualizerUrlState; + | DataVisualizerUrlState + | MlGenericUrlState; interface Params { appBasePath: string; @@ -162,39 +209,50 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition => { - if (page === ML_TABS.ANOMALY_DETECTION) { - return this.createAnomalyDetectionJobManagementUrl( - params as Omit - ); - } - if (page === ML_TABS.ANOMALY_EXPLORER) { - return this.createExplorerUrl(params as Omit); - } - if (page === ML_TABS.TIME_SERIES_EXPLORER) { - return this.createSingleMetricViewerUrl(params as Omit); + public readonly createUrl = async (mlUrlGeneratorState: MlUrlGeneratorState): Promise => { + switch (mlUrlGeneratorState.page) { + case ML_TABS.ANOMALY_DETECTION: + return this.createAnomalyDetectionJobManagementUrl( + mlUrlGeneratorState as AnomalyDetectionUrlState + ); + case ML_TABS.ANOMALY_EXPLORER: + return this.createExplorerUrl(mlUrlGeneratorState as ExplorerUrlState); + case ML_TABS.TIME_SERIES_EXPLORER: + return this.createSingleMetricViewerUrl(mlUrlGeneratorState as TimeSeriesExplorerUrlState); + case ML_TABS.DATA_FRAME_ANALYTICS: + return this.createDataframeAnalyticsUrl(mlUrlGeneratorState as DataFrameAnalyticsUrlState); + case ML_TABS.DATA_FRAME_ANALYTICS_EXPLORATION: + return this.createDataframeAnalyticsExplorationUrl( + mlUrlGeneratorState as DataFrameAnalyticsExplorationUrlState + ); + case ML_TABS.DATA_VISUALIZER: + return this.createDataVisualizerUrl(mlUrlGeneratorState as DataVisualizerUrlState); + case ML_TABS.DATA_VISUALIZER_FILE: + return this.createDataVisualizerUrl(mlUrlGeneratorState as DataVisualizerUrlState); + case ML_TABS.DATA_VISUALIZER_INDEX_SELECT: + return this.createDataVisualizerUrl(mlUrlGeneratorState as DataVisualizerUrlState); + case ML_TABS.DATA_VISUALIZER_NEW_JOB: + return this.createIndexBasedMlUrl(mlUrlGeneratorState as MlGenericUrlState); + case ML_TABS.DATA_VISUALIZER_VIEWER: + return this.createIndexBasedMlUrl(mlUrlGeneratorState as MlGenericUrlState); + default: + throw new Error('Page type is not provided or unknown'); } - if (page === ML_TABS.DATA_FRAME_ANALYTICS) { - return this.createDataframeAnalyticsUrl(params as Omit); - } - if (page === ML_TABS.DATA_FRAME_ANALYTICS_EXPLORATION) { - return this.createDataframeAnalyticsExplorationUrl( - params as Omit - ); - } - if (page === ML_TABS.DATA_VISUALIZER) { - return this.createDataVisualizerUrl(params as Omit); - } - - throw new Error('Page type is not provided or unknown'); }; + private static extractParams(urlState: UrlState) { + // page should be guaranteed to exist here but is unknown + // @ts-ignore + const { page, ...params } = urlState; + return { page, params }; + } /** * Creates URL to the Anomaly Detection Job management page */ private createAnomalyDetectionJobManagementUrl( - params: Omit + mlUrlGeneratorState: AnomalyDetectionUrlState // Omit ): string { + const { params } = MlUrlGenerator.extractParams(mlUrlGeneratorState); let url = `${this.params.appBasePath}/${ML_TABS.ANOMALY_DETECTION}`; if (isEmpty(params)) { return url; @@ -224,7 +282,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition): string { + }: ExplorerUrlState): string { let url = `${this.params.appBasePath}/${ML_TABS.ANOMALY_EXPLORER}`; const appState: Partial = { @@ -271,7 +329,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition): string { + }: TimeSeriesExplorerUrlState): string { let url = `${this.params.appBasePath}/${ML_TABS.TIME_SERIES_EXPLORER}`; const queryState: TimeSeriesExplorerGlobalState = { ml: { @@ -317,9 +375,12 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition + mlUrlGeneratorState: DataFrameAnalyticsExplorationUrlState ): string { let url = `${this.params.appBasePath}/${ML_TABS.DATA_FRAME_ANALYTICS_EXPLORATION}`; + const { params } = MlUrlGenerator.extractParams( + mlUrlGeneratorState + ); if (!isEmpty(params)) { const { jobId, analysisType } = params; @@ -344,8 +405,11 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition): string { + private createDataframeAnalyticsUrl(mlUrlGeneratorState: DataFrameAnalyticsUrlState): string { let url = `${this.params.appBasePath}/${ML_TABS.DATA_FRAME_ANALYTICS}`; + const { params } = MlUrlGenerator.extractParams( + mlUrlGeneratorState + ); if (!isEmpty(params)) { const { jobId, groupIds } = params; @@ -368,8 +432,39 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition): string { - return `${this.params.appBasePath}/${ML_TABS.DATA_VISUALIZER}`; + private createDataVisualizerUrl({ page }: DataVisualizerUrlState): string { + return `${this.params.appBasePath}/${page}`; + } + + private createIndexBasedMlUrl(mlGenericUrlState: MlGenericUrlState): string { + const { globalState, appState, page, index, savedSearchId, ...restParams } = mlGenericUrlState; + let url = `${this.params.appBasePath}/${page}`; + + if (index && !savedSearchId) { + url = url + `?index=${index}`; + } + if (!index && savedSearchId) { + url = url + `?savedSearchId=${savedSearchId}`; + } + + if (!isEmpty(restParams)) { + Object.keys(restParams).forEach((key) => { + url = setStateToKbnUrl( + key, + restParams[key], + { useHash: false, storeInHashQuery: false }, + url + ); + }); + } + + if (globalState) { + url = setStateToKbnUrl('_g', globalState, { useHash: false, storeInHashQuery: false }, url); + } + if (appState) { + url = setStateToKbnUrl('_a', appState, { useHash: false, storeInHashQuery: false }, url); + } + return url; } } From 7d8aba829024fe2dc3db43833a60f11adc9823ad Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Fri, 21 Aug 2020 10:23:39 -0500 Subject: [PATCH 03/29] [ML] Make createIndexBasedMlUrl check more explicit --- x-pack/plugins/ml/public/url_generator.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index d5f7bfb54972e0..aa1fd022965b9b 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -436,14 +436,18 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition Date: Fri, 21 Aug 2020 10:41:58 -0500 Subject: [PATCH 04/29] [ML] Remove commented code --- x-pack/plugins/ml/public/url_generator.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index aa1fd022965b9b..e408af328ccb06 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -56,7 +56,6 @@ export const ML_TABS = { get DATA_VISUALIZER_NEW_JOB() { return `${this.ANOMALY_DETECTION}/new_job/step/job_type`; }, - SETTINGS: 'settings', CALENDARS: 'settings/calendars_list', FILTERS: 'settings/filter_lists', @@ -250,7 +249,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition + mlUrlGeneratorState: AnomalyDetectionUrlState ): string { const { params } = MlUrlGenerator.extractParams(mlUrlGeneratorState); let url = `${this.params.appBasePath}/${ML_TABS.ANOMALY_DETECTION}`; From c1f8cdeebc4b538afcdaa37af8e901ae0d963ea8 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Fri, 21 Aug 2020 10:45:41 -0500 Subject: [PATCH 05/29] [ML] Update type for TimeRange --- src/plugins/data/common/query/timefilter/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/data/common/query/timefilter/types.ts b/src/plugins/data/common/query/timefilter/types.ts index ca741e24d11f4b..ddf6b2e896dc88 100644 --- a/src/plugins/data/common/query/timefilter/types.ts +++ b/src/plugins/data/common/query/timefilter/types.ts @@ -28,7 +28,7 @@ export interface RefreshInterval { export interface TimeRange { from: string; to: string; - mode?: 'absolute' | 'relative'; + mode?: 'absolute' | 'relative' | 'quick'; } export interface TimeRangeBounds { From 98dd2e5dc2fc7b5dddbe8c7a21cdfd8393f0d5e3 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Fri, 21 Aug 2020 10:53:14 -0500 Subject: [PATCH 06/29] [ML] Update redirect for dfa wizard to use constants --- .../components/back_to_list_panel/back_to_list_panel.tsx | 3 ++- .../components/view_results_panel/view_results_panel.tsx | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx index f4adfe0f2a18cf..d682403251a7b4 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx @@ -8,6 +8,7 @@ import React, { FC, Fragment } from 'react'; import { EuiCard, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useMlKibana, useMlUrlGenerator } from '../../../../../contexts/kibana'; +import { ML_TABS } from '../../../../../../url_generator'; export const BackToListPanel: FC = () => { const urlGenerator = useMlUrlGenerator(); @@ -18,7 +19,7 @@ export const BackToListPanel: FC = () => { } = useMlKibana(); const redirectToAnalyticsManagementPage = async () => { - const url = await urlGenerator.createUrl({ page: 'data_frame_analytics' }); + const url = await urlGenerator.createUrl({ page: ML_TABS.DATA_FRAME_ANALYTICS }); await navigateToUrl(url); }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx index e1b1f80122da30..49bd4937b5e105 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx @@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n'; import { useMlUrlGenerator } from '../../../../../contexts/kibana'; import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics'; import { useNavigateToPath } from '../../../../../contexts/kibana'; +import { ML_TABS } from '../../../../../../url_generator'; interface Props { jobId: string; @@ -20,9 +21,9 @@ export const ViewResultsPanel: FC = ({ jobId, analysisType }) => { const urlGenerator = useMlUrlGenerator(); const navigateToPath = useNavigateToPath(); - const redirectToAnalyticsManagementPage = async () => { + const redirectToAnalyticsJobPage = async () => { const path = await urlGenerator.createUrl({ - page: 'data_frame_analytics/exploration', + page: ML_TABS.DATA_FRAME_ANALYTICS_EXPLORATION, jobId, analysisType, }); @@ -43,7 +44,7 @@ export const ViewResultsPanel: FC = ({ jobId, analysisType }) => { defaultMessage: 'View results for the analytics job.', } )} - onClick={redirectToAnalyticsManagementPage} + onClick={redirectToAnalyticsJobPage} data-test-subj="analyticsWizardViewResultsCard" /> From 7c9318e162d3ee556f0986bff07973bf66258a64 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Mon, 24 Aug 2020 10:03:03 -0500 Subject: [PATCH 07/29] [ML] Rename ML_TABS to ML_PAGES --- .../back_to_list_panel/back_to_list_panel.tsx | 4 +- .../view_results_panel/view_results_panel.tsx | 4 +- .../new_job/common/job_creator/job_creator.ts | 2 +- .../plugins/ml/public/url_generator.test.ts | 34 ++++++------- x-pack/plugins/ml/public/url_generator.ts | 50 +++++++++---------- 5 files changed, 47 insertions(+), 47 deletions(-) diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx index d682403251a7b4..b8e0cddf0cc3b5 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx @@ -8,7 +8,7 @@ import React, { FC, Fragment } from 'react'; import { EuiCard, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useMlKibana, useMlUrlGenerator } from '../../../../../contexts/kibana'; -import { ML_TABS } from '../../../../../../url_generator'; +import { ML_PAGES } from '../../../../../../url_generator'; export const BackToListPanel: FC = () => { const urlGenerator = useMlUrlGenerator(); @@ -19,7 +19,7 @@ export const BackToListPanel: FC = () => { } = useMlKibana(); const redirectToAnalyticsManagementPage = async () => { - const url = await urlGenerator.createUrl({ page: ML_TABS.DATA_FRAME_ANALYTICS }); + const url = await urlGenerator.createUrl({ page: ML_PAGES.DATA_FRAME_ANALYTICS }); await navigateToUrl(url); }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx index 49bd4937b5e105..50af073658ad89 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; import { useMlUrlGenerator } from '../../../../../contexts/kibana'; import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics'; import { useNavigateToPath } from '../../../../../contexts/kibana'; -import { ML_TABS } from '../../../../../../url_generator'; +import { ML_PAGES } from '../../../../../../url_generator'; interface Props { jobId: string; @@ -23,7 +23,7 @@ export const ViewResultsPanel: FC = ({ jobId, analysisType }) => { const redirectToAnalyticsJobPage = async () => { const path = await urlGenerator.createUrl({ - page: ML_TABS.DATA_FRAME_ANALYTICS_EXPLORATION, + page: ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION, jobId, analysisType, }); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts index 4c030a22f54f77..5894b3acb272dd 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts @@ -647,7 +647,7 @@ export class JobCreator { return this._job_config.analysis_config.per_partition_categorization?.stop_on_warn === true; } - public set perPartitionStopOnWarn(enabled: boolean) { + public set perParttionStopOnWarn(enabled: boolean) { this._initPerPartitionCategorization(); this._job_config.analysis_config.per_partition_categorization!.stop_on_warn = enabled; } diff --git a/x-pack/plugins/ml/public/url_generator.test.ts b/x-pack/plugins/ml/public/url_generator.test.ts index dd7098517c3b0a..e84183d86f2b4b 100644 --- a/x-pack/plugins/ml/public/url_generator.test.ts +++ b/x-pack/plugins/ml/public/url_generator.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { MlUrlGenerator, ML_TABS } from './url_generator'; +import { MlUrlGenerator, ML_PAGES } from './url_generator'; import { ANALYSIS_CONFIG_TYPE } from './application/data_frame_analytics/common'; describe('MlUrlGenerator', () => { @@ -17,14 +17,14 @@ describe('MlUrlGenerator', () => { describe('Job Management Page', () => { it('should generate valid URL for the Anomaly Detection job management page', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.ANOMALY_DETECTION, + page: ML_PAGES.ANOMALY_DETECTION, }); expect(url).toBe('/app/ml/jobs'); }); it('should generate valid URL for the Anomaly Detection job management page for job', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.ANOMALY_DETECTION, + page: ML_PAGES.ANOMALY_DETECTION, jobId: 'fq_single_1', }); expect(url).toBe('/app/ml/jobs?mlManagement=(jobId:fq_single_1)'); @@ -32,7 +32,7 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Anomaly Detection job management page for groupIds', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.ANOMALY_DETECTION, + page: ML_PAGES.ANOMALY_DETECTION, groupIds: ['farequote', 'categorization'], }); expect(url).toBe('/app/ml/jobs?mlManagement=(groupIds:!(farequote,categorization))'); @@ -40,7 +40,7 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Data Visualizer Viewer page', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.DATA_VISUALIZER_NEW_JOB, + page: ML_PAGES.DATA_VISUALIZER_NEW_JOB, index: `3da93760-e0af-11ea-9ad3-3bcfc330e42a`, globalState: { time: { @@ -59,7 +59,7 @@ describe('MlUrlGenerator', () => { describe('Anomaly Explorer Page', () => { it('should generate valid URL for the Anomaly Explorer page', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.ANOMALY_EXPLORER, + page: ML_PAGES.ANOMALY_EXPLORER, jobIds: ['fq_single_1'], mlExplorerSwimlane: { viewByFromPage: 2, viewByPerPage: 20 }, refreshInterval: { @@ -83,7 +83,7 @@ describe('MlUrlGenerator', () => { }); it('should generate valid URL for the Anomaly Explorer page for multiple jobIds', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.ANOMALY_EXPLORER, + page: ML_PAGES.ANOMALY_EXPLORER, jobIds: ['fq_single_1', 'logs_categorization_1'], timeRange: { from: '2019-02-07T00:00:00.000Z', @@ -100,7 +100,7 @@ describe('MlUrlGenerator', () => { describe('Single Metric Viewer Page', () => { it('should generate valid URL for the Single Metric Viewer page', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.TIME_SERIES_EXPLORER, + page: ML_PAGES.TIME_SERIES_EXPLORER, jobIds: ['logs_categorization_1'], refreshInterval: { display: 'Off', @@ -124,7 +124,7 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Single Metric Viewer page with extra settings', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.TIME_SERIES_EXPLORER, + page: ML_PAGES.TIME_SERIES_EXPLORER, jobIds: ['logs_categorization_1'], detectorIndex: 0, entities: { mlcategory: '2' }, @@ -158,13 +158,13 @@ describe('MlUrlGenerator', () => { describe('JobManagement Page', () => { it('should generate valid URL for the Data Frame Analytics job management page', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.DATA_FRAME_ANALYTICS, + page: ML_PAGES.DATA_FRAME_ANALYTICS, }); expect(url).toBe('/app/ml/data_frame_analytics'); }); it('should generate valid URL for the Data Frame Analytics job management page with jobId', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.DATA_FRAME_ANALYTICS, + page: ML_PAGES.DATA_FRAME_ANALYTICS, jobId: 'grid_regression_1', }); expect(url).toBe('/app/ml/data_frame_analytics?mlManagement=(jobId:grid_regression_1)'); @@ -172,7 +172,7 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Data Frame Analytics job management page with groupIds', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.DATA_FRAME_ANALYTICS, + page: ML_PAGES.DATA_FRAME_ANALYTICS, groupIds: ['group_1', 'group_2'], }); expect(url).toBe('/app/ml/data_frame_analytics?mlManagement=(groupIds:!(group_1,group_2))'); @@ -182,7 +182,7 @@ describe('MlUrlGenerator', () => { describe('ExplorationPage', () => { it('should generate valid URL for the Data Frame Analytics exploration page for job', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.DATA_FRAME_ANALYTICS_EXPLORATION, + page: ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION, jobId: 'grid_regression_1', analysisType: ANALYSIS_CONFIG_TYPE.REGRESSION, }); @@ -196,28 +196,28 @@ describe('MlUrlGenerator', () => { describe('DataVisualizer', () => { it('should generate valid URL for the Data Visualizer page', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.DATA_VISUALIZER, + page: ML_PAGES.DATA_VISUALIZER, }); expect(url).toBe('/app/ml/datavisualizer'); }); it('should generate valid URL for the Data Visualizer import file page', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.DATA_VISUALIZER_FILE, + page: ML_PAGES.DATA_VISUALIZER_FILE, }); expect(url).toBe('/app/ml/filedatavisualizer'); }); it('should generate valid URL for the Data Visualizer import by index page', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.DATA_VISUALIZER_INDEX_SELECT, + page: ML_PAGES.DATA_VISUALIZER_INDEX_SELECT, }); expect(url).toBe('/app/ml/datavisualizer_index_select'); }); it('should generate valid URL for the Data Visualizer Viewer page', async () => { const url = await urlGenerator.createUrl({ - page: ML_TABS.DATA_VISUALIZER_VIEWER, + page: ML_PAGES.DATA_VISUALIZER_VIEWER, index: '3da93760-e0af-11ea-9ad3-3bcfc330e42a', globalState: { time: { diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index e408af328ccb06..7976eb0272f7c1 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -26,7 +26,7 @@ declare module '../../../../src/plugins/share/public' { export const ML_APP_URL_GENERATOR = 'ML_APP_URL_GENERATOR'; -export const ML_TABS = { +export const ML_PAGES = { ANOMALY_DETECTION: 'jobs', ANOMALY_EXPLORER: 'explorer', TIME_SERIES_EXPLORER: 'timeseriesexplorer', @@ -74,7 +74,7 @@ export interface MlIndexBasedSearchState { } export interface MlGenericUrlState extends MlIndexBasedSearchState { - page: typeof ML_TABS.DATA_VISUALIZER_VIEWER | typeof ML_TABS.DATA_VISUALIZER_NEW_JOB; + page: typeof ML_PAGES.DATA_VISUALIZER_VIEWER | typeof ML_PAGES.DATA_VISUALIZER_NEW_JOB; globalState?: MlCommonGlobalState; appState?: MlCommonAppState; [key: string]: any; @@ -86,7 +86,7 @@ export interface AnomalyDetectionQueryState { } export interface AnomalyDetectionUrlState { - page: typeof ML_TABS.ANOMALY_DETECTION; + page: typeof ML_PAGES.ANOMALY_DETECTION; jobId?: JobId; groupIds?: string[]; } @@ -100,7 +100,7 @@ export interface ExplorerUrlState { /** * ML App Page */ - page: typeof ML_TABS.ANOMALY_EXPLORER; + page: typeof ML_PAGES.ANOMALY_EXPLORER; /** * Job IDs */ @@ -150,7 +150,7 @@ export interface TimeSeriesExplorerUrlState /** * ML App Page */ - page: typeof ML_TABS.TIME_SERIES_EXPLORER; + page: typeof ML_PAGES.TIME_SERIES_EXPLORER; jobIds: JobId[]; timeRange?: TimeRange; detectorIndex?: number; @@ -163,14 +163,14 @@ export interface DataFrameAnalyticsQueryState { } export interface DataFrameAnalyticsUrlState extends DataFrameAnalyticsQueryState { - page: typeof ML_TABS.DATA_FRAME_ANALYTICS; + page: typeof ML_PAGES.DATA_FRAME_ANALYTICS; } export interface DataVisualizerUrlState { page: - | typeof ML_TABS.DATA_VISUALIZER - | typeof ML_TABS.DATA_VISUALIZER_FILE - | typeof ML_TABS.DATA_VISUALIZER_INDEX_SELECT; + | typeof ML_PAGES.DATA_VISUALIZER + | typeof ML_PAGES.DATA_VISUALIZER_FILE + | typeof ML_PAGES.DATA_VISUALIZER_INDEX_SELECT; } export interface DataFrameAnalyticsExplorationQueryState { @@ -181,7 +181,7 @@ export interface DataFrameAnalyticsExplorationQueryState { } export interface DataFrameAnalyticsExplorationUrlState { - page: typeof ML_TABS.DATA_FRAME_ANALYTICS_EXPLORATION; + page: typeof ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION; jobId: JobId; analysisType: ANALYSIS_CONFIG_TYPE; } @@ -210,29 +210,29 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition => { switch (mlUrlGeneratorState.page) { - case ML_TABS.ANOMALY_DETECTION: + case ML_PAGES.ANOMALY_DETECTION: return this.createAnomalyDetectionJobManagementUrl( mlUrlGeneratorState as AnomalyDetectionUrlState ); - case ML_TABS.ANOMALY_EXPLORER: + case ML_PAGES.ANOMALY_EXPLORER: return this.createExplorerUrl(mlUrlGeneratorState as ExplorerUrlState); - case ML_TABS.TIME_SERIES_EXPLORER: + case ML_PAGES.TIME_SERIES_EXPLORER: return this.createSingleMetricViewerUrl(mlUrlGeneratorState as TimeSeriesExplorerUrlState); - case ML_TABS.DATA_FRAME_ANALYTICS: + case ML_PAGES.DATA_FRAME_ANALYTICS: return this.createDataframeAnalyticsUrl(mlUrlGeneratorState as DataFrameAnalyticsUrlState); - case ML_TABS.DATA_FRAME_ANALYTICS_EXPLORATION: + case ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION: return this.createDataframeAnalyticsExplorationUrl( mlUrlGeneratorState as DataFrameAnalyticsExplorationUrlState ); - case ML_TABS.DATA_VISUALIZER: + case ML_PAGES.DATA_VISUALIZER: return this.createDataVisualizerUrl(mlUrlGeneratorState as DataVisualizerUrlState); - case ML_TABS.DATA_VISUALIZER_FILE: + case ML_PAGES.DATA_VISUALIZER_FILE: return this.createDataVisualizerUrl(mlUrlGeneratorState as DataVisualizerUrlState); - case ML_TABS.DATA_VISUALIZER_INDEX_SELECT: + case ML_PAGES.DATA_VISUALIZER_INDEX_SELECT: return this.createDataVisualizerUrl(mlUrlGeneratorState as DataVisualizerUrlState); - case ML_TABS.DATA_VISUALIZER_NEW_JOB: + case ML_PAGES.DATA_VISUALIZER_NEW_JOB: return this.createIndexBasedMlUrl(mlUrlGeneratorState as MlGenericUrlState); - case ML_TABS.DATA_VISUALIZER_VIEWER: + case ML_PAGES.DATA_VISUALIZER_VIEWER: return this.createIndexBasedMlUrl(mlUrlGeneratorState as MlGenericUrlState); default: throw new Error('Page type is not provided or unknown'); @@ -252,7 +252,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition(mlUrlGeneratorState); - let url = `${this.params.appBasePath}/${ML_TABS.ANOMALY_DETECTION}`; + let url = `${this.params.appBasePath}/${ML_PAGES.ANOMALY_DETECTION}`; if (isEmpty(params)) { return url; } @@ -282,7 +282,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition = { mlExplorerSwimlane, @@ -329,7 +329,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition( mlUrlGeneratorState ); @@ -405,7 +405,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition( mlUrlGeneratorState ); From 7360f32269904c118c8aad9645bac18bac842059 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Mon, 24 Aug 2020 10:28:18 -0500 Subject: [PATCH 08/29] [ML] Update core API docs --- .../kibana-plugin-plugins-data-public.refreshinterval.md | 1 + .../public/kibana-plugin-plugins-data-public.timerange.md | 2 +- .../kibana-plugin-plugins-data-public.timerange.mode.md | 2 +- .../kibana-plugin-plugins-data-server.refreshinterval.md | 1 + .../server/kibana-plugin-plugins-data-server.timerange.md | 2 +- .../kibana-plugin-plugins-data-server.timerange.mode.md | 2 +- src/plugins/data/public/public.api.md | 4 +++- src/plugins/data/server/server.api.md | 4 +++- 8 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.refreshinterval.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.refreshinterval.md index 6a6350d8ba4f6f..50833d1b615f8f 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.refreshinterval.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.refreshinterval.md @@ -14,6 +14,7 @@ export interface RefreshInterval | Property | Type | Description | | --- | --- | --- | +| [display](./kibana-plugin-plugins-data-public.refreshinterval.display.md) | string | | | [pause](./kibana-plugin-plugins-data-public.refreshinterval.pause.md) | boolean | | | [value](./kibana-plugin-plugins-data-public.refreshinterval.value.md) | number | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.md index 69078ca40d20d2..1a589efeb405d2 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.md @@ -15,6 +15,6 @@ export interface TimeRange | Property | Type | Description | | --- | --- | --- | | [from](./kibana-plugin-plugins-data-public.timerange.from.md) | string | | -| [mode](./kibana-plugin-plugins-data-public.timerange.mode.md) | 'absolute' | 'relative' | | +| [mode](./kibana-plugin-plugins-data-public.timerange.mode.md) | 'absolute' | 'relative' | 'quick' | | | [to](./kibana-plugin-plugins-data-public.timerange.to.md) | string | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.mode.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.mode.md index fb9ebd3c9165f5..9e1f928a282cfe 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.mode.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.mode.md @@ -7,5 +7,5 @@ Signature: ```typescript -mode?: 'absolute' | 'relative'; +mode?: 'absolute' | 'relative' | 'quick'; ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.md index ebb983de299425..28398c449c9d5d 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.md @@ -14,6 +14,7 @@ export interface RefreshInterval | Property | Type | Description | | --- | --- | --- | +| [display](./kibana-plugin-plugins-data-server.refreshinterval.display.md) | string | | | [pause](./kibana-plugin-plugins-data-server.refreshinterval.pause.md) | boolean | | | [value](./kibana-plugin-plugins-data-server.refreshinterval.value.md) | number | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.md index 8280d924eb6097..6181da83e245e0 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.md @@ -15,6 +15,6 @@ export interface TimeRange | Property | Type | Description | | --- | --- | --- | | [from](./kibana-plugin-plugins-data-server.timerange.from.md) | string | | -| [mode](./kibana-plugin-plugins-data-server.timerange.mode.md) | 'absolute' | 'relative' | | +| [mode](./kibana-plugin-plugins-data-server.timerange.mode.md) | 'absolute' | 'relative' | 'quick' | | | [to](./kibana-plugin-plugins-data-server.timerange.to.md) | string | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.mode.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.mode.md index 1408fb43cbf39c..6b1915c1156c94 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.mode.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.mode.md @@ -7,5 +7,5 @@ Signature: ```typescript -mode?: 'absolute' | 'relative'; +mode?: 'absolute' | 'relative' | 'quick'; ``` diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index f8a108a5a4c58f..db9e7f81f269ee 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1607,6 +1607,8 @@ export interface RangeFilterParams { // // @public (undocumented) export interface RefreshInterval { + // (undocumented) + display?: string; // (undocumented) pause: boolean; // (undocumented) @@ -1906,7 +1908,7 @@ export interface TimeRange { // (undocumented) from: string; // (undocumented) - mode?: 'absolute' | 'relative'; + mode?: 'absolute' | 'relative' | 'quick'; // (undocumented) to: string; } diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index f870030ae9562c..e5c9a6b1a2a5ad 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -923,6 +923,8 @@ export interface Query { // // @public (undocumented) export interface RefreshInterval { + // (undocumented) + display?: string; // (undocumented) pause: boolean; // (undocumented) @@ -1009,7 +1011,7 @@ export interface TimeRange { // (undocumented) from: string; // (undocumented) - mode?: 'absolute' | 'relative'; + mode?: 'absolute' | 'relative' | 'quick'; // (undocumented) to: string; } From 7ce5a5b52de9a34867dd896b6aba13bee840a710 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Mon, 24 Aug 2020 10:31:18 -0500 Subject: [PATCH 09/29] [ML] Fix perPartitionStopOnWarn typo --- .../application/jobs/new_job/common/job_creator/job_creator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts index 5894b3acb272dd..4c030a22f54f77 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts @@ -647,7 +647,7 @@ export class JobCreator { return this._job_config.analysis_config.per_partition_categorization?.stop_on_warn === true; } - public set perParttionStopOnWarn(enabled: boolean) { + public set perPartitionStopOnWarn(enabled: boolean) { this._initPerPartitionCategorization(); this._job_config.analysis_config.per_partition_categorization!.stop_on_warn = enabled; } From 8179168feab07b3086bebd638cb14ef54811d297 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Tue, 25 Aug 2020 13:20:26 -0500 Subject: [PATCH 10/29] [ML] Update redirect func name & fix for url with base path --- .../application/contexts/kibana/use_navigate_to_path.ts | 2 +- .../components/view_results_panel/view_results_panel.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/use_navigate_to_path.ts b/x-pack/plugins/ml/public/application/contexts/kibana/use_navigate_to_path.ts index b5ad6e168086b5..96d41be03a142e 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/use_navigate_to_path.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/use_navigate_to_path.ts @@ -28,7 +28,7 @@ export const useNavigateToPath = () => { /** * Handle urls generated by MlUrlGenerator where '/app/ml' is automatically prepended */ - const url = modifiedPath.startsWith('/app/ml') + const url = modifiedPath.includes('/app/ml') ? modifiedPath : getUrlForApp(PLUGIN_ID, { path: modifiedPath, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx index 50af073658ad89..047fb0e08810ed 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx @@ -21,7 +21,7 @@ export const ViewResultsPanel: FC = ({ jobId, analysisType }) => { const urlGenerator = useMlUrlGenerator(); const navigateToPath = useNavigateToPath(); - const redirectToAnalyticsJobPage = async () => { + const redirectToAnalyticsExplorationPage = async () => { const path = await urlGenerator.createUrl({ page: ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION, jobId, @@ -44,7 +44,7 @@ export const ViewResultsPanel: FC = ({ jobId, analysisType }) => { defaultMessage: 'View results for the analytics job.', } )} - onClick={redirectToAnalyticsJobPage} + onClick={redirectToAnalyticsExplorationPage} data-test-subj="analyticsWizardViewResultsCard" /> From c552644af9106cf2d2f18b434f395dc7631e41e4 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Tue, 25 Aug 2020 13:53:15 -0500 Subject: [PATCH 11/29] [ML] Change ml url state types to its own --- .../ml/common/constants/ml_url_generator.ts | 42 ++++ .../ml/common/types/ml_url_generator.ts | 171 +++++++++++++++ .../application/contexts/kibana/index.ts | 2 +- .../contexts/kibana/use_create_url.ts | 3 +- .../view_results_panel/view_results_panel.tsx | 4 +- .../explorer/explorer_dashboard_service.ts | 20 +- .../plugins/ml/public/url_generator.test.ts | 5 +- x-pack/plugins/ml/public/url_generator.ts | 202 ++---------------- 8 files changed, 242 insertions(+), 207 deletions(-) create mode 100644 x-pack/plugins/ml/common/constants/ml_url_generator.ts create mode 100644 x-pack/plugins/ml/common/types/ml_url_generator.ts diff --git a/x-pack/plugins/ml/common/constants/ml_url_generator.ts b/x-pack/plugins/ml/common/constants/ml_url_generator.ts new file mode 100644 index 00000000000000..8e38d4ac1b6516 --- /dev/null +++ b/x-pack/plugins/ml/common/constants/ml_url_generator.ts @@ -0,0 +1,42 @@ +/* + * 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 const ML_APP_URL_GENERATOR = 'ML_APP_URL_GENERATOR'; + +export const ML_PAGES = { + ANOMALY_DETECTION: 'jobs', + ANOMALY_EXPLORER: 'explorer', + TIME_SERIES_EXPLORER: 'timeseriesexplorer', + DATA_FRAME_ANALYTICS: 'data_frame_analytics', + DATA_FRAME_ANALYTICS_EXPLORATION: 'data_frame_analytics/exploration', + /** + * Page: Data Visualizer + */ + DATA_VISUALIZER: 'datavisualizer', + /** + * Page: Data Visualizer + * Create data visualizer by selecting an existing Elasticsearch index + */ + DATA_VISUALIZER_INDEX_SELECT: 'datavisualizer_index_select', + /** + * Page: Data Visualizer + * Create data visualizer by importing log data + */ + DATA_VISUALIZER_FILE: 'filedatavisualizer', + /** + * Page: Data Visualizer + * Create a job from the index pattern + */ + get DATA_VISUALIZER_INDEX_VIEWER() { + return `${this.ANOMALY_DETECTION}/new_job/${this.DATA_VISUALIZER}`; + }, + get DATA_VISUALIZER_NEW_JOB() { + return `${this.ANOMALY_DETECTION}/new_job/step/job_type`; + }, + SETTINGS: 'settings', + CALENDARS: 'settings/calendars_list', + FILTERS: 'settings/filter_lists', +} as const; diff --git a/x-pack/plugins/ml/common/types/ml_url_generator.ts b/x-pack/plugins/ml/common/types/ml_url_generator.ts new file mode 100644 index 00000000000000..af49c0f30f910f --- /dev/null +++ b/x-pack/plugins/ml/common/types/ml_url_generator.ts @@ -0,0 +1,171 @@ +/* + * 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 { RefreshInterval, TimeRange } from '../../../../../src/plugins/data/common/query'; +import { JobId } from '../../../reporting/common/types'; +import { ML_PAGES } from '../constants/ml_url_generator'; + +export const ANALYSIS_CONFIG_TYPE = { + OUTLIER_DETECTION: 'outlier_detection', + REGRESSION: 'regression', + CLASSIFICATION: 'classification', +} as const; + +export interface MlCommonGlobalState { + time?: TimeRange; +} +export interface MlCommonAppState { + [key: string]: any; +} + +export interface MlIndexBasedSearchState { + index?: string; + savedSearchId?: string; +} + +export interface MlGenericUrlState extends MlIndexBasedSearchState { + page: typeof ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER | typeof ML_PAGES.DATA_VISUALIZER_NEW_JOB; + globalState?: MlCommonGlobalState; + appState?: MlCommonAppState; + [key: string]: any; +} + +export interface AnomalyDetectionQueryState { + jobId?: JobId; + groupIds?: string[]; +} + +export interface AnomalyDetectionUrlState { + page: typeof ML_PAGES.ANOMALY_DETECTION; + jobId?: JobId; + groupIds?: string[]; +} + +export interface ExplorerAppState { + mlExplorerSwimlane: { + selectedType?: string; + selectedLanes?: string[]; + selectedTimes?: number[]; + showTopFieldValues?: boolean; + viewByFieldName?: string; + viewByPerPage?: number; + viewByFromPage?: number; + }; + mlExplorerFilter: { + influencersFilterQuery?: unknown; + filterActive?: boolean; + filteredFields?: string[]; + queryString?: string; + }; + query?: any; +} +export interface ExplorerGlobalState { + ml: { jobIds: JobId[] }; + time?: TimeRange; + refreshInterval?: RefreshInterval; +} + +export interface ExplorerUrlState { + /** + * ML App Page + */ + page: typeof ML_PAGES.ANOMALY_EXPLORER; + /** + * Job IDs + */ + jobIds: JobId[]; + /** + * Optionally set the time range in the time picker. + */ + timeRange?: TimeRange; + /** + * Optionally set the refresh interval. + */ + refreshInterval?: RefreshInterval; + /** + * Optionally set the query. + */ + query?: any; + /** + * Optional state for the swim lane + */ + mlExplorerSwimlane?: ExplorerAppState['mlExplorerSwimlane']; + mlExplorerFilter?: ExplorerAppState['mlExplorerFilter']; +} + +export interface TimeSeriesExplorerGlobalState { + ml: { + jobIds: JobId[]; + }; + time?: TimeRange; + refreshInterval?: RefreshInterval; +} + +export interface TimeSeriesExplorerAppState { + zoom?: { + from?: string; + to?: string; + }; + mlTimeSeriesExplorer?: { + detectorIndex?: number; + entities?: Record; + }; + query?: any; +} + +export interface TimeSeriesExplorerUrlState + extends Pick, + Pick { + /** + * ML App Page + */ + page: typeof ML_PAGES.TIME_SERIES_EXPLORER; + jobIds: JobId[]; + timeRange?: TimeRange; + detectorIndex?: number; + entities?: Record; +} + +export interface DataFrameAnalyticsQueryState { + jobId?: JobId | JobId[]; + groupIds?: string[]; +} + +export interface DataFrameAnalyticsUrlState extends DataFrameAnalyticsQueryState { + page: typeof ML_PAGES.DATA_FRAME_ANALYTICS; +} + +export interface DataVisualizerUrlState { + page: + | typeof ML_PAGES.DATA_VISUALIZER + | typeof ML_PAGES.DATA_VISUALIZER_FILE + | typeof ML_PAGES.DATA_VISUALIZER_INDEX_SELECT; +} + +export interface DataFrameAnalyticsExplorationQueryState { + ml: { + jobId: JobId; + analysisType: typeof ANALYSIS_CONFIG_TYPE; + }; +} + +export interface DataFrameAnalyticsExplorationUrlState { + page: typeof ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION; + jobId: JobId; + analysisType: typeof ANALYSIS_CONFIG_TYPE; +} + +/** + * Union type of ML URL state based on page + */ +export type MlUrlGeneratorState = + | AnomalyDetectionUrlState + | ExplorerUrlState + | TimeSeriesExplorerUrlState + | DataFrameAnalyticsUrlState + | DataFrameAnalyticsExplorationUrlState + | DataVisualizerUrlState + | MlGenericUrlState; diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/index.ts b/x-pack/plugins/ml/public/application/contexts/kibana/index.ts index 44979a1b9c60ae..34976074ca0dd5 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/index.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/index.ts @@ -9,4 +9,4 @@ export { useNavigateToPath, NavigateToPath } from './use_navigate_to_path'; export { useUiSettings } from './use_ui_settings_context'; export { useTimefilter } from './use_timefilter'; export { useNotifications } from './use_notifications_context'; -export { useMlUrlGenerator } from './use_create_url'; +export { useMlUrlGenerator, ML_PAGES } from './use_create_url'; diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts b/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts index 1b8f0d1d64bbb5..14eac087e036b4 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts @@ -5,7 +5,7 @@ */ import { useMlKibana } from './kibana_context'; -import { ML_APP_URL_GENERATOR } from '../../../url_generator'; +import { ML_PAGES, ML_APP_URL_GENERATOR } from '../../../../common/constants/ml_url_generator'; export const useMlUrlGenerator = () => { const { @@ -18,3 +18,4 @@ export const useMlUrlGenerator = () => { return getUrlGenerator(ML_APP_URL_GENERATOR); }; +export { ML_PAGES }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx index 047fb0e08810ed..901274683ef2c5 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx @@ -7,11 +7,9 @@ import React, { FC, Fragment } from 'react'; import { EuiCard, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useMlUrlGenerator } from '../../../../../contexts/kibana'; +import { useMlUrlGenerator, ML_PAGES } from '../../../../../contexts/kibana'; import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics'; import { useNavigateToPath } from '../../../../../contexts/kibana'; -import { ML_PAGES } from '../../../../../../url_generator'; - interface Props { jobId: string; analysisType: ANALYSIS_CONFIG_TYPE; diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_dashboard_service.ts b/x-pack/plugins/ml/public/application/explorer/explorer_dashboard_service.ts index 12ec394c668eaa..e0ed2ea6cf5e08 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_dashboard_service.ts +++ b/x-pack/plugins/ml/public/application/explorer/explorer_dashboard_service.ts @@ -21,6 +21,7 @@ import { ExplorerChartsData } from './explorer_charts/explorer_charts_container_ import { EXPLORER_ACTION } from './explorer_constants'; import { AppStateSelectedCells, TimeRangeBounds } from './explorer_utils'; import { explorerReducer, getExplorerDefaultState, ExplorerState } from './reducers'; +import { ExplorerAppState } from '../../../common/types/ml_url_generator'; export const ALLOW_CELL_RANGE_SELECTION = true; @@ -49,25 +50,6 @@ const explorerState$: Observable = explorerFilteredAction$.pipe( shareReplay(1) ); -export interface ExplorerAppState { - mlExplorerSwimlane: { - selectedType?: string; - selectedLanes?: string[]; - selectedTimes?: number[]; - showTopFieldValues?: boolean; - viewByFieldName?: string; - viewByPerPage?: number; - viewByFromPage?: number; - }; - mlExplorerFilter: { - influencersFilterQuery?: unknown; - filterActive?: boolean; - filteredFields?: string[]; - queryString?: string; - }; - query?: any; -} - const explorerAppState$: Observable = explorerState$.pipe( map( (state: ExplorerState): ExplorerAppState => { diff --git a/x-pack/plugins/ml/public/url_generator.test.ts b/x-pack/plugins/ml/public/url_generator.test.ts index e84183d86f2b4b..795a3c14b98aa8 100644 --- a/x-pack/plugins/ml/public/url_generator.test.ts +++ b/x-pack/plugins/ml/public/url_generator.test.ts @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { MlUrlGenerator, ML_PAGES } from './url_generator'; +import { MlUrlGenerator } from './url_generator'; +import { ML_PAGES } from '../common/constants/ml_url_generator'; import { ANALYSIS_CONFIG_TYPE } from './application/data_frame_analytics/common'; describe('MlUrlGenerator', () => { @@ -217,7 +218,7 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Data Visualizer Viewer page', async () => { const url = await urlGenerator.createUrl({ - page: ML_PAGES.DATA_VISUALIZER_VIEWER, + page: ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER, index: '3da93760-e0af-11ea-9ad3-3bcfc330e42a', globalState: { time: { diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index 7976eb0272f7c1..382a9661b30b89 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -11,12 +11,26 @@ import { UrlGeneratorsDefinition, UrlGeneratorState, } from '../../../../src/plugins/share/public'; -import { TimeRange, RefreshInterval } from '../../../../src/plugins/data/public'; import { setStateToKbnUrl } from '../../../../src/plugins/kibana_utils/public'; -import { JobId } from '../../reporting/common/types'; -import { ExplorerAppState } from './application/explorer/explorer_dashboard_service'; import { MlStartDependencies } from './plugin'; -import { ANALYSIS_CONFIG_TYPE } from './application/data_frame_analytics/common'; +import { ML_PAGES, ML_APP_URL_GENERATOR } from '../common/constants/ml_url_generator'; +import { + MlUrlGeneratorState, + AnomalyDetectionUrlState, + ExplorerUrlState, + TimeSeriesExplorerUrlState, + DataFrameAnalyticsUrlState, + DataFrameAnalyticsExplorationUrlState, + DataVisualizerUrlState, + MlGenericUrlState, + AnomalyDetectionQueryState, + ExplorerGlobalState, + TimeSeriesExplorerGlobalState, + TimeSeriesExplorerAppState, + DataFrameAnalyticsExplorationQueryState, + DataFrameAnalyticsQueryState, + ExplorerAppState, +} from '../common/types/ml_url_generator'; declare module '../../../../src/plugins/share/public' { export interface UrlGeneratorStateMapping { @@ -24,180 +38,6 @@ declare module '../../../../src/plugins/share/public' { } } -export const ML_APP_URL_GENERATOR = 'ML_APP_URL_GENERATOR'; - -export const ML_PAGES = { - ANOMALY_DETECTION: 'jobs', - ANOMALY_EXPLORER: 'explorer', - TIME_SERIES_EXPLORER: 'timeseriesexplorer', - DATA_FRAME_ANALYTICS: 'data_frame_analytics', - DATA_FRAME_ANALYTICS_EXPLORATION: 'data_frame_analytics/exploration', - /** - * Page: Data Visualizer - */ - DATA_VISUALIZER: 'datavisualizer', - /** - * Page: Data Visualizer - * Create data visualizer by selecting an existing Elasticsearch index - */ - DATA_VISUALIZER_INDEX_SELECT: 'datavisualizer_index_select', - /** - * Page: Data Visualizer - * Create data visualizer by importing log data - */ - DATA_VISUALIZER_FILE: 'filedatavisualizer', - /** - * Page: Data Visualizer - * Create a job from the index pattern - */ - get DATA_VISUALIZER_VIEWER() { - return `${this.ANOMALY_DETECTION}/new_job/${this.DATA_VISUALIZER}`; - }, - get DATA_VISUALIZER_NEW_JOB() { - return `${this.ANOMALY_DETECTION}/new_job/step/job_type`; - }, - SETTINGS: 'settings', - CALENDARS: 'settings/calendars_list', - FILTERS: 'settings/filter_lists', -} as const; - -export interface MlCommonGlobalState { - time?: TimeRange; -} -export interface MlCommonAppState { - [key: string]: any; -} - -export interface MlIndexBasedSearchState { - index?: string; - savedSearchId?: string; -} - -export interface MlGenericUrlState extends MlIndexBasedSearchState { - page: typeof ML_PAGES.DATA_VISUALIZER_VIEWER | typeof ML_PAGES.DATA_VISUALIZER_NEW_JOB; - globalState?: MlCommonGlobalState; - appState?: MlCommonAppState; - [key: string]: any; -} - -export interface AnomalyDetectionQueryState { - jobId?: JobId; - groupIds?: string[]; -} - -export interface AnomalyDetectionUrlState { - page: typeof ML_PAGES.ANOMALY_DETECTION; - jobId?: JobId; - groupIds?: string[]; -} -export interface ExplorerGlobalState { - ml: { jobIds: JobId[] }; - time?: TimeRange; - refreshInterval?: RefreshInterval; -} - -export interface ExplorerUrlState { - /** - * ML App Page - */ - page: typeof ML_PAGES.ANOMALY_EXPLORER; - /** - * Job IDs - */ - jobIds: JobId[]; - /** - * Optionally set the time range in the time picker. - */ - timeRange?: TimeRange; - /** - * Optionally set the refresh interval. - */ - refreshInterval?: RefreshInterval; - /** - * Optionally set the query. - */ - query?: any; - /** - * Optional state for the swim lane - */ - mlExplorerSwimlane?: ExplorerAppState['mlExplorerSwimlane']; - mlExplorerFilter?: ExplorerAppState['mlExplorerFilter']; -} - -export interface TimeSeriesExplorerGlobalState { - ml: { - jobIds: JobId[]; - }; - time?: TimeRange; - refreshInterval?: RefreshInterval; -} - -export interface TimeSeriesExplorerAppState { - zoom?: { - from?: string; - to?: string; - }; - mlTimeSeriesExplorer?: { - detectorIndex?: number; - entities?: Record; - }; - query?: any; -} - -export interface TimeSeriesExplorerUrlState - extends Pick, - Pick { - /** - * ML App Page - */ - page: typeof ML_PAGES.TIME_SERIES_EXPLORER; - jobIds: JobId[]; - timeRange?: TimeRange; - detectorIndex?: number; - entities?: Record; -} - -export interface DataFrameAnalyticsQueryState { - jobId?: JobId | JobId[]; - groupIds?: string[]; -} - -export interface DataFrameAnalyticsUrlState extends DataFrameAnalyticsQueryState { - page: typeof ML_PAGES.DATA_FRAME_ANALYTICS; -} - -export interface DataVisualizerUrlState { - page: - | typeof ML_PAGES.DATA_VISUALIZER - | typeof ML_PAGES.DATA_VISUALIZER_FILE - | typeof ML_PAGES.DATA_VISUALIZER_INDEX_SELECT; -} - -export interface DataFrameAnalyticsExplorationQueryState { - ml: { - jobId: JobId; - analysisType: ANALYSIS_CONFIG_TYPE; - }; -} - -export interface DataFrameAnalyticsExplorationUrlState { - page: typeof ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION; - jobId: JobId; - analysisType: ANALYSIS_CONFIG_TYPE; -} - -/** - * Union type of ML URL state based on page - */ -export type MlUrlGeneratorState = - | AnomalyDetectionUrlState - | ExplorerUrlState - | TimeSeriesExplorerUrlState - | DataFrameAnalyticsUrlState - | DataFrameAnalyticsExplorationUrlState - | DataVisualizerUrlState - | MlGenericUrlState; - interface Params { appBasePath: string; useHash: boolean; @@ -232,7 +72,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition Date: Tue, 25 Aug 2020 14:03:00 -0500 Subject: [PATCH 12/29] [ML] Change timeseriesexplorer to SINGLE_METRIC_VIEWER --- x-pack/plugins/ml/common/constants/ml_url_generator.ts | 2 +- x-pack/plugins/ml/common/types/ml_url_generator.ts | 2 +- x-pack/plugins/ml/public/url_generator.test.ts | 4 ++-- x-pack/plugins/ml/public/url_generator.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/ml/common/constants/ml_url_generator.ts b/x-pack/plugins/ml/common/constants/ml_url_generator.ts index 8e38d4ac1b6516..59888e1ed411e5 100644 --- a/x-pack/plugins/ml/common/constants/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/constants/ml_url_generator.ts @@ -9,7 +9,7 @@ export const ML_APP_URL_GENERATOR = 'ML_APP_URL_GENERATOR'; export const ML_PAGES = { ANOMALY_DETECTION: 'jobs', ANOMALY_EXPLORER: 'explorer', - TIME_SERIES_EXPLORER: 'timeseriesexplorer', + SINGLE_METRIC_VIEWER: 'timeseriesexplorer', DATA_FRAME_ANALYTICS: 'data_frame_analytics', DATA_FRAME_ANALYTICS_EXPLORATION: 'data_frame_analytics/exploration', /** diff --git a/x-pack/plugins/ml/common/types/ml_url_generator.ts b/x-pack/plugins/ml/common/types/ml_url_generator.ts index af49c0f30f910f..6f33ae275d164a 100644 --- a/x-pack/plugins/ml/common/types/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/types/ml_url_generator.ts @@ -122,7 +122,7 @@ export interface TimeSeriesExplorerUrlState /** * ML App Page */ - page: typeof ML_PAGES.TIME_SERIES_EXPLORER; + page: typeof ML_PAGES.SINGLE_METRIC_VIEWER; jobIds: JobId[]; timeRange?: TimeRange; detectorIndex?: number; diff --git a/x-pack/plugins/ml/public/url_generator.test.ts b/x-pack/plugins/ml/public/url_generator.test.ts index 795a3c14b98aa8..766d8f95add58e 100644 --- a/x-pack/plugins/ml/public/url_generator.test.ts +++ b/x-pack/plugins/ml/public/url_generator.test.ts @@ -101,7 +101,7 @@ describe('MlUrlGenerator', () => { describe('Single Metric Viewer Page', () => { it('should generate valid URL for the Single Metric Viewer page', async () => { const url = await urlGenerator.createUrl({ - page: ML_PAGES.TIME_SERIES_EXPLORER, + page: ML_PAGES.SINGLE_METRIC_VIEWER, jobIds: ['logs_categorization_1'], refreshInterval: { display: 'Off', @@ -125,7 +125,7 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Single Metric Viewer page with extra settings', async () => { const url = await urlGenerator.createUrl({ - page: ML_PAGES.TIME_SERIES_EXPLORER, + page: ML_PAGES.SINGLE_METRIC_VIEWER, jobIds: ['logs_categorization_1'], detectorIndex: 0, entities: { mlcategory: '2' }, diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index 382a9661b30b89..03fbdb17a0f583 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -56,7 +56,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition Date: Tue, 25 Aug 2020 14:07:42 -0500 Subject: [PATCH 13/29] [ML] Rename/update descriptions - ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE --- x-pack/plugins/ml/common/constants/ml_url_generator.ts | 8 ++++---- x-pack/plugins/ml/common/types/ml_url_generator.ts | 4 +++- x-pack/plugins/ml/public/url_generator.test.ts | 10 +++++----- x-pack/plugins/ml/public/url_generator.ts | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/ml/common/constants/ml_url_generator.ts b/x-pack/plugins/ml/common/constants/ml_url_generator.ts index 59888e1ed411e5..00c978e74860bb 100644 --- a/x-pack/plugins/ml/common/constants/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/constants/ml_url_generator.ts @@ -18,22 +18,22 @@ export const ML_PAGES = { DATA_VISUALIZER: 'datavisualizer', /** * Page: Data Visualizer - * Create data visualizer by selecting an existing Elasticsearch index + * Open data visualizer by selecting a Kibana index pattern or saved search */ DATA_VISUALIZER_INDEX_SELECT: 'datavisualizer_index_select', /** * Page: Data Visualizer - * Create data visualizer by importing log data + * Open data visualizer by importing data from a log file */ DATA_VISUALIZER_FILE: 'filedatavisualizer', /** * Page: Data Visualizer - * Create a job from the index pattern + * Open index data visualizer viewer page */ get DATA_VISUALIZER_INDEX_VIEWER() { return `${this.ANOMALY_DETECTION}/new_job/${this.DATA_VISUALIZER}`; }, - get DATA_VISUALIZER_NEW_JOB() { + get ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE() { return `${this.ANOMALY_DETECTION}/new_job/step/job_type`; }, SETTINGS: 'settings', diff --git a/x-pack/plugins/ml/common/types/ml_url_generator.ts b/x-pack/plugins/ml/common/types/ml_url_generator.ts index 6f33ae275d164a..cf065ecfb0bb31 100644 --- a/x-pack/plugins/ml/common/types/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/types/ml_url_generator.ts @@ -27,7 +27,9 @@ export interface MlIndexBasedSearchState { } export interface MlGenericUrlState extends MlIndexBasedSearchState { - page: typeof ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER | typeof ML_PAGES.DATA_VISUALIZER_NEW_JOB; + page: + | typeof ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER + | typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE; globalState?: MlCommonGlobalState; appState?: MlCommonAppState; [key: string]: any; diff --git a/x-pack/plugins/ml/public/url_generator.test.ts b/x-pack/plugins/ml/public/url_generator.test.ts index 766d8f95add58e..df886caa0194dd 100644 --- a/x-pack/plugins/ml/public/url_generator.test.ts +++ b/x-pack/plugins/ml/public/url_generator.test.ts @@ -39,9 +39,9 @@ describe('MlUrlGenerator', () => { expect(url).toBe('/app/ml/jobs?mlManagement=(groupIds:!(farequote,categorization))'); }); - it('should generate valid URL for the Data Visualizer Viewer page', async () => { + it('should generate valid URL for the page for selecting the type of anomaly detection job to create', async () => { const url = await urlGenerator.createUrl({ - page: ML_PAGES.DATA_VISUALIZER_NEW_JOB, + page: ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE, index: `3da93760-e0af-11ea-9ad3-3bcfc330e42a`, globalState: { time: { @@ -202,21 +202,21 @@ describe('MlUrlGenerator', () => { expect(url).toBe('/app/ml/datavisualizer'); }); - it('should generate valid URL for the Data Visualizer import file page', async () => { + it('should generate valid URL for the File Data Visualizer import page', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.DATA_VISUALIZER_FILE, }); expect(url).toBe('/app/ml/filedatavisualizer'); }); - it('should generate valid URL for the Data Visualizer import by index page', async () => { + it('should generate valid URL for the Index Data Visualizer select index pattern or saved search page', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.DATA_VISUALIZER_INDEX_SELECT, }); expect(url).toBe('/app/ml/datavisualizer_index_select'); }); - it('should generate valid URL for the Data Visualizer Viewer page', async () => { + it('should generate valid URL for the Index Data Visualizer Viewer page', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER, index: '3da93760-e0af-11ea-9ad3-3bcfc330e42a', diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index 03fbdb17a0f583..3fdddb2c811fa8 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -70,7 +70,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition Date: Tue, 25 Aug 2020 14:09:26 -0500 Subject: [PATCH 14/29] [ML] Update calendar and filter manage --- x-pack/plugins/ml/common/constants/ml_url_generator.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ml/common/constants/ml_url_generator.ts b/x-pack/plugins/ml/common/constants/ml_url_generator.ts index 00c978e74860bb..f3d26dd7163b02 100644 --- a/x-pack/plugins/ml/common/constants/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/constants/ml_url_generator.ts @@ -37,6 +37,6 @@ export const ML_PAGES = { return `${this.ANOMALY_DETECTION}/new_job/step/job_type`; }, SETTINGS: 'settings', - CALENDARS: 'settings/calendars_list', - FILTERS: 'settings/filter_lists', + CALENDARS_MANAGE: 'settings/calendars_list', + FILTER_LISTS_MANAGE: 'settings/filter_lists', } as const; From 60d6799ffea948f9f31187805fd40729c2088544 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Tue, 25 Aug 2020 14:17:44 -0500 Subject: [PATCH 15/29] [ML] Rename ANOMALY_DETECTION -> ANOMALY_DETECTION_JOBS_MANAGE --- x-pack/plugins/ml/common/constants/ml_url_generator.ts | 6 +++--- x-pack/plugins/ml/common/types/ml_url_generator.ts | 2 +- .../components/back_to_list_panel/back_to_list_panel.tsx | 3 +-- x-pack/plugins/ml/public/url_generator.test.ts | 6 +++--- x-pack/plugins/ml/public/url_generator.ts | 4 ++-- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/ml/common/constants/ml_url_generator.ts b/x-pack/plugins/ml/common/constants/ml_url_generator.ts index f3d26dd7163b02..c96f4e87e60490 100644 --- a/x-pack/plugins/ml/common/constants/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/constants/ml_url_generator.ts @@ -7,7 +7,7 @@ export const ML_APP_URL_GENERATOR = 'ML_APP_URL_GENERATOR'; export const ML_PAGES = { - ANOMALY_DETECTION: 'jobs', + ANOMALY_DETECTION_JOBS_MANAGE: 'jobs', ANOMALY_EXPLORER: 'explorer', SINGLE_METRIC_VIEWER: 'timeseriesexplorer', DATA_FRAME_ANALYTICS: 'data_frame_analytics', @@ -31,10 +31,10 @@ export const ML_PAGES = { * Open index data visualizer viewer page */ get DATA_VISUALIZER_INDEX_VIEWER() { - return `${this.ANOMALY_DETECTION}/new_job/${this.DATA_VISUALIZER}`; + return `jobs/new_job/${this.DATA_VISUALIZER}`; }, get ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE() { - return `${this.ANOMALY_DETECTION}/new_job/step/job_type`; + return `jobs/new_job/step/job_type`; }, SETTINGS: 'settings', CALENDARS_MANAGE: 'settings/calendars_list', diff --git a/x-pack/plugins/ml/common/types/ml_url_generator.ts b/x-pack/plugins/ml/common/types/ml_url_generator.ts index cf065ecfb0bb31..dbc7cbe8d54e83 100644 --- a/x-pack/plugins/ml/common/types/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/types/ml_url_generator.ts @@ -41,7 +41,7 @@ export interface AnomalyDetectionQueryState { } export interface AnomalyDetectionUrlState { - page: typeof ML_PAGES.ANOMALY_DETECTION; + page: typeof ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE; jobId?: JobId; groupIds?: string[]; } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx index b8e0cddf0cc3b5..cd57ee0c46b6ff 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx @@ -7,8 +7,7 @@ import React, { FC, Fragment } from 'react'; import { EuiCard, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useMlKibana, useMlUrlGenerator } from '../../../../../contexts/kibana'; -import { ML_PAGES } from '../../../../../../url_generator'; +import { useMlKibana, useMlUrlGenerator, ML_PAGES } from '../../../../../contexts/kibana'; export const BackToListPanel: FC = () => { const urlGenerator = useMlUrlGenerator(); diff --git a/x-pack/plugins/ml/public/url_generator.test.ts b/x-pack/plugins/ml/public/url_generator.test.ts index df886caa0194dd..7ab62138a8439d 100644 --- a/x-pack/plugins/ml/public/url_generator.test.ts +++ b/x-pack/plugins/ml/public/url_generator.test.ts @@ -18,14 +18,14 @@ describe('MlUrlGenerator', () => { describe('Job Management Page', () => { it('should generate valid URL for the Anomaly Detection job management page', async () => { const url = await urlGenerator.createUrl({ - page: ML_PAGES.ANOMALY_DETECTION, + page: ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE, }); expect(url).toBe('/app/ml/jobs'); }); it('should generate valid URL for the Anomaly Detection job management page for job', async () => { const url = await urlGenerator.createUrl({ - page: ML_PAGES.ANOMALY_DETECTION, + page: ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE, jobId: 'fq_single_1', }); expect(url).toBe('/app/ml/jobs?mlManagement=(jobId:fq_single_1)'); @@ -33,7 +33,7 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Anomaly Detection job management page for groupIds', async () => { const url = await urlGenerator.createUrl({ - page: ML_PAGES.ANOMALY_DETECTION, + page: ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE, groupIds: ['farequote', 'categorization'], }); expect(url).toBe('/app/ml/jobs?mlManagement=(groupIds:!(farequote,categorization))'); diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index 3fdddb2c811fa8..4b750744a3a59a 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -50,7 +50,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition => { switch (mlUrlGeneratorState.page) { - case ML_PAGES.ANOMALY_DETECTION: + case ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE: return this.createAnomalyDetectionJobManagementUrl( mlUrlGeneratorState as AnomalyDetectionUrlState ); @@ -92,7 +92,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition(mlUrlGeneratorState); - let url = `${this.params.appBasePath}/${ML_PAGES.ANOMALY_DETECTION}`; + let url = `${this.params.appBasePath}/${ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE}`; if (isEmpty(params)) { return url; } From 18b909396dd9bddc539f2dad95c481bf2462d8eb Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Tue, 25 Aug 2020 14:20:35 -0500 Subject: [PATCH 16/29] [ML] Rename DATA_FRAME_ANALYTICS -> DATA_FRAME_ANALYTICS_JOBS_MANAGE --- x-pack/plugins/ml/common/constants/ml_url_generator.ts | 2 +- x-pack/plugins/ml/common/types/ml_url_generator.ts | 2 +- .../components/back_to_list_panel/back_to_list_panel.tsx | 2 +- x-pack/plugins/ml/public/url_generator.test.ts | 6 +++--- x-pack/plugins/ml/public/url_generator.ts | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/ml/common/constants/ml_url_generator.ts b/x-pack/plugins/ml/common/constants/ml_url_generator.ts index c96f4e87e60490..18e9d5ec1ecefd 100644 --- a/x-pack/plugins/ml/common/constants/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/constants/ml_url_generator.ts @@ -10,7 +10,7 @@ export const ML_PAGES = { ANOMALY_DETECTION_JOBS_MANAGE: 'jobs', ANOMALY_EXPLORER: 'explorer', SINGLE_METRIC_VIEWER: 'timeseriesexplorer', - DATA_FRAME_ANALYTICS: 'data_frame_analytics', + DATA_FRAME_ANALYTICS_JOBS_MANAGE: 'data_frame_analytics', DATA_FRAME_ANALYTICS_EXPLORATION: 'data_frame_analytics/exploration', /** * Page: Data Visualizer diff --git a/x-pack/plugins/ml/common/types/ml_url_generator.ts b/x-pack/plugins/ml/common/types/ml_url_generator.ts index dbc7cbe8d54e83..7b8f6800484a2e 100644 --- a/x-pack/plugins/ml/common/types/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/types/ml_url_generator.ts @@ -137,7 +137,7 @@ export interface DataFrameAnalyticsQueryState { } export interface DataFrameAnalyticsUrlState extends DataFrameAnalyticsQueryState { - page: typeof ML_PAGES.DATA_FRAME_ANALYTICS; + page: typeof ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE; } export interface DataVisualizerUrlState { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx index cd57ee0c46b6ff..403e521ad93aa6 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx @@ -18,7 +18,7 @@ export const BackToListPanel: FC = () => { } = useMlKibana(); const redirectToAnalyticsManagementPage = async () => { - const url = await urlGenerator.createUrl({ page: ML_PAGES.DATA_FRAME_ANALYTICS }); + const url = await urlGenerator.createUrl({ page: ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE }); await navigateToUrl(url); }; diff --git a/x-pack/plugins/ml/public/url_generator.test.ts b/x-pack/plugins/ml/public/url_generator.test.ts index 7ab62138a8439d..a82c98994d9a52 100644 --- a/x-pack/plugins/ml/public/url_generator.test.ts +++ b/x-pack/plugins/ml/public/url_generator.test.ts @@ -159,13 +159,13 @@ describe('MlUrlGenerator', () => { describe('JobManagement Page', () => { it('should generate valid URL for the Data Frame Analytics job management page', async () => { const url = await urlGenerator.createUrl({ - page: ML_PAGES.DATA_FRAME_ANALYTICS, + page: ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE, }); expect(url).toBe('/app/ml/data_frame_analytics'); }); it('should generate valid URL for the Data Frame Analytics job management page with jobId', async () => { const url = await urlGenerator.createUrl({ - page: ML_PAGES.DATA_FRAME_ANALYTICS, + page: ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE, jobId: 'grid_regression_1', }); expect(url).toBe('/app/ml/data_frame_analytics?mlManagement=(jobId:grid_regression_1)'); @@ -173,7 +173,7 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Data Frame Analytics job management page with groupIds', async () => { const url = await urlGenerator.createUrl({ - page: ML_PAGES.DATA_FRAME_ANALYTICS, + page: ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE, groupIds: ['group_1', 'group_2'], }); expect(url).toBe('/app/ml/data_frame_analytics?mlManagement=(groupIds:!(group_1,group_2))'); diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index 4b750744a3a59a..1c9e15a56dc506 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -58,7 +58,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition( mlUrlGeneratorState ); From b7f1920ccef491b3881dfbf5a50e57b4949a85bd Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Tue, 25 Aug 2020 14:29:58 -0500 Subject: [PATCH 17/29] [ML] Update imports after moving --- .../plugins/ml/public/application/routing/routes/explorer.tsx | 3 ++- .../ml/public/ui_actions/open_in_anomaly_explorer_action.tsx | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ml/public/application/routing/routes/explorer.tsx b/x-pack/plugins/ml/public/application/routing/routes/explorer.tsx index 62d7e82a214b57..2f2fc77283ef79 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/explorer.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/explorer.tsx @@ -22,7 +22,8 @@ import { useSelectedCells } from '../../explorer/hooks/use_selected_cells'; import { mlJobService } from '../../services/job_service'; import { ml } from '../../services/ml_api_service'; import { useExplorerData } from '../../explorer/actions'; -import { ExplorerAppState, explorerService } from '../../explorer/explorer_dashboard_service'; +import { ExplorerAppState } from '../../../../common/types/ml_url_generator'; +import { explorerService } from '../../explorer/explorer_dashboard_service'; import { getDateFormatTz } from '../../explorer/explorer_utils'; import { useJobSelection } from '../../components/job_selector/use_job_selection'; import { useShowCharts } from '../../components/controls/checkbox_showcharts'; diff --git a/x-pack/plugins/ml/public/ui_actions/open_in_anomaly_explorer_action.tsx b/x-pack/plugins/ml/public/ui_actions/open_in_anomaly_explorer_action.tsx index e327befcf72938..eb3a6e648385a0 100644 --- a/x-pack/plugins/ml/public/ui_actions/open_in_anomaly_explorer_action.tsx +++ b/x-pack/plugins/ml/public/ui_actions/open_in_anomaly_explorer_action.tsx @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import { ActionContextMapping, createAction } from '../../../../../src/plugins/ui_actions/public'; import { MlCoreSetup } from '../plugin'; -import { ML_APP_URL_GENERATOR } from '../url_generator'; +import { ML_APP_URL_GENERATOR } from '../../common/constants/ml_url_generator'; import { ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, SwimLaneDrilldownContext } from '../embeddables'; export const OPEN_IN_ANOMALY_EXPLORER_ACTION = 'openInAnomalyExplorerAction'; From b7cd7fde06963af9c313b9d042e78b4264364736 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Tue, 25 Aug 2020 14:33:27 -0500 Subject: [PATCH 18/29] [ML] Update import from file instead of from context --- x-pack/plugins/ml/public/application/contexts/kibana/index.ts | 2 +- .../ml/public/application/contexts/kibana/use_create_url.ts | 3 +-- .../components/back_to_list_panel/back_to_list_panel.tsx | 3 ++- .../components/view_results_panel/view_results_panel.tsx | 3 ++- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/index.ts b/x-pack/plugins/ml/public/application/contexts/kibana/index.ts index 34976074ca0dd5..44979a1b9c60ae 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/index.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/index.ts @@ -9,4 +9,4 @@ export { useNavigateToPath, NavigateToPath } from './use_navigate_to_path'; export { useUiSettings } from './use_ui_settings_context'; export { useTimefilter } from './use_timefilter'; export { useNotifications } from './use_notifications_context'; -export { useMlUrlGenerator, ML_PAGES } from './use_create_url'; +export { useMlUrlGenerator } from './use_create_url'; diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts b/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts index 14eac087e036b4..48385ad3ae6a82 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/use_create_url.ts @@ -5,7 +5,7 @@ */ import { useMlKibana } from './kibana_context'; -import { ML_PAGES, ML_APP_URL_GENERATOR } from '../../../../common/constants/ml_url_generator'; +import { ML_APP_URL_GENERATOR } from '../../../../common/constants/ml_url_generator'; export const useMlUrlGenerator = () => { const { @@ -18,4 +18,3 @@ export const useMlUrlGenerator = () => { return getUrlGenerator(ML_APP_URL_GENERATOR); }; -export { ML_PAGES }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx index 403e521ad93aa6..0560c3150a424c 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx @@ -7,7 +7,8 @@ import React, { FC, Fragment } from 'react'; import { EuiCard, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useMlKibana, useMlUrlGenerator, ML_PAGES } from '../../../../../contexts/kibana'; +import { useMlKibana, useMlUrlGenerator } from '../../../../../contexts/kibana'; +import { ML_PAGES } from '../../../../../../../common/constants/ml_url_generator'; export const BackToListPanel: FC = () => { const urlGenerator = useMlUrlGenerator(); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx index 901274683ef2c5..586834b3f7c938 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx @@ -7,8 +7,9 @@ import React, { FC, Fragment } from 'react'; import { EuiCard, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useMlUrlGenerator, ML_PAGES } from '../../../../../contexts/kibana'; +import { useMlUrlGenerator } from '../../../../../contexts/kibana'; import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics'; +import { ML_PAGES } from '../../../../../../../common/constants/ml_url_generator'; import { useNavigateToPath } from '../../../../../contexts/kibana'; interface Props { jobId: string; From 49e56edc23a2a9ddc12e9145add11bba8f2b2e7f Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Tue, 25 Aug 2020 14:39:42 -0500 Subject: [PATCH 19/29] [ML] Have dedicated functions for createIndexDataVisualizerUrl and createAnomalyDetectionCreatJobSelectType --- x-pack/plugins/ml/public/url_generator.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index 1c9e15a56dc506..2ef0c7208dc093 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -56,6 +56,10 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition Date: Tue, 25 Aug 2020 15:15:39 -0500 Subject: [PATCH 20/29] [ML] Remove hash based path in initSampleDataSets --- .../ml/server/lib/sample_data_sets/sample_data_sets.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ml/server/lib/sample_data_sets/sample_data_sets.ts b/x-pack/plugins/ml/server/lib/sample_data_sets/sample_data_sets.ts index 902cc907a0eff1..28f12ead7924ba 100644 --- a/x-pack/plugins/ml/server/lib/sample_data_sets/sample_data_sets.ts +++ b/x-pack/plugins/ml/server/lib/sample_data_sets/sample_data_sets.ts @@ -18,7 +18,7 @@ export function initSampleDataSets(mlLicense: MlLicense, plugins: PluginsSetup) addAppLinksToSampleDataset('ecommerce', [ { path: - '/app/ml#/modules/check_view_or_create?id=sample_data_ecommerce&index=ff959d40-b880-11e8-a6d9-e546fe2bba5f', + '/app/ml/modules/check_view_or_create?id=sample_data_ecommerce&index=ff959d40-b880-11e8-a6d9-e546fe2bba5f', label: sampleDataLinkLabel, icon: 'machineLearningApp', }, @@ -27,7 +27,7 @@ export function initSampleDataSets(mlLicense: MlLicense, plugins: PluginsSetup) addAppLinksToSampleDataset('logs', [ { path: - '/app/ml#/modules/check_view_or_create?id=sample_data_weblogs&index=90943e30-9a47-11e8-b64d-95841ca0b247', + '/app/ml/modules/check_view_or_create?id=sample_data_weblogs&index=90943e30-9a47-11e8-b64d-95841ca0b247', label: sampleDataLinkLabel, icon: 'machineLearningApp', }, From 4d6a5a0e30e0046121d1febced6b0399da72b25a Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Mon, 31 Aug 2020 15:55:40 -0500 Subject: [PATCH 21/29] [ML] Refactor to own folder --- .../anomaly_detection_urls_generator.ts | 159 ++++++++ .../ml/public/ml_url_generator/common.ts | 54 +++ .../data_visualizer_urls_generator.ts | 28 ++ .../dataframe_analytics_urls_generator.ts | 74 ++++ .../ml/public/ml_url_generator/index.ts | 6 + .../ml_url_generator.test.ts} | 6 +- .../ml_url_generator/ml_url_generator.ts | 112 ++++++ x-pack/plugins/ml/public/plugin.ts | 2 +- x-pack/plugins/ml/public/url_generator.ts | 341 ------------------ 9 files changed, 437 insertions(+), 345 deletions(-) create mode 100644 x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts create mode 100644 x-pack/plugins/ml/public/ml_url_generator/common.ts create mode 100644 x-pack/plugins/ml/public/ml_url_generator/data_visualizer_urls_generator.ts create mode 100644 x-pack/plugins/ml/public/ml_url_generator/dataframe_analytics_urls_generator.ts create mode 100644 x-pack/plugins/ml/public/ml_url_generator/index.ts rename x-pack/plugins/ml/public/{url_generator.test.ts => ml_url_generator/ml_url_generator.test.ts} (97%) create mode 100644 x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts delete mode 100644 x-pack/plugins/ml/public/url_generator.ts diff --git a/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts new file mode 100644 index 00000000000000..4aa7266398c5b8 --- /dev/null +++ b/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts @@ -0,0 +1,159 @@ +/* + * 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 isEmpty from 'lodash/isEmpty'; +import { + AnomalyDetectionQueryState, + AnomalyDetectionUrlState, + ExplorerAppState, + ExplorerGlobalState, + ExplorerUrlState, + MlGenericUrlState, + TimeSeriesExplorerAppState, + TimeSeriesExplorerGlobalState, + TimeSeriesExplorerUrlState, +} from '../../common/types/ml_url_generator'; +import { ML_PAGES } from '../../common/constants/ml_url_generator'; +import { extractParams, createIndexBasedMlUrl } from './common'; +import { setStateToKbnUrl } from '../../../../../src/plugins/kibana_utils/public'; +/** + * Creates URL to the Anomaly Detection Job management page + */ +export function createAnomalyDetectionJobManagementUrl( + appBasePath: string, + mlUrlGeneratorState: AnomalyDetectionUrlState +): string { + const { params } = extractParams(mlUrlGeneratorState); + let url = `${appBasePath}/${ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE}`; + if (isEmpty(params)) { + return url; + } + const { jobId, groupIds } = params; + const queryState: AnomalyDetectionQueryState = { + jobId, + groupIds, + }; + + url = setStateToKbnUrl( + 'mlManagement', + queryState, + { useHash: false, storeInHashQuery: false }, + url + ); + return url; +} + +export function createAnomalyDetectionCreatJobSelectType( + appBasePath: string, + mlGenericUrlState: MlGenericUrlState +): string { + return createIndexBasedMlUrl(appBasePath, mlGenericUrlState); +} + +/** + * Creates URL to the Anomaly Explorer page + */ +export function createExplorerUrl( + appBasePath: string, + { + refreshInterval, + timeRange, + jobIds, + query, + mlExplorerSwimlane = {}, + mlExplorerFilter = {}, + }: ExplorerUrlState +): string { + let url = `${appBasePath}/${ML_PAGES.ANOMALY_EXPLORER}`; + + const appState: Partial = { + mlExplorerSwimlane, + mlExplorerFilter, + }; + if (query) appState.query = query; + + if (jobIds) { + const queryState: Partial = { + ml: { + jobIds, + }, + }; + + if (timeRange) queryState.time = timeRange; + if (refreshInterval) queryState.refreshInterval = refreshInterval; + + url = setStateToKbnUrl>( + '_g', + queryState, + { useHash: false, storeInHashQuery: false }, + url + ); + url = setStateToKbnUrl>( + '_a', + appState, + { useHash: false, storeInHashQuery: false }, + url + ); + } + + return url; +} + +/** + * Creates URL to the SingleMetricViewer page + */ +export function createSingleMetricViewerUrl( + appBasePath: string, + { + timeRange, + jobIds, + refreshInterval, + zoom, + query, + detectorIndex, + entities, + }: TimeSeriesExplorerUrlState +): string { + let url = `${appBasePath}/${ML_PAGES.SINGLE_METRIC_VIEWER}`; + const queryState: TimeSeriesExplorerGlobalState = { + ml: { + jobIds, + }, + refreshInterval, + time: timeRange, + }; + + const appState: Partial = {}; + const mlTimeSeriesExplorer: Partial = {}; + + if (detectorIndex !== undefined) { + mlTimeSeriesExplorer.detectorIndex = detectorIndex; + } + if (entities !== undefined) { + mlTimeSeriesExplorer.entities = entities; + } + appState.mlTimeSeriesExplorer = mlTimeSeriesExplorer; + + if (zoom) appState.zoom = zoom; + if (query) + appState.query = { + query_string: query, + }; + url = setStateToKbnUrl( + '_g', + queryState, + { useHash: false, storeInHashQuery: false }, + url + ); + url = setStateToKbnUrl( + '_a', + appState, + { useHash: false, storeInHashQuery: false }, + url + ); + + return url; +} diff --git a/x-pack/plugins/ml/public/ml_url_generator/common.ts b/x-pack/plugins/ml/public/ml_url_generator/common.ts new file mode 100644 index 00000000000000..34a7fac9c305f4 --- /dev/null +++ b/x-pack/plugins/ml/public/ml_url_generator/common.ts @@ -0,0 +1,54 @@ +/* + * 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 isEmpty from 'lodash/isEmpty'; +import { MlGenericUrlState } from '../../common/types/ml_url_generator'; +import { setStateToKbnUrl } from '../../../../../src/plugins/kibana_utils/public'; + +export function extractParams(urlState: UrlState) { + // page should be guaranteed to exist here but is unknown + // @ts-ignore + const { page, ...params } = urlState; + return { page, params }; +} + +/** + * Creates generic index based search ML url + * e.g. `jobs/new_job/datavisualizer?index=3da93760-e0af-11ea-9ad3-3bcfc330e42a` + */ +export function createIndexBasedMlUrl( + appBasePath: string, + mlGenericUrlState: MlGenericUrlState +): string { + const { globalState, appState, page, index, savedSearchId, ...restParams } = mlGenericUrlState; + let url = `${appBasePath}/${page}`; + + if (index !== undefined && savedSearchId === undefined) { + url = `${url}?index=${index}`; + } + if (index === undefined && savedSearchId !== undefined) { + url = `${url}?savedSearchId=${savedSearchId}`; + } + + if (!isEmpty(restParams)) { + Object.keys(restParams).forEach((key) => { + url = setStateToKbnUrl( + key, + restParams[key], + { useHash: false, storeInHashQuery: false }, + url + ); + }); + } + + if (globalState) { + url = setStateToKbnUrl('_g', globalState, { useHash: false, storeInHashQuery: false }, url); + } + if (appState) { + url = setStateToKbnUrl('_a', appState, { useHash: false, storeInHashQuery: false }, url); + } + return url; +} diff --git a/x-pack/plugins/ml/public/ml_url_generator/data_visualizer_urls_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/data_visualizer_urls_generator.ts new file mode 100644 index 00000000000000..15d932c8c2f86c --- /dev/null +++ b/x-pack/plugins/ml/public/ml_url_generator/data_visualizer_urls_generator.ts @@ -0,0 +1,28 @@ +/* + * 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. + */ + +/** + * Creates URL to the Data Visualizer page + */ +import { DataVisualizerUrlState, MlGenericUrlState } from '../../common/types/ml_url_generator'; +import { createIndexBasedMlUrl } from './common'; + +export function createDataVisualizerUrl( + appBasePath: string, + { page }: DataVisualizerUrlState +): string { + return `${appBasePath}/${page}`; +} + +/** + * Creates URL to the Index Data Visualizer + */ +export function createIndexDataVisualizerUrl( + appBasePath: string, + mlGenericUrlState: MlGenericUrlState +): string { + return createIndexBasedMlUrl(appBasePath, mlGenericUrlState); +} diff --git a/x-pack/plugins/ml/public/ml_url_generator/dataframe_analytics_urls_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/dataframe_analytics_urls_generator.ts new file mode 100644 index 00000000000000..9d8c8057adb6fd --- /dev/null +++ b/x-pack/plugins/ml/public/ml_url_generator/dataframe_analytics_urls_generator.ts @@ -0,0 +1,74 @@ +/* + * 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. + */ + +/** + * Creates URL to the DataFrameAnalytics page + */ +import isEmpty from 'lodash/isEmpty'; +import { + DataFrameAnalyticsExplorationQueryState, + DataFrameAnalyticsExplorationUrlState, + DataFrameAnalyticsQueryState, + DataFrameAnalyticsUrlState, +} from '../../common/types/ml_url_generator'; +import { ML_PAGES } from '../../common/constants/ml_url_generator'; +import { extractParams } from './common'; +import { setStateToKbnUrl } from '../../../../../src/plugins/kibana_utils/public'; + +export function createDataframeAnalyticsUrl( + appBasePath: string, + mlUrlGeneratorState: DataFrameAnalyticsUrlState +): string { + let url = `${appBasePath}/${ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE}`; + const { params } = extractParams(mlUrlGeneratorState); + + if (!isEmpty(params)) { + const { jobId, groupIds } = params; + const queryState: Partial = { + jobId, + groupIds, + }; + + url = setStateToKbnUrl>( + 'mlManagement', + queryState, + { useHash: false, storeInHashQuery: false }, + url + ); + } + + return url; +} + +/** + * Creates URL to the DataFrameAnalytics Exploration page + */ +export function createDataframeAnalyticsExplorationUrl( + appBasePath: string, + mlUrlGeneratorState: DataFrameAnalyticsExplorationUrlState +): string { + let url = `${appBasePath}/${ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION}`; + const { params } = extractParams(mlUrlGeneratorState); + + if (!isEmpty(params)) { + const { jobId, analysisType } = params; + const queryState: DataFrameAnalyticsExplorationQueryState = { + ml: { + jobId, + analysisType, + }, + }; + + url = setStateToKbnUrl( + '_g', + queryState, + { useHash: false, storeInHashQuery: false }, + url + ); + } + + return url; +} diff --git a/x-pack/plugins/ml/public/ml_url_generator/index.ts b/x-pack/plugins/ml/public/ml_url_generator/index.ts new file mode 100644 index 00000000000000..1579b187278c4f --- /dev/null +++ b/x-pack/plugins/ml/public/ml_url_generator/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 { MlUrlGenerator, registerUrlGenerator } from './ml_url_generator'; diff --git a/x-pack/plugins/ml/public/url_generator.test.ts b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.test.ts similarity index 97% rename from x-pack/plugins/ml/public/url_generator.test.ts rename to x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.test.ts index a82c98994d9a52..68b222c7cd4891 100644 --- a/x-pack/plugins/ml/public/url_generator.test.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.test.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { MlUrlGenerator } from './url_generator'; -import { ML_PAGES } from '../common/constants/ml_url_generator'; -import { ANALYSIS_CONFIG_TYPE } from './application/data_frame_analytics/common'; +import { MlUrlGenerator } from './ml_url_generator'; +import { ML_PAGES } from '../../common/constants/ml_url_generator'; +import { ANALYSIS_CONFIG_TYPE } from '../application/data_frame_analytics/common'; describe('MlUrlGenerator', () => { const urlGenerator = new MlUrlGenerator({ diff --git a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts new file mode 100644 index 00000000000000..40ae58651bb2a7 --- /dev/null +++ b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts @@ -0,0 +1,112 @@ +/* + * 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 { CoreSetup } from 'kibana/public'; +import { + SharePluginSetup, + UrlGeneratorsDefinition, + UrlGeneratorState, +} from '../../../../../src/plugins/share/public'; +import { MlStartDependencies } from '../plugin'; +import { ML_PAGES, ML_APP_URL_GENERATOR } from '../../common/constants/ml_url_generator'; +import { + MlUrlGeneratorState, + AnomalyDetectionUrlState, + ExplorerUrlState, + TimeSeriesExplorerUrlState, + DataFrameAnalyticsUrlState, + DataFrameAnalyticsExplorationUrlState, + DataVisualizerUrlState, + MlGenericUrlState, +} from '../../common/types/ml_url_generator'; +import { + createAnomalyDetectionJobManagementUrl, + createAnomalyDetectionCreatJobSelectType, + createExplorerUrl, + createSingleMetricViewerUrl, +} from './anomaly_detection_urls_generator'; +import { + createDataframeAnalyticsUrl, + createDataframeAnalyticsExplorationUrl, +} from './dataframe_analytics_urls_generator'; +import { + createIndexDataVisualizerUrl, + createDataVisualizerUrl, +} from './data_visualizer_urls_generator'; + +declare module '../../../../../src/plugins/share/public' { + export interface UrlGeneratorStateMapping { + [ML_APP_URL_GENERATOR]: UrlGeneratorState; + } +} + +interface Params { + appBasePath: string; + useHash: boolean; +} + +export class MlUrlGenerator implements UrlGeneratorsDefinition { + constructor(private readonly params: Params) {} + + public readonly id = ML_APP_URL_GENERATOR; + + public readonly createUrl = async (mlUrlGeneratorState: MlUrlGeneratorState): Promise => { + const appBasePath = this.params.appBasePath; + switch (mlUrlGeneratorState.page) { + case ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE: + return createAnomalyDetectionJobManagementUrl( + appBasePath, + mlUrlGeneratorState as AnomalyDetectionUrlState + ); + case ML_PAGES.ANOMALY_EXPLORER: + return createExplorerUrl(appBasePath, mlUrlGeneratorState as ExplorerUrlState); + case ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE: + return createAnomalyDetectionCreatJobSelectType( + appBasePath, + mlUrlGeneratorState as MlGenericUrlState + ); + case ML_PAGES.SINGLE_METRIC_VIEWER: + return createSingleMetricViewerUrl( + appBasePath, + mlUrlGeneratorState as TimeSeriesExplorerUrlState + ); + case ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE: + return createDataframeAnalyticsUrl( + appBasePath, + mlUrlGeneratorState as DataFrameAnalyticsUrlState + ); + case ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION: + return createDataframeAnalyticsExplorationUrl( + appBasePath, + mlUrlGeneratorState as DataFrameAnalyticsExplorationUrlState + ); + case ML_PAGES.DATA_VISUALIZER: + case ML_PAGES.DATA_VISUALIZER_FILE: + case ML_PAGES.DATA_VISUALIZER_INDEX_SELECT: + return createDataVisualizerUrl(appBasePath, mlUrlGeneratorState as DataVisualizerUrlState); + case ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER: + return createIndexDataVisualizerUrl(appBasePath, mlUrlGeneratorState as MlGenericUrlState); + default: + throw new Error('Page type is not provided or unknown'); + } + }; +} + +/** + * Registers the URL generator + */ +export function registerUrlGenerator( + share: SharePluginSetup, + core: CoreSetup +) { + const baseUrl = core.http.basePath.prepend('/app/ml'); + share.urlGenerators.registerUrlGenerator( + new MlUrlGenerator({ + appBasePath: baseUrl, + useHash: core.uiSettings.get('state:storeInSessionStorage'), + }) + ); +} diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index 4f8ceb8effe982..a1a127cc2baed3 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -34,7 +34,7 @@ import { registerFeature } from './register_feature'; import { UiActionsSetup, UiActionsStart } from '../../../../src/plugins/ui_actions/public'; import { registerMlUiActions } from './ui_actions'; import { KibanaLegacyStart } from '../../../../src/plugins/kibana_legacy/public'; -import { registerUrlGenerator } from './url_generator'; +import { registerUrlGenerator } from './ml_url_generator'; import { isFullLicense, isMlEnabled } from '../common/license'; import { registerEmbeddables } from './embeddables'; diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts deleted file mode 100644 index 2ef0c7208dc093..00000000000000 --- a/x-pack/plugins/ml/public/url_generator.ts +++ /dev/null @@ -1,341 +0,0 @@ -/* - * 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 { CoreSetup } from 'kibana/public'; -import isEmpty from 'lodash/isEmpty'; -import { - SharePluginSetup, - UrlGeneratorsDefinition, - UrlGeneratorState, -} from '../../../../src/plugins/share/public'; -import { setStateToKbnUrl } from '../../../../src/plugins/kibana_utils/public'; -import { MlStartDependencies } from './plugin'; -import { ML_PAGES, ML_APP_URL_GENERATOR } from '../common/constants/ml_url_generator'; -import { - MlUrlGeneratorState, - AnomalyDetectionUrlState, - ExplorerUrlState, - TimeSeriesExplorerUrlState, - DataFrameAnalyticsUrlState, - DataFrameAnalyticsExplorationUrlState, - DataVisualizerUrlState, - MlGenericUrlState, - AnomalyDetectionQueryState, - ExplorerGlobalState, - TimeSeriesExplorerGlobalState, - TimeSeriesExplorerAppState, - DataFrameAnalyticsExplorationQueryState, - DataFrameAnalyticsQueryState, - ExplorerAppState, -} from '../common/types/ml_url_generator'; - -declare module '../../../../src/plugins/share/public' { - export interface UrlGeneratorStateMapping { - [ML_APP_URL_GENERATOR]: UrlGeneratorState; - } -} - -interface Params { - appBasePath: string; - useHash: boolean; -} - -export class MlUrlGenerator implements UrlGeneratorsDefinition { - constructor(private readonly params: Params) {} - - public readonly id = ML_APP_URL_GENERATOR; - - public readonly createUrl = async (mlUrlGeneratorState: MlUrlGeneratorState): Promise => { - switch (mlUrlGeneratorState.page) { - case ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE: - return this.createAnomalyDetectionJobManagementUrl( - mlUrlGeneratorState as AnomalyDetectionUrlState - ); - case ML_PAGES.ANOMALY_EXPLORER: - return this.createExplorerUrl(mlUrlGeneratorState as ExplorerUrlState); - case ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE: - return this.createAnomalyDetectionCreatJobSelectType( - mlUrlGeneratorState as MlGenericUrlState - ); - case ML_PAGES.SINGLE_METRIC_VIEWER: - return this.createSingleMetricViewerUrl(mlUrlGeneratorState as TimeSeriesExplorerUrlState); - case ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE: - return this.createDataframeAnalyticsUrl(mlUrlGeneratorState as DataFrameAnalyticsUrlState); - case ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION: - return this.createDataframeAnalyticsExplorationUrl( - mlUrlGeneratorState as DataFrameAnalyticsExplorationUrlState - ); - case ML_PAGES.DATA_VISUALIZER: - return this.createDataVisualizerUrl(mlUrlGeneratorState as DataVisualizerUrlState); - case ML_PAGES.DATA_VISUALIZER_FILE: - return this.createDataVisualizerUrl(mlUrlGeneratorState as DataVisualizerUrlState); - case ML_PAGES.DATA_VISUALIZER_INDEX_SELECT: - return this.createDataVisualizerUrl(mlUrlGeneratorState as DataVisualizerUrlState); - case ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER: - return this.createIndexDataVisualizerUrl(mlUrlGeneratorState as MlGenericUrlState); - default: - throw new Error('Page type is not provided or unknown'); - } - }; - - private static extractParams(urlState: UrlState) { - // page should be guaranteed to exist here but is unknown - // @ts-ignore - const { page, ...params } = urlState; - return { page, params }; - } - /** - * Creates URL to the Anomaly Detection Job management page - */ - private createAnomalyDetectionJobManagementUrl( - mlUrlGeneratorState: AnomalyDetectionUrlState - ): string { - const { params } = MlUrlGenerator.extractParams(mlUrlGeneratorState); - let url = `${this.params.appBasePath}/${ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE}`; - if (isEmpty(params)) { - return url; - } - const { jobId, groupIds } = params; - const queryState: AnomalyDetectionQueryState = { - jobId, - groupIds, - }; - - url = setStateToKbnUrl( - 'mlManagement', - queryState, - { useHash: false, storeInHashQuery: false }, - url - ); - return url; - } - - private createAnomalyDetectionCreatJobSelectType(mlGenericUrlState: MlGenericUrlState): string { - return this.createIndexBasedMlUrl(mlGenericUrlState); - } - - /** - * Creates URL to the Anomaly Explorer page - */ - private createExplorerUrl({ - refreshInterval, - timeRange, - jobIds, - query, - mlExplorerSwimlane = {}, - mlExplorerFilter = {}, - }: ExplorerUrlState): string { - let url = `${this.params.appBasePath}/${ML_PAGES.ANOMALY_EXPLORER}`; - - const appState: Partial = { - mlExplorerSwimlane, - mlExplorerFilter, - }; - if (query) appState.query = query; - - if (jobIds) { - const queryState: Partial = { - ml: { - jobIds, - }, - }; - - if (timeRange) queryState.time = timeRange; - if (refreshInterval) queryState.refreshInterval = refreshInterval; - - url = setStateToKbnUrl>( - '_g', - queryState, - { useHash: false, storeInHashQuery: false }, - url - ); - url = setStateToKbnUrl>( - '_a', - appState, - { useHash: false, storeInHashQuery: false }, - url - ); - } - - return url; - } - - /** - * Creates URL to the SingleMetricViewer page - */ - private createSingleMetricViewerUrl({ - timeRange, - jobIds, - refreshInterval, - zoom, - query, - detectorIndex, - entities, - }: TimeSeriesExplorerUrlState): string { - let url = `${this.params.appBasePath}/${ML_PAGES.SINGLE_METRIC_VIEWER}`; - const queryState: TimeSeriesExplorerGlobalState = { - ml: { - jobIds, - }, - refreshInterval, - time: timeRange, - }; - - const appState: Partial = {}; - const mlTimeSeriesExplorer: Partial = {}; - - if (detectorIndex !== undefined) { - mlTimeSeriesExplorer.detectorIndex = detectorIndex; - } - if (entities !== undefined) { - mlTimeSeriesExplorer.entities = entities; - } - appState.mlTimeSeriesExplorer = mlTimeSeriesExplorer; - - if (zoom) appState.zoom = zoom; - if (query) - appState.query = { - query_string: query, - }; - url = setStateToKbnUrl( - '_g', - queryState, - { useHash: false, storeInHashQuery: false }, - url - ); - url = setStateToKbnUrl( - '_a', - appState, - { useHash: false, storeInHashQuery: false }, - url - ); - - return url; - } - - /** - * Creates URL to the DataFrameAnalytics Exploration page - */ - private createDataframeAnalyticsExplorationUrl( - mlUrlGeneratorState: DataFrameAnalyticsExplorationUrlState - ): string { - let url = `${this.params.appBasePath}/${ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION}`; - const { params } = MlUrlGenerator.extractParams( - mlUrlGeneratorState - ); - - if (!isEmpty(params)) { - const { jobId, analysisType } = params; - const queryState: DataFrameAnalyticsExplorationQueryState = { - ml: { - jobId, - analysisType, - }, - }; - - url = setStateToKbnUrl( - '_g', - queryState, - { useHash: false, storeInHashQuery: false }, - url - ); - } - - return url; - } - - /** - * Creates URL to the DataFrameAnalytics page - */ - private createDataframeAnalyticsUrl(mlUrlGeneratorState: DataFrameAnalyticsUrlState): string { - let url = `${this.params.appBasePath}/${ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE}`; - const { params } = MlUrlGenerator.extractParams( - mlUrlGeneratorState - ); - - if (!isEmpty(params)) { - const { jobId, groupIds } = params; - const queryState: Partial = { - jobId, - groupIds, - }; - - url = setStateToKbnUrl>( - 'mlManagement', - queryState, - { useHash: false, storeInHashQuery: false }, - url - ); - } - - return url; - } - - /** - * Creates URL to the Data Visualizer page - */ - private createDataVisualizerUrl({ page }: DataVisualizerUrlState): string { - return `${this.params.appBasePath}/${page}`; - } - - /** - * Creates URL to the Index Data Visualizer - */ - private createIndexDataVisualizerUrl(mlGenericUrlState: MlGenericUrlState): string { - return this.createIndexBasedMlUrl(mlGenericUrlState); - } - - /** - * Creates generic index based search ML url - * e.g. `jobs/new_job/datavisualizer?index=3da93760-e0af-11ea-9ad3-3bcfc330e42a` - */ - private createIndexBasedMlUrl(mlGenericUrlState: MlGenericUrlState): string { - const { globalState, appState, page, index, savedSearchId, ...restParams } = mlGenericUrlState; - let url = `${this.params.appBasePath}/${page}`; - - if (index !== undefined && savedSearchId === undefined) { - url = `${url}?index=${index}`; - } - if (index === undefined && savedSearchId !== undefined) { - url = `${url}?savedSearchId=${savedSearchId}`; - } - - if (!isEmpty(restParams)) { - Object.keys(restParams).forEach((key) => { - url = setStateToKbnUrl( - key, - restParams[key], - { useHash: false, storeInHashQuery: false }, - url - ); - }); - } - - if (globalState) { - url = setStateToKbnUrl('_g', globalState, { useHash: false, storeInHashQuery: false }, url); - } - if (appState) { - url = setStateToKbnUrl('_a', appState, { useHash: false, storeInHashQuery: false }, url); - } - return url; - } -} - -/** - * Registers the URL generator - */ -export function registerUrlGenerator( - share: SharePluginSetup, - core: CoreSetup -) { - const baseUrl = core.http.basePath.prepend('/app/ml'); - share.urlGenerators.registerUrlGenerator( - new MlUrlGenerator({ - appBasePath: baseUrl, - useHash: core.uiSettings.get('state:storeInSessionStorage'), - }) - ); -} From 5eefb05b65a11c4bb52098e4e99b2914d44aca8e Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Mon, 31 Aug 2020 18:51:51 -0500 Subject: [PATCH 22/29] [ML] Revert changes to data/common/types --- src/plugins/data/common/query/timefilter/types.ts | 3 +-- .../ml_url_generator/ml_url_generator.test.ts | 15 +++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/plugins/data/common/query/timefilter/types.ts b/src/plugins/data/common/query/timefilter/types.ts index ddf6b2e896dc88..60008ce6054e1b 100644 --- a/src/plugins/data/common/query/timefilter/types.ts +++ b/src/plugins/data/common/query/timefilter/types.ts @@ -20,7 +20,6 @@ import { Moment } from 'moment'; export interface RefreshInterval { - display?: string; pause: boolean; value: number; } @@ -28,7 +27,7 @@ export interface RefreshInterval { export interface TimeRange { from: string; to: string; - mode?: 'absolute' | 'relative' | 'quick'; + mode?: 'absolute' | 'relative'; } export interface TimeRangeBounds { diff --git a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.test.ts b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.test.ts index 68b222c7cd4891..fc8194a45d3c6f 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.test.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.test.ts @@ -47,12 +47,11 @@ describe('MlUrlGenerator', () => { time: { from: 'now-30m', to: 'now', - mode: 'quick', }, }, }); expect(url).toBe( - '/app/ml/jobs/new_job/step/job_type?index=3da93760-e0af-11ea-9ad3-3bcfc330e42a&_g=(time:(from:now-30m,mode:quick,to:now))' + '/app/ml/jobs/new_job/step/job_type?index=3da93760-e0af-11ea-9ad3-3bcfc330e42a&_g=(time:(from:now-30m,to:now))' ); }); }); @@ -64,7 +63,6 @@ describe('MlUrlGenerator', () => { jobIds: ['fq_single_1'], mlExplorerSwimlane: { viewByFromPage: 2, viewByPerPage: 20 }, refreshInterval: { - display: 'Off', pause: false, value: 0, }, @@ -79,7 +77,7 @@ describe('MlUrlGenerator', () => { }, }); expect(url).toBe( - "/app/ml/explorer?_g=(ml:(jobIds:!(fq_single_1)),refreshInterval:(display:Off,pause:!f,value:0),time:(from:'2019-02-07T00:00:00.000Z',mode:absolute,to:'2020-08-13T17:15:00.000Z'))&_a=(mlExplorerFilter:(),mlExplorerSwimlane:(viewByFromPage:2,viewByPerPage:20),query:(analyze_wildcard:!t,query:'*'))" + "/app/ml/explorer?_g=(ml:(jobIds:!(fq_single_1)),refreshInterval:(pause:!f,value:0),time:(from:'2019-02-07T00:00:00.000Z',mode:absolute,to:'2020-08-13T17:15:00.000Z'))&_a=(mlExplorerFilter:(),mlExplorerSwimlane:(viewByFromPage:2,viewByPerPage:20),query:(analyze_wildcard:!t,query:'*'))" ); }); it('should generate valid URL for the Anomaly Explorer page for multiple jobIds', async () => { @@ -104,7 +102,6 @@ describe('MlUrlGenerator', () => { page: ML_PAGES.SINGLE_METRIC_VIEWER, jobIds: ['logs_categorization_1'], refreshInterval: { - display: 'Off', pause: false, value: 0, }, @@ -119,7 +116,7 @@ describe('MlUrlGenerator', () => { }, }); expect(url).toBe( - "/app/ml/timeseriesexplorer?_g=(ml:(jobIds:!(logs_categorization_1)),refreshInterval:(display:Off,pause:!f,value:0),time:(from:'2020-07-12T00:39:02.912Z',mode:absolute,to:'2020-07-22T15:52:18.613Z'))&_a=(mlTimeSeriesExplorer:(),query:(query_string:(analyze_wildcard:!t,query:'*')))" + "/app/ml/timeseriesexplorer?_g=(ml:(jobIds:!(logs_categorization_1)),refreshInterval:(pause:!f,value:0),time:(from:'2020-07-12T00:39:02.912Z',mode:absolute,to:'2020-07-22T15:52:18.613Z'))&_a=(mlTimeSeriesExplorer:(),query:(query_string:(analyze_wildcard:!t,query:'*')))" ); }); @@ -130,7 +127,6 @@ describe('MlUrlGenerator', () => { detectorIndex: 0, entities: { mlcategory: '2' }, refreshInterval: { - display: 'Off', pause: false, value: 0, }, @@ -149,7 +145,7 @@ describe('MlUrlGenerator', () => { }, }); expect(url).toBe( - "/app/ml/timeseriesexplorer?_g=(ml:(jobIds:!(logs_categorization_1)),refreshInterval:(display:Off,pause:!f,value:0),time:(from:'2020-07-12T00:39:02.912Z',mode:absolute,to:'2020-07-22T15:52:18.613Z'))&_a=(mlTimeSeriesExplorer:(detectorIndex:0,entities:(mlcategory:'2')),query:(query_string:(analyze_wildcard:!t,query:'*')),zoom:(from:'2020-07-20T23:58:29.367Z',to:'2020-07-21T11:00:13.173Z'))" + "/app/ml/timeseriesexplorer?_g=(ml:(jobIds:!(logs_categorization_1)),refreshInterval:(pause:!f,value:0),time:(from:'2020-07-12T00:39:02.912Z',mode:absolute,to:'2020-07-22T15:52:18.613Z'))&_a=(mlTimeSeriesExplorer:(detectorIndex:0,entities:(mlcategory:'2')),query:(query_string:(analyze_wildcard:!t,query:'*')),zoom:(from:'2020-07-20T23:58:29.367Z',to:'2020-07-21T11:00:13.173Z'))" ); }); }); @@ -224,12 +220,11 @@ describe('MlUrlGenerator', () => { time: { from: 'now-30m', to: 'now', - mode: 'quick', }, }, }); expect(url).toBe( - '/app/ml/jobs/new_job/datavisualizer?index=3da93760-e0af-11ea-9ad3-3bcfc330e42a&_g=(time:(from:now-30m,mode:quick,to:now))' + '/app/ml/jobs/new_job/datavisualizer?index=3da93760-e0af-11ea-9ad3-3bcfc330e42a&_g=(time:(from:now-30m,to:now))' ); }); }); From a1e9118036cf0dae85ea00e61367f0f87b95ed68 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Tue, 1 Sep 2020 10:41:02 -0500 Subject: [PATCH 23/29] [ML] Fix createAnomalyDetectionCreateJobSelectType name and update api docs --- .../kibana-plugin-plugins-data-public.refreshinterval.md | 1 - .../public/kibana-plugin-plugins-data-public.timerange.md | 2 +- .../kibana-plugin-plugins-data-public.timerange.mode.md | 2 +- .../kibana-plugin-plugins-data-server.refreshinterval.md | 1 - .../server/kibana-plugin-plugins-data-server.timerange.md | 2 +- .../kibana-plugin-plugins-data-server.timerange.mode.md | 2 +- src/plugins/data/public/public.api.md | 4 +--- src/plugins/data/server/server.api.md | 4 +--- .../ml_url_generator/anomaly_detection_urls_generator.ts | 2 +- x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts | 4 ++-- 10 files changed, 9 insertions(+), 15 deletions(-) diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.refreshinterval.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.refreshinterval.md index 50833d1b615f8f..6a6350d8ba4f6f 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.refreshinterval.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.refreshinterval.md @@ -14,7 +14,6 @@ export interface RefreshInterval | Property | Type | Description | | --- | --- | --- | -| [display](./kibana-plugin-plugins-data-public.refreshinterval.display.md) | string | | | [pause](./kibana-plugin-plugins-data-public.refreshinterval.pause.md) | boolean | | | [value](./kibana-plugin-plugins-data-public.refreshinterval.value.md) | number | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.md index 1a589efeb405d2..69078ca40d20d2 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.md @@ -15,6 +15,6 @@ export interface TimeRange | Property | Type | Description | | --- | --- | --- | | [from](./kibana-plugin-plugins-data-public.timerange.from.md) | string | | -| [mode](./kibana-plugin-plugins-data-public.timerange.mode.md) | 'absolute' | 'relative' | 'quick' | | +| [mode](./kibana-plugin-plugins-data-public.timerange.mode.md) | 'absolute' | 'relative' | | | [to](./kibana-plugin-plugins-data-public.timerange.to.md) | string | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.mode.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.mode.md index 9e1f928a282cfe..fb9ebd3c9165f5 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.mode.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timerange.mode.md @@ -7,5 +7,5 @@ Signature: ```typescript -mode?: 'absolute' | 'relative' | 'quick'; +mode?: 'absolute' | 'relative'; ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.md index 28398c449c9d5d..ebb983de299425 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.md @@ -14,7 +14,6 @@ export interface RefreshInterval | Property | Type | Description | | --- | --- | --- | -| [display](./kibana-plugin-plugins-data-server.refreshinterval.display.md) | string | | | [pause](./kibana-plugin-plugins-data-server.refreshinterval.pause.md) | boolean | | | [value](./kibana-plugin-plugins-data-server.refreshinterval.value.md) | number | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.md index 6181da83e245e0..8280d924eb6097 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.md @@ -15,6 +15,6 @@ export interface TimeRange | Property | Type | Description | | --- | --- | --- | | [from](./kibana-plugin-plugins-data-server.timerange.from.md) | string | | -| [mode](./kibana-plugin-plugins-data-server.timerange.mode.md) | 'absolute' | 'relative' | 'quick' | | +| [mode](./kibana-plugin-plugins-data-server.timerange.mode.md) | 'absolute' | 'relative' | | | [to](./kibana-plugin-plugins-data-server.timerange.to.md) | string | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.mode.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.mode.md index 6b1915c1156c94..1408fb43cbf39c 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.mode.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.timerange.mode.md @@ -7,5 +7,5 @@ Signature: ```typescript -mode?: 'absolute' | 'relative' | 'quick'; +mode?: 'absolute' | 'relative'; ``` diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 12c77247b49c88..ba40dece25df9b 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1625,8 +1625,6 @@ export interface RangeFilterParams { // // @public (undocumented) export interface RefreshInterval { - // (undocumented) - display?: string; // (undocumented) pause: boolean; // (undocumented) @@ -1926,7 +1924,7 @@ export interface TimeRange { // (undocumented) from: string; // (undocumented) - mode?: 'absolute' | 'relative' | 'quick'; + mode?: 'absolute' | 'relative'; // (undocumented) to: string; } diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index 8f2da42ccceb08..9f114f21320098 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -930,8 +930,6 @@ export interface Query { // // @public (undocumented) export interface RefreshInterval { - // (undocumented) - display?: string; // (undocumented) pause: boolean; // (undocumented) @@ -1018,7 +1016,7 @@ export interface TimeRange { // (undocumented) from: string; // (undocumented) - mode?: 'absolute' | 'relative' | 'quick'; + mode?: 'absolute' | 'relative'; // (undocumented) to: string; } diff --git a/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts index 4aa7266398c5b8..1e50b42e2e8135 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts @@ -46,7 +46,7 @@ export function createAnomalyDetectionJobManagementUrl( return url; } -export function createAnomalyDetectionCreatJobSelectType( +export function createAnomalyDetectionCreateJobSelectType( appBasePath: string, mlGenericUrlState: MlGenericUrlState ): string { diff --git a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts index 40ae58651bb2a7..795b25309b3668 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts @@ -24,7 +24,7 @@ import { } from '../../common/types/ml_url_generator'; import { createAnomalyDetectionJobManagementUrl, - createAnomalyDetectionCreatJobSelectType, + createAnomalyDetectionCreateJobSelectType, createExplorerUrl, createSingleMetricViewerUrl, } from './anomaly_detection_urls_generator'; @@ -64,7 +64,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition Date: Tue, 1 Sep 2020 11:43:32 -0500 Subject: [PATCH 24/29] [ML] Change shape to use `page` and `pageState` --- .../ml/common/constants/ml_url_generator.ts | 8 +- .../ml/common/types/ml_url_generator.ts | 80 +++++---- .../view_results_panel/view_results_panel.tsx | 6 +- .../anomaly_detection_urls_generator.ts | 44 ++--- .../ml/public/ml_url_generator/common.ts | 5 +- .../data_visualizer_urls_generator.ts | 5 +- .../dataframe_analytics_urls_generator.ts | 16 +- .../ml_url_generator/ml_url_generator.test.ts | 158 ++++++++++-------- .../ml_url_generator/ml_url_generator.ts | 39 +---- .../open_in_anomaly_explorer_action.tsx | 28 ++-- 10 files changed, 207 insertions(+), 182 deletions(-) diff --git a/x-pack/plugins/ml/common/constants/ml_url_generator.ts b/x-pack/plugins/ml/common/constants/ml_url_generator.ts index 18e9d5ec1ecefd..44f33aa329e7ae 100644 --- a/x-pack/plugins/ml/common/constants/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/constants/ml_url_generator.ts @@ -30,12 +30,8 @@ export const ML_PAGES = { * Page: Data Visualizer * Open index data visualizer viewer page */ - get DATA_VISUALIZER_INDEX_VIEWER() { - return `jobs/new_job/${this.DATA_VISUALIZER}`; - }, - get ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE() { - return `jobs/new_job/step/job_type`; - }, + DATA_VISUALIZER_INDEX_VIEWER: 'jobs/new_job/datavisualizer', + ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE: `jobs/new_job/step/job_type`, SETTINGS: 'settings', CALENDARS_MANAGE: 'settings/calendars_list', FILTER_LISTS_MANAGE: 'settings/filter_lists', diff --git a/x-pack/plugins/ml/common/types/ml_url_generator.ts b/x-pack/plugins/ml/common/types/ml_url_generator.ts index 7b8f6800484a2e..0eaddfb04dbcbb 100644 --- a/x-pack/plugins/ml/common/types/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/types/ml_url_generator.ts @@ -8,12 +8,19 @@ import { RefreshInterval, TimeRange } from '../../../../../src/plugins/data/comm import { JobId } from '../../../reporting/common/types'; import { ML_PAGES } from '../constants/ml_url_generator'; +export interface MLPageState { + page: PageType; + pageState?: PageState; +} + export const ANALYSIS_CONFIG_TYPE = { OUTLIER_DETECTION: 'outlier_detection', REGRESSION: 'regression', CLASSIFICATION: 'classification', } as const; +type DATAFRAME_ANALYTICS_TYPE = typeof ANALYSIS_CONFIG_TYPE[keyof typeof ANALYSIS_CONFIG_TYPE]; + export interface MlCommonGlobalState { time?: TimeRange; } @@ -26,26 +33,39 @@ export interface MlIndexBasedSearchState { savedSearchId?: string; } -export interface MlGenericUrlState extends MlIndexBasedSearchState { - page: - | typeof ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER - | typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE; +export interface MlGenericUrlPageState extends MlIndexBasedSearchState { globalState?: MlCommonGlobalState; appState?: MlCommonAppState; [key: string]: any; } -export interface AnomalyDetectionQueryState { - jobId?: JobId; - groupIds?: string[]; +export interface MlGenericUrlState { + page: + | typeof ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER + | typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE; + pageState: MlGenericUrlPageState; } -export interface AnomalyDetectionUrlState { - page: typeof ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE; +export interface AnomalyDetectionQueryState { jobId?: JobId; groupIds?: string[]; } - +// +// export interface AnomalyDetectionUrlState { +// page: typeof ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE; +// pageState: { +// jobId?: JobId; +// groupIds?: string[]; +// }; +// } + +export type AnomalyDetectionUrlState = MLPageState< + typeof ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE, + { + jobId?: JobId; + groupIds?: string[]; + } +>; export interface ExplorerAppState { mlExplorerSwimlane: { selectedType?: string; @@ -70,11 +90,7 @@ export interface ExplorerGlobalState { refreshInterval?: RefreshInterval; } -export interface ExplorerUrlState { - /** - * ML App Page - */ - page: typeof ML_PAGES.ANOMALY_EXPLORER; +export interface ExplorerUrlPageState { /** * Job IDs */ @@ -98,6 +114,8 @@ export interface ExplorerUrlState { mlExplorerFilter?: ExplorerAppState['mlExplorerFilter']; } +export type ExplorerUrlState = MLPageState; + export interface TimeSeriesExplorerGlobalState { ml: { jobIds: JobId[]; @@ -118,27 +136,29 @@ export interface TimeSeriesExplorerAppState { query?: any; } -export interface TimeSeriesExplorerUrlState +export interface TimeSeriesExplorerPageState extends Pick, Pick { - /** - * ML App Page - */ - page: typeof ML_PAGES.SINGLE_METRIC_VIEWER; jobIds: JobId[]; timeRange?: TimeRange; detectorIndex?: number; entities?: Record; } +export type TimeSeriesExplorerUrlState = MLPageState< + typeof ML_PAGES.SINGLE_METRIC_VIEWER, + TimeSeriesExplorerPageState +>; + export interface DataFrameAnalyticsQueryState { jobId?: JobId | JobId[]; groupIds?: string[]; } -export interface DataFrameAnalyticsUrlState extends DataFrameAnalyticsQueryState { - page: typeof ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE; -} +export type DataFrameAnalyticsUrlState = MLPageState< + typeof ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE, + DataFrameAnalyticsQueryState +>; export interface DataVisualizerUrlState { page: @@ -150,15 +170,17 @@ export interface DataVisualizerUrlState { export interface DataFrameAnalyticsExplorationQueryState { ml: { jobId: JobId; - analysisType: typeof ANALYSIS_CONFIG_TYPE; + analysisType: DATAFRAME_ANALYTICS_TYPE; }; } -export interface DataFrameAnalyticsExplorationUrlState { - page: typeof ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION; - jobId: JobId; - analysisType: typeof ANALYSIS_CONFIG_TYPE; -} +export type DataFrameAnalyticsExplorationUrlState = MLPageState< + typeof ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION, + { + jobId: JobId; + analysisType: DATAFRAME_ANALYTICS_TYPE; + } +>; /** * Union type of ML URL state based on page diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx index 586834b3f7c938..b832bfb2549c6d 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx @@ -23,8 +23,10 @@ export const ViewResultsPanel: FC = ({ jobId, analysisType }) => { const redirectToAnalyticsExplorationPage = async () => { const path = await urlGenerator.createUrl({ page: ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION, - jobId, - analysisType, + pageState: { + jobId, + analysisType, + }, }); await navigateToPath(path); }; diff --git a/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts index 1e50b42e2e8135..c4aebb108e7b92 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts @@ -17,18 +17,17 @@ import { TimeSeriesExplorerUrlState, } from '../../common/types/ml_url_generator'; import { ML_PAGES } from '../../common/constants/ml_url_generator'; -import { extractParams, createIndexBasedMlUrl } from './common'; +import { createIndexBasedMlUrl } from './common'; import { setStateToKbnUrl } from '../../../../../src/plugins/kibana_utils/public'; /** * Creates URL to the Anomaly Detection Job management page */ export function createAnomalyDetectionJobManagementUrl( appBasePath: string, - mlUrlGeneratorState: AnomalyDetectionUrlState + params: AnomalyDetectionUrlState['pageState'] ): string { - const { params } = extractParams(mlUrlGeneratorState); let url = `${appBasePath}/${ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE}`; - if (isEmpty(params)) { + if (!params || isEmpty(params)) { return url; } const { jobId, groupIds } = params; @@ -48,9 +47,13 @@ export function createAnomalyDetectionJobManagementUrl( export function createAnomalyDetectionCreateJobSelectType( appBasePath: string, - mlGenericUrlState: MlGenericUrlState + pageState: MlGenericUrlState['pageState'] ): string { - return createIndexBasedMlUrl(appBasePath, mlGenericUrlState); + return createIndexBasedMlUrl( + appBasePath, + ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE, + pageState + ); } /** @@ -58,17 +61,21 @@ export function createAnomalyDetectionCreateJobSelectType( */ export function createExplorerUrl( appBasePath: string, - { + params: ExplorerUrlState['pageState'] +): string { + let url = `${appBasePath}/${ML_PAGES.ANOMALY_EXPLORER}`; + + if (!params) { + return url; + } + const { refreshInterval, timeRange, jobIds, query, mlExplorerSwimlane = {}, mlExplorerFilter = {}, - }: ExplorerUrlState -): string { - let url = `${appBasePath}/${ML_PAGES.ANOMALY_EXPLORER}`; - + } = params; const appState: Partial = { mlExplorerSwimlane, mlExplorerFilter, @@ -107,17 +114,14 @@ export function createExplorerUrl( */ export function createSingleMetricViewerUrl( appBasePath: string, - { - timeRange, - jobIds, - refreshInterval, - zoom, - query, - detectorIndex, - entities, - }: TimeSeriesExplorerUrlState + params: TimeSeriesExplorerUrlState['pageState'] ): string { let url = `${appBasePath}/${ML_PAGES.SINGLE_METRIC_VIEWER}`; + if (!params) { + return url; + } + const { timeRange, jobIds, refreshInterval, zoom, query, detectorIndex, entities } = params; + const queryState: TimeSeriesExplorerGlobalState = { ml: { jobIds, diff --git a/x-pack/plugins/ml/public/ml_url_generator/common.ts b/x-pack/plugins/ml/public/ml_url_generator/common.ts index 34a7fac9c305f4..57cfc52045282b 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/common.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/common.ts @@ -21,9 +21,10 @@ export function extractParams(urlState: UrlState) { */ export function createIndexBasedMlUrl( appBasePath: string, - mlGenericUrlState: MlGenericUrlState + page: MlGenericUrlState['page'], + pageState: MlGenericUrlState['pageState'] ): string { - const { globalState, appState, page, index, savedSearchId, ...restParams } = mlGenericUrlState; + const { globalState, appState, index, savedSearchId, ...restParams } = pageState; let url = `${appBasePath}/${page}`; if (index !== undefined && savedSearchId === undefined) { diff --git a/x-pack/plugins/ml/public/ml_url_generator/data_visualizer_urls_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/data_visualizer_urls_generator.ts index 15d932c8c2f86c..24693df5025d9d 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/data_visualizer_urls_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/data_visualizer_urls_generator.ts @@ -9,6 +9,7 @@ */ import { DataVisualizerUrlState, MlGenericUrlState } from '../../common/types/ml_url_generator'; import { createIndexBasedMlUrl } from './common'; +import { ML_PAGES } from '../../common/constants/ml_url_generator'; export function createDataVisualizerUrl( appBasePath: string, @@ -22,7 +23,7 @@ export function createDataVisualizerUrl( */ export function createIndexDataVisualizerUrl( appBasePath: string, - mlGenericUrlState: MlGenericUrlState + pageState: MlGenericUrlState['pageState'] ): string { - return createIndexBasedMlUrl(appBasePath, mlGenericUrlState); + return createIndexBasedMlUrl(appBasePath, ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER, pageState); } diff --git a/x-pack/plugins/ml/public/ml_url_generator/dataframe_analytics_urls_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/dataframe_analytics_urls_generator.ts index 9d8c8057adb6fd..0f711eb9db85d1 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/dataframe_analytics_urls_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/dataframe_analytics_urls_generator.ts @@ -7,7 +7,6 @@ /** * Creates URL to the DataFrameAnalytics page */ -import isEmpty from 'lodash/isEmpty'; import { DataFrameAnalyticsExplorationQueryState, DataFrameAnalyticsExplorationUrlState, @@ -15,18 +14,16 @@ import { DataFrameAnalyticsUrlState, } from '../../common/types/ml_url_generator'; import { ML_PAGES } from '../../common/constants/ml_url_generator'; -import { extractParams } from './common'; import { setStateToKbnUrl } from '../../../../../src/plugins/kibana_utils/public'; export function createDataframeAnalyticsUrl( appBasePath: string, - mlUrlGeneratorState: DataFrameAnalyticsUrlState + mlUrlGeneratorState: DataFrameAnalyticsUrlState['pageState'] ): string { let url = `${appBasePath}/${ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE}`; - const { params } = extractParams(mlUrlGeneratorState); - if (!isEmpty(params)) { - const { jobId, groupIds } = params; + if (mlUrlGeneratorState) { + const { jobId, groupIds } = mlUrlGeneratorState; const queryState: Partial = { jobId, groupIds, @@ -48,13 +45,12 @@ export function createDataframeAnalyticsUrl( */ export function createDataframeAnalyticsExplorationUrl( appBasePath: string, - mlUrlGeneratorState: DataFrameAnalyticsExplorationUrlState + mlUrlGeneratorState: DataFrameAnalyticsExplorationUrlState['pageState'] ): string { let url = `${appBasePath}/${ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION}`; - const { params } = extractParams(mlUrlGeneratorState); - if (!isEmpty(params)) { - const { jobId, analysisType } = params; + if (mlUrlGeneratorState) { + const { jobId, analysisType } = mlUrlGeneratorState; const queryState: DataFrameAnalyticsExplorationQueryState = { ml: { jobId, diff --git a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.test.ts b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.test.ts index fc8194a45d3c6f..55bc6d3668de78 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.test.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.test.ts @@ -6,7 +6,7 @@ import { MlUrlGenerator } from './ml_url_generator'; import { ML_PAGES } from '../../common/constants/ml_url_generator'; -import { ANALYSIS_CONFIG_TYPE } from '../application/data_frame_analytics/common'; +import { ANALYSIS_CONFIG_TYPE } from '../../common/types/ml_url_generator'; describe('MlUrlGenerator', () => { const urlGenerator = new MlUrlGenerator({ @@ -26,7 +26,9 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Anomaly Detection job management page for job', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE, - jobId: 'fq_single_1', + pageState: { + jobId: 'fq_single_1', + }, }); expect(url).toBe('/app/ml/jobs?mlManagement=(jobId:fq_single_1)'); }); @@ -34,7 +36,9 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Anomaly Detection job management page for groupIds', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE, - groupIds: ['farequote', 'categorization'], + pageState: { + groupIds: ['farequote', 'categorization'], + }, }); expect(url).toBe('/app/ml/jobs?mlManagement=(groupIds:!(farequote,categorization))'); }); @@ -42,11 +46,13 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the page for selecting the type of anomaly detection job to create', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE, - index: `3da93760-e0af-11ea-9ad3-3bcfc330e42a`, - globalState: { - time: { - from: 'now-30m', - to: 'now', + pageState: { + index: `3da93760-e0af-11ea-9ad3-3bcfc330e42a`, + globalState: { + time: { + from: 'now-30m', + to: 'now', + }, }, }, }); @@ -60,20 +66,22 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Anomaly Explorer page', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.ANOMALY_EXPLORER, - jobIds: ['fq_single_1'], - mlExplorerSwimlane: { viewByFromPage: 2, viewByPerPage: 20 }, - refreshInterval: { - pause: false, - value: 0, - }, - timeRange: { - from: '2019-02-07T00:00:00.000Z', - to: '2020-08-13T17:15:00.000Z', - mode: 'absolute', - }, - query: { - analyze_wildcard: true, - query: '*', + pageState: { + jobIds: ['fq_single_1'], + mlExplorerSwimlane: { viewByFromPage: 2, viewByPerPage: 20 }, + refreshInterval: { + pause: false, + value: 0, + }, + timeRange: { + from: '2019-02-07T00:00:00.000Z', + to: '2020-08-13T17:15:00.000Z', + mode: 'absolute', + }, + query: { + analyze_wildcard: true, + query: '*', + }, }, }); expect(url).toBe( @@ -83,11 +91,13 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Anomaly Explorer page for multiple jobIds', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.ANOMALY_EXPLORER, - jobIds: ['fq_single_1', 'logs_categorization_1'], - timeRange: { - from: '2019-02-07T00:00:00.000Z', - to: '2020-08-13T17:15:00.000Z', - mode: 'absolute', + pageState: { + jobIds: ['fq_single_1', 'logs_categorization_1'], + timeRange: { + from: '2019-02-07T00:00:00.000Z', + to: '2020-08-13T17:15:00.000Z', + mode: 'absolute', + }, }, }); expect(url).toBe( @@ -100,19 +110,21 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Single Metric Viewer page', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.SINGLE_METRIC_VIEWER, - jobIds: ['logs_categorization_1'], - refreshInterval: { - pause: false, - value: 0, - }, - timeRange: { - from: '2020-07-12T00:39:02.912Z', - to: '2020-07-22T15:52:18.613Z', - mode: 'absolute', - }, - query: { - analyze_wildcard: true, - query: '*', + pageState: { + jobIds: ['logs_categorization_1'], + refreshInterval: { + pause: false, + value: 0, + }, + timeRange: { + from: '2020-07-12T00:39:02.912Z', + to: '2020-07-22T15:52:18.613Z', + mode: 'absolute', + }, + query: { + analyze_wildcard: true, + query: '*', + }, }, }); expect(url).toBe( @@ -123,25 +135,27 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Single Metric Viewer page with extra settings', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.SINGLE_METRIC_VIEWER, - jobIds: ['logs_categorization_1'], - detectorIndex: 0, - entities: { mlcategory: '2' }, - refreshInterval: { - pause: false, - value: 0, - }, - timeRange: { - from: '2020-07-12T00:39:02.912Z', - to: '2020-07-22T15:52:18.613Z', - mode: 'absolute', - }, - zoom: { - from: '2020-07-20T23:58:29.367Z', - to: '2020-07-21T11:00:13.173Z', - }, - query: { - analyze_wildcard: true, - query: '*', + pageState: { + jobIds: ['logs_categorization_1'], + detectorIndex: 0, + entities: { mlcategory: '2' }, + refreshInterval: { + pause: false, + value: 0, + }, + timeRange: { + from: '2020-07-12T00:39:02.912Z', + to: '2020-07-22T15:52:18.613Z', + mode: 'absolute', + }, + zoom: { + from: '2020-07-20T23:58:29.367Z', + to: '2020-07-21T11:00:13.173Z', + }, + query: { + analyze_wildcard: true, + query: '*', + }, }, }); expect(url).toBe( @@ -162,7 +176,9 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Data Frame Analytics job management page with jobId', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE, - jobId: 'grid_regression_1', + pageState: { + jobId: 'grid_regression_1', + }, }); expect(url).toBe('/app/ml/data_frame_analytics?mlManagement=(jobId:grid_regression_1)'); }); @@ -170,7 +186,9 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Data Frame Analytics job management page with groupIds', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE, - groupIds: ['group_1', 'group_2'], + pageState: { + groupIds: ['group_1', 'group_2'], + }, }); expect(url).toBe('/app/ml/data_frame_analytics?mlManagement=(groupIds:!(group_1,group_2))'); }); @@ -180,8 +198,10 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Data Frame Analytics exploration page for job', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION, - jobId: 'grid_regression_1', - analysisType: ANALYSIS_CONFIG_TYPE.REGRESSION, + pageState: { + jobId: 'grid_regression_1', + analysisType: ANALYSIS_CONFIG_TYPE.REGRESSION, + }, }); expect(url).toBe( '/app/ml/data_frame_analytics/exploration?_g=(ml:(analysisType:regression,jobId:grid_regression_1))' @@ -215,11 +235,13 @@ describe('MlUrlGenerator', () => { it('should generate valid URL for the Index Data Visualizer Viewer page', async () => { const url = await urlGenerator.createUrl({ page: ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER, - index: '3da93760-e0af-11ea-9ad3-3bcfc330e42a', - globalState: { - time: { - from: 'now-30m', - to: 'now', + pageState: { + index: '3da93760-e0af-11ea-9ad3-3bcfc330e42a', + globalState: { + time: { + from: 'now-30m', + to: 'now', + }, }, }, }); diff --git a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts index 795b25309b3668..107f5b2e388eb8 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts @@ -12,16 +12,7 @@ import { } from '../../../../../src/plugins/share/public'; import { MlStartDependencies } from '../plugin'; import { ML_PAGES, ML_APP_URL_GENERATOR } from '../../common/constants/ml_url_generator'; -import { - MlUrlGeneratorState, - AnomalyDetectionUrlState, - ExplorerUrlState, - TimeSeriesExplorerUrlState, - DataFrameAnalyticsUrlState, - DataFrameAnalyticsExplorationUrlState, - DataVisualizerUrlState, - MlGenericUrlState, -} from '../../common/types/ml_url_generator'; +import { MlUrlGeneratorState } from '../../common/types/ml_url_generator'; import { createAnomalyDetectionJobManagementUrl, createAnomalyDetectionCreateJobSelectType, @@ -57,38 +48,26 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition Date: Tue, 1 Sep 2020 11:45:30 -0500 Subject: [PATCH 25/29] [ML] Remove commented block code --- x-pack/plugins/ml/common/types/ml_url_generator.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/x-pack/plugins/ml/common/types/ml_url_generator.ts b/x-pack/plugins/ml/common/types/ml_url_generator.ts index 0eaddfb04dbcbb..7481dbb70a6dad 100644 --- a/x-pack/plugins/ml/common/types/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/types/ml_url_generator.ts @@ -50,14 +50,6 @@ export interface AnomalyDetectionQueryState { jobId?: JobId; groupIds?: string[]; } -// -// export interface AnomalyDetectionUrlState { -// page: typeof ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE; -// pageState: { -// jobId?: JobId; -// groupIds?: string[]; -// }; -// } export type AnomalyDetectionUrlState = MLPageState< typeof ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE, From 9962c25afba12c5d6ebc699f1134f010176b068f Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Wed, 2 Sep 2020 09:30:48 -0500 Subject: [PATCH 26/29] [ML] Rename dataframe -> data frame, update types for MLPagestype --- .../ml/common/types/ml_url_generator.ts | 18 +++++++++--------- ... => data_frame_analytics_urls_generator.ts} | 4 ++-- .../ml_url_generator/ml_url_generator.ts | 10 +++++----- 3 files changed, 16 insertions(+), 16 deletions(-) rename x-pack/plugins/ml/public/ml_url_generator/{dataframe_analytics_urls_generator.ts => data_frame_analytics_urls_generator.ts} (94%) diff --git a/x-pack/plugins/ml/common/types/ml_url_generator.ts b/x-pack/plugins/ml/common/types/ml_url_generator.ts index 7481dbb70a6dad..e16e9000c13355 100644 --- a/x-pack/plugins/ml/common/types/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/types/ml_url_generator.ts @@ -8,10 +8,9 @@ import { RefreshInterval, TimeRange } from '../../../../../src/plugins/data/comm import { JobId } from '../../../reporting/common/types'; import { ML_PAGES } from '../constants/ml_url_generator'; -export interface MLPageState { - page: PageType; - pageState?: PageState; -} +export type MLPageState = PageState extends undefined + ? { page: PageType } + : { page: PageType; pageState: PageState }; export const ANALYSIS_CONFIG_TYPE = { OUTLIER_DETECTION: 'outlier_detection', @@ -53,10 +52,11 @@ export interface AnomalyDetectionQueryState { export type AnomalyDetectionUrlState = MLPageState< typeof ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE, - { - jobId?: JobId; - groupIds?: string[]; - } + | { + jobId?: JobId; + groupIds?: string[]; + } + | undefined >; export interface ExplorerAppState { mlExplorerSwimlane: { @@ -149,7 +149,7 @@ export interface DataFrameAnalyticsQueryState { export type DataFrameAnalyticsUrlState = MLPageState< typeof ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE, - DataFrameAnalyticsQueryState + DataFrameAnalyticsQueryState | undefined >; export interface DataVisualizerUrlState { diff --git a/x-pack/plugins/ml/public/ml_url_generator/dataframe_analytics_urls_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/data_frame_analytics_urls_generator.ts similarity index 94% rename from x-pack/plugins/ml/public/ml_url_generator/dataframe_analytics_urls_generator.ts rename to x-pack/plugins/ml/public/ml_url_generator/data_frame_analytics_urls_generator.ts index 0f711eb9db85d1..8cf10a2acb64f2 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/dataframe_analytics_urls_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/data_frame_analytics_urls_generator.ts @@ -16,7 +16,7 @@ import { import { ML_PAGES } from '../../common/constants/ml_url_generator'; import { setStateToKbnUrl } from '../../../../../src/plugins/kibana_utils/public'; -export function createDataframeAnalyticsUrl( +export function createDataFrameAnalyticsJobManagementUrl( appBasePath: string, mlUrlGeneratorState: DataFrameAnalyticsUrlState['pageState'] ): string { @@ -43,7 +43,7 @@ export function createDataframeAnalyticsUrl( /** * Creates URL to the DataFrameAnalytics Exploration page */ -export function createDataframeAnalyticsExplorationUrl( +export function createDataFrameAnalyticsExplorationUrl( appBasePath: string, mlUrlGeneratorState: DataFrameAnalyticsExplorationUrlState['pageState'] ): string { diff --git a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts index 107f5b2e388eb8..b69260d8d4157b 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts @@ -20,9 +20,9 @@ import { createSingleMetricViewerUrl, } from './anomaly_detection_urls_generator'; import { - createDataframeAnalyticsUrl, - createDataframeAnalyticsExplorationUrl, -} from './dataframe_analytics_urls_generator'; + createDataFrameAnalyticsJobManagementUrl, + createDataFrameAnalyticsExplorationUrl, +} from './data_frame_analytics_urls_generator'; import { createIndexDataVisualizerUrl, createDataVisualizerUrl, @@ -59,9 +59,9 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition Date: Wed, 2 Sep 2020 09:32:11 -0500 Subject: [PATCH 27/29] [ML] Rename DataFrameAnalyticsType --- x-pack/plugins/ml/common/types/ml_url_generator.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/ml/common/types/ml_url_generator.ts b/x-pack/plugins/ml/common/types/ml_url_generator.ts index e16e9000c13355..611eda20091422 100644 --- a/x-pack/plugins/ml/common/types/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/types/ml_url_generator.ts @@ -18,7 +18,7 @@ export const ANALYSIS_CONFIG_TYPE = { CLASSIFICATION: 'classification', } as const; -type DATAFRAME_ANALYTICS_TYPE = typeof ANALYSIS_CONFIG_TYPE[keyof typeof ANALYSIS_CONFIG_TYPE]; +type DataFrameAnalyticsType = typeof ANALYSIS_CONFIG_TYPE[keyof typeof ANALYSIS_CONFIG_TYPE]; export interface MlCommonGlobalState { time?: TimeRange; @@ -162,7 +162,7 @@ export interface DataVisualizerUrlState { export interface DataFrameAnalyticsExplorationQueryState { ml: { jobId: JobId; - analysisType: DATAFRAME_ANALYTICS_TYPE; + analysisType: DataFrameAnalyticsType; }; } @@ -170,7 +170,7 @@ export type DataFrameAnalyticsExplorationUrlState = MLPageState< typeof ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION, { jobId: JobId; - analysisType: DATAFRAME_ANALYTICS_TYPE; + analysisType: DataFrameAnalyticsType; } >; From a6cb7dafcc9a36baecf8e05340aec1dab07237e2 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen Date: Wed, 2 Sep 2020 10:25:47 -0500 Subject: [PATCH 28/29] [ML] Update typings --- x-pack/plugins/ml/common/types/ml_url_generator.ts | 6 +----- .../anomaly_detection_urls_generator.ts | 3 +-- .../data_frame_analytics_urls_generator.ts | 3 +-- .../ml/public/ml_url_generator/ml_url_generator.ts | 10 ++++++++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/ml/common/types/ml_url_generator.ts b/x-pack/plugins/ml/common/types/ml_url_generator.ts index 611eda20091422..3ded7afb6d88b7 100644 --- a/x-pack/plugins/ml/common/types/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/types/ml_url_generator.ts @@ -52,11 +52,7 @@ export interface AnomalyDetectionQueryState { export type AnomalyDetectionUrlState = MLPageState< typeof ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE, - | { - jobId?: JobId; - groupIds?: string[]; - } - | undefined + AnomalyDetectionQueryState | undefined >; export interface ExplorerAppState { mlExplorerSwimlane: { diff --git a/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts index c4aebb108e7b92..5e95849eabe82f 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts @@ -7,7 +7,6 @@ import isEmpty from 'lodash/isEmpty'; import { AnomalyDetectionQueryState, - AnomalyDetectionUrlState, ExplorerAppState, ExplorerGlobalState, ExplorerUrlState, @@ -24,7 +23,7 @@ import { setStateToKbnUrl } from '../../../../../src/plugins/kibana_utils/public */ export function createAnomalyDetectionJobManagementUrl( appBasePath: string, - params: AnomalyDetectionUrlState['pageState'] + params: AnomalyDetectionQueryState | undefined ): string { let url = `${appBasePath}/${ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE}`; if (!params || isEmpty(params)) { diff --git a/x-pack/plugins/ml/public/ml_url_generator/data_frame_analytics_urls_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/data_frame_analytics_urls_generator.ts index 8cf10a2acb64f2..d3d86fe74ad3c0 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/data_frame_analytics_urls_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/data_frame_analytics_urls_generator.ts @@ -11,14 +11,13 @@ import { DataFrameAnalyticsExplorationQueryState, DataFrameAnalyticsExplorationUrlState, DataFrameAnalyticsQueryState, - DataFrameAnalyticsUrlState, } from '../../common/types/ml_url_generator'; import { ML_PAGES } from '../../common/constants/ml_url_generator'; import { setStateToKbnUrl } from '../../../../../src/plugins/kibana_utils/public'; export function createDataFrameAnalyticsJobManagementUrl( appBasePath: string, - mlUrlGeneratorState: DataFrameAnalyticsUrlState['pageState'] + mlUrlGeneratorState: DataFrameAnalyticsQueryState | undefined ): string { let url = `${appBasePath}/${ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE}`; diff --git a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts index b69260d8d4157b..0ed7b7bc54f0e1 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts @@ -48,7 +48,10 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition Date: Wed, 2 Sep 2020 19:19:51 +0200 Subject: [PATCH 29/29] [ML] fix base type --- x-pack/plugins/ml/common/types/ml_url_generator.ts | 10 +++++++--- .../anomaly_detection_urls_generator.ts | 3 ++- .../data_frame_analytics_urls_generator.ts | 3 ++- .../ml/public/ml_url_generator/ml_url_generator.ts | 10 ++-------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/ml/common/types/ml_url_generator.ts b/x-pack/plugins/ml/common/types/ml_url_generator.ts index 3ded7afb6d88b7..234be8b6faf909 100644 --- a/x-pack/plugins/ml/common/types/ml_url_generator.ts +++ b/x-pack/plugins/ml/common/types/ml_url_generator.ts @@ -8,9 +8,13 @@ import { RefreshInterval, TimeRange } from '../../../../../src/plugins/data/comm import { JobId } from '../../../reporting/common/types'; import { ML_PAGES } from '../constants/ml_url_generator'; -export type MLPageState = PageState extends undefined - ? { page: PageType } - : { page: PageType; pageState: PageState }; +type OptionalPageState = object | undefined; + +export type MLPageState = PageState extends OptionalPageState + ? { page: PageType; pageState?: PageState } + : PageState extends object + ? { page: PageType; pageState: PageState } + : { page: PageType }; export const ANALYSIS_CONFIG_TYPE = { OUTLIER_DETECTION: 'outlier_detection', diff --git a/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts index 5e95849eabe82f..c4aebb108e7b92 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/anomaly_detection_urls_generator.ts @@ -7,6 +7,7 @@ import isEmpty from 'lodash/isEmpty'; import { AnomalyDetectionQueryState, + AnomalyDetectionUrlState, ExplorerAppState, ExplorerGlobalState, ExplorerUrlState, @@ -23,7 +24,7 @@ import { setStateToKbnUrl } from '../../../../../src/plugins/kibana_utils/public */ export function createAnomalyDetectionJobManagementUrl( appBasePath: string, - params: AnomalyDetectionQueryState | undefined + params: AnomalyDetectionUrlState['pageState'] ): string { let url = `${appBasePath}/${ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE}`; if (!params || isEmpty(params)) { diff --git a/x-pack/plugins/ml/public/ml_url_generator/data_frame_analytics_urls_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/data_frame_analytics_urls_generator.ts index d3d86fe74ad3c0..8cf10a2acb64f2 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/data_frame_analytics_urls_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/data_frame_analytics_urls_generator.ts @@ -11,13 +11,14 @@ import { DataFrameAnalyticsExplorationQueryState, DataFrameAnalyticsExplorationUrlState, DataFrameAnalyticsQueryState, + DataFrameAnalyticsUrlState, } from '../../common/types/ml_url_generator'; import { ML_PAGES } from '../../common/constants/ml_url_generator'; import { setStateToKbnUrl } from '../../../../../src/plugins/kibana_utils/public'; export function createDataFrameAnalyticsJobManagementUrl( appBasePath: string, - mlUrlGeneratorState: DataFrameAnalyticsQueryState | undefined + mlUrlGeneratorState: DataFrameAnalyticsUrlState['pageState'] ): string { let url = `${appBasePath}/${ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE}`; diff --git a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts index 0ed7b7bc54f0e1..b69260d8d4157b 100644 --- a/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts +++ b/x-pack/plugins/ml/public/ml_url_generator/ml_url_generator.ts @@ -48,10 +48,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition