Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ML] Allows temporary data views in AD job wizards #170112

Expand Up @@ -399,6 +399,7 @@ export class JobsList extends Component {
rowProps={(item) => ({
'data-test-subj': `mlJobListRow row-${item.id}`,
})}
css={{ '.euiTableRow-isExpandedRow .euiTableCellContent': { animation: 'none' } }}
/>
);
}
Expand Down
Expand Up @@ -16,7 +16,6 @@ import {
import { getApplication, getToastNotifications } from '../../../util/dependency_cache';
import { ml } from '../../../services/ml_api_service';
import { stringMatch } from '../../../util/string_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';
Expand Down Expand Up @@ -222,25 +221,6 @@ export async function cloneJob(jobId) {
loadFullJob(jobId, false),
]);

const dataViewNames = await getDataViewNames();
const dataViewTitle = datafeed.indices.join(',');
const jobIndicesAvailable = dataViewNames.includes(dataViewTitle);

if (jobIndicesAvailable === false) {
const warningText = i18n.translate(
'xpack.ml.jobsList.managementActions.noSourceDataViewForClone',
{
defaultMessage:
'Unable to clone the anomaly detection job {jobId}. No data view exists for index {dataViewTitle}.',
values: { jobId, dataViewTitle },
}
);
getToastNotificationService().displayDangerToast(warningText, {
'data-test-subj': 'mlCloneJobNoDataViewExistsWarningToast',
});
return;
}

const createdBy = originalJob?.custom_settings?.created_by;
if (
cloneableJob !== undefined &&
Expand Down
Expand Up @@ -80,7 +80,7 @@ export const Page: FC<PageProps> = ({ nextStepPath }) => {
uiSettings,
}}
>
<CreateDataViewButton onDataViewCreated={onObjectSelection} />
<CreateDataViewButton onDataViewCreated={onObjectSelection} allowAdHocDataView={true} />
</SavedObjectFinder>
</EuiPanel>
</EuiPageBody>
Expand Down
Expand Up @@ -8,7 +8,7 @@
import type { ApplicationStart } from '@kbn/core/public';
import type { DataViewsContract } from '@kbn/data-views-plugin/public';
import { mlJobService } from '../../../../services/job_service';
import { Datafeed } from '../../../../../../common/types/anomaly_detection_jobs';
import type { Job, Datafeed } from '../../../../../../common/types/anomaly_detection_jobs';
import { CREATED_BY_LABEL, JOB_TYPE } from '../../../../../../common/constants/new_job';

