[8.12] Fix warnings generated by the model selection list (#173629) (#173741)

# Backport

This will backport the following commits from `main` to `8.12`:
- [Fix warnings generated by the model selection list
(#173629)](https://github.com/elastic/kibana/pull/173629)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Mike
Pellegrini","email":"mike.pellegrini@elastic.co"},"sourceCommit":{"committedDate":"2023-12-20T13:29:12Z","message":"Fix
warnings generated by the model selection list (#173629)\n\n##
Summary\r\n\r\nFix DOM attribute warnings generated by the model
selection list. This\r\napproach uses the
[`option.data`\r\nprop](https://eui.elastic.co/#/forms/selectable#rendering-the-options)\r\nto
pass custom data for option rendering, which prevents the custom
data\r\nfrom being added to the rendered DOM
element.","sha":"3c75764e0763ce6adee5a2aac51a0e4216492363","branchLabelMapping":{"^v8.13.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:EnterpriseSearch","v8.12.0","v8.13.0"],"number":173629,"url":"https://github.com/elastic/kibana/pull/173629","mergeCommit":{"message":"Fix
warnings generated by the model selection list (#173629)\n\n##
Summary\r\n\r\nFix DOM attribute warnings generated by the model
selection list. This\r\napproach uses the
[`option.data`\r\nprop](https://eui.elastic.co/#/forms/selectable#rendering-the-options)\r\nto
pass custom data for option rendering, which prevents the custom
data\r\nfrom being added to the rendered DOM
element.","sha":"3c75764e0763ce6adee5a2aac51a0e4216492363"}},"sourceBranch":"main","suggestedTargetBranches":["8.12"],"targetPullRequestStates":[{"branch":"8.12","label":"v8.12.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.13.0","labelRegex":"^v8.13.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/173629","number":173629,"mergeCommit":{"message":"Fix
warnings generated by the model selection list (#173629)\n\n##
Summary\r\n\r\nFix DOM attribute warnings generated by the model
selection list. This\r\napproach uses the
[`option.data`\r\nprop](https://eui.elastic.co/#/forms/selectable#rendering-the-options)\r\nto
pass custom data for option rendering, which prevents the custom
data\r\nfrom being added to the rendered DOM
element.","sha":"3c75764e0763ce6adee5a2aac51a0e4216492363"}}]}]
BACKPORT-->

Co-authored-by: Mike Pellegrini <mike.pellegrini@elastic.co>
This commit is contained in:
Kibana Machine 2023-12-20 09:42:58 -05:00 committed by GitHub
parent ec6ab78106
commit db717ad064
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 26 deletions

View file

@ -83,11 +83,15 @@ describe('ModelSelect', () => {
const selectable = wrapper.find(EuiSelectable);
expect(selectable.prop('options')).toEqual([
{
modelId: 'model_1',
data: {
modelId: 'model_1',
},
label: 'model_1',
},
{
modelId: 'model_2',
data: {
modelId: 'model_2',
},
label: 'model_2',
},
]);
@ -114,7 +118,10 @@ describe('ModelSelect', () => {
const wrapper = shallow(<ModelSelect />);
expect(wrapper.find(EuiSelectable)).toHaveLength(1);
const selectable = wrapper.find(EuiSelectable);
selectable.simulate('change', [{ modelId: 'model_1' }, { modelId: 'model_2', checked: 'on' }]);
selectable.simulate('change', [
{ data: { modelId: 'model_1' } },
{ data: { modelId: 'model_2' }, checked: 'on' },
]);
expect(MOCK_ACTIONS.setInferencePipelineConfiguration).toHaveBeenCalledWith(
expect.objectContaining({
inferenceConfig: undefined,
@ -130,8 +137,8 @@ describe('ModelSelect', () => {
expect(wrapper.find(EuiSelectable)).toHaveLength(1);
const selectable = wrapper.find(EuiSelectable);
selectable.simulate('change', [
{ modelId: 'model_1' },
{ modelId: 'model_2', isPlaceholder: true, checked: 'on' },
{ data: { modelId: 'model_1' } },
{ data: { modelId: 'model_2', isPlaceholder: true }, checked: 'on' },
]);
expect(MOCK_ACTIONS.setInferencePipelineConfiguration).toHaveBeenCalledWith(
expect.objectContaining({
@ -146,7 +153,10 @@ describe('ModelSelect', () => {
const wrapper = shallow(<ModelSelect />);
expect(wrapper.find(EuiSelectable)).toHaveLength(1);
const selectable = wrapper.find(EuiSelectable);
selectable.simulate('change', [{ modelId: 'model_1' }, { modelId: 'model_2', checked: 'on' }]);
selectable.simulate('change', [
{ data: { modelId: 'model_1' } },
{ data: { modelId: 'model_2' }, checked: 'on' },
]);
expect(MOCK_ACTIONS.setInferencePipelineConfiguration).toHaveBeenCalledWith(
expect.objectContaining({
pipelineName: 'my-index-model_2',
@ -168,7 +178,10 @@ describe('ModelSelect', () => {
const wrapper = shallow(<ModelSelect />);
expect(wrapper.find(EuiSelectable)).toHaveLength(1);
const selectable = wrapper.find(EuiSelectable);
selectable.simulate('change', [{ modelId: 'model_1' }, { modelId: 'model_2', checked: 'on' }]);
selectable.simulate('change', [
{ data: { modelId: 'model_1' } },
{ data: { modelId: 'model_2' }, checked: 'on' },
]);
expect(MOCK_ACTIONS.setInferencePipelineConfiguration).toHaveBeenCalledWith(
expect.objectContaining({
pipelineName: 'user-pipeline',

View file

@ -18,6 +18,7 @@ import {
EuiPanel,
EuiScreenReaderLive,
EuiSelectable,
EuiSelectableOption,
EuiText,
EuiTextColor,
EuiTitle,
@ -31,9 +32,13 @@ import { MlModel, MlModelDeploymentState } from '../../../../../../../common/typ
import { LicenseBadge } from './license_badge';
import { ModelSelectLogic } from './model_select_logic';
import { ModelSelectOption, ModelSelectOptionProps } from './model_select_option';
import { ModelSelectOption } from './model_select_option';
import { normalizeModelName } from './utils';
type EuiSelectableOptionWithMlModelData = EuiSelectableOption & {
data: MlModel;
};
export const DeployModelButton: React.FC<{
onClick: () => void;
modelId: string;
@ -297,33 +302,37 @@ export const ModelSelect: React.FC = () => {
const maxVisibleOptions = 4.5;
const [listHeight, setListHeight] = useState(maxVisibleOptions * rowHeight);
const getModelSelectOptionProps = (models: MlModel[]): ModelSelectOptionProps[] =>
const getModelSelectOptionProps = (models: MlModel[]): EuiSelectableOptionWithMlModelData[] =>
(models ?? []).map((model) => ({
...model,
label: model.modelId,
checked: model.modelId === modelID ? 'on' : undefined,
data: { ...model },
}));
const onChange = (options: ModelSelectOptionProps[]) => {
const onChange = (options: EuiSelectableOptionWithMlModelData[]) => {
const selectedModelOption = options.find((option) => option.checked === 'on');
setInferencePipelineConfiguration({
...configuration,
inferenceConfig: undefined,
modelID: selectedModelOption?.modelId ?? '',
isModelPlaceholderSelected: selectedModelOption?.isPlaceholder ?? false,
modelID: selectedModelOption?.data.modelId ?? '',
isModelPlaceholderSelected: selectedModelOption?.data.isPlaceholder ?? false,
fieldMappings: undefined,
pipelineName: isPipelineNameUserSupplied
? pipelineName
: indexName + '-' + normalizeModelName(selectedModelOption?.modelId ?? ''),
: indexName + '-' + normalizeModelName(selectedModelOption?.data.modelId ?? ''),
});
};
const onSearchChange = (_: string, matchingOptions: ModelSelectOptionProps[]) => {
const onSearchChange = (_: string, matchingOptions: EuiSelectableOptionWithMlModelData[]) => {
setListHeight(Math.min(maxVisibleOptions, matchingOptions.length) * rowHeight);
};
const renderOption = (option: ModelSelectOptionProps) => <ModelSelectOption {...option} />;
const renderOption = (option: EuiSelectableOptionWithMlModelData) => {
const { data, ...optionExclData } = option;
const flattenedOption = { ...optionExclData, ...data };
return <ModelSelectOption {...flattenedOption} />;
};
return (
<EuiFlexGroup>

View file

@ -11,15 +11,15 @@ import React from 'react';
import { shallow } from 'enzyme';
import { EuiText } from '@elastic/eui';
import { EuiSelectableOption, EuiText } from '@elastic/eui';
import { MlModelDeploymentState } from '../../../../../../../common/types/ml';
import { MlModel, MlModelDeploymentState } from '../../../../../../../common/types/ml';
import { TrainedModelHealth } from '../ml_model_health';
import { LicenseBadge } from './license_badge';
import { ModelSelectOption, ModelSelectOptionProps } from './model_select_option';
import { ModelSelectOption } from './model_select_option';
const DEFAULT_PROPS: ModelSelectOptionProps = {
const DEFAULT_PROPS: EuiSelectableOption<MlModel> = {
modelId: 'model_1',
type: 'ner',
label: 'Model 1',

View file

@ -10,6 +10,7 @@ import React from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
EuiSelectableOption,
EuiText,
EuiTextColor,
EuiTextTruncate,
@ -22,12 +23,7 @@ import { TrainedModelHealth } from '../ml_model_health';
import { LicenseBadge } from './license_badge';
export type ModelSelectOptionProps = MlModel & {
label: string;
checked?: 'on';
};
export const ModelSelectOption: React.FC<ModelSelectOptionProps> = ({
export const ModelSelectOption: React.FC<EuiSelectableOption<MlModel>> = ({
modelId,
title,
description,