[Ingest Pipelines] Add doc links to processor types (#69279)

* added doc links to processor types

* Bring doc links in line with mappings editor

Also refactor the processors type map

* remove helpText prop from Custom field

* fix i18n

* rename doc button and refactor type map const name

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Jean-Louis Leysens 2020-06-17 18:47:20 +02:00 committed by GitHub
parent 1cef65e56f
commit a077fdea32
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 463 additions and 181 deletions

View file

@ -128,8 +128,7 @@ export const PipelineFormFields: React.FunctionComponent<Props> = ({
return (
<PipelineProcessorsEditor
onFlyoutOpen={onEditorFlyoutOpen}
learnMoreAboutProcessorsUrl={services.documentation.getProcessorsUrl()}
learnMoreAboutOnFailureProcessorsUrl={services.documentation.getHandlingFailureUrl()}
esDocsBasePath={services.documentation.getEsDocsBasePath()}
isTestButtonDisabled={isTestButtonDisabled}
onTestPipelineClick={onTestPipelineClick}
onUpdate={onProcessorsUpdate}

View file

@ -36,8 +36,7 @@ describe('Pipeline Editor', () => {
onUpdate,
isTestButtonDisabled: false,
onTestPipelineClick: jest.fn(),
learnMoreAboutProcessorsUrl: 'test',
learnMoreAboutOnFailureProcessorsUrl: 'test',
esDocsBasePath: 'test',
});
const {
@ -56,8 +55,7 @@ describe('Pipeline Editor', () => {
onUpdate: jest.fn(),
isTestButtonDisabled: false,
onTestPipelineClick: jest.fn(),
learnMoreAboutProcessorsUrl: 'test',
learnMoreAboutOnFailureProcessorsUrl: 'test',
esDocsBasePath: 'test',
});
expect(exists('pipelineEditorOnFailureTree')).toBe(false);

View file

@ -4,9 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
export { SettingsFormFlyout, OnSubmitHandler } from './settings_form_flyout';
export { ProcessorSettingsForm, ProcessorSettingsFromOnSubmitArg } from './processor_settings_form';
export {
ProcessorSettingsForm,
ProcessorSettingsFromOnSubmitArg,
OnSubmitHandler,
} from './processor_settings_form';
export { ProcessorsTree, ProcessorInfo, OnActionHandler } from './processors_tree';

View file

@ -34,7 +34,10 @@ export const OnFailureProcessorsTitle: FunctionComponent = () => {
defaultMessage="The processors used to pre-process documents before indexing. {learnMoreLink}"
values={{
learnMoreLink: (
<EuiLink href={links.learnMoreAboutOnFailureProcessorsUrl} target="_blank">
<EuiLink
href={links.esDocsBasePath + '/handling-failure-in-pipelines.html'}
target="_blank"
>
{i18n.translate(
'xpack.ingestPipelines.pipelineEditor.onFailureProcessorsDocumentationLink',
{

View file

@ -0,0 +1,25 @@
/*
* 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.
*/
import React, { FunctionComponent } from 'react';
import { EuiButtonEmpty } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
interface Props {
processorLabel: string;
docLink: string;
}
export const DocumentationButton: FunctionComponent<Props> = ({ processorLabel, docLink }) => {
return (
<EuiButtonEmpty size="s" flush="right" href={docLink} target="_blank" iconType="help">
{i18n.translate(
'xpack.ingestPipelines.pipelineEditor.settingsForm.learnMoreLabelLink.processor',
{ defaultMessage: '{processorLabel} documentation', values: { processorLabel } }
)}
</EuiButtonEmpty>
);
};

View file

@ -7,4 +7,5 @@
export {
ProcessorSettingsForm,
ProcessorSettingsFromOnSubmitArg,
OnSubmitHandler,
} from './processor_settings_form.container';

View file

@ -4,53 +4,270 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { i18n } from '@kbn/i18n';
import { FunctionComponent } from 'react';
// import { SetProcessor } from './processors/set';
// import { Gsub } from './processors/gsub';
const mapProcessorTypeToForm = {
append: undefined, // TODO: Implement
bytes: undefined, // TODO: Implement
circle: undefined, // TODO: Implement
convert: undefined, // TODO: Implement
csv: undefined, // TODO: Implement
date: undefined, // TODO: Implement
date_index_name: undefined, // TODO: Implement
dissect: undefined, // TODO: Implement
dot_expander: undefined, // TODO: Implement
drop: undefined, // TODO: Implement
enrich: undefined, // TODO: Implement
fail: undefined, // TODO: Implement
foreach: undefined, // TODO: Implement
geoip: undefined, // TODO: Implement
grok: undefined, // TODO: Implement
html_strip: undefined, // TODO: Implement
inference: undefined, // TODO: Implement
join: undefined, // TODO: Implement
json: undefined, // TODO: Implement
kv: undefined, // TODO: Implement
lowercase: undefined, // TODO: Implement
pipeline: undefined, // TODO: Implement
remove: undefined, // TODO: Implement
rename: undefined, // TODO: Implement
script: undefined, // TODO: Implement
set_security_user: undefined, // TODO: Implement
split: undefined, // TODO: Implement
sort: undefined, // TODO: Implement
trim: undefined, // TODO: Implement
uppercase: undefined, // TODO: Implement
urldecode: undefined, // TODO: Implement
user_agent: undefined, // TODO: Implement
interface FieldsFormDescriptor {
FieldsComponent?: FunctionComponent;
docLinkPath: string;
/**
* A sentence case label that can be displayed to users
*/
label: string;
}
gsub: undefined,
set: undefined,
const mapProcessorTypeToFormDescriptor: Record<string, FieldsFormDescriptor> = {
append: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/append-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.append', {
defaultMessage: 'Append',
}),
},
bytes: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/bytes-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.bytes', {
defaultMessage: 'Bytes',
}),
},
circle: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/ingest-circle-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.circle', {
defaultMessage: 'Circle',
}),
},
convert: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/convert-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.convert', {
defaultMessage: 'Convert',
}),
},
csv: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/csv-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.csv', {
defaultMessage: 'CSV',
}),
},
date: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/date-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.date', {
defaultMessage: 'Date',
}),
},
date_index_name: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/date-index-name-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.dateIndexName', {
defaultMessage: 'Date Index Name',
}),
},
dissect: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/dissect-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.dissect', {
defaultMessage: 'Dissect',
}),
},
dot_expander: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/dot-expand-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.dotExpander', {
defaultMessage: 'Dot Expander',
}),
},
drop: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/drop-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.drop', {
defaultMessage: 'Drop',
}),
},
enrich: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/enrich-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.enrich', {
defaultMessage: 'Enrich',
}),
},
fail: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/fail-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.fail', {
defaultMessage: 'Fail',
}),
},
foreach: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/foreach-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.foreach', {
defaultMessage: 'Foreach',
}),
},
geoip: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/geoip-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.geoip', {
defaultMessage: 'GeoIP',
}),
},
gsub: {
FieldsComponent: undefined,
docLinkPath: '/gsub-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.gsub', {
defaultMessage: 'Gsub',
}),
},
html_strip: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/htmlstrip-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.htmlStrip', {
defaultMessage: 'HTML Strip',
}),
},
inference: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/inference-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.inference', {
defaultMessage: 'Inference',
}),
},
join: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/join-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.join', {
defaultMessage: 'Join',
}),
},
json: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/json-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.json', {
defaultMessage: 'JSON',
}),
},
kv: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/kv-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.kv', {
defaultMessage: 'KV',
}),
},
lowercase: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/lowercase-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.lowercase', {
defaultMessage: 'Lowercase',
}),
},
pipeline: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/pipeline-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.pipeline', {
defaultMessage: 'Pipeline',
}),
},
remove: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/remove-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.remove', {
defaultMessage: 'Remove',
}),
},
rename: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/rename-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.rename', {
defaultMessage: 'Rename',
}),
},
script: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/script-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.script', {
defaultMessage: 'Script',
}),
},
set_security_user: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/ingest-node-set-security-user-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.setSecurityUser', {
defaultMessage: 'Set Security User',
}),
},
split: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/split-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.split', {
defaultMessage: 'Split',
}),
},
sort: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/sort-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.sort', {
defaultMessage: 'Sort',
}),
},
trim: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/trim-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.trim', {
defaultMessage: 'Trim',
}),
},
uppercase: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/uppercase-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.uppercase', {
defaultMessage: 'Uppercase',
}),
},
urldecode: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/urldecode-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.urldecode', {
defaultMessage: 'URL Decode',
}),
},
user_agent: {
FieldsComponent: undefined, // TODO: Implement
docLinkPath: '/user-agent-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.userAgent', {
defaultMessage: 'User Agent',
}),
},
// --- The below processor descriptors have components implemented ---
set: {
FieldsComponent: undefined,
docLinkPath: '/set-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.set', {
defaultMessage: 'Set',
}),
},
grok: {
FieldsComponent: undefined,
docLinkPath: '/grok-processor.html',
label: i18n.translate('xpack.ingestPipelines.processors.label.grok', {
defaultMessage: 'Grok',
}),
},
};
export const types = Object.keys(mapProcessorTypeToForm);
export const types = Object.keys(mapProcessorTypeToFormDescriptor).sort();
export type ProcessorType = keyof typeof mapProcessorTypeToForm;
export type ProcessorType = keyof typeof mapProcessorTypeToFormDescriptor;
export const getProcessorForm = (type: ProcessorType | string): FunctionComponent | undefined => {
return mapProcessorTypeToForm[type as ProcessorType];
export const getProcessorFormDescriptor = (
type: ProcessorType | string
): FieldsFormDescriptor | undefined => {
return mapProcessorTypeToFormDescriptor[type as ProcessorType];
};

View file

@ -13,9 +13,16 @@ import { ProcessorSettingsForm as ViewComponent } from './processor_settings_for
export type ProcessorSettingsFromOnSubmitArg = Omit<ProcessorInternal, 'id'>;
export type OnSubmitHandler = (processor: ProcessorSettingsFromOnSubmitArg) => void;
export type OnFormUpdateHandler = (form: OnFormUpdateArg<any>) => void;
interface Props {
onFormUpdate: (form: OnFormUpdateArg<any>) => void;
onSubmit: (processor: ProcessorSettingsFromOnSubmitArg) => void;
onFormUpdate: OnFormUpdateHandler;
onSubmit: OnSubmitHandler;
isOnFailure: boolean;
onOpen: () => void;
onClose: () => void;
processor?: ProcessorInternal;
}
@ -23,6 +30,7 @@ export const ProcessorSettingsForm: FunctionComponent<Props> = ({
processor,
onFormUpdate,
onSubmit,
...rest
}) => {
const handleSubmit = useCallback(
async (data: FormData, isValid: boolean) => {
@ -52,5 +60,5 @@ export const ProcessorSettingsForm: FunctionComponent<Props> = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [onFormUpdate]);
return <ViewComponent processor={processor} form={form} />;
return <ViewComponent processor={processor} form={form} {...rest} />;
};

View file

@ -3,67 +3,141 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { i18n } from '@kbn/i18n';
import React, { FunctionComponent, memo } from 'react';
import { EuiButton, EuiHorizontalRule } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import React, { FunctionComponent, memo, useEffect } from 'react';
import {
EuiButton,
EuiHorizontalRule,
EuiFlyout,
EuiFlyoutHeader,
EuiTitle,
EuiFlyoutBody,
EuiFlexGroup,
EuiFlexItem,
} from '@elastic/eui';
import { Form, useForm, FormDataProvider } from '../../../../../shared_imports';
import { usePipelineProcessorsContext } from '../../context';
import { ProcessorInternal } from '../../types';
import { getProcessorForm } from './map_processor_type_to_form';
import { DocumentationButton } from './documentation_button';
import { ProcessorSettingsFromOnSubmitArg } from './processor_settings_form.container';
import { getProcessorFormDescriptor } from './map_processor_type_to_form';
import { CommonProcessorFields, ProcessorTypeField } from './processors/common_fields';
import { Custom } from './processors/custom';
export type OnSubmitHandler = (processor: ProcessorSettingsFromOnSubmitArg) => void;
export interface Props {
isOnFailure: boolean;
processor?: ProcessorInternal;
form: ReturnType<typeof useForm>['form'];
onClose: () => void;
onOpen: () => void;
}
export const ProcessorSettingsForm: FunctionComponent<Props> = memo(
({ processor, form }) => {
({ processor, form, isOnFailure, onClose, onOpen }) => {
const {
links: { esDocsBasePath },
} = usePipelineProcessorsContext();
const flyoutTitleContent = isOnFailure ? (
<FormattedMessage
id="xpack.ingestPipelines.settingsFormOnFailureFlyout.title"
defaultMessage="Configure on-failure processor"
/>
) : (
<FormattedMessage
id="xpack.ingestPipelines.settingsFormFlyout.title"
defaultMessage="Configure processor"
/>
);
useEffect(
() => {
onOpen();
},
[] /* eslint-disable-line react-hooks/exhaustive-deps */
);
return (
<Form form={form}>
<ProcessorTypeField initialType={processor?.type} />
<EuiFlyout onClose={onClose}>
<EuiFlyoutHeader>
<EuiFlexGroup gutterSize="xs">
<EuiFlexItem>
<div>
<EuiTitle size="m">
<h2>{flyoutTitleContent}</h2>
</EuiTitle>
</div>
</EuiFlexItem>
<EuiHorizontalRule />
<EuiFlexItem grow={false}>
<FormDataProvider pathsToWatch="type">
{({ type }) => {
const formDescriptor = getProcessorFormDescriptor(type as any);
<FormDataProvider pathsToWatch="type">
{(arg: any) => {
const { type } = arg;
let formContent: React.ReactNode | undefined;
if (formDescriptor) {
return (
<DocumentationButton
processorLabel={formDescriptor.label}
docLink={esDocsBasePath + formDescriptor.docLinkPath}
/>
);
}
return null;
}}
</FormDataProvider>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlyoutHeader>
<EuiFlyoutBody>
<ProcessorTypeField initialType={processor?.type} />
if (type?.length) {
const ProcessorFormFields = getProcessorForm(type as any);
<EuiHorizontalRule />
if (ProcessorFormFields) {
formContent = (
<>
<ProcessorFormFields />
<CommonProcessorFields />
</>
);
} else {
formContent = <Custom defaultOptions={processor?.options} />;
}
<FormDataProvider pathsToWatch="type">
{(arg: any) => {
const { type } = arg;
let formContent: React.ReactNode | undefined;
return (
<>
{formContent}
<EuiButton onClick={form.submit}>
{i18n.translate(
'xpack.ingestPipelines.pipelineEditor.settingsForm.submitButtonLabel',
{ defaultMessage: 'Submit' }
)}
</EuiButton>
</>
);
}
if (type?.length) {
const formDescriptor = getProcessorFormDescriptor(type as any);
// If the user has not yet defined a type, we do not show any settings fields
return null;
}}
</FormDataProvider>
if (formDescriptor?.FieldsComponent) {
formContent = (
<>
<formDescriptor.FieldsComponent />
<CommonProcessorFields />
</>
);
} else {
formContent = <Custom defaultOptions={processor?.options} />;
}
return (
<>
{formContent}
<EuiButton onClick={form.submit}>
{i18n.translate(
'xpack.ingestPipelines.pipelineEditor.settingsForm.submitButtonLabel',
{ defaultMessage: 'Submit' }
)}
</EuiButton>
</>
);
}
// If the user has not yet defined a type, we do not show any settings fields
return null;
}}
</FormDataProvider>
</EuiFlyoutBody>
</EuiFlyout>
</Form>
);
},

View file

@ -42,7 +42,7 @@ export const ProcessorsTitleAndTestButton: FunctionComponent<Props> = ({
defaultMessage="The processors used to pre-process documents before indexing. {learnMoreLink}"
values={{
learnMoreLink: (
<EuiLink href={links.learnMoreAboutProcessorsUrl} target="_blank">
<EuiLink href={links.esDocsBasePath + '/ingest-processors.html'} target="_blank">
{i18n.translate(
'xpack.ingestPipelines.pipelineEditor.processorsDocumentationLink',
{

View file

@ -1,67 +0,0 @@
/*
* 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.
*/
import { EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui';
import React, { FunctionComponent, memo, useEffect } from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { OnFormUpdateArg } from '../../../../shared_imports';
import { ProcessorInternal } from '../types';
import { ProcessorSettingsForm, ProcessorSettingsFromOnSubmitArg } from '.';
export type OnSubmitHandler = (processor: ProcessorSettingsFromOnSubmitArg) => void;
export interface Props {
processor: ProcessorInternal | undefined;
onFormUpdate: (form: OnFormUpdateArg<any>) => void;
onSubmit: OnSubmitHandler;
isOnFailureProcessor: boolean;
onOpen: () => void;
onClose: () => void;
}
export const SettingsFormFlyout: FunctionComponent<Props> = memo(
({ onClose, processor, onSubmit, onFormUpdate, onOpen, isOnFailureProcessor }) => {
useEffect(
() => {
onOpen();
},
[] /* eslint-disable-line react-hooks/exhaustive-deps */
);
const flyoutTitleContent = isOnFailureProcessor ? (
<FormattedMessage
id="xpack.ingestPipelines.settingsFormOnFailureFlyout.title"
defaultMessage="Configure on-failure processor"
/>
) : (
<FormattedMessage
id="xpack.ingestPipelines.settingsFormFlyout.title"
defaultMessage="Configure processor"
/>
);
return (
<EuiFlyout onClose={onClose}>
<EuiFlyoutHeader>
<EuiTitle>
<h2>{flyoutTitleContent}</h2>
</EuiTitle>
</EuiFlyoutHeader>
<EuiFlyoutBody>
<ProcessorSettingsForm
onFormUpdate={onFormUpdate}
processor={processor}
onSubmit={onSubmit}
/>
</EuiFlyoutBody>
</EuiFlyout>
);
}
);

View file

@ -9,8 +9,7 @@ import { EditorMode } from './types';
import { ProcessorsDispatch } from './processors_reducer';
interface Links {
learnMoreAboutProcessorsUrl: string;
learnMoreAboutOnFailureProcessorsUrl: string;
esDocsBasePath: string;
}
const PipelineProcessorsContext = createContext<{

View file

@ -26,8 +26,7 @@ export interface Props {
onUpdate: (arg: OnUpdateHandlerArg) => void;
isTestButtonDisabled: boolean;
onTestPipelineClick: () => void;
learnMoreAboutProcessorsUrl: string;
learnMoreAboutOnFailureProcessorsUrl: string;
esDocsBasePath: string;
/**
* Give users a way to react to this component opening a flyout
*/
@ -41,8 +40,7 @@ export const PipelineProcessorsEditor: FunctionComponent<Props> = ({
onFlyoutOpen,
onUpdate,
isTestButtonDisabled,
learnMoreAboutOnFailureProcessorsUrl,
learnMoreAboutProcessorsUrl,
esDocsBasePath,
onTestPipelineClick,
}) => {
const deserializedResult = useMemo(
@ -61,7 +59,7 @@ export const PipelineProcessorsEditor: FunctionComponent<Props> = ({
return (
<PipelineProcessorsContextProvider
processorsDispatch={processorsDispatch}
links={{ learnMoreAboutOnFailureProcessorsUrl, learnMoreAboutProcessorsUrl }}
links={{ esDocsBasePath }}
>
<PipelineProcessorsEditorUI
onFlyoutOpen={onFlyoutOpen}

View file

@ -14,19 +14,22 @@ import {
ProcessorsTitleAndTestButton,
OnFailureProcessorsTitle,
ProcessorsTree,
SettingsFormFlyout,
ProcessorRemoveModal,
OnActionHandler,
OnSubmitHandler,
ProcessorSettingsForm,
} from './components';
import { ProcessorInternal, OnUpdateHandlerArg, FormValidityState, OnFormUpdateArg } from './types';
import {
ProcessorInternal,
ProcessorSelector,
OnUpdateHandlerArg,
FormValidityState,
OnFormUpdateArg,
} from './types';
ON_FAILURE_STATE_SCOPE,
PROCESSOR_STATE_SCOPE,
isOnFailureSelector,
} from './processors_reducer';
const PROCESSORS_BASE_SELECTOR = [PROCESSOR_STATE_SCOPE];
const ON_FAILURE_BASE_SELECTOR = [ON_FAILURE_STATE_SCOPE];
import { serialize } from './serialize';
import { getValue } from './utils';
@ -41,9 +44,6 @@ export interface Props {
onFlyoutOpen: () => void;
}
const PROCESSOR_STATE_SCOPE: ProcessorSelector = ['processors'];
const ON_FAILURE_STATE_SCOPE: ProcessorSelector = ['onFailure'];
export const PipelineProcessorsEditor: FunctionComponent<Props> = memo(
function PipelineProcessorsEditor({
processors,
@ -168,7 +168,7 @@ export const PipelineProcessorsEditor: FunctionComponent<Props> = memo(
</EuiFlexItem>
<EuiFlexItem grow={false}>
<ProcessorsTree
baseSelector={PROCESSOR_STATE_SCOPE}
baseSelector={PROCESSORS_BASE_SELECTOR}
processors={processors}
onAction={onTreeAction}
movingProcessor={movingProcessor}
@ -197,7 +197,7 @@ export const PipelineProcessorsEditor: FunctionComponent<Props> = memo(
<EuiFlexItem grow={false}>
<ProcessorsTree
data-test-subj="pipelineEditorOnFailureTree"
baseSelector={ON_FAILURE_STATE_SCOPE}
baseSelector={ON_FAILURE_BASE_SELECTOR}
processors={onFailureProcessors}
onAction={onTreeAction}
movingProcessor={movingProcessor}
@ -206,8 +206,8 @@ export const PipelineProcessorsEditor: FunctionComponent<Props> = memo(
) : undefined}
</EuiFlexGroup>
{editorMode.id === 'editingProcessor' || editorMode.id === 'creatingProcessor' ? (
<SettingsFormFlyout
isOnFailureProcessor={editorMode.arg.selector.length > 1}
<ProcessorSettingsForm
isOnFailure={isOnFailureSelector(editorMode.arg.selector)}
processor={editorMode.id === 'editingProcessor' ? editorMode.arg.processor : undefined}
onOpen={onFlyoutOpen}
onFormUpdate={onFormUpdate}

View file

@ -0,0 +1,8 @@
/*
* 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 const PROCESSOR_STATE_SCOPE = 'processors';
export const ON_FAILURE_STATE_SCOPE = 'onFailure';

View file

@ -12,4 +12,6 @@ export {
Action,
} from './processors_reducer';
export { isChildPath } from './utils';
export { ON_FAILURE_STATE_SCOPE, PROCESSOR_STATE_SCOPE } from './constants';
export { isChildPath, isOnFailureSelector } from './utils';

View file

@ -9,6 +9,17 @@ import { ProcessorInternal, ProcessorSelector } from '../types';
import { DropSpecialLocations } from '../constants';
import { checkIfSamePath, getValue } from '../utils';
import { ON_FAILURE_STATE_SCOPE } from './constants';
/**
* We know that it must be an on-failure handler if the selector length is greater than 2
* because the first element will always be either processors or the global on-failure
* array and the second element will be a number indicating the processor position in the
* array. Anything more than that we know we are add an on failure handler.
*/
export const isOnFailureSelector = (selector: ProcessorSelector) =>
selector[0] === ON_FAILURE_STATE_SCOPE || selector.length > 2;
export const PARENT_CHILD_NEST_ERROR = 'PARENT_CHILD_NEST_ERROR';
export const duplicateProcessor = (sourceProcessor: ProcessorInternal): ProcessorInternal => {

View file

@ -15,6 +15,10 @@ export class DocumentationService {
this.esDocBasePath = `${docsBase}/elasticsearch/reference/${DOC_LINK_VERSION}`;
}
public getEsDocsBasePath() {
return this.esDocBasePath;
}
public getIngestNodeUrl() {
return `${this.esDocBasePath}/ingest.html`;
}