Skip to content

Commit 92289b6

Browse files
[Ingest Node Pipelines] Sentence-case processor names (#74645)
* wip on fixing processor names * added comment * fix Jest test element selector Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
1 parent ce6011e commit 92289b6

File tree

6 files changed

+126
-32
lines changed

6 files changed

+126
-32
lines changed

x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ const createActions = (testBed: TestBed<TestSubject>) => {
8989
async addProcessor(processorsSelector: string, type: string, options: Record<string, any>) {
9090
find(`${processorsSelector}.addProcessorButton`).simulate('click');
9191
await act(async () => {
92-
find('processorTypeSelector').simulate('change', [{ value: type, label: type }]);
92+
find('processorTypeSelector.input').simulate('change', [{ value: type, label: type }]);
9393
});
9494
component.update();
9595
await act(async () => {
@@ -129,7 +129,7 @@ const createActions = (testBed: TestBed<TestSubject>) => {
129129
find(`${processorSelector}.moreMenu.button`).simulate('click');
130130
find(`${processorSelector}.moreMenu.addOnFailureButton`).simulate('click');
131131
await act(async () => {
132-
find('processorTypeSelector').simulate('change', [{ value: type, label: type }]);
132+
find('processorTypeSelector.input').simulate('change', [{ value: type, label: type }]);
133133
});
134134
component.update();
135135
await act(async () => {

x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import { ProcessorsDispatch } from '../../processors_reducer';
2222

2323
import { ProcessorInfo } from '../processors_tree';
2424

25+
import { getProcessorDescriptor } from '../shared';
26+
2527
import './pipeline_processors_editor_item.scss';
2628

2729
import { InlineTextInput } from './inline_text_input';
@@ -139,7 +141,7 @@ export const PipelineProcessorsEditorItem: FunctionComponent<Props> = memo(
139141
className="pipelineProcessorsEditor__item__processorTypeLabel"
140142
color={isDimmed ? 'subdued' : undefined}
141143
>
142-
<b>{processor.type}</b>
144+
<b>{getProcessorDescriptor(processor.type)?.label ?? processor.type}</b>
143145
</EuiText>
144146
</EuiFlexItem>
145147
<EuiFlexItem className={inlineTextInputContainerClasses} grow={false}>

x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processor_settings_form.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ import {
2323
import { Form, FormDataProvider, FormHook } from '../../../../../shared_imports';
2424
import { ProcessorInternal } from '../../types';
2525

26+
import { getProcessorDescriptor } from '../shared';
27+
2628
import { DocumentationButton } from './documentation_button';
27-
import { getProcessorFormDescriptor } from './map_processor_type_to_form';
2829
import { CommonProcessorFields, ProcessorTypeField } from './processors/common_fields';
2930
import { Custom } from './processors/custom';
3031

@@ -88,7 +89,7 @@ export const ProcessorSettingsForm: FunctionComponent<Props> = memo(
8889
<EuiFlexItem grow={false}>
8990
<FormDataProvider pathsToWatch="type">
9091
{({ type }) => {
91-
const formDescriptor = getProcessorFormDescriptor(type as any);
92+
const formDescriptor = getProcessorDescriptor(type as any);
9293

9394
if (formDescriptor) {
9495
return (
@@ -114,7 +115,7 @@ export const ProcessorSettingsForm: FunctionComponent<Props> = memo(
114115
const { type } = arg;
115116

116117
if (type?.length) {
117-
const formDescriptor = getProcessorFormDescriptor(type as any);
118+
const formDescriptor = getProcessorDescriptor(type as any);
118119

119120
if (formDescriptor?.FieldsComponent) {
120121
return (

x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/common_fields/processor_type_field.tsx

Lines changed: 98 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,42 @@
33
* or more contributor license agreements. Licensed under the Elastic License;
44
* you may not use this file except in compliance with the Elastic License.
55
*/
6+
import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui';
67
import { i18n } from '@kbn/i18n';
78
import React, { FunctionComponent } from 'react';
9+
import { flow } from 'fp-ts/lib/function';
10+
import { map } from 'fp-ts/lib/Array';
11+
812
import {
913
FIELD_TYPES,
1014
FieldConfig,
1115
UseField,
1216
fieldValidators,
13-
ComboBoxField,
1417
} from '../../../../../../../shared_imports';
15-
import { types } from '../../map_processor_type_to_form';
18+
19+
import { getProcessorDescriptor, mapProcessorTypeToDescriptor } from '../../../shared';
20+
import {
21+
FieldValidateResponse,
22+
VALIDATION_TYPES,
23+
} from '../../../../../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib';
24+
25+
const extractProcessorTypesAndLabels = flow(
26+
Object.entries,
27+
map(([type, { label }]) => ({
28+
label,
29+
value: type,
30+
})),
31+
(arr) => arr.sort((a, b) => a.label.localeCompare(b.label))
32+
);
33+
34+
interface ProcessorTypeAndLabel {
35+
value: string;
36+
label: string;
37+
}
38+
39+
const processorTypesAndLabels: ProcessorTypeAndLabel[] = extractProcessorTypesAndLabels(
40+
mapProcessorTypeToDescriptor
41+
);
1642

1743
interface Props {
1844
initialType?: string;
@@ -47,22 +73,76 @@ const typeConfig: FieldConfig = {
4773

4874
export const ProcessorTypeField: FunctionComponent<Props> = ({ initialType }) => {
4975
return (
50-
<UseField
51-
config={typeConfig}
52-
defaultValue={initialType}
53-
path="type"
54-
component={ComboBoxField}
55-
componentProps={{
56-
euiFieldProps: {
57-
'data-test-subj': 'processorTypeSelector',
58-
fullWidth: true,
59-
options: types.map((type) => ({ label: type, value: type })),
60-
noSuggestions: false,
61-
singleSelection: {
62-
asPlainText: true,
63-
},
64-
},
76+
<UseField config={typeConfig} defaultValue={initialType} path="type">
77+
{(typeField) => {
78+
let selectedOptions: ProcessorTypeAndLabel[];
79+
if ((typeField.value as string[]).length) {
80+
const [type] = typeField.value as string[];
81+
const descriptor = getProcessorDescriptor(type);
82+
selectedOptions = descriptor
83+
? [{ label: descriptor.label, value: type }]
84+
: // If there is no label for this processor type, just use the type as the label
85+
[{ label: type, value: type }];
86+
} else {
87+
selectedOptions = [];
88+
}
89+
90+
const error = typeField.getErrorsMessages();
91+
const isInvalid = error ? Boolean(error.length) : false;
92+
93+
const onCreateComboOption = (value: string) => {
94+
// Note: for now, all validations for a comboBox array item have to be synchronous
95+
// If there is a need to support asynchronous validation, we'll work on it (and will need to update the <EuiComboBox /> logic).
96+
const { isValid } = typeField.validate({
97+
value,
98+
validationType: VALIDATION_TYPES.ARRAY_ITEM,
99+
}) as FieldValidateResponse;
100+
101+
if (!isValid) {
102+
// Return false to explicitly reject the user's input.
103+
return false;
104+
}
105+
106+
const newValue = [...(typeField.value as string[]), value];
107+
108+
typeField.setValue(newValue);
109+
};
110+
111+
return (
112+
<EuiFormRow
113+
label={typeField.label}
114+
labelAppend={typeField.labelAppend}
115+
helpText={
116+
typeof typeField.helpText === 'function' ? typeField.helpText() : typeField.helpText
117+
}
118+
error={error}
119+
isInvalid={isInvalid}
120+
fullWidth
121+
data-test-subj="processorTypeSelector"
122+
>
123+
<EuiComboBox
124+
fullWidth
125+
placeholder={i18n.translate(
126+
'xpack.ingestPipelines.pipelineEditor.typeField.typeFieldComboboxPlaceholder',
127+
{
128+
defaultMessage: 'Type and then hit "ENTER"',
129+
}
130+
)}
131+
options={processorTypesAndLabels}
132+
selectedOptions={selectedOptions}
133+
onCreateOption={onCreateComboOption}
134+
onChange={(options: EuiComboBoxOptionOption[]) => {
135+
typeField.setValue(options.map(({ value }) => value));
136+
}}
137+
noSuggestions={false}
138+
singleSelection={{
139+
asPlainText: true,
140+
}}
141+
data-test-subj="input"
142+
/>
143+
</EuiFormRow>
144+
);
65145
}}
66-
/>
146+
</UseField>
67147
);
68148
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
export {
8+
getProcessorDescriptor,
9+
mapProcessorTypeToDescriptor,
10+
ProcessorType,
11+
} from './map_processor_type_to_form';
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { FunctionComponent } from 'react';
1010
// import { SetProcessor } from './processors/set';
1111
// import { Gsub } from './processors/gsub';
1212

13-
interface FieldsFormDescriptor {
13+
interface FieldDescriptor {
1414
FieldsComponent?: FunctionComponent;
1515
docLinkPath: string;
1616
/**
@@ -19,7 +19,9 @@ interface FieldsFormDescriptor {
1919
label: string;
2020
}
2121

22-
const mapProcessorTypeToFormDescriptor: Record<string, FieldsFormDescriptor> = {
22+
type MapProcessorTypeToDescriptor = Record<string, FieldDescriptor>;
23+
24+
export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = {
2325
append: {
2426
FieldsComponent: undefined, // TODO: Implement
2527
docLinkPath: '/append-processor.html',
@@ -262,12 +264,10 @@ const mapProcessorTypeToFormDescriptor: Record<string, FieldsFormDescriptor> = {
262264
},
263265
};
264266

265-
export const types = Object.keys(mapProcessorTypeToFormDescriptor).sort();
266-
267-
export type ProcessorType = keyof typeof mapProcessorTypeToFormDescriptor;
267+
export type ProcessorType = keyof typeof mapProcessorTypeToDescriptor;
268268

269-
export const getProcessorFormDescriptor = (
269+
export const getProcessorDescriptor = (
270270
type: ProcessorType | string
271-
): FieldsFormDescriptor | undefined => {
272-
return mapProcessorTypeToFormDescriptor[type as ProcessorType];
271+
): FieldDescriptor | undefined => {
272+
return mapProcessorTypeToDescriptor[type as ProcessorType];
273273
};

0 commit comments

Comments
 (0)