From ed496adc84aea0f18f762169dc175de66d807b8c Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Wed, 27 Oct 2021 15:36:12 +0100 Subject: [PATCH 1/6] [ML] Data view loading refactor --- x-pack/plugins/ml/public/application/app.tsx | 2 +- .../components/anomalies_table/links_menu.js | 14 ++--- .../application/contexts/ml/ml_context.ts | 2 +- .../application/contexts/ml/use_ml_context.ts | 2 +- .../common/use_results_view_config.ts | 11 ++-- .../use_create_analytics_form.ts | 6 +- .../pages/job_map/components/controls.tsx | 4 +- .../explorer/actions/job_selection.ts | 3 +- .../components/custom_url_editor/editor.tsx | 10 ++-- .../components/custom_url_editor/utils.d.ts | 4 +- .../components/custom_url_editor/utils.js | 16 ++--- .../edit_job_flyout/edit_utils.d.ts | 2 + .../components/edit_job_flyout/edit_utils.js | 7 ++- .../edit_job_flyout/tabs/custom_urls.tsx | 23 ++++---- .../components/job_actions/management.js | 18 +----- .../jobs/jobs_list/components/utils.js | 10 ++++ .../preconfigured_job_redirect.ts | 33 ++++++++--- .../public/application/routing/resolvers.ts | 8 +-- .../ml/public/application/routing/router.tsx | 2 +- .../routing/routes/access_denied.tsx | 2 +- .../analytics_job_creation.tsx | 4 +- .../analytics_job_exploration.tsx | 8 ++- .../analytics_jobs_list.tsx | 8 ++- .../data_frame_analytics/analytics_map.tsx | 8 ++- .../routes/datavisualizer/datavisualizer.tsx | 2 +- .../routes/datavisualizer/file_based.tsx | 6 +- .../routes/datavisualizer/index_based.tsx | 6 +- .../application/routing/routes/explorer.tsx | 16 +++-- .../application/routing/routes/jobs_list.tsx | 8 ++- .../routes/new_job/index_or_search.tsx | 7 ++- .../routing/routes/new_job/job_type.tsx | 8 ++- .../routing/routes/new_job/recognize.tsx | 16 +++-- .../routing/routes/new_job/wizard.tsx | 20 ++++--- .../application/routing/routes/overview.tsx | 2 +- .../routing/routes/settings/calendar_list.tsx | 2 +- .../routes/settings/calendar_new_edit.tsx | 2 +- .../routing/routes/settings/filter_list.tsx | 2 +- .../routes/settings/filter_list_new_edit.tsx | 2 +- .../routing/routes/settings/settings.tsx | 2 +- .../routing/routes/timeseriesexplorer.tsx | 16 +++-- .../routes/trained_models/models_list.tsx | 8 ++- .../application/routing/use_resolver.test.ts | 7 ++- .../application/routing/use_resolver.ts | 5 +- .../services/field_format_service.ts | 57 +++++++++--------- .../timeseriesexplorer/timeseriesexplorer.js | 4 +- .../ml/public/application/util/index_utils.ts | 58 +++++++++---------- 46 files changed, 275 insertions(+), 188 deletions(-) diff --git a/x-pack/plugins/ml/public/application/app.tsx b/x-pack/plugins/ml/public/application/app.tsx index 1df0a7afe475b1..de212cbe4916e8 100644 --- a/x-pack/plugins/ml/public/application/app.tsx +++ b/x-pack/plugins/ml/public/application/app.tsx @@ -70,7 +70,7 @@ const App: FC = ({ coreStart, deps, appMountParams }) => { const pageDeps = { history: appMountParams.history, - indexPatterns: deps.data.indexPatterns, + dataViewsContract: deps.data.dataViews, config: coreStart.uiSettings!, setBreadcrumbs: coreStart.chrome!.setBreadcrumbs, redirectToMlAccessDeniedPage, diff --git a/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.js b/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.js index 18fc10e69bc052..f2ea7ec31881bb 100644 --- a/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.js +++ b/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.js @@ -258,18 +258,18 @@ class LinksMenuUI extends Component { }; const createAndOpenUrl = (index, categorizationFieldType) => { - // Find the ID of the data view with a title attribute which matches the - // index configured in the datafeed. If a Kibana data view has not been created - // for this index, then the user will see a warning message on the Discover tab advising - // them that no matching data view has been configured. - const indexPatternId = getIndexPatternIdFromName(index) || index; - // Get the definition of the category and use the terms or regex to view the // matching events in the Kibana Discover tab depending on whether the // categorization field is of mapping type text (preferred) or keyword. ml.results .getCategoryDefinition(record.job_id, categoryId) - .then((resp) => { + .then(async (resp) => { + // Find the ID of the data view with a title attribute which matches the + // index configured in the datafeed. If a Kibana data view has not been created + // for this index, then the user will see a warning message on the Discover tab advising + // them that no matching data view has been configured. + const indexPatternId = (await getIndexPatternIdFromName(index)) ?? index; + let query = null; // Build query using categorization regex (if keyword type) or terms (if text type). // Check for terms or regex in case categoryId represents an anomaly from the absence of the diff --git a/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts b/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts index cd7059b5302f23..e724c6d737eaaf 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts @@ -14,7 +14,7 @@ export interface MlContextValue { combinedQuery: any; currentIndexPattern: DataView; // TODO this should be IndexPattern or null currentSavedSearch: SavedSearchSavedObject | null; - indexPatterns: DataViewsContract; + dataViewsContract: DataViewsContract; kibanaConfig: any; // IUiSettingsClient; kibanaVersion: string; } diff --git a/x-pack/plugins/ml/public/application/contexts/ml/use_ml_context.ts b/x-pack/plugins/ml/public/application/contexts/ml/use_ml_context.ts index 3d81c46684bef5..f0f2adb14e299c 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/use_ml_context.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/use_ml_context.ts @@ -16,7 +16,7 @@ export const useMlContext = () => { context.combinedQuery === undefined || context.currentIndexPattern === undefined || context.currentSavedSearch === undefined || - context.indexPatterns === undefined || + context.dataViewsContract === undefined || context.kibanaConfig === undefined ) { throw new Error('required attribute is undefined'); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts index ac638fe1f41a07..1a12153f173852 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts @@ -98,17 +98,17 @@ export const useResultsViewConfig = (jobId: string) => { const destIndex = Array.isArray(jobConfigUpdate.dest.index) ? jobConfigUpdate.dest.index[0] : jobConfigUpdate.dest.index; - const destIndexPatternId = getIndexPatternIdFromName(destIndex) || destIndex; + const destIndexPatternId = (await getIndexPatternIdFromName(destIndex)) ?? destIndex; let indexP: DataView | undefined; try { - indexP = await mlContext.indexPatterns.get(destIndexPatternId); + indexP = await mlContext.dataViewsContract.get(destIndexPatternId); // Force refreshing the fields list here because a user directly coming // from the job creation wizard might land on the page without the // data view being fully initialized because it was created // before the analytics job populated the destination index. - await mlContext.indexPatterns.refreshFields(indexP); + await mlContext.dataViewsContract.refreshFields(indexP); } catch (e) { indexP = undefined; } @@ -116,9 +116,10 @@ export const useResultsViewConfig = (jobId: string) => { if (indexP === undefined) { setNeedsDestIndexPattern(true); const sourceIndex = jobConfigUpdate.source.index[0]; - const sourceIndexPatternId = getIndexPatternIdFromName(sourceIndex) || sourceIndex; + const sourceIndexPatternId = + (await getIndexPatternIdFromName(sourceIndex)) ?? sourceIndex; try { - indexP = await mlContext.indexPatterns.get(sourceIndexPatternId); + indexP = await mlContext.dataViewsContract.get(sourceIndexPatternId); } catch (e) { indexP = undefined; } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts index 18abc9be270be3..88b0774e107e2e 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts @@ -127,7 +127,7 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { const dataViewName = destinationIndex; try { - await mlContext.indexPatterns.createAndSave( + await mlContext.dataViewsContract.createAndSave( { title: dataViewName, }, @@ -179,7 +179,7 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { try { // Set the existing data view names. const indexPatternsMap: SourceIndexMap = {}; - const savedObjects = (await mlContext.indexPatterns.getCache()) || []; + const savedObjects = (await mlContext.dataViewsContract.getCache()) || []; savedObjects.forEach((obj) => { const title = obj?.attributes?.title; if (title !== undefined) { @@ -201,7 +201,7 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { }; const initiateWizard = async () => { - await mlContext.indexPatterns.clearCache(); + await mlContext.dataViewsContract.clearCache(); await prepareFormValidation(); }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/components/controls.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/components/controls.tsx index 1b961c05b2f308..e2738e0fad4d4d 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/components/controls.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/components/controls.tsx @@ -112,9 +112,9 @@ export const Controls: FC = React.memo( const nodeType = selectedNode?.data('type'); const onCreateJobClick = useCallback(async () => { - const indexId = getIndexPatternIdFromName(nodeLabel); + const indexId = await getIndexPatternIdFromName(nodeLabel); - if (indexId) { + if (indexId !== null) { const path = await mlLocator.getUrl({ page: ML_PAGES.DATA_FRAME_ANALYTICS_CREATE_JOB, pageState: { index: indexId }, diff --git a/x-pack/plugins/ml/public/application/explorer/actions/job_selection.ts b/x-pack/plugins/ml/public/application/explorer/actions/job_selection.ts index 46d47bb5547055..ed244cbd894bab 100644 --- a/x-pack/plugins/ml/public/application/explorer/actions/job_selection.ts +++ b/x-pack/plugins/ml/public/application/explorer/actions/job_selection.ts @@ -17,8 +17,7 @@ import { createJobs } from '../explorer_utils'; export function jobSelectionActionCreator(selectedJobIds: string[]) { return from(mlFieldFormatService.populateFormats(selectedJobIds)).pipe( map((resp) => { - if (resp.err) { - console.log('Error populating field formats:', resp.err); // eslint-disable-line no-console + if (resp.error) { return null; } diff --git a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx index c769e2548370c3..e48c4da5815dc5 100644 --- a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx +++ b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx @@ -29,7 +29,7 @@ import { isValidLabel } from '../../../util/custom_url_utils'; import { TIME_RANGE_TYPE, URL_TYPE } from './constants'; import { UrlConfig } from '../../../../../common/types/custom_urls'; -import { DataView } from '../../../../../../../../src/plugins/data_views/common'; +import { DataViewListItem } from '../../../../../../../../src/plugins/data_views/common'; function getLinkToOptions() { return [ @@ -59,7 +59,7 @@ interface CustomUrlEditorProps { setEditCustomUrl: (url: any) => void; savedCustomUrls: UrlConfig[]; dashboards: any[]; - indexPatterns: DataView[]; + dataViewListItems: DataViewListItem[]; queryEntityFieldNames: string[]; } @@ -71,7 +71,7 @@ export const CustomUrlEditor: FC = ({ setEditCustomUrl, savedCustomUrls, dashboards, - indexPatterns, + dataViewListItems, queryEntityFieldNames, }) => { if (customUrl === undefined) { @@ -164,8 +164,8 @@ export const CustomUrlEditor: FC = ({ return { value: dashboard.id, text: dashboard.title }; }); - const indexPatternOptions = indexPatterns.map((indexPattern) => { - return { value: indexPattern.id, text: indexPattern.title }; + const indexPatternOptions = dataViewListItems.map(({ id, title }) => { + return { value: id, text: title }; }); const entityOptions = queryEntityFieldNames.map((fieldName) => ({ label: fieldName })); diff --git a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts index 1f815759c62429..1c7978a54b2b05 100644 --- a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts +++ b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.d.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { DataView } from '../../../../../../../../src/plugins/data_views/common'; +import { DataViewListItem } from '../../../../../../../../src/plugins/data_views/common'; import { UrlConfig } from '../../../../../common/types/custom_urls'; import { Job } from '../../../../../common/types/anomaly_detection_jobs'; import { TimeRangeType } from './constants'; @@ -34,7 +34,7 @@ export function isValidCustomUrlSettingsTimeRange(timeRangeSettings: any): boole export function getNewCustomUrlDefaults( job: Job, dashboards: any[], - indexPatterns: DataView[] + dataViews: DataViewListItem[] ): CustomUrlSettings; export function getQueryEntityFieldNames(job: Job): string[]; export function isValidCustomUrlSettings( diff --git a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.js b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.js index 0f12afe36b3886..63bbbffa4536bd 100644 --- a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.js +++ b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.js @@ -15,12 +15,12 @@ import { DASHBOARD_APP_URL_GENERATOR } from '../../../../../../../../src/plugins import { getPartitioningFieldNames } from '../../../../../common/util/job_utils'; import { parseInterval } from '../../../../../common/util/parse_interval'; import { replaceTokensInUrlValue, isValidLabel } from '../../../util/custom_url_utils'; -import { getIndexPatternIdFromName } from '../../../util/index_utils'; +// import { getIndexPatternIdFromName } from '../../../util/index_utils'; import { ml } from '../../../services/ml_api_service'; import { escapeForElasticsearchQuery } from '../../../util/string_utils'; import { getSavedObjectsClient, getGetUrlGenerator } from '../../../util/dependency_cache'; -export function getNewCustomUrlDefaults(job, dashboards, indexPatterns) { +export function getNewCustomUrlDefaults(job, dashboards, dataViews) { // Returns the settings object in the format used by the custom URL editor // for a new custom URL. const kibanaSettings = { @@ -32,7 +32,7 @@ export function getNewCustomUrlDefaults(job, dashboards, indexPatterns) { if (dashboards !== undefined && dashboards.length > 0) { urlType = URL_TYPE.KIBANA_DASHBOARD; kibanaSettings.dashboardId = dashboards[0].id; - } else if (indexPatterns !== undefined && indexPatterns.length > 0) { + } else if (dataViews !== undefined && dataViews.length > 0) { urlType = URL_TYPE.KIBANA_DISCOVER; } @@ -40,14 +40,16 @@ export function getNewCustomUrlDefaults(job, dashboards, indexPatterns) { // which matches the indices configured in the job datafeed. const datafeedConfig = job.datafeed_config; if ( - indexPatterns !== undefined && - indexPatterns.length > 0 && + dataViews !== undefined && + dataViews.length > 0 && datafeedConfig !== undefined && datafeedConfig.indices !== undefined && datafeedConfig.indices.length > 0 ) { - const defaultIndexPatternId = - getIndexPatternIdFromName(datafeedConfig.indices.join()) ?? indexPatterns[0].id; + // const defaultIndexPatternId = + // (await getIndexPatternIdFromName(datafeedConfig.indices.join())) ?? dataViews[0].id; + const indicesName = datafeedConfig.indices.join(); + const defaultIndexPatternId = dataViews.find((dv) => dv.title === indicesName)?.id; kibanaSettings.discoverIndexPatternId = defaultIndexPatternId; } diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts index 32e99e3e433e0b..9868b6c8bcfc89 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts @@ -6,6 +6,8 @@ */ import type { DataView } from 'src/plugins/data_views/common'; +import type { DataView, DataViewListItem } from 'src/plugins/data_views/common'; export function loadSavedDashboards(maxNumber: number): Promise; export function loadIndexPatterns(maxNumber: number): Promise; +export function loadDataViewListItems(): Promise; diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js index f32800d6b7b7ff..bfc5838d582a47 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js @@ -102,7 +102,12 @@ export function loadSavedDashboards(maxNumber) { }); } -export function loadIndexPatterns(maxNumber) { +export async function loadDataViewListItems() { + const dataViewsContract = getDataViews(); + return (await dataViewsContract.getIdsWithTitle()).sort((a, b) => a.title.localeCompare(b.title)); +} + +export function loadIndexPatterns2(maxNumber) { // Loads the list of Kibana data views, as used in editing custom URLs. return new Promise((resolve, reject) => { const dataViewsContract = getDataViews(); diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx index 45f059690c3a93..035836373adf6e 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx @@ -33,15 +33,14 @@ import { CustomUrlSettings, } from '../../../../components/custom_url_editor/utils'; import { withKibana } from '../../../../../../../../../../src/plugins/kibana_react/public'; -import { loadSavedDashboards, loadIndexPatterns } from '../edit_utils'; +import { loadSavedDashboards, loadDataViewListItems } from '../edit_utils'; import { openCustomUrlWindow } from '../../../../../util/custom_url_utils'; import { Job } from '../../../../../../../common/types/anomaly_detection_jobs'; import { UrlConfig } from '../../../../../../../common/types/custom_urls'; -import { DataView } from '../../../../../../../../../../src/plugins/data_views/common'; +import { DataViewListItem } from '../../../../../../../../../../src/plugins/data_views/common'; import { MlKibanaReactContextValue } from '../../../../../contexts/kibana'; const MAX_NUMBER_DASHBOARDS = 1000; -const MAX_NUMBER_INDEX_PATTERNS = 1000; interface CustomUrlsProps { job: Job; @@ -54,7 +53,7 @@ interface CustomUrlsProps { interface CustomUrlsState { customUrls: UrlConfig[]; dashboards: any[]; - indexPatterns: DataView[]; + dataViewListItems: DataViewListItem[]; queryEntityFieldNames: string[]; editorOpen: boolean; editorSettings?: CustomUrlSettings; @@ -67,7 +66,7 @@ class CustomUrlsUI extends Component { this.state = { customUrls: [], dashboards: [], - indexPatterns: [], + dataViewListItems: [], queryEntityFieldNames: [], editorOpen: false, }; @@ -100,9 +99,9 @@ class CustomUrlsUI extends Component { ); }); - loadIndexPatterns(MAX_NUMBER_INDEX_PATTERNS) - .then((indexPatterns) => { - this.setState({ indexPatterns }); + loadDataViewListItems() + .then((dataViewListItems) => { + this.setState({ dataViewListItems }); }) .catch((resp) => { // eslint-disable-next-line no-console @@ -121,11 +120,11 @@ class CustomUrlsUI extends Component { editNewCustomUrl = () => { // Opens the editor for configuring a new custom URL. this.setState((prevState) => { - const { dashboards, indexPatterns } = prevState; + const { dashboards, dataViewListItems } = prevState; return { editorOpen: true, - editorSettings: getNewCustomUrlDefaults(this.props.job, dashboards, indexPatterns), + editorSettings: getNewCustomUrlDefaults(this.props.job, dashboards, dataViewListItems), }; }); }; @@ -209,7 +208,7 @@ class CustomUrlsUI extends Component { editorOpen, editorSettings, dashboards, - indexPatterns, + dataViewListItems, queryEntityFieldNames, } = this.state; @@ -220,7 +219,7 @@ class CustomUrlsUI extends Component { setEditCustomUrl={this.setEditCustomUrl} savedCustomUrls={customUrls} dashboards={dashboards} - indexPatterns={indexPatterns} + dataViewListItems={dataViewListItems} queryEntityFieldNames={queryEntityFieldNames} /> ); diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_actions/management.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_actions/management.js index 1124052f863671..64bc7f4a517c28 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_actions/management.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_actions/management.js @@ -7,7 +7,6 @@ import { checkPermission } from '../../../../capabilities/check_capabilities'; import { mlNodesAvailable } from '../../../../ml_nodes_check/check_ml_nodes'; -import { getIndexPatternNames } from '../../../../util/index_utils'; import { JOB_ACTION } from '../../../../../../common/constants/job_actions'; import { @@ -19,7 +18,6 @@ import { isClosable, isResettable, } from '../utils'; -import { getToastNotifications } from '../../../../util/dependency_cache'; import { i18n } from '@kbn/i18n'; export function actionsMenuContent( @@ -136,21 +134,7 @@ export function actionsMenuContent( return isJobBlocked(item) === false && canCreateJob; }, onClick: (item) => { - const indexPatternNames = getIndexPatternNames(); - const indexPatternTitle = item.datafeedIndices.join(','); - const jobIndicesAvailable = indexPatternNames.includes(indexPatternTitle); - - if (!jobIndicesAvailable) { - getToastNotifications().addDanger( - i18n.translate('xpack.ml.jobsList.managementActions.noSourceDataViewForClone', { - defaultMessage: - 'Unable to clone the anomaly detection job {jobId}. No data view exists for index {indexPatternTitle}.', - values: { jobId: item.id, indexPatternTitle }, - }) - ); - } else { - cloneJob(item.id); - } + cloneJob(item.id); closeMenu(true); }, 'data-test-subj': 'mlActionButtonCloneJob', diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js index 414d920237e8c7..4d1bedb647e37c 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js @@ -16,6 +16,7 @@ import { import { getToastNotifications } from '../../../util/dependency_cache'; import { ml } from '../../../services/ml_api_service'; import { stringMatch } from '../../../util/string_utils'; +import { getIndexPatternNames } from '../../../util/index_utils'; import { JOB_STATE, DATAFEED_STATE } from '../../../../../common/constants/states'; import { JOB_ACTION } from '../../../../../common/constants/job_actions'; import { parseInterval } from '../../../../../common/util/parse_interval'; @@ -217,6 +218,15 @@ export async function cloneJob(jobId) { loadJobForCloning(jobId), loadFullJob(jobId, false), ]); + + const indexPatternNames = await getIndexPatternNames(); + const indexPatternTitle = datafeed.indices.join(','); + const jobIndicesAvailable = indexPatternNames.includes(indexPatternTitle); + + if (jobIndicesAvailable === false) { + return; + } + if (cloneableJob !== undefined && originalJob?.custom_settings?.created_by !== undefined) { // if the job is from a wizards, i.e. contains a created_by property // use tempJobCloningObjects to temporarily store the job diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts b/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts index 03428bd47e4904..d2b842549be48f 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts @@ -8,20 +8,24 @@ import type { ApplicationStart } from 'kibana/public'; import type { DataViewsContract } from '../../../../../../../../../src/plugins/data_views/public'; import { mlJobService } from '../../../../services/job_service'; -import { loadIndexPatterns, getIndexPatternIdFromName } from '../../../../util/index_utils'; -import { Datafeed, Job } from '../../../../../../common/types/anomaly_detection_jobs'; +import { Datafeed } from '../../../../../../common/types/anomaly_detection_jobs'; import { CREATED_BY_LABEL, JOB_TYPE } from '../../../../../../common/constants/new_job'; export async function preConfiguredJobRedirect( - indexPatterns: DataViewsContract, + dataViewsContract: DataViewsContract, basePath: string, navigateToUrl: ApplicationStart['navigateToUrl'] ) { const { createdBy, job, datafeed } = mlJobService.tempJobCloningObjects; + if (job && datafeed) { + const indexPatternId = await getIndexPatternIdFromName(datafeed, dataViewsContract); + if (indexPatternId === null) { + return Promise.resolve(); + } + try { - await loadIndexPatterns(indexPatterns); - const redirectUrl = getWizardUrlFromCloningJob(createdBy, job, datafeed); + const redirectUrl = await getWizardUrlFromCloningJob(createdBy, indexPatternId); await navigateToUrl(`${basePath}/app/ml/${redirectUrl}`); return Promise.reject(); } catch (error) { @@ -34,7 +38,7 @@ export async function preConfiguredJobRedirect( } } -function getWizardUrlFromCloningJob(createdBy: string | undefined, job: Job, datafeed: Datafeed) { +async function getWizardUrlFromCloningJob(createdBy: string | undefined, indexPatternId: string) { const created = createdBy; let page = ''; @@ -59,7 +63,20 @@ function getWizardUrlFromCloningJob(createdBy: string | undefined, job: Job, dat break; } - const indexPatternId = getIndexPatternIdFromName(datafeed.indices.join()); - return `jobs/new_job/${page}?index=${indexPatternId}&_g=()`; } + +async function getIndexPatternIdFromName( + datafeed: Datafeed, + dataViewsContract: DataViewsContract +): Promise { + if (dataViewsContract === null) { + throw Error('ARGGHH'); + } + + const [dv] = await dataViewsContract?.find(datafeed.indices.join(',')); + if (!dv) { + return null; + } + return dv.id ?? dv.title; +} diff --git a/x-pack/plugins/ml/public/application/routing/resolvers.ts b/x-pack/plugins/ml/public/application/routing/resolvers.ts index 3479005809efba..d95dfc9d2784f6 100644 --- a/x-pack/plugins/ml/public/application/routing/resolvers.ts +++ b/x-pack/plugins/ml/public/application/routing/resolvers.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { loadIndexPatterns, loadSavedSearches } from '../util/index_utils'; +import { cacheDataViewsContract, loadSavedSearches } from '../util/index_utils'; import { checkFullLicense } from '../license'; import { checkGetJobsCapabilitiesResolver } from '../capabilities/check_capabilities'; import { getMlNodeCount } from '../ml_nodes_check/check_ml_nodes'; @@ -21,18 +21,18 @@ export interface ResolverResults { } interface BasicResolverDependencies { - indexPatterns: DataViewsContract; + dataViewsContract: DataViewsContract; redirectToMlAccessDeniedPage: () => Promise; } export const basicResolvers = ({ - indexPatterns, + dataViewsContract, redirectToMlAccessDeniedPage, }: BasicResolverDependencies): Resolvers => ({ checkFullLicense, getMlNodeCount, loadMlServerInfo, - loadIndexPatterns: () => loadIndexPatterns(indexPatterns), + cacheDataViewsContract: () => cacheDataViewsContract(dataViewsContract), checkGetJobsCapabilities: () => checkGetJobsCapabilitiesResolver(redirectToMlAccessDeniedPage), loadSavedSearches, }); diff --git a/x-pack/plugins/ml/public/application/routing/router.tsx b/x-pack/plugins/ml/public/application/routing/router.tsx index 847dcc1ae11078..5f220d86cd6ad1 100644 --- a/x-pack/plugins/ml/public/application/routing/router.tsx +++ b/x-pack/plugins/ml/public/application/routing/router.tsx @@ -43,7 +43,7 @@ export interface PageProps { interface PageDependencies { config: IUiSettingsClient; history: AppMountParameters['history']; - indexPatterns: DataViewsContract; + dataViewsContract: DataViewsContract; setBreadcrumbs: ChromeStart['setBreadcrumbs']; redirectToMlAccessDeniedPage: () => Promise; } diff --git a/x-pack/plugins/ml/public/application/routing/routes/access_denied.tsx b/x-pack/plugins/ml/public/application/routing/routes/access_denied.tsx index afb36b89732f14..10b2d1438c32b4 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/access_denied.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/access_denied.tsx @@ -27,7 +27,7 @@ export const accessDeniedRouteFactory = (): MlRoute => ({ }); const PageWrapper: FC = ({ deps }) => { - const { context } = useResolver(undefined, undefined, deps.config, {}); + const { context } = useResolver(undefined, undefined, deps.config, deps.dataViewsContract, {}); return ( diff --git a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_creation.tsx b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_creation.tsx index ab57c264683ca4..e550eaa338b08b 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_creation.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_creation.tsx @@ -44,10 +44,10 @@ const PageWrapper: FC = ({ location, deps }) => { sort: false, }); - const { context } = useResolver(index, savedSearchId, deps.config, { + const { context } = useResolver(index, savedSearchId, deps.config, deps.dataViewsContract, { ...basicResolvers(deps), analyticsFields: () => - loadNewJobCapabilities(index, savedSearchId, deps.indexPatterns, DATA_FRAME_ANALYTICS), + loadNewJobCapabilities(index, savedSearchId, deps.dataViewsContract, DATA_FRAME_ANALYTICS), }); return ( diff --git a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_exploration.tsx b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_exploration.tsx index 98603f69f382f7..49a756fd12ced5 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_exploration.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_exploration.tsx @@ -39,7 +39,13 @@ export const analyticsJobExplorationRouteFactory = ( }); const PageWrapper: FC = ({ location, deps }) => { - const { context } = useResolver(undefined, undefined, deps.config, basicResolvers(deps)); + const { context } = useResolver( + undefined, + undefined, + deps.config, + deps.dataViewsContract, + basicResolvers(deps) + ); const [globalState] = useUrlState('_g'); diff --git a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_jobs_list.tsx b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_jobs_list.tsx index d6a70105a71b42..2e55a9e85fb6eb 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_jobs_list.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_jobs_list.tsx @@ -35,7 +35,13 @@ export const analyticsJobsListRouteFactory = ( }); const PageWrapper: FC = ({ location, deps }) => { - const { context } = useResolver(undefined, undefined, deps.config, basicResolvers(deps)); + const { context } = useResolver( + undefined, + undefined, + deps.config, + deps.dataViewsContract, + basicResolvers(deps) + ); return ( diff --git a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_map.tsx b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_map.tsx index 77e7d3b3740ef7..29bf616041624b 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_map.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_map.tsx @@ -35,7 +35,13 @@ export const analyticsMapRouteFactory = ( }); const PageWrapper: FC = ({ deps }) => { - const { context } = useResolver(undefined, undefined, deps.config, basicResolvers(deps)); + const { context } = useResolver( + undefined, + undefined, + deps.config, + deps.dataViewsContract, + basicResolvers(deps) + ); return ( diff --git a/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/datavisualizer.tsx b/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/datavisualizer.tsx index b2466c74667472..4db8d9a0c72f39 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/datavisualizer.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/datavisualizer.tsx @@ -32,7 +32,7 @@ export const selectorRouteFactory = ( const PageWrapper: FC = ({ location, deps }) => { const { redirectToMlAccessDeniedPage } = deps; - const { context } = useResolver(undefined, undefined, deps.config, { + const { context } = useResolver(undefined, undefined, deps.config, deps.dataViewsContract, { checkBasicLicense, checkFindFileStructurePrivilege: () => checkFindFileStructurePrivilegeResolver(redirectToMlAccessDeniedPage), diff --git a/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/file_based.tsx b/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/file_based.tsx index 5b16bf8352b27b..9e48940a29b568 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/file_based.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/file_based.tsx @@ -16,7 +16,7 @@ import { FileDataVisualizerPage } from '../../../datavisualizer/file_based'; import { checkBasicLicense } from '../../../license'; import { checkFindFileStructurePrivilegeResolver } from '../../../capabilities/check_capabilities'; -import { loadIndexPatterns } from '../../../util/index_utils'; +import { cacheDataViewsContract } from '../../../util/index_utils'; import { getBreadcrumbWithUrlForApp } from '../../breadcrumbs'; @@ -41,9 +41,9 @@ export const fileBasedRouteFactory = ( const PageWrapper: FC = ({ deps }) => { const { redirectToMlAccessDeniedPage } = deps; - const { context } = useResolver(undefined, undefined, deps.config, { + const { context } = useResolver(undefined, undefined, deps.config, deps.dataViewsContract, { checkBasicLicense, - loadIndexPatterns: () => loadIndexPatterns(deps.indexPatterns), + cacheDataViewsContract: () => cacheDataViewsContract(deps.dataViewsContract), checkFindFileStructurePrivilege: () => checkFindFileStructurePrivilegeResolver(redirectToMlAccessDeniedPage), }); diff --git a/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx b/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx index 04543a28ab3e6b..dde1a3a7685532 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx @@ -18,7 +18,7 @@ import { IndexDataVisualizerPage as Page } from '../../../datavisualizer/index_b import { checkBasicLicense } from '../../../license'; import { checkGetJobsCapabilitiesResolver } from '../../../capabilities/check_capabilities'; -import { loadIndexPatterns } from '../../../util/index_utils'; +import { cacheDataViewsContract } from '../../../util/index_utils'; import { getBreadcrumbWithUrlForApp } from '../../breadcrumbs'; export const indexBasedRouteFactory = ( @@ -43,9 +43,9 @@ const PageWrapper: FC = ({ location, deps }) => { const { redirectToMlAccessDeniedPage } = deps; const { index, savedSearchId }: Record = parse(location.search, { sort: false }); - const { context } = useResolver(index, savedSearchId, deps.config, { + const { context } = useResolver(index, savedSearchId, deps.config, deps.dataViewsContract, { checkBasicLicense, - loadIndexPatterns: () => loadIndexPatterns(deps.indexPatterns), + cacheDataViewsContract: () => cacheDataViewsContract(deps.dataViewsContract), checkGetJobsCapabilities: () => checkGetJobsCapabilitiesResolver(redirectToMlAccessDeniedPage), }); 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 49e7857eee082c..e50dc301f970b5 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/explorer.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/explorer.tsx @@ -57,11 +57,17 @@ export const explorerRouteFactory = ( }); const PageWrapper: FC = ({ deps }) => { - const { context, results } = useResolver(undefined, undefined, deps.config, { - ...basicResolvers(deps), - jobs: mlJobService.loadJobsWrapper, - jobsWithTimeRange: () => ml.jobs.jobsWithTimerange(getDateFormatTz()), - }); + const { context, results } = useResolver( + undefined, + undefined, + deps.config, + deps.dataViewsContract, + { + ...basicResolvers(deps), + jobs: mlJobService.loadJobsWrapper, + jobsWithTimeRange: () => ml.jobs.jobsWithTimerange(getDateFormatTz()), + } + ); const annotationUpdatesService = useMemo(() => new AnnotationUpdatesService(), []); return ( diff --git a/x-pack/plugins/ml/public/application/routing/routes/jobs_list.tsx b/x-pack/plugins/ml/public/application/routing/routes/jobs_list.tsx index ecaa0a9e42e3f6..52cdfc5c42b2d0 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/jobs_list.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/jobs_list.tsx @@ -39,7 +39,13 @@ export const jobListRouteFactory = (navigateToPath: NavigateToPath, basePath: st }); const PageWrapper: FC = ({ deps }) => { - const { context } = useResolver(undefined, undefined, deps.config, basicResolvers(deps)); + const { context } = useResolver( + undefined, + undefined, + deps.config, + deps.dataViewsContract, + basicResolvers(deps) + ); const timefilter = useTimefilter({ timeRangeSelector: false, autoRefreshSelector: true }); const [globalState, setGlobalState] = useUrlState('_g'); diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/index_or_search.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/index_or_search.tsx index 53057cb16c1320..e92bac32debcbd 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/index_or_search.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/index_or_search.tsx @@ -17,7 +17,7 @@ import { basicResolvers } from '../../resolvers'; import { Page, preConfiguredJobRedirect } from '../../../jobs/new_job/pages/index_or_search'; import { getBreadcrumbWithUrlForApp } from '../../breadcrumbs'; import { checkBasicLicense } from '../../../license'; -import { loadIndexPatterns } from '../../../util/index_utils'; +import { cacheDataViewsContract } from '../../../util/index_utils'; import { checkGetJobsCapabilitiesResolver } from '../../../capabilities/check_capabilities'; enum MODE { @@ -86,11 +86,11 @@ const PageWrapper: FC = ({ nextStepPath, deps, mode }) = const newJobResolvers = { ...basicResolvers(deps), preConfiguredJobRedirect: () => - preConfiguredJobRedirect(deps.indexPatterns, basePath.get(), navigateToUrl), + preConfiguredJobRedirect(deps.dataViewsContract, basePath.get(), navigateToUrl), }; const dataVizResolvers = { checkBasicLicense, - loadIndexPatterns: () => loadIndexPatterns(deps.indexPatterns), + cacheDataViewsContract: () => cacheDataViewsContract(deps.dataViewsContract), checkGetJobsCapabilities: () => checkGetJobsCapabilitiesResolver(redirectToMlAccessDeniedPage), }; @@ -98,6 +98,7 @@ const PageWrapper: FC = ({ nextStepPath, deps, mode }) = undefined, undefined, deps.config, + deps.dataViewsContract, mode === MODE.NEW_JOB ? newJobResolvers : dataVizResolvers ); return ( diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/job_type.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/job_type.tsx index 235a91ea737911..cdd2b890f086ed 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/job_type.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/job_type.tsx @@ -35,7 +35,13 @@ export const jobTypeRouteFactory = (navigateToPath: NavigateToPath, basePath: st const PageWrapper: FC = ({ location, deps }) => { const { index, savedSearchId }: Record = parse(location.search, { sort: false }); - const { context } = useResolver(index, savedSearchId, deps.config, basicResolvers(deps)); + const { context } = useResolver( + index, + savedSearchId, + deps.config, + deps.dataViewsContract, + basicResolvers(deps) + ); return ( diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx index 125d7cbb0f84a9..26c18d9813376b 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx @@ -49,10 +49,16 @@ export const checkViewOrCreateRouteFactory = (): MlRoute => ({ const PageWrapper: FC = ({ location, deps }) => { const { id, index, savedSearchId }: Record = parse(location.search, { sort: false }); - const { context, results } = useResolver(index, savedSearchId, deps.config, { - ...basicResolvers(deps), - existingJobsAndGroups: mlJobService.getJobAndGroupIds, - }); + const { context, results } = useResolver( + index, + savedSearchId, + deps.config, + deps.dataViewsContract, + { + ...basicResolvers(deps), + existingJobsAndGroups: mlJobService.getJobAndGroupIds, + } + ); return ( @@ -70,7 +76,7 @@ const CheckViewOrCreateWrapper: FC = ({ location, deps }) => { const navigateToPath = useNavigateToPath(); // the single resolver checkViewOrCreateJobs redirects only. so will always reject - useResolver(undefined, undefined, deps.config, { + useResolver(undefined, undefined, deps.config, deps.dataViewsContract, { checkViewOrCreateJobs: () => checkViewOrCreateJobs(moduleId, indexPatternId, createLinkWithUserDefaults, navigateToPath), }); diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/wizard.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/wizard.tsx index d95fbcaba9f67f..7953d15a55b1e0 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/wizard.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/wizard.tsx @@ -153,13 +153,19 @@ const PageWrapper: FC = ({ location, jobType, deps }) => { ); const { index, savedSearchId }: Record = parse(location.search, { sort: false }); - const { context, results } = useResolver(index, savedSearchId, deps.config, { - ...basicResolvers(deps), - privileges: () => checkCreateJobsCapabilitiesResolver(redirectToJobsManagementPage), - jobCaps: () => - loadNewJobCapabilities(index, savedSearchId, deps.indexPatterns, ANOMALY_DETECTOR), - existingJobsAndGroups: mlJobService.getJobAndGroupIds, - }); + const { context, results } = useResolver( + index, + savedSearchId, + deps.config, + deps.dataViewsContract, + { + ...basicResolvers(deps), + privileges: () => checkCreateJobsCapabilitiesResolver(redirectToJobsManagementPage), + jobCaps: () => + loadNewJobCapabilities(index, savedSearchId, deps.dataViewsContract, ANOMALY_DETECTOR), + existingJobsAndGroups: mlJobService.getJobAndGroupIds, + } + ); return ( diff --git a/x-pack/plugins/ml/public/application/routing/routes/overview.tsx b/x-pack/plugins/ml/public/application/routing/routes/overview.tsx index 9f21609db35ca3..dd3fc70a6425e4 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/overview.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/overview.tsx @@ -44,7 +44,7 @@ export const overviewRouteFactory = ( const PageWrapper: FC = ({ deps }) => { const { redirectToMlAccessDeniedPage } = deps; - const { context } = useResolver(undefined, undefined, deps.config, { + const { context } = useResolver(undefined, undefined, deps.config, deps.dataViewsContract, { checkFullLicense, checkGetJobsCapabilities: () => checkGetJobsCapabilitiesResolver(redirectToMlAccessDeniedPage), getMlNodeCount, diff --git a/x-pack/plugins/ml/public/application/routing/routes/settings/calendar_list.tsx b/x-pack/plugins/ml/public/application/routing/routes/settings/calendar_list.tsx index d8a59ebed9de69..08949d5d514b2b 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/settings/calendar_list.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/settings/calendar_list.tsx @@ -38,7 +38,7 @@ export const calendarListRouteFactory = ( const PageWrapper: FC = ({ deps }) => { const { redirectToMlAccessDeniedPage } = deps; - const { context } = useResolver(undefined, undefined, deps.config, { + const { context } = useResolver(undefined, undefined, deps.config, deps.dataViewsContract, { checkFullLicense, checkGetJobsCapabilities: () => checkGetJobsCapabilitiesResolver(redirectToMlAccessDeniedPage), getMlNodeCount, diff --git a/x-pack/plugins/ml/public/application/routing/routes/settings/calendar_new_edit.tsx b/x-pack/plugins/ml/public/application/routing/routes/settings/calendar_new_edit.tsx index 18c4d43b564d7b..05f9f92479f45c 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/settings/calendar_new_edit.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/settings/calendar_new_edit.tsx @@ -83,7 +83,7 @@ const PageWrapper: FC = ({ location, mode, deps }) => { ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE ); - const { context } = useResolver(undefined, undefined, deps.config, { + const { context } = useResolver(undefined, undefined, deps.config, deps.dataViewsContract, { checkFullLicense, checkGetJobsCapabilities: () => checkGetJobsCapabilitiesResolver(redirectToMlAccessDeniedPage), checkMlNodesAvailable: () => checkMlNodesAvailable(redirectToJobsManagementPage), diff --git a/x-pack/plugins/ml/public/application/routing/routes/settings/filter_list.tsx b/x-pack/plugins/ml/public/application/routing/routes/settings/filter_list.tsx index d28569ff8aaa40..8e956ecf59d5d5 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/settings/filter_list.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/settings/filter_list.tsx @@ -39,7 +39,7 @@ export const filterListRouteFactory = ( const PageWrapper: FC = ({ deps }) => { const { redirectToMlAccessDeniedPage } = deps; - const { context } = useResolver(undefined, undefined, deps.config, { + const { context } = useResolver(undefined, undefined, deps.config, deps.dataViewsContract, { checkFullLicense, checkGetJobsCapabilities: () => checkGetJobsCapabilitiesResolver(redirectToMlAccessDeniedPage), getMlNodeCount, diff --git a/x-pack/plugins/ml/public/application/routing/routes/settings/filter_list_new_edit.tsx b/x-pack/plugins/ml/public/application/routing/routes/settings/filter_list_new_edit.tsx index e12a33b48439cf..cf320632106242 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/settings/filter_list_new_edit.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/settings/filter_list_new_edit.tsx @@ -85,7 +85,7 @@ const PageWrapper: FC = ({ location, mode, deps }) => { ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE ); - const { context } = useResolver(undefined, undefined, deps.config, { + const { context } = useResolver(undefined, undefined, deps.config, deps.dataViewsContract, { checkFullLicense, checkGetJobsCapabilities: () => checkGetJobsCapabilitiesResolver(redirectToMlAccessDeniedPage), checkMlNodesAvailable: () => checkMlNodesAvailable(redirectToJobsManagementPage), diff --git a/x-pack/plugins/ml/public/application/routing/routes/settings/settings.tsx b/x-pack/plugins/ml/public/application/routing/routes/settings/settings.tsx index 51b8e8e8376330..5e0e8dbc801e7f 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/settings/settings.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/settings/settings.tsx @@ -37,7 +37,7 @@ export const settingsRouteFactory = ( const PageWrapper: FC = ({ deps }) => { const { redirectToMlAccessDeniedPage } = deps; - const { context } = useResolver(undefined, undefined, deps.config, { + const { context } = useResolver(undefined, undefined, deps.config, deps.dataViewsContract, { checkFullLicense, checkGetJobsCapabilities: () => checkGetJobsCapabilitiesResolver(redirectToMlAccessDeniedPage), getMlNodeCount, diff --git a/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer.tsx b/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer.tsx index 8c704ef4240a05..91697b8a89bd79 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer.tsx @@ -65,11 +65,17 @@ export const timeSeriesExplorerRouteFactory = ( }); const PageWrapper: FC = ({ deps }) => { - const { context, results } = useResolver(undefined, undefined, deps.config, { - ...basicResolvers(deps), - jobs: mlJobService.loadJobsWrapper, - jobsWithTimeRange: () => ml.jobs.jobsWithTimerange(getDateFormatTz()), - }); + const { context, results } = useResolver( + undefined, + undefined, + deps.config, + deps.dataViewsContract, + { + ...basicResolvers(deps), + jobs: mlJobService.loadJobsWrapper, + jobsWithTimeRange: () => ml.jobs.jobsWithTimerange(getDateFormatTz()), + } + ); const annotationUpdatesService = useMemo(() => new AnnotationUpdatesService(), []); return ( diff --git a/x-pack/plugins/ml/public/application/routing/routes/trained_models/models_list.tsx b/x-pack/plugins/ml/public/application/routing/routes/trained_models/models_list.tsx index 9367a58372484e..646df84aee5e70 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/trained_models/models_list.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/trained_models/models_list.tsx @@ -35,7 +35,13 @@ export const modelsListRouteFactory = ( }); const PageWrapper: FC = ({ location, deps }) => { - const { context } = useResolver(undefined, undefined, deps.config, basicResolvers(deps)); + const { context } = useResolver( + undefined, + undefined, + deps.config, + deps.dataViewsContract, + basicResolvers(deps) + ); return ( diff --git a/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts b/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts index 4c5c8c7b21ddd9..7b8b10710b7ae0 100644 --- a/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts +++ b/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts @@ -11,6 +11,7 @@ import { IUiSettingsClient } from 'kibana/public'; import { useCreateAndNavigateToMlLink } from '../contexts/kibana/use_create_url'; import { useNotifications } from '../contexts/kibana'; +import type { DataViewsContract } from '../../../../../../src/plugins/data_views/public'; import { useResolver } from './use_resolver'; @@ -46,7 +47,7 @@ describe('useResolver', () => { it('should accept undefined as indexPatternId and savedSearchId.', async () => { const { result, waitForNextUpdate } = renderHook(() => - useResolver(undefined, undefined, {} as IUiSettingsClient, {}) + useResolver(undefined, undefined, {} as IUiSettingsClient, {} as DataViewsContract, {}) ); await act(async () => { @@ -76,7 +77,9 @@ describe('useResolver', () => { }); it('should add an error toast and redirect if indexPatternId is an empty string.', async () => { - const { result } = renderHook(() => useResolver('', undefined, {} as IUiSettingsClient, {})); + const { result } = renderHook(() => + useResolver('', undefined, {} as IUiSettingsClient, {} as DataViewsContract, {}) + ); await act(async () => {}); diff --git a/x-pack/plugins/ml/public/application/routing/use_resolver.ts b/x-pack/plugins/ml/public/application/routing/use_resolver.ts index 62450106d0dfbe..f15e66f1e75c0c 100644 --- a/x-pack/plugins/ml/public/application/routing/use_resolver.ts +++ b/x-pack/plugins/ml/public/application/routing/use_resolver.ts @@ -10,7 +10,6 @@ import { IUiSettingsClient } from 'kibana/public'; import { i18n } from '@kbn/i18n'; import { getIndexPatternById, - getIndexPatternsContract, getIndexPatternAndSavedSearch, IndexPatternAndSavedSearch, } from '../util/index_utils'; @@ -20,6 +19,7 @@ import { MlContextValue } from '../contexts/ml'; import { useNotifications } from '../contexts/kibana'; import { useCreateAndNavigateToMlLink } from '../contexts/kibana/use_create_url'; import { ML_PAGES } from '../../../common/constants/locator'; +import type { DataViewsContract } from '../../../../../../src/plugins/data_views/public'; /** * Hook to resolve route specific requirements @@ -33,6 +33,7 @@ export const useResolver = ( indexPatternId: string | undefined, savedSearchId: string | undefined, config: IUiSettingsClient, + dataViewsContract: DataViewsContract, resolvers: Resolvers ): { context: MlContextValue; results: ResolverResults } => { const notifications = useNotifications(); @@ -94,7 +95,7 @@ export const useResolver = ( combinedQuery, currentIndexPattern: indexPattern, currentSavedSearch: savedSearch, - indexPatterns: getIndexPatternsContract(), + dataViewsContract, kibanaConfig: config, }); } catch (error) { diff --git a/x-pack/plugins/ml/public/application/services/field_format_service.ts b/x-pack/plugins/ml/public/application/services/field_format_service.ts index d95975156a99d9..252f83ab514816 100644 --- a/x-pack/plugins/ml/public/application/services/field_format_service.ts +++ b/x-pack/plugins/ml/public/application/services/field_format_service.ts @@ -25,35 +25,40 @@ class FieldFormatService { // configured in the datafeed of each job. // Builds a map of Kibana FieldFormats (plugins/data/common/field_formats) // against detector index by job ID. - populateFormats(jobIds: string[]): Promise { - return new Promise((resolve, reject) => { - // Populate a map of data view IDs against job ID, by finding the ID of the data - // view with a title attribute which matches the indices configured in the datafeed. - // If a Kibana data view has not been created - // for this index, then no custom field formatting will occur. - jobIds.forEach((jobId) => { - const jobObj = mlJobService.getJob(jobId); - const datafeedIndices = jobObj.datafeed_config.indices; - const id = getIndexPatternIdFromName(datafeedIndices.length ? datafeedIndices[0] : ''); - if (id !== null) { - this.indexPatternIdsByJob[jobId] = id; - } - }); + async populateFormats(jobIds: string[]): Promise { + // Populate a map of data view IDs against job ID, by finding the ID of the data + // view with a title attribute which matches the indices configured in the datafeed. + // If a Kibana data view has not been created + // for this index, then no custom field formatting will occur. + ( + await Promise.all( + jobIds.map(async (jobId) => { + const jobObj = mlJobService.getJob(jobId); + return { + jobId, + dataViewId: await getIndexPatternIdFromName(jobObj.datafeed_config.indices.join(',')), + }; + }) + ) + ).forEach(({ jobId, dataViewId }) => { + if (dataViewId !== null) { + this.indexPatternIdsByJob[jobId] = dataViewId; + } + }); - const promises = jobIds.map((jobId) => Promise.all([this.getFormatsForJob(jobId)])); + const promises = jobIds.map((jobId) => Promise.all([this.getFormatsForJob(jobId)])); - Promise.all(promises) - .then((fmtsByJobByDetector) => { - fmtsByJobByDetector.forEach((formatsByDetector, i) => { - this.formatsByJob[jobIds[i]] = formatsByDetector[0]; - }); + try { + const fmtsByJobByDetector = await Promise.all(promises); + fmtsByJobByDetector.forEach((formatsByDetector, i) => { + this.formatsByJob[jobIds[i]] = formatsByDetector[0]; + }); - resolve(this.formatsByJob); - }) - .catch((err) => { - reject({ formats: {}, err }); - }); - }); + return this.formatsByJob; + } catch (error) { + console.log('Error populating field formats:', error); // eslint-disable-line no-console + return { formats: {}, error }; + } } // Return the FieldFormat to use for formatting values from diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js index 9b8770350909ea..c15114bbd2a24a 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js @@ -720,9 +720,7 @@ export class TimeSeriesExplorer extends React.Component { appStateHandler(APP_STATE_ACTION.SET_DETECTOR_INDEX, detectorId); } // Populate the map of jobs / detectors / field formatters for the selected IDs and refresh. - mlFieldFormatService.populateFormats([jobId]).catch((err) => { - console.log('Error populating field formats:', err); - }); + mlFieldFormatService.populateFormats([jobId]); } componentDidMount() { diff --git a/x-pack/plugins/ml/public/application/util/index_utils.ts b/x-pack/plugins/ml/public/application/util/index_utils.ts index b105761e5ebcff..f9d8107529243d 100644 --- a/x-pack/plugins/ml/public/application/util/index_utils.ts +++ b/x-pack/plugins/ml/public/application/util/index_utils.ts @@ -9,17 +9,13 @@ import { i18n } from '@kbn/i18n'; import type { Query } from '../../../../../../src/plugins/data/public'; import type { DataView, DataViewsContract } from '../../../../../../src/plugins/data_views/public'; import type { SavedSearchSavedObject } from '../../../common/types/kibana'; -import { getToastNotifications, getSavedObjectsClient, getDataViews } from './dependency_cache'; +import { getToastNotifications, getSavedObjectsClient } from './dependency_cache'; -let indexPatternCache: DataView[] = []; let savedSearchesCache: SavedSearchSavedObject[] = []; -let indexPatternsContract: DataViewsContract | null = null; +let dataViewsContract: DataViewsContract | null = null; -export async function loadIndexPatterns(indexPatterns: DataViewsContract) { - indexPatternsContract = indexPatterns; - const dataViewsContract = getDataViews(); - indexPatternCache = await dataViewsContract.find('*', 10000); - return indexPatternCache; +export async function cacheDataViewsContract(dvc: DataViewsContract) { + dataViewsContract = dvc; } export function loadSavedSearches() { @@ -41,25 +37,41 @@ export async function loadSavedSearchById(id: string) { return ss.error === undefined ? ss : null; } -export function getIndexPatterns() { - return indexPatternCache; +export async function getIndexPatternNames() { + if (dataViewsContract === null) { + throw new Error('Data views are not initialized!'); + } + return (await dataViewsContract.getIdsWithTitle()).map(({ title }) => title); } -export function getIndexPatternsContract() { - return indexPatternsContract; +export async function getIndexPatternIdFromName(name: string): Promise { + if (dataViewsContract === null) { + throw new Error('Data views are not initialized!'); + } + const [dv] = await dataViewsContract?.find(name); + if (!dv) { + return null; + } + return dv.id ?? dv.title; } -export function getIndexPatternNames() { - return indexPatternCache.map((i) => i.title); -} +export function getIndexPatternById(id: string): Promise { + if (dataViewsContract === null) { + throw new Error('Data views are not initialized!'); + } -export function getIndexPatternIdFromName(name: string) { - return indexPatternCache.find((i) => i.title === name)?.id ?? null; + if (id) { + return dataViewsContract.get(id); + } else { + return dataViewsContract.create({}); + } } + export interface IndexPatternAndSavedSearch { savedSearch: SavedSearchSavedObject | null; indexPattern: DataView | null; } + export async function getIndexPatternAndSavedSearch(savedSearchId: string) { const resp: IndexPatternAndSavedSearch = { savedSearch: null, @@ -88,18 +100,6 @@ export function getQueryFromSavedSearchObject(savedSearch: SavedSearchSavedObjec }; } -export function getIndexPatternById(id: string): Promise { - if (indexPatternsContract !== null) { - if (id) { - return indexPatternsContract.get(id); - } else { - return indexPatternsContract.create({}); - } - } else { - throw new Error('Data views are not initialized!'); - } -} - export function getSavedSearchById(id: string): SavedSearchSavedObject | undefined { return savedSearchesCache.find((s) => s.id === id); } From c2c4093ccc89cb432d7b01b9959cb16b340ec394 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Wed, 27 Oct 2021 16:33:00 +0100 Subject: [PATCH 2/6] more renaming --- .../components/anomalies_table/links_menu.js | 6 ++-- .../full_time_range_selector.test.tsx | 4 +-- .../full_time_range_selector.tsx | 8 ++--- .../ml/__mocks__/kibana_context_value.ts | 2 +- .../application/contexts/ml/ml_context.ts | 4 +-- .../contexts/ml/use_current_index_pattern.ts | 6 ++-- .../application/contexts/ml/use_ml_context.ts | 2 +- .../common/use_results_view_config.ts | 27 +++++++------- .../configuration_step_details.tsx | 4 +-- .../configuration_step_form.tsx | 22 ++++++------ .../configuration_step/use_saved_search.ts | 4 +-- .../runtime_mappings/runtime_mappings.tsx | 7 ++-- .../pages/analytics_creation/page.tsx | 6 ++-- .../source_selection.test.tsx | 35 ++++++++----------- .../source_selection/source_selection.tsx | 6 ++-- .../pages/job_map/components/controls.tsx | 8 ++--- .../custom_url_editor/editor.test.tsx | 8 ++--- .../components/custom_url_editor/editor.tsx | 4 +-- .../components/custom_url_editor/utils.js | 7 ++-- .../edit_job_flyout/edit_utils.d.ts | 4 +-- .../components/edit_job_flyout/edit_utils.js | 16 --------- .../jobs/jobs_list/components/utils.js | 7 ++-- .../estimate_bucket_span.ts | 4 +-- .../components/time_range_step/time_range.tsx | 2 +- .../preconfigured_job_redirect.ts | 12 +++---- .../jobs/new_job/pages/job_type/page.tsx | 18 +++++----- .../jobs/new_job/pages/new_job/page.tsx | 4 +-- .../new_job/pages/new_job/wizard_steps.tsx | 4 +-- .../components/job_settings_form.tsx | 4 +-- .../jobs/new_job/recognize/page.tsx | 12 +++---- .../routes/trained_models/nodes_list.tsx | 8 ++++- .../application/routing/use_resolver.test.ts | 2 +- .../application/routing/use_resolver.ts | 30 ++++++++-------- .../services/field_format_service.ts | 17 +++++---- .../load_new_job_capabilities.ts | 18 +++++----- .../new_job_capabilities._service.test.ts | 8 ++--- .../new_job_capabilities_service.ts | 8 ++--- .../new_job_capabilities_service_analytics.ts | 8 ++--- .../ml/public/application/util/index_utils.ts | 26 +++++++------- 39 files changed, 178 insertions(+), 204 deletions(-) diff --git a/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.js b/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.js index f2ea7ec31881bb..b0561893eb19f9 100644 --- a/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.js +++ b/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.js @@ -28,7 +28,7 @@ import { ml } from '../../services/ml_api_service'; import { mlJobService } from '../../services/job_service'; import { getUrlForRecord, openCustomUrlWindow } from '../../util/custom_url_utils'; import { formatHumanReadableDateTimeSeconds } from '../../../../common/util/date_utils'; -import { getIndexPatternIdFromName } from '../../util/index_utils'; +import { getDataViewIdFromName } from '../../util/index_utils'; import { replaceStringTokens } from '../../util/string_utils'; import { ML_APP_LOCATOR, ML_PAGES } from '../../../../common/constants/locator'; /* @@ -268,7 +268,7 @@ class LinksMenuUI extends Component { // index configured in the datafeed. If a Kibana data view has not been created // for this index, then the user will see a warning message on the Discover tab advising // them that no matching data view has been configured. - const indexPatternId = (await getIndexPatternIdFromName(index)) ?? index; + const dataViewId = (await getDataViewIdFromName(index)) ?? index; let query = null; // Build query using categorization regex (if keyword type) or terms (if text type). @@ -313,7 +313,7 @@ class LinksMenuUI extends Component { }); const appStateProps = { - index: indexPatternId, + index: dataViewId, filters: [], }; if (query !== null) { diff --git a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.test.tsx b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.test.tsx index afa4acdd8583d8..d04f8f7b648f5d 100644 --- a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.test.tsx +++ b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.test.tsx @@ -21,7 +21,7 @@ jest.mock('./full_time_range_selector_service', () => ({ })); describe('FullTimeRangeSelector', () => { - const indexPattern = { + const dataView = { id: '0844fc70-5ab5-11e9-935e-836737467b0f', fields: [], title: 'test-data-view', @@ -34,7 +34,7 @@ describe('FullTimeRangeSelector', () => { }; const requiredProps = { - indexPattern, + dataView, query, }; diff --git a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx index 4ab35a7c03f5a2..846c79468b823e 100644 --- a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx +++ b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx @@ -14,7 +14,7 @@ import type { DataView } from '../../../../../../../src/plugins/data_views/publi import { setFullTimeRange } from './full_time_range_selector_service'; interface Props { - indexPattern: DataView; + dataView: DataView; query: Query; disabled: boolean; callback?: (a: any) => void; @@ -22,7 +22,7 @@ interface Props { // Component for rendering a button which automatically sets the range of the time filter // to the time range of data in the index(es) mapped to the supplied Kibana index pattern or query. -export const FullTimeRangeSelector: FC = ({ indexPattern, query, disabled, callback }) => { +export const FullTimeRangeSelector: FC = ({ dataView, query, disabled, callback }) => { // wrapper around setFullTimeRange to allow for the calling of the optional callBack prop async function setRange(i: DataView, q: Query) { const fullTimeRange = await setFullTimeRange(i, q); @@ -33,14 +33,14 @@ export const FullTimeRangeSelector: FC = ({ indexPattern, query, disabled return ( setRange(indexPattern, query)} + onClick={() => setRange(dataView, query)} data-test-subj="mlButtonUseFullData" > diff --git a/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/kibana_context_value.ts b/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/kibana_context_value.ts index 7045e08947f35b..0efec68198ae82 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/kibana_context_value.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/kibana_context_value.ts @@ -15,7 +15,7 @@ export const kibanaContextValueMock = { query: 'the-query-string', language: 'the-query-language', }, - currentIndexPattern: indexPatternMock, + currentDataView: indexPatternMock, currentSavedSearch: savedSearchMock, indexPatterns: indexPatternsMock, kibanaConfig: kibanaConfigMock, diff --git a/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts b/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts index e724c6d737eaaf..2c73259a21bb42 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts @@ -12,7 +12,7 @@ import { MlServicesContext } from '../../app'; export interface MlContextValue { combinedQuery: any; - currentIndexPattern: DataView; // TODO this should be IndexPattern or null + currentDataView: DataView; // TODO this should be IndexPattern or null currentSavedSearch: SavedSearchSavedObject | null; dataViewsContract: DataViewsContract; kibanaConfig: any; // IUiSettingsClient; @@ -22,7 +22,7 @@ export interface MlContextValue { export type SavedSearchQuery = object; // This context provides dependencies which can be injected -// via angularjs only (like services, currentIndexPattern etc.). +// via angularjs only (like services, currentDataView etc.). // Because we cannot just import these dependencies, the default value // for the context is just {} and of type `Partial` // for the angularjs based dependencies. Therefore, the diff --git a/x-pack/plugins/ml/public/application/contexts/ml/use_current_index_pattern.ts b/x-pack/plugins/ml/public/application/contexts/ml/use_current_index_pattern.ts index 4a8b77bdb2fde2..69c36ee09d7450 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/use_current_index_pattern.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/use_current_index_pattern.ts @@ -12,9 +12,9 @@ import { MlContext } from './ml_context'; export const useCurrentIndexPattern = () => { const context = useContext(MlContext); - if (context.currentIndexPattern === undefined) { - throw new Error('currentIndexPattern is undefined'); + if (context.currentDataView === undefined) { + throw new Error('currentDataView is undefined'); } - return context.currentIndexPattern; + return context.currentDataView; }; diff --git a/x-pack/plugins/ml/public/application/contexts/ml/use_ml_context.ts b/x-pack/plugins/ml/public/application/contexts/ml/use_ml_context.ts index f0f2adb14e299c..1a07cb0338855f 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/use_ml_context.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/use_ml_context.ts @@ -14,7 +14,7 @@ export const useMlContext = () => { if ( context.combinedQuery === undefined || - context.currentIndexPattern === undefined || + context.currentDataView === undefined || context.currentSavedSearch === undefined || context.dataViewsContract === undefined || context.kibanaConfig === undefined diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts index 1a12153f173852..43dff4142023d0 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts @@ -13,7 +13,7 @@ import type { DataView } from '../../../../../../../src/plugins/data_views/publi import { extractErrorMessage } from '../../../../common/util/errors'; -import { getIndexPatternIdFromName } from '../../util/index_utils'; +import { getDataViewIdFromName } from '../../util/index_utils'; import { ml } from '../../services/ml_api_service'; import { newJobCapsServiceAnalytics } from '../../services/new_job_capabilities/new_job_capabilities_service_analytics'; import { useMlContext } from '../../contexts/ml'; @@ -98,37 +98,36 @@ export const useResultsViewConfig = (jobId: string) => { const destIndex = Array.isArray(jobConfigUpdate.dest.index) ? jobConfigUpdate.dest.index[0] : jobConfigUpdate.dest.index; - const destIndexPatternId = (await getIndexPatternIdFromName(destIndex)) ?? destIndex; - let indexP: DataView | undefined; + const destDataViewId = (await getDataViewIdFromName(destIndex)) ?? destIndex; + let dataView: DataView | undefined; try { - indexP = await mlContext.dataViewsContract.get(destIndexPatternId); + dataView = await mlContext.dataViewsContract.get(destDataViewId); // Force refreshing the fields list here because a user directly coming // from the job creation wizard might land on the page without the // data view being fully initialized because it was created // before the analytics job populated the destination index. - await mlContext.dataViewsContract.refreshFields(indexP); + await mlContext.dataViewsContract.refreshFields(dataView); } catch (e) { - indexP = undefined; + dataView = undefined; } - if (indexP === undefined) { + if (dataView === undefined) { setNeedsDestIndexPattern(true); const sourceIndex = jobConfigUpdate.source.index[0]; - const sourceIndexPatternId = - (await getIndexPatternIdFromName(sourceIndex)) ?? sourceIndex; + const sourceDataViewId = (await getDataViewIdFromName(sourceIndex)) ?? sourceIndex; try { - indexP = await mlContext.dataViewsContract.get(sourceIndexPatternId); + dataView = await mlContext.dataViewsContract.get(sourceDataViewId); } catch (e) { - indexP = undefined; + dataView = undefined; } } - if (indexP !== undefined) { - await newJobCapsServiceAnalytics.initializeFromIndexPattern(indexP); + if (dataView !== undefined) { + await newJobCapsServiceAnalytics.initializeFromDataVIew(dataView); setJobConfig(analyticsConfigs.data_frame_analytics[0]); - setIndexPattern(indexP); + setIndexPattern(dataView); setIsInitialized(true); setIsLoadingJobConfig(false); } else { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_details.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_details.tsx index 53270bf60ae8ec..2c812226bfabbf 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_details.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_details.tsx @@ -31,7 +31,7 @@ interface Props { export const ConfigurationStepDetails: FC = ({ setCurrentStep, state }) => { const mlContext = useMlContext(); - const { currentIndexPattern } = mlContext; + const { currentDataView } = mlContext; const { form, isJobCreated } = state; const { dependentVariable, includes, jobConfigQueryString, jobType, trainingPercent } = form; @@ -43,7 +43,7 @@ export const ConfigurationStepDetails: FC = ({ setCurrentStep, state }) = title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.sourceIndex', { defaultMessage: 'Source index', }), - description: currentIndexPattern.title || UNSET_CONFIG_ITEM, + description: currentDataView.title || UNSET_CONFIG_ITEM, }, { title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.Query', { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx index df42c5b8eb1ca2..f53567cce6d87b 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx @@ -102,7 +102,7 @@ export const ConfigurationStepForm: FC = ({ setCurrentStep, }) => { const mlContext = useMlContext(); - const { currentSavedSearch, currentIndexPattern } = mlContext; + const { currentSavedSearch, currentDataView } = mlContext; const { savedSearchQuery, savedSearchQueryStr } = useSavedSearch(); const [fieldOptionsFetchFail, setFieldOptionsFetchFail] = useState(false); @@ -168,7 +168,7 @@ export const ConfigurationStepForm: FC = ({ }; const indexData = useIndexData( - currentIndexPattern, + currentDataView, getIndexDataQuery(savedSearchQuery, jobConfigQuery), toastNotifications, runtimeMappings @@ -197,7 +197,7 @@ export const ConfigurationStepForm: FC = ({ setMaxDistinctValuesError(undefined); try { - if (currentIndexPattern !== undefined) { + if (currentDataView !== undefined) { const depVarOptions = []; let depVarUpdate = formState.dependentVariable; // Get fields and filter for supported types for job type @@ -335,7 +335,7 @@ export const ConfigurationStepForm: FC = ({ }, 300); useEffect(() => { - setFormState({ sourceIndex: currentIndexPattern.title }); + setFormState({ sourceIndex: currentDataView.title }); }, []); const indexPatternFieldsTableItems = useMemo(() => { @@ -357,7 +357,7 @@ export const ConfigurationStepForm: FC = ({ useEffect(() => { if (isJobTypeWithDepVar) { - const indexPatternRuntimeFields = getCombinedRuntimeMappings(currentIndexPattern); + const indexPatternRuntimeFields = getCombinedRuntimeMappings(currentDataView); let runtimeOptions; if (indexPatternRuntimeFields) { @@ -499,14 +499,14 @@ export const ConfigurationStepForm: FC = ({ fields: includesTableItems .filter((d) => d.feature_type === 'numerical' && d.is_included) .map((d) => d.name), - index: currentIndexPattern.title, + index: currentDataView.title, legendType: getScatterplotMatrixLegendType(jobType), searchQuery: jobConfigQuery, runtimeMappings, - indexPattern: currentIndexPattern, + indexPattern: currentDataView, }), [ - currentIndexPattern.title, + currentDataView.title, dependentVariable, includesTableItems, isJobTypeWithDepVar, @@ -549,7 +549,7 @@ export const ConfigurationStepForm: FC = ({ fullWidth > @@ -569,7 +569,7 @@ export const ConfigurationStepForm: FC = ({ {savedSearchQuery !== null ? currentSavedSearch?.attributes.title - : currentIndexPattern.title} + : currentDataView.title} } @@ -587,7 +587,7 @@ export const ConfigurationStepForm: FC = ({ helpText={ dependentVariableOptions.length === 0 && dependentVariableFetchFail === false && - currentIndexPattern && + currentDataView && i18n.translate( 'xpack.ml.dataframe.analytics.create.dependentVariableOptionsNoNumericalFields', { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts index ad23c018afbbb8..c4611a1740913f 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts @@ -33,7 +33,7 @@ export function useSavedSearch() { const [savedSearchQueryStr, setSavedSearchQueryStr] = useState(undefined); const mlContext = useMlContext(); - const { currentSavedSearch, currentIndexPattern, kibanaConfig } = mlContext; + const { currentSavedSearch, currentDataView, kibanaConfig } = mlContext; const getQueryData = () => { let qry: estypes.QueryDslQueryContainer = {}; @@ -46,7 +46,7 @@ export function useSavedSearch() { if (queryLanguage === SEARCH_QUERY_LANGUAGE.KUERY) { const ast = fromKueryExpression(qryString); - qry = toElasticsearchQuery(ast, currentIndexPattern); + qry = toElasticsearchQuery(ast, currentDataView); } else { qry = luceneStringToDsl(qryString); decorateQuery(qry, kibanaConfig.get('query:queryString:options')); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/runtime_mappings/runtime_mappings.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/runtime_mappings/runtime_mappings.tsx index 95881fc3289768..e24d8e89d464ea 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/runtime_mappings/runtime_mappings.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/runtime_mappings/runtime_mappings.tsx @@ -95,7 +95,7 @@ export const RuntimeMappings: FC = ({ actions, state }) => { } = useXJsonMode(runtimeMappings || ''); const mlContext = useMlContext(); - const { currentIndexPattern } = mlContext; + const { currentDataView } = mlContext; const applyChanges = () => { const removeRuntimeMappings = advancedRuntimeMappingsConfig === ''; @@ -133,10 +133,7 @@ export const RuntimeMappings: FC = ({ actions, state }) => { }; useEffect(function getInitialRuntimeMappings() { - const combinedRuntimeMappings = getCombinedRuntimeMappings( - currentIndexPattern, - runtimeMappings - ); + const combinedRuntimeMappings = getCombinedRuntimeMappings(currentDataView, runtimeMappings); const prettySourceConfig = JSON.stringify(combinedRuntimeMappings, null, 2); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/page.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/page.tsx index 42a56d6327a600..8b136cfcd36376 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/page.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/page.tsx @@ -57,7 +57,7 @@ export const Page: FC = ({ jobId }) => { ]); const mlContext = useMlContext(); - const { currentIndexPattern } = mlContext; + const { currentDataView } = mlContext; const createAnalyticsForm = useCreateAnalyticsForm(); const { state } = createAnalyticsForm; @@ -69,7 +69,7 @@ export const Page: FC = ({ jobId }) => { useEffect(() => { initiateWizard(); - if (currentIndexPattern) { + if (currentDataView) { (async function () { if (jobId !== undefined) { const analyticsConfigs = await ml.dataFrameAnalytics.getDataFrameAnalytics(jobId, true); @@ -192,7 +192,7 @@ export const Page: FC = ({ jobId }) => { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.test.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.test.tsx index 48760f412725fc..c9bf469bd1f406 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.test.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.test.tsx @@ -10,10 +10,7 @@ import { render, fireEvent, waitFor, screen } from '@testing-library/react'; import { __IntlProvider as IntlProvider } from '@kbn/i18n/react'; -import { - getIndexPatternAndSavedSearch, - IndexPatternAndSavedSearch, -} from '../../../../../util/index_utils'; +import { getDataViewAndSavedSearch, DataViewAndSavedSearch } from '../../../../../util/index_utils'; import { SourceSelection } from './source_selection'; @@ -83,27 +80,25 @@ jest.mock('../../../../../contexts/kibana', () => ({ jest.mock('../../../../../util/index_utils', () => { return { - getIndexPatternAndSavedSearch: jest.fn( - async (id: string): Promise => { - return { - indexPattern: { - // @ts-expect-error fields should not be empty - fields: [], - title: - id === 'the-remote-saved-search-id' - ? 'my_remote_cluster:index-pattern-title' - : 'index-pattern-title', - }, - savedSearch: null, - }; - } - ), + getDataViewAndSavedSearch: jest.fn(async (id: string): Promise => { + return { + dataView: { + // @ts-expect-error fields should not be empty + fields: [], + title: + id === 'the-remote-saved-search-id' + ? 'my_remote_cluster:index-pattern-title' + : 'index-pattern-title', + }, + savedSearch: null, + }; + }), isCcsIndexPattern: (a: string) => a.includes(':'), }; }); const mockOnClose = jest.fn(); -const mockGetDataViewAndSavedSearch = getIndexPatternAndSavedSearch as jest.Mock; +const mockGetDataViewAndSavedSearch = getDataViewAndSavedSearch as jest.Mock; describe('Data Frame Analytics: ', () => { afterEach(() => { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.tsx index c2f17a45c1e066..e0922d7e12653d 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.tsx @@ -25,7 +25,7 @@ import { useMlKibana, useNavigateToPath } from '../../../../../contexts/kibana'; import { getNestedProperty } from '../../../../../util/object_utils'; -import { getIndexPatternAndSavedSearch, isCcsIndexPattern } from '../../../../../util/index_utils'; +import { getDataViewAndSavedSearch, isCcsIndexPattern } from '../../../../../util/index_utils'; const fixedPageSize: number = 8; @@ -57,8 +57,8 @@ export const SourceSelection: FC = ({ onClose }) => { if (type === 'index-pattern') { dataViewName = getNestedProperty(savedObject, 'attributes.title'); } else if (type === 'search') { - const indexPatternAndSavedSearch = await getIndexPatternAndSavedSearch(id); - dataViewName = indexPatternAndSavedSearch.indexPattern?.title ?? ''; + const dataViewAndSavedSearch = await getDataViewAndSavedSearch(id); + dataViewName = dataViewAndSavedSearch.dataView?.title ?? ''; } if (isCcsIndexPattern(dataViewName)) { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/components/controls.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/components/controls.tsx index e2738e0fad4d4d..b2879e2ffde542 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/components/controls.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/components/controls.tsx @@ -33,7 +33,7 @@ import { JOB_MAP_NODE_TYPES } from '../../../../../../common/constants/data_fram import { ML_PAGES } from '../../../../../../common/constants/locator'; import { checkPermission } from '../../../../capabilities/check_capabilities'; import { useMlLocator, useNotifications, useNavigateToPath } from '../../../../contexts/kibana'; -import { getIndexPatternIdFromName } from '../../../../util/index_utils'; +import { getDataViewIdFromName } from '../../../../util/index_utils'; import { useNavigateToWizardWithClonedJob } from '../../analytics_management/components/action_clone/clone_action_name'; import { useDeleteAction, @@ -112,12 +112,12 @@ export const Controls: FC = React.memo( const nodeType = selectedNode?.data('type'); const onCreateJobClick = useCallback(async () => { - const indexId = await getIndexPatternIdFromName(nodeLabel); + const dataViewId = await getDataViewIdFromName(nodeLabel); - if (indexId !== null) { + if (dataViewId !== null) { const path = await mlLocator.getUrl({ page: ML_PAGES.DATA_FRAME_ANALYTICS_CREATE_JOB, - pageState: { index: indexId }, + pageState: { index: dataViewId }, }); await navigateToPath(path); diff --git a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.test.tsx b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.test.tsx index 409f6a5911bb70..8fb4c43d772073 100644 --- a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.test.tsx +++ b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.test.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { CustomUrlEditor } from './editor'; import { TIME_RANGE_TYPE, URL_TYPE } from './constants'; import { CustomUrlSettings } from './utils'; -import { DataView } from '../../../../../../../../src/plugins/data_views/common'; +import { DataViewListItem } from '../../../../../../../../src/plugins/data_views/common'; function prepareTest(customUrl: CustomUrlSettings, setEditCustomUrlFn: (url: UrlConfig) => void) { const savedCustomUrls = [ @@ -47,10 +47,10 @@ function prepareTest(customUrl: CustomUrlSettings, setEditCustomUrlFn: (url: Url { id: 'dash2', title: 'Dashboard 2' }, ]; - const indexPatterns = [ + const dataViewListItems = [ { id: 'pattern1', title: 'Data view 1' }, { id: 'pattern2', title: 'Data view 2' }, - ] as DataView[]; + ] as DataViewListItem[]; const queryEntityFieldNames = ['airline']; @@ -59,7 +59,7 @@ function prepareTest(customUrl: CustomUrlSettings, setEditCustomUrlFn: (url: Url setEditCustomUrl: setEditCustomUrlFn, savedCustomUrls, dashboards, - indexPatterns, + dataViewListItems, queryEntityFieldNames, }; diff --git a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx index e48c4da5815dc5..b140c950d52ef6 100644 --- a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx +++ b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx @@ -164,7 +164,7 @@ export const CustomUrlEditor: FC = ({ return { value: dashboard.id, text: dashboard.title }; }); - const indexPatternOptions = dataViewListItems.map(({ id, title }) => { + const dataViewOptions = dataViewListItems.map(({ id, title }) => { return { value: id, text: title }; }); @@ -274,7 +274,7 @@ export const CustomUrlEditor: FC = ({ display="rowCompressed" > 0 ) { - // const defaultIndexPatternId = - // (await getIndexPatternIdFromName(datafeedConfig.indices.join())) ?? dataViews[0].id; const indicesName = datafeedConfig.indices.join(); - const defaultIndexPatternId = dataViews.find((dv) => dv.title === indicesName)?.id; - kibanaSettings.discoverIndexPatternId = defaultIndexPatternId; + const defaultDataViewId = dataViews.find((dv) => dv.title === indicesName)?.id; + kibanaSettings.discoverIndexPatternId = defaultDataViewId; } return { diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts index 9868b6c8bcfc89..9e9f112cee25d0 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.d.ts @@ -5,9 +5,7 @@ * 2.0. */ -import type { DataView } from 'src/plugins/data_views/common'; -import type { DataView, DataViewListItem } from 'src/plugins/data_views/common'; +import type { DataViewListItem } from 'src/plugins/data_views/common'; export function loadSavedDashboards(maxNumber: number): Promise; -export function loadIndexPatterns(maxNumber: number): Promise; export function loadDataViewListItems(): Promise; diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js index bfc5838d582a47..3a94cf6c673f35 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js @@ -107,22 +107,6 @@ export async function loadDataViewListItems() { return (await dataViewsContract.getIdsWithTitle()).sort((a, b) => a.title.localeCompare(b.title)); } -export function loadIndexPatterns2(maxNumber) { - // Loads the list of Kibana data views, as used in editing custom URLs. - return new Promise((resolve, reject) => { - const dataViewsContract = getDataViews(); - dataViewsContract - .find('*', maxNumber) - .then((dataViews) => { - const sortedDataViews = dataViews.sort((a, b) => a.title.localeCompare(b.title)); - resolve(sortedDataViews); - }) - .catch((resp) => { - reject(resp); - }); - }); -} - function extractDescription(job, newJobData) { const description = newJobData.description; if (newJobData.description !== job.description) { diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js index 4d1bedb647e37c..fe09ed45f1274a 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js @@ -16,7 +16,7 @@ import { import { getToastNotifications } from '../../../util/dependency_cache'; import { ml } from '../../../services/ml_api_service'; import { stringMatch } from '../../../util/string_utils'; -import { getIndexPatternNames } from '../../../util/index_utils'; +import { getDataViewNames } from '../../../util/index_utils'; import { JOB_STATE, DATAFEED_STATE } from '../../../../../common/constants/states'; import { JOB_ACTION } from '../../../../../common/constants/job_actions'; import { parseInterval } from '../../../../../common/util/parse_interval'; @@ -219,9 +219,8 @@ export async function cloneJob(jobId) { loadFullJob(jobId, false), ]); - const indexPatternNames = await getIndexPatternNames(); - const indexPatternTitle = datafeed.indices.join(','); - const jobIndicesAvailable = indexPatternNames.includes(indexPatternTitle); + const dataViewNames = await getDataViewNames(); + const jobIndicesAvailable = dataViewNames.includes(datafeed.indices.join(',')); if (jobIndicesAvailable === false) { return; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/bucket_span_estimator/estimate_bucket_span.ts b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/bucket_span_estimator/estimate_bucket_span.ts index 88ed17cba00035..eb9c4bf7557077 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/bucket_span_estimator/estimate_bucket_span.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/bucket_span_estimator/estimate_bucket_span.ts @@ -38,10 +38,10 @@ export function useEstimateBucketSpan() { end: jobCreator.end, }, fields: jobCreator.fields.map((f) => (f.id === EVENT_RATE_FIELD_ID ? null : f.id)), - index: mlContext.currentIndexPattern.title, + index: mlContext.currentDataView.title, query: mlContext.combinedQuery, splitField: undefined, - timeField: mlContext.currentIndexPattern.timeFieldName, + timeField: mlContext.currentDataView.timeFieldName, runtimeMappings: jobCreator.runtimeMappings ?? undefined, indicesOptions: jobCreator.datafeedConfig.indices_options, }; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/time_range_step/time_range.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/time_range_step/time_range.tsx index 4c13130ae4ce34..9924bf1674f790 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/time_range_step/time_range.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/time_range_step/time_range.tsx @@ -104,7 +104,7 @@ export const TimeRangeStep: FC = ({ setCurrentStep, isCurrentStep }) { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/job_type/page.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/job_type/page.tsx index 15ca0b82695ffb..5e621589772808 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/job_type/page.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/job_type/page.tsx @@ -45,9 +45,9 @@ export const Page: FC = () => { const [recognizerResultsCount, setRecognizerResultsCount] = useState(0); - const { currentSavedSearch, currentIndexPattern } = mlContext; + const { currentSavedSearch, currentDataView } = mlContext; - const isTimeBasedIndex = timeBasedIndexCheck(currentIndexPattern); + const isTimeBasedIndex = timeBasedIndexCheck(currentDataView); const indexWarningTitle = !isTimeBasedIndex && isSavedSearchSavedObject(currentSavedSearch) ? i18n.translate( @@ -57,13 +57,13 @@ export const Page: FC = () => { '{savedSearchTitle} uses data view {dataViewName} which is not time based', values: { savedSearchTitle: currentSavedSearch.attributes.title as string, - dataViewName: currentIndexPattern.title, + dataViewName: currentDataView.title, }, } ) : i18n.translate('xpack.ml.newJob.wizard.jobType.dataViewNotTimeBasedMessage', { defaultMessage: 'Data view {dataViewName} is not time based', - values: { dataViewName: currentIndexPattern.title }, + values: { dataViewName: currentDataView.title }, }); const pageTitleLabel = isSavedSearchSavedObject(currentSavedSearch) @@ -73,7 +73,7 @@ export const Page: FC = () => { }) : i18n.translate('xpack.ml.newJob.wizard.jobType.dataViewPageTitleLabel', { defaultMessage: 'data view {dataViewName}', - values: { dataViewName: currentIndexPattern.title }, + values: { dataViewName: currentDataView.title }, }); const recognizerResults = { @@ -85,13 +85,13 @@ export const Page: FC = () => { const getUrlParams = () => { return !isSavedSearchSavedObject(currentSavedSearch) - ? `?index=${currentIndexPattern.id}` + ? `?index=${currentDataView.id}` : `?savedSearchId=${currentSavedSearch.id}`; }; const addSelectionToRecentlyAccessed = async () => { const title = !isSavedSearchSavedObject(currentSavedSearch) - ? currentIndexPattern.title + ? currentDataView.title : (currentSavedSearch.attributes.title as string); const mlLocator = share.url.locators.get(ML_APP_LOCATOR)!; @@ -101,7 +101,7 @@ export const Page: FC = () => { pageState: { ...(currentSavedSearch?.id ? { savedSearchId: currentSavedSearch.id } - : { index: currentIndexPattern.id }), + : { index: currentDataView.id }), }, }, { absolute: true } @@ -270,7 +270,7 @@ export const Page: FC = () => { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/page.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/page.tsx index f708ea83f1d0d3..52e3c55afc15aa 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/page.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/page.tsx @@ -55,7 +55,7 @@ export interface PageProps { export const Page: FC = ({ existingJobsAndGroups, jobType }) => { const mlContext = useMlContext(); const jobCreator = jobCreatorFactory(jobType)( - mlContext.currentIndexPattern, + mlContext.currentDataView, mlContext.currentSavedSearch, mlContext.combinedQuery ); @@ -184,7 +184,7 @@ export const Page: FC = ({ existingJobsAndGroups, jobType }) => { chartInterval.setMaxBars(MAX_BARS); chartInterval.setInterval('auto'); - const chartLoader = new ChartLoader(mlContext.currentIndexPattern, mlContext.combinedQuery); + const chartLoader = new ChartLoader(mlContext.currentDataView, mlContext.combinedQuery); const jobValidator = new JobValidator(jobCreator); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/wizard_steps.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/wizard_steps.tsx index c24fb2521ea580..b2e5a4ee1c22f2 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/wizard_steps.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/wizard_steps.tsx @@ -40,10 +40,10 @@ export const WizardSteps: FC = ({ currentStep, setCurrentStep }) => { defaultMessage: 'New job from saved search {title}', values: { title: mlContext.currentSavedSearch.attributes.title as string }, }); - } else if (mlContext.currentIndexPattern.id !== undefined) { + } else if (mlContext.currentDataView.id !== undefined) { return i18n.translate('xpack.ml.newJob.wizard.stepComponentWrapper.summaryTitleDataView', { defaultMessage: 'New job from data view {dataViewName}', - values: { dataViewName: mlContext.currentIndexPattern.title }, + values: { dataViewName: mlContext.currentDataView.title }, }); } return ''; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/recognize/components/job_settings_form.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/recognize/components/job_settings_form.tsx index 8dc0ca0ddbdc47..c996f50ea5018a 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/recognize/components/job_settings_form.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/recognize/components/job_settings_form.tsx @@ -53,7 +53,7 @@ export const JobSettingsForm: FC = ({ jobs, }) => { const { from, to } = getTimeFilterRange(); - const { currentIndexPattern: indexPattern } = useMlContext(); + const { currentDataView: dataView } = useMlContext(); const jobPrefixValidator = composeValidators( patternValidator(/^([a-z0-9]+[a-z0-9\-_]*)?$/), @@ -181,7 +181,7 @@ export const JobSettingsForm: FC = ({ } checked={formState.useFullIndexData} diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx index dbf9bce64b114e..7603855d47e5cb 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx @@ -92,7 +92,7 @@ export const Page: FC = ({ moduleId, existingGroupIds }) => { const { currentSavedSearch: savedSearch, - currentIndexPattern: indexPattern, + currentDataView: dataView, combinedQuery, } = useMlContext(); const pageTitle = @@ -103,7 +103,7 @@ export const Page: FC = ({ moduleId, existingGroupIds }) => { }) : i18n.translate('xpack.ml.newJob.recognize.dataViewPageTitle', { defaultMessage: 'data view {dataViewName}', - values: { dataViewName: indexPattern.title }, + values: { dataViewName: dataView.title }, }); const displayQueryWarning = savedSearch !== null; const tempQuery = savedSearch === null ? undefined : combinedQuery; @@ -135,10 +135,10 @@ export const Page: FC = ({ moduleId, existingGroupIds }) => { timeRange: TimeRange ): Promise => { if (useFullIndexData) { - const runtimeMappings = indexPattern.getComputedFields().runtimeFields as RuntimeMappings; + const runtimeMappings = dataView.getComputedFields().runtimeFields as RuntimeMappings; const { start, end } = await ml.getTimeFieldRange({ - index: indexPattern.title, - timeFieldName: indexPattern.timeFieldName, + index: dataView.title, + timeFieldName: dataView.timeFieldName, query: combinedQuery, ...(isPopulatedObject(runtimeMappings) ? { runtimeMappings } : {}), }); @@ -178,7 +178,7 @@ export const Page: FC = ({ moduleId, existingGroupIds }) => { moduleId, prefix: resultJobPrefix, query: tempQuery, - indexPatternName: indexPattern.title, + indexPatternName: dataView.title, useDedicatedIndex, startDatafeed: startDatafeedAfterSave, ...(jobOverridesPayload !== null ? { jobOverrides: jobOverridesPayload } : {}), diff --git a/x-pack/plugins/ml/public/application/routing/routes/trained_models/nodes_list.tsx b/x-pack/plugins/ml/public/application/routing/routes/trained_models/nodes_list.tsx index bd88527af1a8df..c0bd22e657bb03 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/trained_models/nodes_list.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/trained_models/nodes_list.tsx @@ -35,7 +35,13 @@ export const nodesListRouteFactory = ( }); const PageWrapper: FC = ({ location, deps }) => { - const { context } = useResolver(undefined, undefined, deps.config, basicResolvers(deps)); + const { context } = useResolver( + undefined, + undefined, + deps.config, + deps.dataViewsContract, + basicResolvers(deps) + ); return ( diff --git a/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts b/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts index 7b8b10710b7ae0..895b8e18dbb2ae 100644 --- a/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts +++ b/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts @@ -65,7 +65,7 @@ describe('useResolver', () => { ], }, }, - currentIndexPattern: null, + currentDataView: null, currentSavedSearch: null, indexPatterns: null, kibanaConfig: {}, diff --git a/x-pack/plugins/ml/public/application/routing/use_resolver.ts b/x-pack/plugins/ml/public/application/routing/use_resolver.ts index f15e66f1e75c0c..59d64f412cc804 100644 --- a/x-pack/plugins/ml/public/application/routing/use_resolver.ts +++ b/x-pack/plugins/ml/public/application/routing/use_resolver.ts @@ -9,9 +9,9 @@ import { useEffect, useState } from 'react'; import { IUiSettingsClient } from 'kibana/public'; import { i18n } from '@kbn/i18n'; import { - getIndexPatternById, - getIndexPatternAndSavedSearch, - IndexPatternAndSavedSearch, + getDataViewById, + getDataViewAndSavedSearch, + DataViewAndSavedSearch, } from '../util/index_utils'; import { createSearchItems } from '../jobs/new_job/utils/new_job_utils'; import { ResolverResults, Resolvers } from './resolvers'; @@ -23,14 +23,14 @@ import type { DataViewsContract } from '../../../../../../src/plugins/data_views /** * Hook to resolve route specific requirements - * @param indexPatternId optional Kibana index pattern id, used for wizards + * @param dataViewId optional Kibana data view id, used for wizards * @param savedSearchId optional Kibana saved search id, used for wizards * @param config Kibana UI Settings * @param resolvers an array of resolvers to be executed for the route * @return { context, results } returns the ML context and resolver results */ export const useResolver = ( - indexPatternId: string | undefined, + dataViewId: string | undefined, savedSearchId: string | undefined, config: IUiSettingsClient, dataViewsContract: DataViewsContract, @@ -64,36 +64,36 @@ export const useResolver = ( } try { - if (indexPatternId === '') { + if (dataViewId === '') { throw new Error( i18n.translate('xpack.ml.useResolver.errorIndexPatternIdEmptyString', { - defaultMessage: 'indexPatternId must not be empty string.', + defaultMessage: 'dataViewId must not be empty string.', }) ); } - let indexPatternAndSavedSearch: IndexPatternAndSavedSearch = { + let dataViewAndSavedSearch: DataViewAndSavedSearch = { savedSearch: null, - indexPattern: null, + dataView: null, }; if (savedSearchId !== undefined) { - indexPatternAndSavedSearch = await getIndexPatternAndSavedSearch(savedSearchId); - } else if (indexPatternId !== undefined) { - indexPatternAndSavedSearch.indexPattern = await getIndexPatternById(indexPatternId); + dataViewAndSavedSearch = await getDataViewAndSavedSearch(savedSearchId); + } else if (dataViewId !== undefined) { + dataViewAndSavedSearch.dataView = await getDataViewById(dataViewId); } - const { savedSearch, indexPattern } = indexPatternAndSavedSearch; + const { savedSearch, dataView } = dataViewAndSavedSearch; const { combinedQuery } = createSearchItems( config, - indexPattern !== null ? indexPattern : undefined, + dataView !== null ? dataView : undefined, savedSearch ); setContext({ combinedQuery, - currentIndexPattern: indexPattern, + currentDataView: dataView, currentSavedSearch: savedSearch, dataViewsContract, kibanaConfig: config, diff --git a/x-pack/plugins/ml/public/application/services/field_format_service.ts b/x-pack/plugins/ml/public/application/services/field_format_service.ts index 252f83ab514816..ddcb447430a456 100644 --- a/x-pack/plugins/ml/public/application/services/field_format_service.ts +++ b/x-pack/plugins/ml/public/application/services/field_format_service.ts @@ -6,7 +6,7 @@ */ import { mlFunctionToESAggregation } from '../../../common/util/job_utils'; -import { getIndexPatternById, getIndexPatternIdFromName } from '../util/index_utils'; +import { getDataViewById, getDataViewIdFromName } from '../util/index_utils'; import { mlJobService } from './job_service'; import type { DataView } from '../../../../../../src/plugins/data_views/public'; @@ -36,7 +36,7 @@ class FieldFormatService { const jobObj = mlJobService.getJob(jobId); return { jobId, - dataViewId: await getIndexPatternIdFromName(jobObj.datafeed_config.indices.join(',')), + dataViewId: await getDataViewIdFromName(jobObj.datafeed_config.indices.join(',')), }; }) ) @@ -92,13 +92,13 @@ class FieldFormatService { const detectors = jobObj.analysis_config.detectors || []; const formatsByDetector: any[] = []; - const indexPatternId = this.indexPatternIdsByJob[jobId]; - if (indexPatternId !== undefined) { + const dataViewId = this.indexPatternIdsByJob[jobId]; + if (dataViewId !== undefined) { // Load the full data view configuration to obtain the formats of each field. - getIndexPatternById(indexPatternId) - .then((indexPatternData) => { + getDataViewById(dataViewId) + .then((dataView) => { // Store the FieldFormat for each job by detector_index. - const fieldList = indexPatternData.fields; + const fieldList = dataView.fields; detectors.forEach((dtr) => { const esAgg = mlFunctionToESAggregation(dtr.function); // distinct_count detectors should fall back to the default @@ -106,8 +106,7 @@ class FieldFormatService { if (dtr.field_name !== undefined && esAgg !== 'cardinality') { const field = fieldList.getByName(dtr.field_name); if (field !== undefined) { - formatsByDetector[dtr.detector_index!] = - indexPatternData.getFormatterForField(field); + formatsByDetector[dtr.detector_index!] = dataView.getFormatterForField(field); } } }); diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts index b4d3c47364a3dd..8c05d5a4182192 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts @@ -6,7 +6,7 @@ */ import { DataView, DataViewsContract } from '../../../../../../../src/plugins/data_views/public'; -import { getIndexPatternAndSavedSearch } from '../../util/index_utils'; +import { getDataViewAndSavedSearch } from '../../util/index_utils'; import { JobType } from '../../../../common/types/saved_objects'; import { newJobCapsServiceAnalytics } from '../new_job_capabilities/new_job_capabilities_service_analytics'; import { newJobCapsService } from '../new_job_capabilities/new_job_capabilities_service'; @@ -17,9 +17,9 @@ export const DATA_FRAME_ANALYTICS = 'data-frame-analytics'; // called in the routing resolve block to initialize the NewJobCapabilites // service for the corresponding job type with the currently selected data view export function loadNewJobCapabilities( - indexPatternId: string, + dataViewId: string, savedSearchId: string, - indexPatterns: DataViewsContract, + dataViewContract: DataViewsContract, jobType: JobType ) { return new Promise(async (resolve, reject) => { @@ -27,24 +27,24 @@ export function loadNewJobCapabilities( const serviceToUse = jobType === ANOMALY_DETECTOR ? newJobCapsService : newJobCapsServiceAnalytics; - if (indexPatternId !== undefined) { + if (dataViewId !== undefined) { // index pattern is being used - const indexPattern: DataView = await indexPatterns.get(indexPatternId); - await serviceToUse.initializeFromIndexPattern(indexPattern); + const dataView: DataView = await dataViewContract.get(dataViewId); + await serviceToUse.initializeFromDataVIew(dataView); resolve(serviceToUse.newJobCaps); } else if (savedSearchId !== undefined) { // saved search is being used // load the data view from the saved search - const { indexPattern } = await getIndexPatternAndSavedSearch(savedSearchId); + const { dataView } = await getDataViewAndSavedSearch(savedSearchId); - if (indexPattern === null) { + if (dataView === null) { // eslint-disable-next-line no-console console.error('Cannot retrieve data view from saved search'); reject(); return; } - await serviceToUse.initializeFromIndexPattern(indexPattern); + await serviceToUse.initializeFromDataVIew(dataView); resolve(serviceToUse.newJobCaps); } else { reject(); diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts index 49c8b08007d52d..373de76d594576 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities._service.test.ts @@ -20,7 +20,7 @@ jest.mock('../ml_api_service', () => ({ }, })); -const indexPattern = { +const dataView = { id: 'cloudwatch-*', title: 'cloudwatch-*', } as unknown as DataView; @@ -28,7 +28,7 @@ const indexPattern = { describe('new_job_capabilities_service', () => { describe('cloudwatch newJobCaps()', () => { it('can construct job caps objects from endpoint json', async () => { - await newJobCapsService.initializeFromIndexPattern(indexPattern); + await newJobCapsService.initializeFromDataVIew(dataView); const { fields, aggs } = await newJobCapsService.newJobCaps; const networkOutField = fields.find((f) => f.id === 'NetworkOut') || { aggs: [] }; @@ -47,7 +47,7 @@ describe('new_job_capabilities_service', () => { }); it('job caps including text fields', async () => { - await newJobCapsService.initializeFromIndexPattern(indexPattern, true, false); + await newJobCapsService.initializeFromDataVIew(dataView, true, false); const { fields, aggs } = await newJobCapsService.newJobCaps; expect(fields).toHaveLength(13); // one more field @@ -55,7 +55,7 @@ describe('new_job_capabilities_service', () => { }); it('job caps excluding event rate', async () => { - await newJobCapsService.initializeFromIndexPattern(indexPattern, false, true); + await newJobCapsService.initializeFromDataVIew(dataView, false, true); const { fields, aggs } = await newJobCapsService.newJobCaps; expect(fields).toHaveLength(11); // one less field diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts index 45dc71ed6a6b93..210c409e8e281c 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts @@ -36,8 +36,8 @@ class NewJobCapsService extends NewJobCapabilitiesServiceBase { return filterCategoryFields(this._fields); } - public async initializeFromIndexPattern( - indexPattern: DataView, + public async initializeFromDataVIew( + dataView: DataView, includeEventRateField = true, removeTextFields = true ) { @@ -45,8 +45,8 @@ class NewJobCapsService extends NewJobCapabilitiesServiceBase { this._includeEventRateField = includeEventRateField; this._removeTextFields = removeTextFields; - const resp = await ml.jobs.newJobCaps(indexPattern.title, indexPattern.type === 'rollup'); - const { fields: allFields, aggs } = createObjects(resp, indexPattern.title); + const resp = await ml.jobs.newJobCaps(dataView.title, dataView.type === 'rollup'); + const { fields: allFields, aggs } = createObjects(resp, dataView.title); if (this._includeEventRateField === true) { addEventRateField(aggs, allFields); diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts index f8f9ae6b2b0a37..2786c14127ecd3 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts @@ -43,14 +43,14 @@ export function removeNestedFieldChildren(resp: NewJobCapsResponse, indexPattern } class NewJobCapsServiceAnalytics extends NewJobCapabilitiesServiceBase { - public async initializeFromIndexPattern(indexPattern: DataView) { + public async initializeFromDataVIew(dataView: DataView) { try { const resp: NewJobCapsResponse = await ml.dataFrameAnalytics.newJobCapsAnalytics( - indexPattern.title, - indexPattern.type === 'rollup' + dataView.title, + dataView.type === 'rollup' ); - const allFields = removeNestedFieldChildren(resp, indexPattern.title); + const allFields = removeNestedFieldChildren(resp, dataView.title); const { fieldsPreferringKeyword } = processTextAndKeywordFields(allFields); diff --git a/x-pack/plugins/ml/public/application/util/index_utils.ts b/x-pack/plugins/ml/public/application/util/index_utils.ts index f9d8107529243d..5d35081dcb0fc6 100644 --- a/x-pack/plugins/ml/public/application/util/index_utils.ts +++ b/x-pack/plugins/ml/public/application/util/index_utils.ts @@ -37,14 +37,14 @@ export async function loadSavedSearchById(id: string) { return ss.error === undefined ? ss : null; } -export async function getIndexPatternNames() { +export async function getDataViewNames() { if (dataViewsContract === null) { throw new Error('Data views are not initialized!'); } return (await dataViewsContract.getIdsWithTitle()).map(({ title }) => title); } -export async function getIndexPatternIdFromName(name: string): Promise { +export async function getDataViewIdFromName(name: string): Promise { if (dataViewsContract === null) { throw new Error('Data views are not initialized!'); } @@ -55,7 +55,7 @@ export async function getIndexPatternIdFromName(name: string): Promise { +export function getDataViewById(id: string): Promise { if (dataViewsContract === null) { throw new Error('Data views are not initialized!'); } @@ -67,15 +67,15 @@ export function getIndexPatternById(id: string): Promise { } } -export interface IndexPatternAndSavedSearch { +export interface DataViewAndSavedSearch { savedSearch: SavedSearchSavedObject | null; - indexPattern: DataView | null; + dataView: DataView | null; } -export async function getIndexPatternAndSavedSearch(savedSearchId: string) { - const resp: IndexPatternAndSavedSearch = { +export async function getDataViewAndSavedSearch(savedSearchId: string) { + const resp: DataViewAndSavedSearch = { savedSearch: null, - indexPattern: null, + dataView: null, }; if (savedSearchId === undefined) { @@ -86,8 +86,8 @@ export async function getIndexPatternAndSavedSearch(savedSearchId: string) { if (ss === null) { return resp; } - const indexPatternId = ss.references.find((r) => r.type === 'index-pattern')?.id; - resp.indexPattern = await getIndexPatternById(indexPatternId!); + const dataViewId = ss.references.find((r) => r.type === 'index-pattern')?.id; + resp.dataView = await getDataViewById(dataViewId!); resp.savedSearch = ss; return resp; } @@ -109,14 +109,14 @@ export function getSavedSearchById(id: string): SavedSearchSavedObject | undefin * an optional flag will trigger the display a notification at the top of the page * warning that the index is not time based */ -export function timeBasedIndexCheck(indexPattern: DataView, showNotification = false) { - if (!indexPattern.isTimeBased()) { +export function timeBasedIndexCheck(dataView: DataView, showNotification = false) { + if (!dataView.isTimeBased()) { if (showNotification) { const toastNotifications = getToastNotifications(); toastNotifications.addWarning({ title: i18n.translate('xpack.ml.dataViewNotBasedOnTimeSeriesNotificationTitle', { defaultMessage: 'The data view {dataViewName} is not based on a time series', - values: { dataViewName: indexPattern.title }, + values: { dataViewName: dataView.title }, }), text: i18n.translate('xpack.ml.dataViewNotBasedOnTimeSeriesNotificationDescription', { defaultMessage: 'Anomaly detection only runs over time-based indices', From dbe5b2ae240715f3fa1ad98b71d1e3ad634e11fe Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Wed, 27 Oct 2021 17:29:04 +0100 Subject: [PATCH 3/6] more renaming --- .../file_based/file_datavisualizer.tsx | 4 ++-- .../index_based/index_data_visualizer.tsx | 4 ++-- .../jobs/new_job/recognize/resolvers.ts | 4 ++-- .../routing/routes/new_job/recognize.tsx | 4 ++-- .../application/routing/use_resolver.test.ts | 4 ++-- .../data_frame_analytics/index_patterns.ts | 8 ++++---- .../ml/server/routes/data_frame_analytics.ts | 20 +++++++++---------- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx b/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx index 5fe519f25efb69..93c0291d4f9d4b 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx @@ -30,7 +30,7 @@ export const FileDataVisualizerPage: FC = () => { docLinks, dataVisualizer, data: { - indexPatterns: { get: getIndexPattern }, + dataViews: { get: getDataView }, }, }, } = useMlKibana(); @@ -60,7 +60,7 @@ export const FileDataVisualizerPage: FC = () => { }, canDisplay: async ({ indexPatternId }) => { try { - const { timeFieldName } = await getIndexPattern(indexPatternId); + const { timeFieldName } = await getDataView(indexPatternId); return ( isFullLicense() && timeFieldName !== undefined && diff --git a/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx b/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx index 0faf5b775d23eb..7ae2712a2edd82 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx @@ -29,7 +29,7 @@ export const IndexDataVisualizerPage: FC = () => { docLinks, dataVisualizer, data: { - indexPatterns: { get: getIndexPattern }, + dataViews: { get: getDataView }, }, }, } = useMlKibana(); @@ -74,7 +74,7 @@ export const IndexDataVisualizerPage: FC = () => { }, canDisplay: async ({ indexPatternId }) => { try { - const { timeFieldName } = await getIndexPattern(indexPatternId); + const { timeFieldName } = await getDataView(indexPatternId); return ( isFullLicense() && timeFieldName !== undefined && diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/recognize/resolvers.ts b/x-pack/plugins/ml/public/application/jobs/new_job/recognize/resolvers.ts index b4e581d46bcc39..6dca394c0227dd 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/recognize/resolvers.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/recognize/resolvers.ts @@ -19,7 +19,7 @@ import { CreateLinkWithUserDefaults } from '../../../components/custom_hooks/use */ export function checkViewOrCreateJobs( moduleId: string, - indexPatternId: string, + dataViewId: string, createLinkWithUserDefaults: CreateLinkWithUserDefaults, navigateToPath: NavigateToPath ): Promise { @@ -36,7 +36,7 @@ export function checkViewOrCreateJobs( await navigateToPath(url); reject(); } else { - await navigateToPath(`/jobs/new_job/recognize?id=${moduleId}&index=${indexPatternId}`); + await navigateToPath(`/jobs/new_job/recognize?id=${moduleId}&index=${dataViewId}`); reject(); } }) diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx index 26c18d9813376b..7e7da6c79a858f 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx @@ -68,7 +68,7 @@ const PageWrapper: FC = ({ location, deps }) => { }; const CheckViewOrCreateWrapper: FC = ({ location, deps }) => { - const { id: moduleId, index: indexPatternId }: Record = parse(location.search, { + const { id: moduleId, index: dataViewId }: Record = parse(location.search, { sort: false, }); const { createLinkWithUserDefaults } = useCreateADLinks(); @@ -78,7 +78,7 @@ const CheckViewOrCreateWrapper: FC = ({ location, deps }) => { // the single resolver checkViewOrCreateJobs redirects only. so will always reject useResolver(undefined, undefined, deps.config, deps.dataViewsContract, { checkViewOrCreateJobs: () => - checkViewOrCreateJobs(moduleId, indexPatternId, createLinkWithUserDefaults, navigateToPath), + checkViewOrCreateJobs(moduleId, dataViewId, createLinkWithUserDefaults, navigateToPath), }); return null; }; diff --git a/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts b/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts index 895b8e18dbb2ae..4434af158b8891 100644 --- a/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts +++ b/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts @@ -45,7 +45,7 @@ describe('useResolver', () => { jest.useRealTimers(); }); - it('should accept undefined as indexPatternId and savedSearchId.', async () => { + it('should accept undefined as dataViewId and savedSearchId.', async () => { const { result, waitForNextUpdate } = renderHook(() => useResolver(undefined, undefined, {} as IUiSettingsClient, {} as DataViewsContract, {}) ); @@ -76,7 +76,7 @@ describe('useResolver', () => { expect(redirectToJobsManagementPage).toHaveBeenCalledTimes(0); }); - it('should add an error toast and redirect if indexPatternId is an empty string.', async () => { + it('should add an error toast and redirect if dataViewId is an empty string.', async () => { const { result } = renderHook(() => useResolver('', undefined, {} as IUiSettingsClient, {} as DataViewsContract, {}) ); diff --git a/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts b/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts index 568be4197baf8f..b0135b0295fd80 100644 --- a/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts +++ b/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts @@ -7,17 +7,17 @@ import { DataViewsService } from '../../../../../../src/plugins/data_views/common'; -export class IndexPatternHandler { +export class DataViewHandler { constructor(private dataViewService: DataViewsService) {} // returns a id based on an index pattern name - async getIndexPatternId(indexName: string) { + async getDataViewId(indexName: string) { const dv = (await this.dataViewService.find(indexName)).find( ({ title }) => title === indexName ); return dv?.id; } - async deleteIndexPatternById(indexId: string) { - return await this.dataViewService.delete(indexId); + async deleteDataViewById(dataViewId: string) { + return await this.dataViewService.delete(dataViewId); } } diff --git a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts index ac90659a6f3c91..cb84d709c91ac3 100644 --- a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts +++ b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts @@ -29,7 +29,7 @@ import type { GetAnalyticsMapArgs, ExtendAnalyticsMapArgs, } from '../models/data_frame_analytics/types'; -import { IndexPatternHandler } from '../models/data_frame_analytics/index_patterns'; +import { DataViewHandler } from '../models/data_frame_analytics/index_patterns'; import { AnalyticsManager } from '../models/data_frame_analytics/analytics_manager'; import { validateAnalyticsJob } from '../models/data_frame_analytics/validation'; import { fieldServiceProvider } from '../models/job_service/new_job_caps/field_service'; @@ -38,14 +38,14 @@ import { getAuthorizationHeader } from '../lib/request_authorization'; import type { MlClient } from '../lib/ml_client'; import type { DataViewsService } from '../../../../../src/plugins/data_views/common'; -function getIndexPatternId(dataViewsService: DataViewsService, patternName: string) { - const iph = new IndexPatternHandler(dataViewsService); - return iph.getIndexPatternId(patternName); +function getDataVIewId(dataViewsService: DataViewsService, patternName: string) { + const iph = new DataViewHandler(dataViewsService); + return iph.getDataViewId(patternName); } -function deleteDestIndexPatternById(dataViewsService: DataViewsService, indexPatternId: string) { - const iph = new IndexPatternHandler(dataViewsService); - return iph.deleteIndexPatternById(indexPatternId); +function deleteDestDataViewById(dataViewsService: DataViewsService, dataViewId: string) { + const iph = new DataViewHandler(dataViewsService); + return iph.deleteDataViewById(dataViewId); } function getAnalyticsMap( @@ -427,9 +427,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout if (destinationIndex && deleteDestIndexPattern) { try { const dataViewsService = await getDataViewsService(); - const indexPatternId = await getIndexPatternId(dataViewsService, destinationIndex); - if (indexPatternId) { - await deleteDestIndexPatternById(dataViewsService, indexPatternId); + const dataViewId = await getDataVIewId(dataViewsService, destinationIndex); + if (dataViewId) { + await deleteDestDataViewById(dataViewsService, dataViewId); } destIndexPatternDeleted.success = true; } catch (deleteDestIndexPatternError) { From eebe4d34cfe2d7f3101ab0324e4f0f8e39c6e866 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Thu, 28 Oct 2021 08:07:02 +0100 Subject: [PATCH 4/6] fixing tests --- .../ml/__mocks__/{index_pattern.ts => data_view.ts} | 2 +- .../{index_patterns.ts => data_view_contract.ts} | 2 +- .../contexts/ml/__mocks__/kibana_context_value.ts | 8 ++++---- .../ml/public/application/routing/use_resolver.test.ts | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) rename x-pack/plugins/ml/public/application/contexts/ml/__mocks__/{index_pattern.ts => data_view.ts} (92%) rename x-pack/plugins/ml/public/application/contexts/ml/__mocks__/{index_patterns.ts => data_view_contract.ts} (92%) diff --git a/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts b/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/data_view.ts similarity index 92% rename from x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts rename to x-pack/plugins/ml/public/application/contexts/ml/__mocks__/data_view.ts index 93f92002c4bfdc..0d3c0993c880b9 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_pattern.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/data_view.ts @@ -7,7 +7,7 @@ import type { DataView } from '../../../../../../../../src/plugins/data_views/public'; -export const indexPatternMock = { +export const dataViewMock = { id: 'the-index-pattern-id', title: 'the-index-pattern-title', fields: [], diff --git a/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts b/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/data_view_contract.ts similarity index 92% rename from x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts rename to x-pack/plugins/ml/public/application/contexts/ml/__mocks__/data_view_contract.ts index 571ce8ac3f4232..61a466b6496ef9 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/index_patterns.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/data_view_contract.ts @@ -7,7 +7,7 @@ import type { DataViewsContract } from '../../../../../../../../src/plugins/data_views/public'; -export const indexPatternsMock = new (class { +export const dataViewsContractMock = new (class { fieldFormats = []; config = {}; savedObjectsClient = {}; diff --git a/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/kibana_context_value.ts b/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/kibana_context_value.ts index 0efec68198ae82..642bc4baee712a 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/kibana_context_value.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/__mocks__/kibana_context_value.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { indexPatternMock } from './index_pattern'; -import { indexPatternsMock } from './index_patterns'; +import { dataViewMock } from './data_view'; +import { dataViewsContractMock } from './data_view_contract'; import { kibanaConfigMock } from './kibana_config'; import { savedSearchMock } from './saved_search'; @@ -15,8 +15,8 @@ export const kibanaContextValueMock = { query: 'the-query-string', language: 'the-query-language', }, - currentDataView: indexPatternMock, + currentDataView: dataViewMock, currentSavedSearch: savedSearchMock, - indexPatterns: indexPatternsMock, + dataViewsContract: dataViewsContractMock, kibanaConfig: kibanaConfigMock, }; diff --git a/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts b/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts index 4434af158b8891..a0b8c783feed39 100644 --- a/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts +++ b/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts @@ -67,7 +67,7 @@ describe('useResolver', () => { }, currentDataView: null, currentSavedSearch: null, - indexPatterns: null, + dataViewsContract: null, kibanaConfig: {}, }, results: {}, From b1da80d93e32dcdd09990a1146301465947fa36c Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Mon, 1 Nov 2021 09:58:27 +0000 Subject: [PATCH 5/6] fixing jest test --- .../plugins/ml/public/application/routing/use_resolver.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts b/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts index a0b8c783feed39..98deb8df7b60d5 100644 --- a/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts +++ b/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts @@ -67,7 +67,7 @@ describe('useResolver', () => { }, currentDataView: null, currentSavedSearch: null, - dataViewsContract: null, + dataViewsContract: {}, kibanaConfig: {}, }, results: {}, From 7ee9241872df9cecf890ae7dce916bfa3f491d84 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 2 Nov 2021 14:21:06 +0000 Subject: [PATCH 6/6] small changes based on review --- .../public/application/contexts/ml/ml_context.ts | 14 +++----------- .../index_or_search/preconfigured_job_redirect.ts | 2 +- .../application/services/annotations_service.tsx | 5 ++--- .../ml/server/routes/data_frame_analytics.ts | 4 ++-- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts b/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts index 2c73259a21bb42..d707f56b10a340 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts +++ b/x-pack/plugins/ml/public/application/contexts/ml/ml_context.ts @@ -12,7 +12,7 @@ import { MlServicesContext } from '../../app'; export interface MlContextValue { combinedQuery: any; - currentDataView: DataView; // TODO this should be IndexPattern or null + currentDataView: DataView; // TODO this should be DataView or null currentSavedSearch: SavedSearchSavedObject | null; dataViewsContract: DataViewsContract; kibanaConfig: any; // IUiSettingsClient; @@ -21,16 +21,8 @@ export interface MlContextValue { export type SavedSearchQuery = object; -// This context provides dependencies which can be injected -// via angularjs only (like services, currentDataView etc.). -// Because we cannot just import these dependencies, the default value -// for the context is just {} and of type `Partial` -// for the angularjs based dependencies. Therefore, the -// actual dependencies are set like we did previously with KibanaContext -// in the wrapping angularjs directive. In the custom hook we check if -// the dependencies are present with error reporting if they weren't -// added properly. That's why in tests, these custom hooks must not -// be mocked, instead ` needs +// In tests, these custom hooks must not be mocked, +// instead ` needs // to be used. This guarantees that we have both properly set up // TypeScript support and runtime checks for these dependencies. // Multiple custom hooks can be created to access subsets of diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts b/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts index aa9bd1dffd8f11..d607fd2edf4bae 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts @@ -71,7 +71,7 @@ async function getDataViewIdFromName( dataViewsContract: DataViewsContract ): Promise { if (dataViewsContract === null) { - throw Error('ARGGHH'); + throw new Error('Data views are not initialized!'); } const [dv] = await dataViewsContract?.find(datafeed.indices.join(',')); diff --git a/x-pack/plugins/ml/public/application/services/annotations_service.tsx b/x-pack/plugins/ml/public/application/services/annotations_service.tsx index a84cd7ee000f2c..f3d50115f02062 100644 --- a/x-pack/plugins/ml/public/application/services/annotations_service.tsx +++ b/x-pack/plugins/ml/public/application/services/annotations_service.tsx @@ -17,7 +17,7 @@ export type AnnotationState = Annotation | null; /* This observable offers a way to share state between components that don't have a direct parent -> * -> child relationship. - It's also useful in mixed angularjs/React environments. + It's also useful in mixed React environments. For example, we want to trigger the flyout for editing annotations from both the timeseries_chart and the annotations_table. Since we don't want two flyout instances, @@ -75,8 +75,7 @@ export const annotation$ = new BehaviorSubject(null); /* This observable provides a way to trigger a reload of annotations based on a given event. - Instead of passing around callbacks or deeply nested props, it can be imported for both - angularjs controllers/directives and React components. + Instead of passing around callbacks or deeply nested props, it can be imported in React components. */ export const annotationsRefresh$ = new BehaviorSubject(Date.now()); export const annotationsRefreshed = () => annotationsRefresh$.next(Date.now()); diff --git a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts index cb84d709c91ac3..7c435a247d7fa1 100644 --- a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts +++ b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts @@ -38,7 +38,7 @@ import { getAuthorizationHeader } from '../lib/request_authorization'; import type { MlClient } from '../lib/ml_client'; import type { DataViewsService } from '../../../../../src/plugins/data_views/common'; -function getDataVIewId(dataViewsService: DataViewsService, patternName: string) { +function getDataViewId(dataViewsService: DataViewsService, patternName: string) { const iph = new DataViewHandler(dataViewsService); return iph.getDataViewId(patternName); } @@ -427,7 +427,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout if (destinationIndex && deleteDestIndexPattern) { try { const dataViewsService = await getDataViewsService(); - const dataViewId = await getDataVIewId(dataViewsService, destinationIndex); + const dataViewId = await getDataViewId(dataViewsService, destinationIndex); if (dataViewId) { await deleteDestDataViewById(dataViewsService, dataViewId); }