export async function preConfiguredJobRedirect(
Expand All @@ -19,7 +19,7 @@ export async function preConfiguredJobRedirect(
const { createdBy, job, datafeed } = mlJobService.tempJobCloningObjects;

if (job && datafeed) {
const dataViewId = await getDataViewIdFromName(datafeed, dataViewsService);
const dataViewId = await getDataViewIdFromName(job, datafeed, dataViewsService);
if (dataViewId === null) {
return Promise.resolve();
}
Expand Down Expand Up @@ -73,16 +73,27 @@ async function getWizardUrlFromCloningJob(createdBy: string | undefined, dataVie
}

async function getDataViewIdFromName(
job: Job,
datafeed: Datafeed,
dataViewsService: DataViewsContract
): Promise<string | null> {
if (dataViewsService === null) {
throw new Error('Data views are not initialized!');
}

const [dv] = await dataViewsService?.find(datafeed.indices.join(','));
if (!dv) {
return null;
const indexPattern = datafeed.indices.join(',');

const [dv] = await dataViewsService?.find(indexPattern);
if (!dv || dv.getIndexPattern() !== indexPattern) {
qn895 marked this conversation as resolved.
Show resolved Hide resolved
// create a temporary data view if we can't find one
// matching the index pattern
const dataView = await dataViewsService.create({
id: undefined,
name: indexPattern,
title: indexPattern,
timeFieldName: job.data_description.time_field!,
});
return dataView.id ?? null;
}
return dv.id ?? dv.title;
}
Expand Up @@ -232,11 +232,19 @@ export const Page: FC<PageProps> = ({ existingJobsAndGroups, jobType }) => {

<div style={{ backgroundColor: 'inherit' }} data-test-subj={`mlPageJobWizard ${jobType}`}>
<EuiText size={'s'}>
<FormattedMessage
id="xpack.ml.newJob.page.createJob.dataViewName"
defaultMessage="Using data view {dataViewName}"
values={{ dataViewName: jobCreator.indexPatternDisplayName }}
/>
{dataSourceContext.selectedDataView.isPersisted() ? (
<FormattedMessage
id="xpack.ml.newJob.page.createJob.dataViewName"
defaultMessage="Using data view {dataViewName}"
values={{ dataViewName: jobCreator.indexPatternDisplayName }}
/>
) : (
<FormattedMessage
id="xpack.ml.newJob.page.createJob.tempDataViewName"
defaultMessage="Using temporary data view {dataViewName}"
values={{ dataViewName: jobCreator.indexPatternDisplayName }}
/>
)}
</EuiText>

<Wizard
Expand Down
3 changes: 1 addition & 2 deletions x-pack/plugins/translations/translations/fr-FR.json
Expand Up @@ -22522,7 +22522,6 @@
"xpack.ml.jobsList.jobDetails.forecastsTable.viewAriaLabel": "Afficher la prévision créée le {createdDate}",
"xpack.ml.jobsList.jobFilterBar.invalidSearchErrorMessage": "Recherche non valide : {errorMessage}",
"xpack.ml.jobsList.jobFilterBar.jobGroupTitle": "({jobsCount, plural, one {# tâche} many {# tâches} other {# tâches}})",
"xpack.ml.jobsList.managementActions.noSourceDataViewForClone": "Impossible de cloner la tâche de détection des anomalies {jobId}. Il n'existe aucune vue de données pour l'index {dataViewTitle}.",
"xpack.ml.jobsList.missingSavedObjectWarning.link": " {link}",
"xpack.ml.jobsList.multiJobActions.groupSelector.applyGroupsToJobTitle": "Appliquer des groupes {jobsCount, plural, one {tâche} many {tâches} other {aux tâches}}",
"xpack.ml.jobsList.multiJobsActions.closeJobsLabel": "Fermer {jobsCount, plural, one {tâche} many {tâches} other {les tâches}}",
Expand Down Expand Up @@ -39373,4 +39372,4 @@
"xpack.painlessLab.walkthroughButtonLabel": "Présentation",
"xpack.serverlessObservability.nav.getStarted": "Démarrer"
}
}
}
3 changes: 1 addition & 2 deletions x-pack/plugins/translations/translations/ja-JP.json
Expand Up @@ -22534,7 +22534,6 @@
"xpack.ml.jobsList.jobDetails.forecastsTable.viewAriaLabel": "{createdDate}に作成された予測を表示",
"xpack.ml.jobsList.jobFilterBar.invalidSearchErrorMessage": "無効な検索:{errorMessage}",
"xpack.ml.jobsList.jobFilterBar.jobGroupTitle": "({jobsCount, plural, other {#個のジョブ}})",
"xpack.ml.jobsList.managementActions.noSourceDataViewForClone": "異常検知ジョブ{jobId}を複製できません。インデックス{dataViewTitle}のデータビューは存在しません。",
"xpack.ml.jobsList.missingSavedObjectWarning.link": " {link}",
"xpack.ml.jobsList.multiJobActions.groupSelector.applyGroupsToJobTitle": "{jobsCount, plural, other {ジョブ}}にグループを適用",
"xpack.ml.jobsList.multiJobsActions.closeJobsLabel": "{jobsCount, plural, other {ジョブ}}を閉じる",
Expand Down Expand Up @@ -39364,4 +39363,4 @@
"xpack.painlessLab.walkthroughButtonLabel": "実地検証",
"xpack.serverlessObservability.nav.getStarted": "使ってみる"
}
}
}
3 changes: 1 addition & 2 deletions x-pack/plugins/translations/translations/zh-CN.json
Expand Up @@ -22533,7 +22533,6 @@
"xpack.ml.jobsList.jobDetails.forecastsTable.viewAriaLabel": "查看在 {createdDate} 创建的预测",
"xpack.ml.jobsList.jobFilterBar.invalidSearchErrorMessage": "无效搜索:{errorMessage}",
"xpack.ml.jobsList.jobFilterBar.jobGroupTitle": "({jobsCount, plural, other {# 个作业}})",
"xpack.ml.jobsList.managementActions.noSourceDataViewForClone": "无法克隆异常检测作业 {jobId}。对于索引 {dataViewTitle},不存在数据视图。",
"xpack.ml.jobsList.missingSavedObjectWarning.link": " {link}",
"xpack.ml.jobsList.multiJobActions.groupSelector.applyGroupsToJobTitle": "将组应用到{jobsCount, plural, other {作业}}",
"xpack.ml.jobsList.multiJobsActions.closeJobsLabel": "关闭{jobsCount, plural, other {作业}}",
Expand Down Expand Up @@ -39358,4 +39357,4 @@
"xpack.painlessLab.walkthroughButtonLabel": "指导",
"xpack.serverlessObservability.nav.getStarted": "开始使用"
}
}
}
Expand Up @@ -228,7 +228,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.api.assertDetectorResultsExist(jobId, 0);
});

it('job cloning fails in the single metric wizard if a matching data view does not exist', async () => {
it('job cloning opens in the single metric wizard if a matching data view does not exist', async () => {
jgowdyelastic marked this conversation as resolved.
Show resolved Hide resolved
await ml.testExecution.logTestStep('delete data view used by job');
await ml.testResources.deleteIndexPatternByTitle(indexPatternString);

Expand All @@ -238,7 +238,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep(
'job cloning clicks the clone action and displays an error toast'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably should update the log test step here to reflect that it is opening the wizard

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 5773dd2

);
await ml.jobTable.clickCloneJobActionWhenNoDataViewExists(jobId);
await ml.jobTypeSelection.assertSingleMetricJobWizardOpen();
});

it('job cloning opens the existing job in the single metric wizard', async () => {
Expand Down