Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { Fragment, FC } from 'react';
import React, { FC, useState } from 'react';
import { i18n } from '@kbn/i18n';

import { EuiFormRow, EuiSelect } from '@elastic/eui';
import { EuiCard, EuiIcon, EuiFlexItem, EuiFlexGroup, EuiSpacer } from '@elastic/eui';
import { ANALYSIS_CONFIG_TYPE } from '../../../../../../../common/constants/data_frame_analytics';
import { DataFrameAnalysisConfigType } from '../../../../../../../common/types/data_frame_analytics';

import { AnalyticsJobType } from '../../../analytics_management/hooks/use_create_analytics_form/state';

Expand All @@ -17,64 +18,81 @@ interface Props {
setFormState: React.Dispatch<React.SetStateAction<any>>;
}

export const JobType: FC<Props> = ({ type, setFormState }) => {
const outlierHelpText = i18n.translate(
'xpack.ml.dataframe.analytics.create.outlierDetectionHelpText',
{
defaultMessage: 'Outlier detection identifies unusual data points in the data set.',
}
);
interface Details {
helpText: string;
icon: string;
title: string;
}

const regressionHelpText = i18n.translate(
'xpack.ml.dataframe.analytics.create.outlierRegressionHelpText',
{
defaultMessage: 'Regression predicts numerical values in the data set.',
}
);
type JobDetails = Record<DataFrameAnalysisConfigType, Details>;

const classificationHelpText = i18n.translate(
'xpack.ml.dataframe.analytics.create.classificationHelpText',
{
const jobDetails: JobDetails = {
[ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION]: {
helpText: i18n.translate('xpack.ml.dataframe.analytics.create.outlierDetectionHelpText', {
defaultMessage: 'Outlier detection identifies unusual data points in the data set.',
}),
icon: 'outlierDetectionJob',
title: i18n.translate('xpack.ml.dataframe.analytics.create.outlierDetectionTitle', {
defaultMessage: 'Outlier detection',
}),
},
[ANALYSIS_CONFIG_TYPE.REGRESSION]: {
helpText: i18n.translate('xpack.ml.dataframe.analytics.create.regressionHelpText', {
defaultMessage: 'Regression predicts numerical values in the data set.',
}),
icon: 'regressionJob',
title: i18n.translate('xpack.ml.dataframe.analytics.create.regressionTitle', {
defaultMessage: 'Regression',
}),
},
[ANALYSIS_CONFIG_TYPE.CLASSIFICATION]: {
helpText: i18n.translate('xpack.ml.dataframe.analytics.create.classificationHelpText', {
defaultMessage: 'Classification predicts labels of data points in the data set.',
}
);
}),
icon: 'classificationJob',
title: i18n.translate('xpack.ml.dataframe.analytics.create.classificationTitle', {
defaultMessage: 'Classification',
}),
},
};

const helpText = {
[ANALYSIS_CONFIG_TYPE.REGRESSION]: regressionHelpText,
[ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION]: outlierHelpText,
[ANALYSIS_CONFIG_TYPE.CLASSIFICATION]: classificationHelpText,
};
export const JobType: FC<Props> = ({ type, setFormState }) => {
const [selectedCard, setSelectedCard] = useState<any>({});

return (
<Fragment>
<EuiFormRow
fullWidth
label={i18n.translate('xpack.ml.dataframe.analytics.create.jobTypeLabel', {
defaultMessage: 'Job type',
})}
helpText={type !== undefined ? helpText[type] : ''}
>
<EuiSelect
fullWidth
options={Object.values(ANALYSIS_CONFIG_TYPE).map((jobType) => ({
value: jobType,
text: jobType.replace(/_/g, ' '),
'data-test-subj': `mlAnalyticsCreation-${jobType}-option`,
}))}
value={type}
hasNoInitialSelection={true}
onChange={(e) => {
const value = e.target.value as AnalyticsJobType;
setFormState({
previousJobType: type,
jobType: value,
includes: [],
requiredFieldsError: undefined,
});
}}
data-test-subj="mlAnalyticsCreateJobWizardJobTypeSelect"
/>
</EuiFormRow>
</Fragment>
<>
<EuiFlexGroup gutterSize="m" data-test-subj="mlAnalyticsCreateJobWizardJobTypeSelect">
{(Object.keys(jobDetails) as Array<keyof typeof jobDetails>).map((jobType) => (
<EuiFlexItem key={jobType} grow={1}>
<EuiCard
icon={<EuiIcon size="xl" type={jobDetails[jobType].icon} />}
title={jobDetails[jobType].title}
description={jobDetails[jobType].helpText}
data-test-subj={`mlAnalyticsCreation-${jobType}-option${
type === jobType ? ' selectedJobType' : ''
}`}
selectable={{
onClick: () => {
// Only allow one job selected at a time and don't allow deselection
if (selectedCard[jobType] === true) {
return;
}

setFormState({
previousJobType: type,
jobType,
includes: [],
requiredFieldsError: undefined,
});
setSelectedCard({ [jobType]: !selectedCard[jobType] });
},
isSelected: selectedCard[jobType] === true || type === jobType,
}}
/>
</EuiFlexItem>
))}
</EuiFlexGroup>
<EuiSpacer size="m" />
</>
);
};
2 changes: 0 additions & 2 deletions x-pack/plugins/translations/translations/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -10678,7 +10678,6 @@
"xpack.ml.dataframe.analytics.create.jobIdInvalidMaxLengthErrorMessage": "ジョブ ID は {maxLength, plural, one {# 文字} other {# 文字}} 以内でなければなりません。",
"xpack.ml.dataframe.analytics.create.jobIdLabel": "ジョブID",
"xpack.ml.dataframe.analytics.create.jobIdPlaceholder": "ジョブID",
"xpack.ml.dataframe.analytics.create.jobTypeLabel": "ジョブタイプ",
"xpack.ml.dataframe.analytics.create.lambdaHelpText": "学習データセットの過剰適合を防止するための正則化パラメーター。非負の値でなければなりません。",
"xpack.ml.dataframe.analytics.create.lambdaInputAriaLabel": "学習データセットの過剰適合を防止するための正則化パラメーター。",
"xpack.ml.dataframe.analytics.create.lambdaLabel": "ラムダ",
Expand Down Expand Up @@ -10711,7 +10710,6 @@
"xpack.ml.dataframe.analytics.create.outlierFractionHelpText": "異常値検出の前に異常であると想定されるデータセットの比率を設定します。",
"xpack.ml.dataframe.analytics.create.outlierFractionInputAriaLabel": "異常値検出の前に異常であると想定されるデータセットの比率を設定します。",
"xpack.ml.dataframe.analytics.create.outlierFractionLabel": "異常値割合",
"xpack.ml.dataframe.analytics.create.outlierRegressionHelpText": "回帰はデータセットにおける数値を予測します。",
"xpack.ml.dataframe.analytics.create.predictionFieldNameHelpText": "結果で予測フィールドの名前を定義します。デフォルトは<dependent_variable>_predictionです。",
"xpack.ml.dataframe.analytics.create.predictionFieldNameLabel": "予測フィールド名",
"xpack.ml.dataframe.analytics.create.randomizeSeedInputAriaLabel": "学習で使用されるドキュメントを選択するために使用される乱数生成器のシード",
Expand Down
2 changes: 0 additions & 2 deletions x-pack/plugins/translations/translations/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -10684,7 +10684,6 @@
"xpack.ml.dataframe.analytics.create.jobIdInvalidMaxLengthErrorMessage": "作业 ID 的长度不得超过 {maxLength, plural, one {# 个字符} other {# 个字符}}。",
"xpack.ml.dataframe.analytics.create.jobIdLabel": "作业 ID",
"xpack.ml.dataframe.analytics.create.jobIdPlaceholder": "作业 ID",
"xpack.ml.dataframe.analytics.create.jobTypeLabel": "作业类型",
"xpack.ml.dataframe.analytics.create.lambdaHelpText": "在训练数据集上防止过度拟合的正则化参数。必须为非负值。",
"xpack.ml.dataframe.analytics.create.lambdaInputAriaLabel": "在训练数据集上防止过度拟合的正则化参数。",
"xpack.ml.dataframe.analytics.create.lambdaLabel": "Lambda",
Expand Down Expand Up @@ -10717,7 +10716,6 @@
"xpack.ml.dataframe.analytics.create.outlierFractionHelpText": "设置在离群值检测之前被假设为离群的数据集比例。",
"xpack.ml.dataframe.analytics.create.outlierFractionInputAriaLabel": "设置在离群值检测之前被假设为离群的数据集比例。",
"xpack.ml.dataframe.analytics.create.outlierFractionLabel": "离群值比例",
"xpack.ml.dataframe.analytics.create.outlierRegressionHelpText": "回归用于预测数据集中的数值。",
"xpack.ml.dataframe.analytics.create.predictionFieldNameHelpText": "定义结果中预测字段的名称。默认为 <dependent_variable>_prediction。",
"xpack.ml.dataframe.analytics.create.predictionFieldNameLabel": "预测字段名称",
"xpack.ml.dataframe.analytics.create.randomizeSeedInputAriaLabel": "用于选取哪个文档用于训练的随机生成器种子",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,16 @@ export function MachineLearningDataFrameAnalyticsCreationProvider(
await testSubjects.existOrFail('mlAnalyticsCreateJobWizardJobTypeSelect');
},

async assertJobTypeSelection(expectedSelection: string) {
async assertJobTypeSelection(jobTypeAttribute: string) {
await retry.tryForTime(5000, async () => {
const actualSelection = await testSubjects.getAttribute(
'mlAnalyticsCreateJobWizardJobTypeSelect',
'value'
);
expect(actualSelection).to.eql(
expectedSelection,
`Job type selection should be '${expectedSelection}' (got '${actualSelection}')`
);
await testSubjects.existOrFail(`${jobTypeAttribute} selectedJobType`);
});
},

async selectJobType(jobType: string) {
await testSubjects.click('mlAnalyticsCreateJobWizardJobTypeSelect');
await testSubjects.click(`mlAnalyticsCreation-${jobType}-option`);
await this.assertJobTypeSelection(jobType);
const jobTypeAttribute = `mlAnalyticsCreation-${jobType}-option`;
await testSubjects.click(jobTypeAttribute);
await this.assertJobTypeSelection(jobTypeAttribute);
},

async assertAdvancedEditorSwitchExists() {
Expand Down Expand Up @@ -505,7 +498,8 @@ export function MachineLearningDataFrameAnalyticsCreationProvider(

async assertInitialCloneJobConfigStep(job: DataFrameAnalyticsConfig) {
const jobType = Object.keys(job.analysis)[0];
await this.assertJobTypeSelection(jobType);
const jobTypeAttribute = `mlAnalyticsCreation-${jobType}-option`;
await this.assertJobTypeSelection(jobTypeAttribute);
if (isClassificationAnalysis(job.analysis) || isRegressionAnalysis(job.analysis)) {
await this.assertDependentVariableSelection([job.analysis[jobType].dependent_variable]);
await this.assertTrainingPercentValue(String(job.analysis[jobType].training_percent));
Expand Down