Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import type { FC } from 'react';
import React, { memo } from 'react';
import { i18n } from '@kbn/i18n';
import { useEuiTheme, type EuiComboBoxOptionOption } from '@elastic/eui';
import { useEuiTheme, useGeneratedHtmlId, type EuiComboBoxOptionOption } from '@elastic/eui';
import { EuiComboBox } from '@elastic/eui';
import type { Validation } from '../job_validator';
import { tabColor } from '../../../../../../common/util/group_color_utils';
Expand All @@ -24,7 +24,7 @@ export interface JobGroupsInputProps {
export const JobGroupsInput: FC<JobGroupsInputProps> = memo(
({ existingGroups, selectedGroups, onChange, validation }) => {
const { euiTheme } = useEuiTheme();

const groupsTitleId = useGeneratedHtmlId({ prefix: 'groupsTitleId' });
const options = existingGroups.map<EuiComboBoxOptionOption>((g) => ({
label: g,
color: tabColor(g, euiTheme),
Expand Down Expand Up @@ -63,7 +63,7 @@ export const JobGroupsInput: FC<JobGroupsInputProps> = memo(
}

return (
<Description validation={validation}>
<Description validation={validation} titleId={groupsTitleId}>
<EuiComboBox
placeholder={i18n.translate(
'xpack.ml.newJob.wizard.jobDetailsStep.jobGroupSelect.placeholder',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,31 @@ import type { Validation } from '../../../../common/job_validator';

interface Props {
validation: Validation;
titleId: string;
}

export const Description: FC<PropsWithChildren<Props>> = memo(({ children, validation }) => {
const title = i18n.translate(
'xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.modelMemoryLimit.title',
{
defaultMessage: 'Model memory limit',
}
);
return (
<EuiDescribedFormGroup
title={<h3>{title}</h3>}
description={
<FormattedMessage
id="xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.modelMemoryLimit.description"
defaultMessage="An approximate upper limit for the amount of memory that can be used by the analytical models."
/>
export const Description: FC<PropsWithChildren<Props>> = memo(
({ children, validation, titleId }) => {
const title = i18n.translate(
'xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.modelMemoryLimit.title',
{
defaultMessage: 'Model memory limit',
}
>
<EuiFormRow error={validation.message} isInvalid={validation.valid === false}>
<>{children}</>
</EuiFormRow>
</EuiDescribedFormGroup>
);
});
);
return (
<EuiDescribedFormGroup
title={<h3 id={titleId}>{title}</h3>}
description={
<FormattedMessage
id="xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.modelMemoryLimit.description"
defaultMessage="An approximate upper limit for the amount of memory that can be used by the analytical models."
/>
}
>
<EuiFormRow error={validation.message} isInvalid={validation.valid === false}>
<>{children}</>
</EuiFormRow>
</EuiDescribedFormGroup>
);
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import type { FC } from 'react';
import React, { useState, useContext, useEffect } from 'react';
import { EuiFieldText } from '@elastic/eui';
import { EuiFieldText, useGeneratedHtmlId } from '@elastic/eui';
import { getNewJobDefaults } from '../../../../../../services/ml_server_info';
import { JobCreatorContext } from '../../job_creator_context';
import { Description } from './description';
Expand All @@ -22,7 +22,9 @@ export const ModelMemoryLimitInput: FC = () => {

const { anomaly_detectors: anomalyDetectors } = getNewJobDefaults();
const { model_memory_limit: modelMemoryLimitDefault } = anomalyDetectors;

const modelMemoryLimitTitleId = useGeneratedHtmlId({
prefix: 'modelMemoryLimitTitleId',
});
useEffect(() => {
jobCreator.modelMemoryLimit = modelMemoryLimit === '' ? null : modelMemoryLimit;
jobCreatorUpdate();
Expand All @@ -40,13 +42,14 @@ export const ModelMemoryLimitInput: FC = () => {
}, [jobValidatorUpdated]);

return (
<Description validation={validation}>
<Description validation={validation} titleId={modelMemoryLimitTitleId}>
<EuiFieldText
value={modelMemoryLimit}
placeholder={modelMemoryLimitDefault}
onChange={(e) => setModelMemoryLimit(e.target.value)}
isInvalid={validation.valid === false}
data-test-subj="mlJobWizardInputModelMemoryLimit"
aria-labelledby={modelMemoryLimitTitleId}
/>
</Description>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
EuiSpacer,
EuiText,
EuiToolTip,
useGeneratedHtmlId,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import {
Expand Down Expand Up @@ -50,6 +51,7 @@ export const CalendarsSelection: FC<Props> = ({ isDst = false }) => {
>([]);
const [options, setOptions] = useState<Array<EuiComboBoxOptionOption<MlCalendar>>>([]);
const [isLoading, setIsLoading] = useState(false);
const calendarsTitleId = useGeneratedHtmlId({ prefix: 'calendarsTitleId' });

async function loadCalendars() {
setIsLoading(true);
Expand Down Expand Up @@ -94,10 +96,14 @@ export const CalendarsSelection: FC<Props> = ({ isDst = false }) => {
const Desc = isDst ? DescriptionDst : Description;

return (
<Desc>
<Desc titleId={isDst ? `Dst${calendarsTitleId}` : calendarsTitleId}>
<EuiFlexGroup gutterSize="xs" alignItems="center">
<EuiFlexItem>
<EuiComboBox {...comboBoxProps} data-test-subj="mlJobWizardComboBoxCalendars" />
<EuiComboBox
{...comboBoxProps}
data-test-subj="mlJobWizardComboBoxCalendars"
aria-labelledby={isDst ? `Dst${calendarsTitleId}` : calendarsTitleId}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiToolTip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { EuiDescribedFormGroup, EuiFormRow, EuiLink } from '@elastic/eui';
import { useMlKibana } from '../../../../../../../../../contexts/kibana';

export const Description: FC<PropsWithChildren<unknown>> = memo(({ children }) => {
interface Props {
titleId: string;
}

export const Description: FC<PropsWithChildren<Props>> = memo(({ children, titleId }) => {
const {
services: { docLinks },
} = useMlKibana();
Expand All @@ -25,7 +29,7 @@ export const Description: FC<PropsWithChildren<unknown>> = memo(({ children }) =
);
return (
<EuiDescribedFormGroup
title={<h3>{title}</h3>}
title={<h3 id={titleId}>{title}</h3>}
description={
<FormattedMessage
id="xpack.ml.newJob.wizard.jobDetailsStep.additionalSection.calendarsSelection.description"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { EuiDescribedFormGroup, EuiFormRow, EuiLink } from '@elastic/eui';
import { useMlKibana } from '../../../../../../../../../contexts/kibana';

export const DescriptionDst: FC<PropsWithChildren<unknown>> = memo(({ children }) => {
interface Props {
titleId: string;
}

export const DescriptionDst: FC<PropsWithChildren<Props>> = memo(({ children, titleId }) => {
const {
services: { docLinks },
} = useMlKibana();
Expand All @@ -25,7 +29,7 @@ export const DescriptionDst: FC<PropsWithChildren<unknown>> = memo(({ children }
);
return (
<EuiDescribedFormGroup
title={<h3>{title}</h3>}
title={<h3 id={titleId}>{title}</h3>}
description={
<FormattedMessage
id="xpack.ml.newJob.wizard.jobDetailsStep.additionalSection.calendarsDstSelection.description"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,28 @@ import type { Validation } from '../../../../../common/job_validator';

interface Props {
validation: Validation;
titleId: string;
}

export const Description: FC<PropsWithChildren<Props>> = memo(({ children, validation }) => {
const title = i18n.translate('xpack.ml.newJob.wizard.jobDetailsStep.jobGroupSelect.title', {
defaultMessage: 'Groups',
});
return (
<EuiDescribedFormGroup
title={<h3>{title}</h3>}
description={
<FormattedMessage
id="xpack.ml.newJob.wizard.jobDetailsStep.jobGroupSelect.description"
defaultMessage=" Optional grouping for jobs. New groups can be created or picked from the list of existing groups."
/>
}
>
<EuiFormRow error={validation.message} isInvalid={validation.valid === false}>
<>{children}</>
</EuiFormRow>
</EuiDescribedFormGroup>
);
});
export const Description: FC<PropsWithChildren<Props>> = memo(
({ children, validation, titleId }) => {
const title = i18n.translate('xpack.ml.newJob.wizard.jobDetailsStep.jobGroupSelect.title', {
defaultMessage: 'Groups',
});
return (
<EuiDescribedFormGroup
title={<h3 id={titleId}>{title}</h3>}
description={
<FormattedMessage
id="xpack.ml.newJob.wizard.jobDetailsStep.jobGroupSelect.description"
defaultMessage=" Optional grouping for jobs. New groups can be created or picked from the list of existing groups."
/>
}
>
<EuiFormRow error={validation.message} isInvalid={validation.valid === false}>
<>{children}</>
</EuiFormRow>
</EuiDescribedFormGroup>
);
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@

import type { FC } from 'react';
import React, { useState, useContext, useEffect, useMemo } from 'react';
import { useEuiTheme, type EuiComboBoxOptionOption } from '@elastic/eui';
import { EuiComboBox } from '@elastic/eui';
import {
useEuiTheme,
EuiComboBox,
type EuiComboBoxOptionOption,
useGeneratedHtmlId,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { JobCreatorContext } from '../../../job_creator_context';
import { tabColor } from '../../../../../../../../../common/util/group_color_utils';
Expand All @@ -21,6 +25,7 @@ export const GroupsInput: FC = () => {
useContext(JobCreatorContext);
const { existingJobsAndGroups } = useContext(JobCreatorContext);
const [selectedGroups, setSelectedGroups] = useState(jobCreator.groups);
const jobGroupsTitleId = useGeneratedHtmlId({ prefix: 'jobGroupsTitleId' });

const validation = useMemo(() => {
const valid =
Expand Down Expand Up @@ -80,7 +85,7 @@ export const GroupsInput: FC = () => {
}

return (
<Description validation={validation}>
<Description validation={validation} titleId={jobGroupsTitleId}>
<EuiComboBox
placeholder={i18n.translate(
'xpack.ml.newJob.wizard.jobDetailsStep.jobGroupSelect.placeholder',
Expand All @@ -95,6 +100,7 @@ export const GroupsInput: FC = () => {
isClearable={true}
isInvalid={validation.valid === false}
data-test-subj="mlJobWizardComboBoxJobGroups"
aria-labelledby={jobGroupsTitleId}
/>
</Description>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui';

export const Description: FC<PropsWithChildren<unknown>> = memo(({ children }) => {
interface Props {
titleId: string;
}

export const Description: FC<PropsWithChildren<Props>> = memo(({ children, titleId }) => {
const title = i18n.translate('xpack.ml.newJob.wizard.jobDetailsStep.jobDescription.title', {
defaultMessage: 'Job description',
});
return (
<EuiDescribedFormGroup
title={<h3>{title}</h3>}
title={<h3 id={titleId}>{title}</h3>}
description={
<FormattedMessage
id="xpack.ml.newJob.wizard.jobDetailsStep.jobDescription.description"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,27 @@

import type { FC } from 'react';
import React, { useState, useContext, useEffect } from 'react';
import { EuiTextArea } from '@elastic/eui';
import { EuiTextArea, useGeneratedHtmlId } from '@elastic/eui';
import { JobCreatorContext } from '../../../job_creator_context';
import { Description } from './description';

export const JobDescriptionInput: FC = () => {
const { jobCreator, jobCreatorUpdate } = useContext(JobCreatorContext);
const [jobDescription, setJobDescription] = useState(jobCreator.description);

const jobDescriptionTitleId = useGeneratedHtmlId({ prefix: 'jobDescriptionTitleId' });
useEffect(() => {
jobCreator.description = jobDescription;
jobCreatorUpdate();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [jobDescription]);

return (
<Description>
<Description titleId={jobDescriptionTitleId}>
<EuiTextArea
value={jobDescription}
onChange={(e) => setJobDescription(e.target.value)}
data-test-subj="mlJobWizardInputJobDescription"
aria-labelledby={jobDescriptionTitleId}
/>
</Description>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,24 @@ import type { Validation } from '../../../../../common/job_validator';

interface Props {
validation: Validation;
titleId: string;
}

export const Description: FC<PropsWithChildren<Props>> = memo(({ children, validation }) => {
const title = i18n.translate('xpack.ml.newJob.wizard.jobDetailsStep.jobId.title', {
defaultMessage: 'Job ID',
});
const description = i18n.translate('xpack.ml.newJob.wizard.jobDetailsStep.jobId.description', {
defaultMessage:
'A unique identifier for the job. Spaces and the characters / ? , " < > | * are not allowed',
});
return (
<EuiDescribedFormGroup title={<h3>{title}</h3>} description={description}>
<EuiFormRow error={validation.message} isInvalid={validation.valid === false}>
<>{children}</>
</EuiFormRow>
</EuiDescribedFormGroup>
);
});
export const Description: FC<PropsWithChildren<Props>> = memo(
({ children, validation, titleId }) => {
const title = i18n.translate('xpack.ml.newJob.wizard.jobDetailsStep.jobId.title', {
defaultMessage: 'Job ID',
});
const description = i18n.translate('xpack.ml.newJob.wizard.jobDetailsStep.jobId.description', {
defaultMessage:
'A unique identifier for the job. Spaces and the characters / ? , " < > | * are not allowed',
});
return (
<EuiDescribedFormGroup title={<h3 id={titleId}>{title}</h3>} description={description}>
<EuiFormRow error={validation.message} isInvalid={validation.valid === false}>
<>{children}</>
</EuiFormRow>
</EuiDescribedFormGroup>
);
}
);
Loading