[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>
This commit is contained in:
Jean-Louis Leysens 2020-08-11 10:05:54 +02:00 committed by GitHub
parent ce6011e4d5
commit 92289b63ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 126 additions and 32 deletions

View file

@ -89,7 +89,7 @@ const createActions = (testBed: TestBed<TestSubject>) => {
async addProcessor(processorsSelector: string, type: string, options: Record<string, any>) {
find(`${processorsSelector}.addProcessorButton`).simulate('click');
await act(async () => {
find('processorTypeSelector').simulate('change', [{ value: type, label: type }]);
find('processorTypeSelector.input').simulate('change', [{ value: type, label: type }]);
});
component.update();
await act(async () => {
@ -129,7 +129,7 @@ const createActions = (testBed: TestBed<TestSubject>) => {
find(`${processorSelector}.moreMenu.button`).simulate('click');
find(`${processorSelector}.moreMenu.addOnFailureButton`).simulate('click');
await act(async () => {
find('processorTypeSelector').simulate('change', [{ value: type, label: type }]);
find('processorTypeSelector.input').simulate('change', [{ value: type, label: type }]);
});
component.update();
await act(async () => {

View file

@ -22,6 +22,8 @@ import { ProcessorsDispatch } from '../../processors_reducer';
import { ProcessorInfo } from '../processors_tree';
import { getProcessorDescriptor } from '../shared';
import './pipeline_processors_editor_item.scss';
import { InlineTextInput } from './inline_text_input';
@ -139,7 +141,7 @@ export const PipelineProcessorsEditorItem: FunctionComponent<Props> = memo(
className="pipelineProcessorsEditor__item__processorTypeLabel"
color={isDimmed ? 'subdued' : undefined}
>
<b>{processor.type}</b>
<b>{getProcessorDescriptor(processor.type)?.label ?? processor.type}</b>
</EuiText>
</EuiFlexItem>
<EuiFlexItem className={inlineTextInputContainerClasses} grow={false}>

View file

@ -23,8 +23,9 @@ import {
import { Form, FormDataProvider, FormHook } from '../../../../../shared_imports';
import { ProcessorInternal } from '../../types';
import { getProcessorDescriptor } from '../shared';
import { DocumentationButton } from './documentation_button';
import { getProcessorFormDescriptor } from './map_processor_type_to_form';
import { CommonProcessorFields, ProcessorTypeField } from './processors/common_fields';
import { Custom } from './processors/custom';
@ -88,7 +89,7 @@ export const ProcessorSettingsForm: FunctionComponent<Props> = memo(
<EuiFlexItem grow={false}>
<FormDataProvider pathsToWatch="type">
{({ type }) => {
const formDescriptor = getProcessorFormDescriptor(type as any);
const formDescriptor = getProcessorDescriptor(type as any);
if (formDescriptor) {
return (
@ -114,7 +115,7 @@ export const ProcessorSettingsForm: FunctionComponent<Props> = memo(
const { type } = arg;
if (type?.length) {
const formDescriptor = getProcessorFormDescriptor(type as any);
const formDescriptor = getProcessorDescriptor(type as any);
if (formDescriptor?.FieldsComponent) {
return (

View file

@ -3,16 +3,42 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { FunctionComponent } from 'react';
import { flow } from 'fp-ts/lib/function';
import { map } from 'fp-ts/lib/Array';
import {
FIELD_TYPES,
FieldConfig,
UseField,
fieldValidators,
ComboBoxField,
} from '../../../../../../../shared_imports';
import { types } from '../../map_processor_type_to_form';
import { getProcessorDescriptor, mapProcessorTypeToDescriptor } from '../../../shared';
import {
FieldValidateResponse,
VALIDATION_TYPES,
} from '../../../../../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib';
const extractProcessorTypesAndLabels = flow(
Object.entries,
map(([type, { label }]) => ({
label,
value: type,
})),
(arr) => arr.sort((a, b) => a.label.localeCompare(b.label))
);
interface ProcessorTypeAndLabel {
value: string;
label: string;
}
const processorTypesAndLabels: ProcessorTypeAndLabel[] = extractProcessorTypesAndLabels(
mapProcessorTypeToDescriptor
);
interface Props {
initialType?: string;
@ -47,22 +73,76 @@ const typeConfig: FieldConfig = {
export const ProcessorTypeField: FunctionComponent<Props> = ({ initialType }) => {
return (
<UseField
config={typeConfig}
defaultValue={initialType}
path="type"
component={ComboBoxField}
componentProps={{
euiFieldProps: {
'data-test-subj': 'processorTypeSelector',
fullWidth: true,
options: types.map((type) => ({ label: type, value: type })),
noSuggestions: false,
singleSelection: {
asPlainText: true,
},
},
<UseField config={typeConfig} defaultValue={initialType} path="type">
{(typeField) => {
let selectedOptions: ProcessorTypeAndLabel[];
if ((typeField.value as string[]).length) {
const [type] = typeField.value as string[];
const descriptor = getProcessorDescriptor(type);
selectedOptions = descriptor
? [{ label: descriptor.label, value: type }]
: // If there is no label for this processor type, just use the type as the label
[{ label: type, value: type }];
} else {
selectedOptions = [];
}
const error = typeField.getErrorsMessages();
const isInvalid = error ? Boolean(error.length) : false;
const onCreateComboOption = (value: string) => {
// Note: for now, all validations for a comboBox array item have to be synchronous
// If there is a need to support asynchronous validation, we'll work on it (and will need to update the <EuiComboBox /> logic).
const { isValid } = typeField.validate({
value,
validationType: VALIDATION_TYPES.ARRAY_ITEM,
}) as FieldValidateResponse;
if (!isValid) {
// Return false to explicitly reject the user's input.
return false;
}
const newValue = [...(typeField.value as string[]), value];
typeField.setValue(newValue);
};
return (
<EuiFormRow
label={typeField.label}
labelAppend={typeField.labelAppend}
helpText={
typeof typeField.helpText === 'function' ? typeField.helpText() : typeField.helpText
}
error={error}
isInvalid={isInvalid}
fullWidth
data-test-subj="processorTypeSelector"
>
<EuiComboBox
fullWidth
placeholder={i18n.translate(
'xpack.ingestPipelines.pipelineEditor.typeField.typeFieldComboboxPlaceholder',
{
defaultMessage: 'Type and then hit "ENTER"',
}
)}
options={processorTypesAndLabels}
selectedOptions={selectedOptions}
onCreateOption={onCreateComboOption}
onChange={(options: EuiComboBoxOptionOption[]) => {
typeField.setValue(options.map(({ value }) => value));
}}
noSuggestions={false}
singleSelection={{
asPlainText: true,
}}
data-test-subj="input"
/>
</EuiFormRow>
);
}}
/>
</UseField>
);
};

View file

@ -0,0 +1,11 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export {
getProcessorDescriptor,
mapProcessorTypeToDescriptor,
ProcessorType,
} from './map_processor_type_to_form';

View file

@ -10,7 +10,7 @@ import { FunctionComponent } from 'react';
// import { SetProcessor } from './processors/set';
// import { Gsub } from './processors/gsub';
interface FieldsFormDescriptor {
interface FieldDescriptor {
FieldsComponent?: FunctionComponent;
docLinkPath: string;
/**
@ -19,7 +19,9 @@ interface FieldsFormDescriptor {
label: string;
}
const mapProcessorTypeToFormDescriptor: Record<string, FieldsFormDescriptor> = {
type MapProcessorTypeToDescriptor = Record<string, FieldDescriptor>;
export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = {
append: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/append-processor.html',
@ -262,12 +264,10 @@ const mapProcessorTypeToFormDescriptor: Record<string, FieldsFormDescriptor> = {
},
};
export const types = Object.keys(mapProcessorTypeToFormDescriptor).sort();
export type ProcessorType = keyof typeof mapProcessorTypeToDescriptor;
export type ProcessorType = keyof typeof mapProcessorTypeToFormDescriptor;
export const getProcessorFormDescriptor = (
export const getProcessorDescriptor = (
type: ProcessorType | string
): FieldsFormDescriptor | undefined => {
return mapProcessorTypeToFormDescriptor[type as ProcessorType];
): FieldDescriptor | undefined => {
return mapProcessorTypeToDescriptor[type as ProcessorType];
};