[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:
parent
1cef65e56f
commit
a077fdea32
|
@ -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}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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',
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
|
@ -7,4 +7,5 @@
|
|||
export {
|
||||
ProcessorSettingsForm,
|
||||
ProcessorSettingsFromOnSubmitArg,
|
||||
OnSubmitHandler,
|
||||
} from './processor_settings_form.container';
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
|
|
@ -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} />;
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -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',
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
);
|
|
@ -9,8 +9,7 @@ import { EditorMode } from './types';
|
|||
import { ProcessorsDispatch } from './processors_reducer';
|
||||
|
||||
interface Links {
|
||||
learnMoreAboutProcessorsUrl: string;
|
||||
learnMoreAboutOnFailureProcessorsUrl: string;
|
||||
esDocsBasePath: string;
|
||||
}
|
||||
|
||||
const PipelineProcessorsContext = createContext<{
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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';
|
|
@ -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';
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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`;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue