mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
This commit is contained in:
parent
f4b44c70d6
commit
646b58b76b
20 changed files with 158 additions and 97 deletions
|
@ -186,7 +186,7 @@ describe('Pipeline Editor', () => {
|
|||
|
||||
it('prevents moving a processor while in edit mode', () => {
|
||||
const { find, exists } = testBed;
|
||||
find('processors>0.editItemButton').simulate('click');
|
||||
find('processors>0.manageItemButton').simulate('click');
|
||||
expect(exists('processorSettingsForm')).toBe(true);
|
||||
expect(find('processors>0.moveItemButton').props().disabled).toBe(true);
|
||||
expect(find('processors>1.moveItemButton').props().disabled).toBe(true);
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
*/
|
||||
|
||||
export {
|
||||
ProcessorSettingsForm,
|
||||
ProcessorSettingsFromOnSubmitArg,
|
||||
ManageProcessorForm,
|
||||
ManageProcessorFormOnSubmitArg,
|
||||
OnSubmitHandler,
|
||||
} from './processor_settings_form';
|
||||
} from './manage_processor_form';
|
||||
|
||||
export { ProcessorsTree, ProcessorInfo, OnActionHandler } from './processors_tree';
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
export {
|
||||
ProcessorSettingsForm,
|
||||
ProcessorSettingsFromOnSubmitArg,
|
||||
ManageProcessorForm,
|
||||
ManageProcessorFormOnSubmitArg,
|
||||
OnSubmitHandler,
|
||||
} from './processor_settings_form.container';
|
||||
} from './manage_processor_form.container';
|
|
@ -9,12 +9,12 @@ import React, { FunctionComponent, useCallback, useEffect } from 'react';
|
|||
import { useForm, OnFormUpdateArg, FormData } from '../../../../../shared_imports';
|
||||
import { ProcessorInternal } from '../../types';
|
||||
|
||||
import { ProcessorSettingsForm as ViewComponent } from './processor_settings_form';
|
||||
import { ManageProcessorForm as ViewComponent } from './manage_processor_form';
|
||||
import { usePipelineProcessorsContext } from '../../context';
|
||||
|
||||
export type ProcessorSettingsFromOnSubmitArg = Omit<ProcessorInternal, 'id'>;
|
||||
export type ManageProcessorFormOnSubmitArg = Omit<ProcessorInternal, 'id'>;
|
||||
|
||||
export type OnSubmitHandler = (processor: ProcessorSettingsFromOnSubmitArg) => void;
|
||||
export type OnSubmitHandler = (processor: ManageProcessorFormOnSubmitArg) => void;
|
||||
|
||||
export type OnFormUpdateHandler = (form: OnFormUpdateArg<any>) => void;
|
||||
|
||||
|
@ -27,7 +27,7 @@ interface Props {
|
|||
processor?: ProcessorInternal;
|
||||
}
|
||||
|
||||
export const ProcessorSettingsForm: FunctionComponent<Props> = ({
|
||||
export const ManageProcessorForm: FunctionComponent<Props> = ({
|
||||
processor,
|
||||
onFormUpdate,
|
||||
onSubmit,
|
|
@ -6,15 +6,17 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React, { FunctionComponent, memo, useEffect } from 'react';
|
||||
import React, { FunctionComponent, memo, useEffect, useState } from 'react';
|
||||
import {
|
||||
EuiButton,
|
||||
EuiButtonEmpty,
|
||||
EuiHorizontalRule,
|
||||
EuiFlyout,
|
||||
EuiFlyoutHeader,
|
||||
EuiFlyoutBody,
|
||||
EuiFlyoutFooter,
|
||||
EuiSpacer,
|
||||
EuiTabs,
|
||||
EuiTab,
|
||||
EuiTitle,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
|
@ -22,12 +24,10 @@ import {
|
|||
|
||||
import { Form, FormDataProvider, FormHook } from '../../../../../shared_imports';
|
||||
import { ProcessorInternal } from '../../types';
|
||||
|
||||
import { getProcessorDescriptor } from '../shared';
|
||||
|
||||
import { ProcessorSettingsFields } from './processor_settings_fields';
|
||||
import { DocumentationButton } from './documentation_button';
|
||||
import { CommonProcessorFields, ProcessorTypeField } from './processors/common_fields';
|
||||
import { Custom } from './processors/custom';
|
||||
|
||||
export interface Props {
|
||||
isOnFailure: boolean;
|
||||
|
@ -42,6 +42,7 @@ const updateButtonLabel = i18n.translate(
|
|||
'xpack.ingestPipelines.settingsFormOnFailureFlyout.updateButtonLabel',
|
||||
{ defaultMessage: 'Update' }
|
||||
);
|
||||
|
||||
const addButtonLabel = i18n.translate(
|
||||
'xpack.ingestPipelines.settingsFormOnFailureFlyout.addButtonLabel',
|
||||
{ defaultMessage: 'Add' }
|
||||
|
@ -52,20 +53,55 @@ const cancelButtonLabel = i18n.translate(
|
|||
{ defaultMessage: 'Cancel' }
|
||||
);
|
||||
|
||||
export const ProcessorSettingsForm: FunctionComponent<Props> = memo(
|
||||
({ processor, form, isOnFailure, onClose, onOpen, esDocsBasePath }) => {
|
||||
const flyoutTitleContent = isOnFailure ? (
|
||||
export type TabType = 'configuration';
|
||||
|
||||
interface Tab {
|
||||
id: TabType;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const tabs: Tab[] = [
|
||||
{
|
||||
id: 'configuration',
|
||||
name: i18n.translate(
|
||||
'xpack.ingestPipelines.settingsFormOnFailureFlyout.configurationTabTitle',
|
||||
{
|
||||
defaultMessage: 'Configuration',
|
||||
}
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const getFlyoutTitle = (isOnFailure: boolean, isExistingProcessor: boolean) => {
|
||||
if (isExistingProcessor) {
|
||||
return isOnFailure ? (
|
||||
<FormattedMessage
|
||||
id="xpack.ingestPipelines.settingsFormOnFailureFlyout.title"
|
||||
defaultMessage="Configure on-failure processor"
|
||||
id="xpack.ingestPipelines.settingsFormOnFailureFlyout.manageOnFailureTitle"
|
||||
defaultMessage="Manage on-failure processor"
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="xpack.ingestPipelines.settingsFormFlyout.title"
|
||||
defaultMessage="Configure processor"
|
||||
id="xpack.ingestPipelines.settingsFormOnFailureFlyout.manageTitle"
|
||||
defaultMessage="Manage processor"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return isOnFailure ? (
|
||||
<FormattedMessage
|
||||
id="xpack.ingestPipelines.settingsFormOnFailureFlyout.configureOnFailureTitle"
|
||||
defaultMessage="Configure on-failure processor"
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="xpack.ingestPipelines.settingsFormOnFailureFlyout.configureTitle"
|
||||
defaultMessage="Configure processor"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const ManageProcessorForm: FunctionComponent<Props> = memo(
|
||||
({ processor, form, isOnFailure, onClose, onOpen, esDocsBasePath }) => {
|
||||
useEffect(
|
||||
() => {
|
||||
onOpen();
|
||||
|
@ -73,6 +109,10 @@ export const ProcessorSettingsForm: FunctionComponent<Props> = memo(
|
|||
[] /* eslint-disable-line react-hooks/exhaustive-deps */
|
||||
);
|
||||
|
||||
const [activeTab, setActiveTab] = useState<TabType>('configuration');
|
||||
|
||||
const flyoutContent = <ProcessorSettingsFields processor={processor} />;
|
||||
|
||||
return (
|
||||
<Form data-test-subj="processorSettingsForm" form={form}>
|
||||
<EuiFlyout size="m" maxWidth={720} onClose={onClose}>
|
||||
|
@ -81,11 +121,10 @@ export const ProcessorSettingsForm: FunctionComponent<Props> = memo(
|
|||
<EuiFlexItem>
|
||||
<div>
|
||||
<EuiTitle size="m">
|
||||
<h2>{flyoutTitleContent}</h2>
|
||||
<h2>{getFlyoutTitle(isOnFailure, Boolean(processor))}</h2>
|
||||
</EuiTitle>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<FormDataProvider pathsToWatch="type">
|
||||
{({ type }) => {
|
||||
|
@ -106,32 +145,27 @@ export const ProcessorSettingsForm: FunctionComponent<Props> = memo(
|
|||
</EuiFlexGroup>
|
||||
</EuiFlyoutHeader>
|
||||
<EuiFlyoutBody>
|
||||
<ProcessorTypeField initialType={processor?.type} />
|
||||
{processor ? (
|
||||
<>
|
||||
<EuiTabs>
|
||||
{tabs.map((tab) => (
|
||||
<EuiTab
|
||||
onClick={() => {
|
||||
setActiveTab(tab.id);
|
||||
}}
|
||||
isSelected={tab.id === activeTab}
|
||||
key={tab.id}
|
||||
data-test-subj={`${tab.id}Tab`}
|
||||
>
|
||||
{tab.name}
|
||||
</EuiTab>
|
||||
))}
|
||||
</EuiTabs>
|
||||
<EuiSpacer />
|
||||
</>
|
||||
) : undefined}
|
||||
|
||||
<EuiHorizontalRule />
|
||||
|
||||
<FormDataProvider pathsToWatch="type">
|
||||
{(arg: any) => {
|
||||
const { type } = arg;
|
||||
|
||||
if (type?.length) {
|
||||
const formDescriptor = getProcessorDescriptor(type as any);
|
||||
|
||||
if (formDescriptor?.FieldsComponent) {
|
||||
return (
|
||||
<>
|
||||
<formDescriptor.FieldsComponent />
|
||||
<CommonProcessorFields />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return <Custom defaultOptions={processor?.options} />;
|
||||
}
|
||||
|
||||
// If the user has not yet defined a type, we do not show any settings fields
|
||||
return null;
|
||||
}}
|
||||
</FormDataProvider>
|
||||
{flyoutContent}
|
||||
</EuiFlyoutBody>
|
||||
<EuiFlyoutFooter>
|
||||
<EuiFlexGroup justifyContent="flexEnd">
|
||||
|
@ -139,13 +173,7 @@ export const ProcessorSettingsForm: FunctionComponent<Props> = memo(
|
|||
<EuiButtonEmpty onClick={onClose}>{cancelButtonLabel}</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
fill
|
||||
data-test-subj="submitButton"
|
||||
onClick={() => {
|
||||
form.submit();
|
||||
}}
|
||||
>
|
||||
<EuiButton fill data-test-subj="submitButton" onClick={form.submit}>
|
||||
{processor ? updateButtonLabel : addButtonLabel}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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 { EuiHorizontalRule } from '@elastic/eui';
|
||||
|
||||
import { FormDataProvider } from '../../../../../shared_imports';
|
||||
import { ProcessorInternal } from '../../types';
|
||||
|
||||
import { getProcessorDescriptor } from '../shared';
|
||||
import { CommonProcessorFields, ProcessorTypeField } from './processors/common_fields';
|
||||
import { Custom } from './processors/custom';
|
||||
|
||||
export interface Props {
|
||||
processor?: ProcessorInternal;
|
||||
}
|
||||
|
||||
export const ProcessorSettingsFields: FunctionComponent<Props> = ({ processor }) => {
|
||||
return (
|
||||
<>
|
||||
<ProcessorTypeField initialType={processor?.type} />
|
||||
|
||||
<EuiHorizontalRule />
|
||||
|
||||
<FormDataProvider pathsToWatch="type">
|
||||
{(arg: any) => {
|
||||
const { type } = arg;
|
||||
|
||||
if (type?.length) {
|
||||
const formDescriptor = getProcessorDescriptor(type as any);
|
||||
|
||||
if (formDescriptor?.FieldsComponent) {
|
||||
return (
|
||||
<>
|
||||
<formDescriptor.FieldsComponent />
|
||||
<CommonProcessorFields />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return <Custom defaultOptions={processor?.options} />;
|
||||
}
|
||||
|
||||
// If the user has not yet defined a type, we do not show any settings fields
|
||||
return null;
|
||||
}}
|
||||
</FormDataProvider>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -7,10 +7,10 @@
|
|||
import classNames from 'classnames';
|
||||
import React, { FunctionComponent, memo } from 'react';
|
||||
import {
|
||||
EuiButtonIcon,
|
||||
EuiButtonToggle,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiLink,
|
||||
EuiPanel,
|
||||
EuiText,
|
||||
EuiToolTip,
|
||||
|
@ -57,9 +57,9 @@ export const PipelineProcessorsEditorItem: FunctionComponent<Props> = memo(
|
|||
const isInMoveMode = Boolean(movingProcessor);
|
||||
const isMovingThisProcessor = processor.id === movingProcessor?.id;
|
||||
const isEditingThisProcessor =
|
||||
editor.mode.id === 'editingProcessor' && processor.id === editor.mode.arg.processor.id;
|
||||
editor.mode.id === 'managingProcessor' && processor.id === editor.mode.arg.processor.id;
|
||||
const isEditingOtherProcessor =
|
||||
editor.mode.id === 'editingProcessor' && !isEditingThisProcessor;
|
||||
editor.mode.id === 'managingProcessor' && !isEditingThisProcessor;
|
||||
const isMovingOtherProcessor = editor.mode.id === 'movingProcessor' && !isMovingThisProcessor;
|
||||
const isDimmed = isEditingOtherProcessor || isMovingOtherProcessor;
|
||||
|
||||
|
@ -70,11 +70,6 @@ export const PipelineProcessorsEditorItem: FunctionComponent<Props> = memo(
|
|||
'pipelineProcessorsEditor__item--dimmed': isDimmed,
|
||||
});
|
||||
|
||||
const actionElementClasses = classNames({
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
'pipelineProcessorsEditor__item--displayNone': isInMoveMode,
|
||||
});
|
||||
|
||||
const inlineTextInputContainerClasses = classNames({
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
'pipelineProcessorsEditor__item--displayNone': isInMoveMode && !processor.options.description,
|
||||
|
@ -141,7 +136,18 @@ export const PipelineProcessorsEditorItem: FunctionComponent<Props> = memo(
|
|||
className="pipelineProcessorsEditor__item__processorTypeLabel"
|
||||
color={isDimmed ? 'subdued' : undefined}
|
||||
>
|
||||
<b>{getProcessorDescriptor(processor.type)?.label ?? processor.type}</b>
|
||||
<EuiLink
|
||||
disabled={isEditorNotInIdleMode}
|
||||
onClick={() => {
|
||||
editor.setMode({
|
||||
id: 'managingProcessor',
|
||||
arg: { processor, selector },
|
||||
});
|
||||
}}
|
||||
data-test-subj="manageItemButton"
|
||||
>
|
||||
<b>{getProcessorDescriptor(processor.type)?.label ?? processor.type}</b>
|
||||
</EuiLink>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem className={inlineTextInputContainerClasses} grow={false}>
|
||||
|
@ -174,25 +180,6 @@ export const PipelineProcessorsEditorItem: FunctionComponent<Props> = memo(
|
|||
placeholder={i18nTexts.descriptionPlaceholder}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem className={actionElementClasses} grow={false}>
|
||||
{!isInMoveMode && (
|
||||
<EuiToolTip content={i18nTexts.editButtonLabel}>
|
||||
<EuiButtonIcon
|
||||
data-test-subj="editItemButton"
|
||||
disabled={isEditorNotInIdleMode}
|
||||
aria-label={i18nTexts.editButtonLabel}
|
||||
iconType="pencil"
|
||||
size="s"
|
||||
onClick={() => {
|
||||
editor.setMode({
|
||||
id: 'editingProcessor',
|
||||
arg: { processor, selector },
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</EuiToolTip>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
|
|
@ -42,7 +42,7 @@ import { OnActionHandler } from '../components/processors_tree';
|
|||
import {
|
||||
ProcessorRemoveModal,
|
||||
PipelineProcessorsItemTooltip,
|
||||
ProcessorSettingsForm,
|
||||
ManageProcessorForm,
|
||||
OnSubmitHandler,
|
||||
} from '../components';
|
||||
|
||||
|
@ -148,7 +148,7 @@ export const PipelineProcessorsContextProvider: FunctionComponent<Props> = ({
|
|||
},
|
||||
});
|
||||
break;
|
||||
case 'editingProcessor':
|
||||
case 'managingProcessor':
|
||||
processorsDispatch({
|
||||
type: 'updateProcessor',
|
||||
payload: {
|
||||
|
@ -229,10 +229,10 @@ export const PipelineProcessorsContextProvider: FunctionComponent<Props> = ({
|
|||
/>
|
||||
)}
|
||||
|
||||
{mode.id === 'editingProcessor' || mode.id === 'creatingProcessor' ? (
|
||||
<ProcessorSettingsForm
|
||||
{mode.id === 'managingProcessor' || mode.id === 'creatingProcessor' ? (
|
||||
<ManageProcessorForm
|
||||
isOnFailure={isOnFailureSelector(mode.arg.selector)}
|
||||
processor={mode.id === 'editingProcessor' ? mode.arg.processor : undefined}
|
||||
processor={mode.id === 'managingProcessor' ? mode.arg.processor : undefined}
|
||||
onOpen={onFlyoutOpen}
|
||||
onFormUpdate={onFormUpdate}
|
||||
onSubmit={onSubmit}
|
||||
|
|
|
@ -56,7 +56,7 @@ export type OnUpdateHandler = (arg: OnUpdateHandlerArg) => void;
|
|||
export type EditorMode =
|
||||
| { id: 'creatingProcessor'; arg: { selector: ProcessorSelector } }
|
||||
| { id: 'movingProcessor'; arg: ProcessorInfo }
|
||||
| { id: 'editingProcessor'; arg: { processor: ProcessorInternal; selector: ProcessorSelector } }
|
||||
| { id: 'managingProcessor'; arg: { processor: ProcessorInternal; selector: ProcessorSelector } }
|
||||
| { id: 'removingProcessor'; arg: { selector: ProcessorSelector } }
|
||||
| { id: 'idle' };
|
||||
|
||||
|
|
|
@ -9849,11 +9849,8 @@
|
|||
"xpack.ingestPipelines.requestFlyout.descriptionText": "このElasticsearchリクエストは、このパイプラインを作成または更新します。",
|
||||
"xpack.ingestPipelines.requestFlyout.namedTitle": "「{name}」のリクエスト",
|
||||
"xpack.ingestPipelines.requestFlyout.unnamedTitle": "リクエスト",
|
||||
"xpack.ingestPipelines.settingsFormFlyout.title": "プロセッサーの構成",
|
||||
"xpack.ingestPipelines.settingsFormOnFailureFlyout.addButtonLabel": "追加",
|
||||
"xpack.ingestPipelines.settingsFormOnFailureFlyout.cancelButtonLabel": "キャンセル",
|
||||
"xpack.ingestPipelines.settingsFormOnFailureFlyout.title": "エラープロセッサーの構成",
|
||||
"xpack.ingestPipelines.settingsFormOnFailureFlyout.updateButtonLabel": "更新",
|
||||
"xpack.ingestPipelines.tabs.documentsTabTitle": "ドキュメント",
|
||||
"xpack.ingestPipelines.tabs.outputTabTitle": "アウトプット",
|
||||
"xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsFieldLabel": "ドキュメント",
|
||||
|
|
|
@ -9851,11 +9851,8 @@
|
|||
"xpack.ingestPipelines.requestFlyout.descriptionText": "此 Elasticsearch 请求将创建或更新管道。",
|
||||
"xpack.ingestPipelines.requestFlyout.namedTitle": "对“{name}”的请求",
|
||||
"xpack.ingestPipelines.requestFlyout.unnamedTitle": "请求",
|
||||
"xpack.ingestPipelines.settingsFormFlyout.title": "配置处理器",
|
||||
"xpack.ingestPipelines.settingsFormOnFailureFlyout.addButtonLabel": "添加",
|
||||
"xpack.ingestPipelines.settingsFormOnFailureFlyout.cancelButtonLabel": "取消",
|
||||
"xpack.ingestPipelines.settingsFormOnFailureFlyout.title": "配置失败时处理器",
|
||||
"xpack.ingestPipelines.settingsFormOnFailureFlyout.updateButtonLabel": "更新",
|
||||
"xpack.ingestPipelines.tabs.documentsTabTitle": "文档",
|
||||
"xpack.ingestPipelines.tabs.outputTabTitle": "输出",
|
||||
"xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsFieldLabel": "文档",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue