diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx index 2e7a47e0c93de..e46e5156e30f3 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx @@ -126,7 +126,7 @@ const createActions = (testBed: TestBed) => { }); }); await act(async () => { - find('processorSettingsForm.submitButton').simulate('click'); + find('addProcessorForm.submitButton').simulate('click'); }); }, @@ -166,7 +166,7 @@ const createActions = (testBed: TestBed) => { }); }); await act(async () => { - find('processorSettingsForm.submitButton').simulate('click'); + find('addProcessorForm.submitButton').simulate('click'); }); }, @@ -202,8 +202,10 @@ type TestSubject = | 'pipelineEditorDoneButton' | 'pipelineEditorOnFailureToggle' | 'addProcessorsButtonLevel1' - | 'processorSettingsForm' - | 'processorSettingsForm.submitButton' + | 'editProcessorForm' + | 'editProcessorForm.submitButton' + | 'addProcessorForm.submitButton' + | 'addProcessorForm' | 'processorOptionsEditor' | 'processorSettingsFormFlyout' | 'processorTypeSelector' diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx index 38c652f41e5e1..74ae8b8894b9f 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx @@ -180,7 +180,7 @@ describe('Pipeline Editor', () => { it('prevents moving a processor while in edit mode', () => { const { find, exists } = testBed; find('processors>0.manageItemButton').simulate('click'); - expect(exists('processorSettingsForm')).toBe(true); + expect(exists('editProcessorForm')).toBe(true); expect(find('processors>0.moveItemButton').props().disabled).toBe(true); expect(find('processors>1.moveItemButton').props().disabled).toBe(true); }); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.helpers.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.helpers.tsx index fec3259fa019b..f4c89d7a1058a 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.helpers.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.helpers.tsx @@ -140,8 +140,8 @@ const createActions = (testBed: TestBed) => { component.update(); }, - clickProcessorOutputTab() { - act(() => { + async clickProcessorOutputTab() { + await act(async () => { find('outputTab').simulate('click'); }); component.update(); @@ -224,7 +224,8 @@ type TestSubject = | 'processorStatusIcon' | 'documentsTab' | 'manageItemButton' - | 'processorSettingsForm' + | 'addProcessorForm' + | 'editProcessorForm' | 'configurationTab' | 'outputTab' | 'processorOutputTabContent' diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.test.tsx index 339c840bb86f1..e5118a6e465af 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.test.tsx @@ -44,7 +44,7 @@ describe('Test pipeline', () => { describe('Test pipeline actions', () => { it('should successfully add sample documents and execute the pipeline', async () => { - const { find, actions, exists } = testBed; + const { actions, exists } = testBed; httpRequestsMockHelpers.setSimulatePipelineResponse(SIMULATE_RESPONSE); @@ -59,7 +59,6 @@ describe('Test pipeline', () => { expect(exists('testPipelineFlyout')).toBe(true); expect(exists('documentsTabContent')).toBe(true); expect(exists('outputTabContent')).toBe(false); - expect(find('outputTab').props().disabled).toEqual(true); // Add sample documents and click run actions.addDocumentsJson(JSON.stringify(DOCUMENTS)); @@ -89,21 +88,25 @@ describe('Test pipeline', () => { }); // Verify output tab is active - expect(find('outputTab').props().disabled).toEqual(false); expect(exists('documentsTabContent')).toBe(false); expect(exists('outputTabContent')).toBe(true); // Click reload button and verify request const totalRequests = server.requests.length; await actions.clickRefreshOutputButton(); - expect(server.requests.length).toBe(totalRequests + 1); + // There will be two requests made to the simulate API + // the second request will have verbose enabled to update the processor results + expect(server.requests.length).toBe(totalRequests + 2); + expect(server.requests[server.requests.length - 2].url).toBe( + '/api/ingest_pipelines/simulate' + ); expect(server.requests[server.requests.length - 1].url).toBe( '/api/ingest_pipelines/simulate' ); // Click verbose toggle and verify request await actions.toggleVerboseSwitch(); - expect(server.requests.length).toBe(totalRequests + 2); + expect(server.requests.length).toBe(totalRequests + 3); expect(server.requests[server.requests.length - 1].url).toBe( '/api/ingest_pipelines/simulate' ); @@ -228,10 +231,10 @@ describe('Test pipeline', () => { // Click processor to open manage flyout await actions.clickProcessor('processors>0'); // Verify flyout opened - expect(exists('processorSettingsForm')).toBe(true); + expect(exists('editProcessorForm')).toBe(true); // Navigate to "Output" tab - actions.clickProcessorOutputTab(); + await actions.clickProcessorOutputTab(); // Verify content expect(exists('processorOutputTabContent')).toBe(true); }); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/documents_dropdown/documents_dropdown.scss b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/documents_dropdown/documents_dropdown.scss deleted file mode 100644 index c5b14dc129b0e..0000000000000 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/documents_dropdown/documents_dropdown.scss +++ /dev/null @@ -1,3 +0,0 @@ -.documentsDropdown__selectContainer { - max-width: 200px; -} diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/documents_dropdown/documents_dropdown.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/documents_dropdown/documents_dropdown.tsx deleted file mode 100644 index e26b6a2890fe4..0000000000000 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/documents_dropdown/documents_dropdown.tsx +++ /dev/null @@ -1,70 +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 { i18n } from '@kbn/i18n'; -import React, { FunctionComponent } from 'react'; -import { EuiSelect, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; - -import { Document } from '../../types'; - -import './documents_dropdown.scss'; - -const i18nTexts = { - ariaLabel: i18n.translate( - 'xpack.ingestPipelines.pipelineEditor.testPipeline.documentsDropdownAriaLabel', - { - defaultMessage: 'Select documents', - } - ), - dropdownLabel: i18n.translate( - 'xpack.ingestPipelines.pipelineEditor.testPipeline.documentsdropdownLabel', - { - defaultMessage: 'Documents:', - } - ), - buttonLabel: i18n.translate('xpack.ingestPipelines.pipelineEditor.testPipeline.buttonLabel', { - defaultMessage: 'Add documents', - }), -}; - -const getDocumentOptions = (documents: Document[]) => - documents.map((doc, index) => ({ - value: index, - text: doc._id, - })); - -interface Props { - documents: Document[]; - selectedDocumentIndex: number; - updateSelectedDocument: (index: number) => void; -} - -export const DocumentsDropdown: FunctionComponent = ({ - documents, - selectedDocumentIndex, - updateSelectedDocument, -}) => { - return ( - - - - {i18nTexts.dropdownLabel} - - - - { - updateSelectedDocument(Number(e.target.value)); - }} - aria-label={i18nTexts.ariaLabel} - data-test-subj="documentsDropdown" - /> - - - ); -}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts index 435d0ed66c4b0..d476202aa43bb 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts @@ -4,11 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -export { - ManageProcessorForm, - ManageProcessorFormOnSubmitArg, - OnSubmitHandler, -} from './manage_processor_form'; +export { ProcessorForm, ProcessorFormOnSubmitArg, OnSubmitHandler } from './processor_form'; export { ProcessorsTree, ProcessorInfo, OnActionHandler } from './processors_tree'; @@ -22,6 +18,4 @@ export { OnDoneLoadJsonHandler, LoadFromJsonButton } from './load_from_json'; export { TestPipelineActions } from './test_pipeline'; -export { DocumentsDropdown } from './documents_dropdown'; - export { PipelineProcessorsItemTooltip, Position } from './pipeline_processors_editor_item_tooltip'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.container.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.container.tsx deleted file mode 100644 index 083529921b0a7..0000000000000 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.container.tsx +++ /dev/null @@ -1,74 +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 React, { FunctionComponent, useCallback, useEffect } from 'react'; - -import { useForm, OnFormUpdateArg, FormData, useKibana } from '../../../../../shared_imports'; -import { ProcessorInternal } from '../../types'; - -import { ManageProcessorForm as ViewComponent } from './manage_processor_form'; - -export type ManageProcessorFormOnSubmitArg = Omit; - -export type OnSubmitHandler = (processor: ManageProcessorFormOnSubmitArg) => void; - -export type OnFormUpdateHandler = (form: OnFormUpdateArg) => void; - -interface Props { - onFormUpdate: OnFormUpdateHandler; - onSubmit: OnSubmitHandler; - isOnFailure: boolean; - onOpen: () => void; - onClose: () => void; - processor?: ProcessorInternal; -} - -export const ManageProcessorForm: FunctionComponent = ({ - processor, - onFormUpdate, - onSubmit, - ...rest -}) => { - const { services } = useKibana(); - - const handleSubmit = useCallback( - async (data: FormData, isValid: boolean) => { - if (isValid) { - const { type, customOptions, fields } = data; - onSubmit({ - type, - options: customOptions ? customOptions : fields, - }); - } - }, - [onSubmit] - ); - - const maybeProcessorOptions = processor?.options; - const { form } = useForm({ - defaultValue: { fields: maybeProcessorOptions ?? {} }, - onSubmit: handleSubmit, - }); - - useEffect(() => { - const subscription = form.subscribe(onFormUpdate); - return subscription.unsubscribe; - - // TODO: Address this issue - // For some reason adding `form` object to the dependencies array here is causing an - // infinite update loop. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [onFormUpdate]); - - return ( - - ); -}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.tsx deleted file mode 100644 index ee8ca71e58446..0000000000000 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.tsx +++ /dev/null @@ -1,236 +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 { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; -import React, { FunctionComponent, memo, useEffect, useState } from 'react'; -import { - EuiButton, - EuiButtonEmpty, - EuiFlyout, - EuiFlyoutHeader, - EuiFlyoutBody, - EuiFlyoutFooter, - EuiTabs, - EuiTab, - EuiTitle, - EuiFlexGroup, - EuiFlexItem, - EuiSpacer, -} from '@elastic/eui'; - -import { Form, FormDataProvider, FormHook } from '../../../../../shared_imports'; -import { ProcessorInternal } from '../../types'; -import { useTestPipelineContext } from '../../context'; -import { getProcessorDescriptor } from '../shared'; - -import { ProcessorSettingsFields } from './processor_settings_fields'; -import { DocumentationButton } from './documentation_button'; -import { ProcessorOutput } from './processor_output'; - -export interface Props { - isOnFailure: boolean; - processor?: ProcessorInternal; - form: FormHook; - onClose: () => void; - onOpen: () => void; - esDocsBasePath: string; -} - -const updateButtonLabel = i18n.translate( - 'xpack.ingestPipelines.settingsFormOnFailureFlyout.updateButtonLabel', - { defaultMessage: 'Update' } -); - -const addButtonLabel = i18n.translate( - 'xpack.ingestPipelines.settingsFormOnFailureFlyout.addButtonLabel', - { defaultMessage: 'Add' } -); - -const cancelButtonLabel = i18n.translate( - 'xpack.ingestPipelines.settingsFormOnFailureFlyout.cancelButtonLabel', - { defaultMessage: 'Cancel' } -); - -export type TabType = 'configuration' | 'output'; - -interface Tab { - id: TabType; - name: string; -} - -const tabs: Tab[] = [ - { - id: 'configuration', - name: i18n.translate( - 'xpack.ingestPipelines.settingsFormOnFailureFlyout.configurationTabTitle', - { - defaultMessage: 'Configuration', - } - ), - }, - { - id: 'output', - name: i18n.translate('xpack.ingestPipelines.settingsFormOnFailureFlyout.outputTabTitle', { - defaultMessage: 'Output', - }), - }, -]; - -const getFlyoutTitle = (isOnFailure: boolean, isExistingProcessor: boolean) => { - if (isExistingProcessor) { - return isOnFailure ? ( - - ) : ( - - ); - } - - return isOnFailure ? ( - - ) : ( - - ); -}; - -export const ManageProcessorForm: FunctionComponent = memo( - ({ processor, form, isOnFailure, onClose, onOpen, esDocsBasePath }) => { - const { testPipelineData, setCurrentTestPipelineData } = useTestPipelineContext(); - const { - testOutputPerProcessor, - config: { selectedDocumentIndex, documents }, - } = testPipelineData; - - const processorOutput = - processor && - testOutputPerProcessor && - testOutputPerProcessor[selectedDocumentIndex][processor.id]; - - const updateSelectedDocument = (index: number) => { - setCurrentTestPipelineData({ - type: 'updateActiveDocument', - payload: { - config: { - selectedDocumentIndex: index, - }, - }, - }); - }; - - useEffect( - () => { - onOpen(); - }, - [] /* eslint-disable-line react-hooks/exhaustive-deps */ - ); - - const [activeTab, setActiveTab] = useState('configuration'); - - let flyoutContent: React.ReactNode; - - if (activeTab === 'output') { - flyoutContent = ( - - ); - } else { - flyoutContent = ; - } - - return ( -
- - - - -
- -

{getFlyoutTitle(isOnFailure, Boolean(processor))}

-
-
-
- - - {({ type }) => { - const formDescriptor = getProcessorDescriptor(type as any); - - if (formDescriptor) { - return ( - - ); - } - return null; - }} - - -
-
- - {processor ? ( - <> - - {tabs.map((tab) => ( - { - setActiveTab(tab.id); - }} - isSelected={tab.id === activeTab} - key={tab.id} - data-test-subj={`${tab.id}Tab`} - disabled={ - (tab.id === 'output' && Boolean(testOutputPerProcessor) === false) || - Boolean(processorOutput) === false - } - > - {tab.name} - - ))} - - - - ) : undefined} - - {flyoutContent} - - - - - {cancelButtonLabel} - - - - {processor ? updateButtonLabel : addButtonLabel} - - - - -
-
- ); - }, - (previous, current) => { - return previous.processor === current.processor; - } -); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_output.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_output.tsx deleted file mode 100644 index c30fdad969b24..0000000000000 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_output.tsx +++ /dev/null @@ -1,217 +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 React from 'react'; -import { i18n } from '@kbn/i18n'; - -import { - EuiAccordion, - EuiCallOut, - EuiCodeBlock, - EuiText, - EuiFlexGroup, - EuiFlexItem, - EuiSpacer, -} from '@elastic/eui'; - -import { ProcessorResult, Document } from '../../types'; -import { DocumentsDropdown } from '../documents_dropdown'; - -export interface Props { - processorOutput?: ProcessorResult; - documents: Document[]; - selectedDocumentIndex: number; - updateSelectedDocument: (index: number) => void; -} - -const i18nTexts = { - noOutputCalloutTitle: i18n.translate( - 'xpack.ingestPipelines.processorOutput.noOutputCalloutTitle', - { - defaultMessage: 'Unable to load the processor output.', - } - ), - tabDescription: i18n.translate('xpack.ingestPipelines.processorOutput.descriptionText', { - defaultMessage: - 'View how the processor affects the ingest document as it passes through the pipeline.', - }), - skippedCalloutTitle: i18n.translate('xpack.ingestPipelines.processorOutput.skippedCalloutTitle', { - defaultMessage: 'The processor was not run.', - }), - droppedCalloutTitle: i18n.translate('xpack.ingestPipelines.processorOutput.droppedCalloutTitle', { - defaultMessage: 'The document was dropped.', - }), - processorOutputLabel: i18n.translate( - 'xpack.ingestPipelines.processorOutput.processorOutputCodeBlockLabel', - { - defaultMessage: 'Processor output', - } - ), - processorErrorLabel: i18n.translate( - 'xpack.ingestPipelines.processorOutput.processorErrorCodeBlockLabel', - { - defaultMessage: 'Processor error', - } - ), - prevProcessorLabel: i18n.translate( - 'xpack.ingestPipelines.processorOutput.previousOutputCodeBlockLabel', - { - defaultMessage: 'View previous processor output', - } - ), - processorIgnoredErrorLabel: i18n.translate( - 'xpack.ingestPipelines.processorOutput.ignoredErrorCodeBlockLabel', - { - defaultMessage: 'View ignored error', - } - ), -}; - -export const ProcessorOutput: React.FunctionComponent = ({ - processorOutput, - documents, - selectedDocumentIndex, - updateSelectedDocument, -}) => { - // This code should not be reached, - // but if for some reason the output is undefined, we render a callout message - if (!processorOutput) { - return ; - } - - const { - prevProcessorResult, - doc: currentResult, - ignored_error: ignoredError, - error, - status, - } = processorOutput!; - - return ( -
- -

{i18nTexts.tabDescription}

-
- - {/* There is no output for "skipped" status, so we render an info callout */} - {status === 'skipped' && ( - <> - - - - )} - - {/* There is no output for "dropped status", so we render a warning callout */} - {status === 'dropped' && ( - <> - - - - )} - - {currentResult && ( - <> - - - - -

{i18nTexts.processorOutputLabel}

-
- - - -
- - - - - {JSON.stringify(currentResult, null, 2)} - - - )} - - {error && ( - <> - - - - -

{i18nTexts.processorErrorLabel}

-
- - - -
- - - - - {JSON.stringify(error, null, 2)} - - - )} - - {prevProcessorResult?.doc && ( - <> - - - -

{i18nTexts.prevProcessorLabel}

- - } - > - <> - - - - {JSON.stringify(prevProcessorResult.doc, null, 2)} - - -
- - )} - - {ignoredError && ( - <> - - - -

{i18nTexts.processorIgnoredErrorLabel}

- - } - > - <> - - - - {JSON.stringify(ignoredError, null, 2)} - - -
- - )} -
- ); -}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.scss b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.scss index d9c3d84eec082..55630fa96d9b0 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.scss +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.scss @@ -63,6 +63,6 @@ &__statusContainer { // Prevent content jump when spinner renders - min-width: 12px; + min-width: 15px; } } diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item_status.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item_status.tsx index a58d482022b4d..08d456b47180c 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item_status.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item_status.tsx @@ -6,11 +6,12 @@ import React, { FunctionComponent } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiToolTip, EuiIcon } from '@elastic/eui'; +import { EuiToolTip, EuiIcon, IconType } from '@elastic/eui'; import { ProcessorStatus } from '../types'; +import { ErrorIcon, ErrorIgnoredIcon, SkippedIcon } from './shared'; interface ProcessorStatusIcon { - icon: string; + icon: IconType; iconColor: string; label: string; } @@ -24,28 +25,28 @@ const processorStatusToIconMap: Record = { }), }, error: { - icon: 'crossInACircleFilled', + icon: ErrorIcon, iconColor: 'danger', label: i18n.translate('xpack.ingestPipelines.pipelineEditorItem.errorStatusAriaLabel', { defaultMessage: 'Error', }), }, error_ignored: { - icon: 'alert', - iconColor: 'warning', + icon: ErrorIgnoredIcon, + iconColor: 'danger', label: i18n.translate('xpack.ingestPipelines.pipelineEditorItem.errorIgnoredStatusAriaLabel', { defaultMessage: 'Error ignored', }), }, dropped: { - icon: 'alert', - iconColor: 'warning', + icon: 'indexClose', + iconColor: 'subdued', label: i18n.translate('xpack.ingestPipelines.pipelineEditorItem.droppedStatusAriaLabel', { defaultMessage: 'Dropped', }), }, skipped: { - icon: 'dot', + icon: SkippedIcon, iconColor: 'subdued', label: i18n.translate('xpack.ingestPipelines.pipelineEditorItem.skippedStatusAriaLabel', { defaultMessage: 'Skipped', @@ -53,7 +54,7 @@ const processorStatusToIconMap: Record = { }, inactive: { icon: 'dot', - iconColor: 'subdued', + iconColor: '#D3DAE6', // $euiColorLightShade label: i18n.translate('xpack.ingestPipelines.pipelineEditorItem.inactiveStatusAriaLabel', { defaultMessage: 'Not run', }), @@ -64,7 +65,7 @@ const processorStatusToIconMap: Record = { // This is not expected and likely means we need to modify the code to support a new status const unknownStatus = { icon: 'dot', - iconColor: 'subdued', + iconColor: '#D3DAE6', // $euiColorLightShade label: i18n.translate('xpack.ingestPipelines.pipelineEditorItem.unknownStatusAriaLabel', { defaultMessage: 'Unknown', }), diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/add_processor_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/add_processor_form.tsx new file mode 100644 index 0000000000000..5231a3d17811b --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/add_processor_form.tsx @@ -0,0 +1,134 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import React, { FunctionComponent, useEffect } from 'react'; +import { + EuiButton, + EuiButtonEmpty, + EuiFlyout, + EuiFlyoutHeader, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiTitle, + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; + +import { Form, FormDataProvider, FormHook } from '../../../../../shared_imports'; +import { getProcessorDescriptor } from '../shared'; + +import { DocumentationButton } from './documentation_button'; +import { ProcessorSettingsFields } from './processor_settings_fields'; + +interface Fields { + fields: { [key: string]: any }; +} +export interface Props { + isOnFailure: boolean; + form: FormHook; + onOpen: () => void; + esDocsBasePath: string; + closeFlyout: () => void; + handleSubmit: (shouldCloseFlyout?: boolean) => Promise; +} + +const addButtonLabel = i18n.translate( + 'xpack.ingestPipelines.addProcessorFormOnFailureFlyout.addButtonLabel', + { defaultMessage: 'Add' } +); + +const cancelButtonLabel = i18n.translate( + 'xpack.ingestPipelines.addProcesorFormOnFailureFlyout.cancelButtonLabel', + { defaultMessage: 'Cancel' } +); + +const getFlyoutTitle = (isOnFailure: boolean) => { + return isOnFailure ? ( + + ) : ( + + ); +}; + +export const AddProcessorForm: FunctionComponent = ({ + isOnFailure, + onOpen, + form, + esDocsBasePath, + closeFlyout, + handleSubmit, +}) => { + useEffect( + () => { + onOpen(); + }, + [] /* eslint-disable-line react-hooks/exhaustive-deps */ + ); + + return ( +
+ + + + +
+ +

{getFlyoutTitle(isOnFailure)}

+
+
+
+ + + {({ type }) => { + const formDescriptor = getProcessorDescriptor(type as any); + + if (formDescriptor) { + return ( + + ); + } + return null; + }} + + +
+
+ + + + + + + {cancelButtonLabel} + + + { + await handleSubmit(); + }} + > + {addButtonLabel} + + + + +
+
+ ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/documentation_button.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/documentation_button.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/documentation_button.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/documentation_button.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/edit_processor_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/edit_processor_form.tsx new file mode 100644 index 0000000000000..e449ed75b6343 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/edit_processor_form.tsx @@ -0,0 +1,253 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import React, { FunctionComponent, useEffect, useState } from 'react'; +import { + EuiButton, + EuiButtonEmpty, + EuiFlyout, + EuiFlyoutHeader, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiTabs, + EuiTab, + EuiTitle, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, +} from '@elastic/eui'; + +import { Form, FormDataProvider, FormHook } from '../../../../../shared_imports'; +import { ProcessorInternal } from '../../types'; +import { useTestPipelineContext } from '../../context'; +import { getProcessorDescriptor } from '../shared'; + +import { ProcessorSettingsFields } from './processor_settings_fields'; +import { DocumentationButton } from './documentation_button'; +import { ProcessorOutput } from './processor_output'; +import { Fields } from './processor_form.container'; + +export interface Props { + isOnFailure: boolean; + form: FormHook; + onOpen: () => void; + esDocsBasePath: string; + closeFlyout: () => void; + resetProcessors: () => void; + handleSubmit: (shouldCloseFlyout?: boolean) => Promise; + getProcessor: () => ProcessorInternal; +} + +const updateButtonLabel = i18n.translate( + 'xpack.ingestPipelines.processorFormFlyout.updateButtonLabel', + { defaultMessage: 'Update' } +); + +const cancelButtonLabel = i18n.translate( + 'xpack.ingestPipelines.processorFormFlyout.cancelButtonLabel', + { defaultMessage: 'Cancel' } +); + +export type TabType = 'configuration' | 'output'; + +interface Tab { + id: TabType; + name: string; +} + +const tabs: Tab[] = [ + { + id: 'configuration', + name: i18n.translate( + 'xpack.ingestPipelines.settingsFormOnFailureFlyout.configurationTabTitle', + { + defaultMessage: 'Configuration', + } + ), + }, + { + id: 'output', + name: i18n.translate('xpack.ingestPipelines.settingsFormOnFailureFlyout.outputTabTitle', { + defaultMessage: 'Output', + }), + }, +]; + +const getFlyoutTitle = (isOnFailure: boolean) => { + return isOnFailure ? ( + + ) : ( + + ); +}; + +export const EditProcessorForm: FunctionComponent = ({ + getProcessor, + form, + isOnFailure, + onOpen, + esDocsBasePath, + closeFlyout, + handleSubmit, + resetProcessors, +}) => { + const { testPipelineData, setCurrentTestPipelineData } = useTestPipelineContext(); + const { + testOutputPerProcessor, + config: { selectedDocumentIndex, documents }, + isExecutingPipeline, + } = testPipelineData; + + const processor = getProcessor(); + + const processorOutput = + processor && + testOutputPerProcessor && + testOutputPerProcessor[selectedDocumentIndex][processor.id]; + + const updateSelectedDocument = (index: number) => { + setCurrentTestPipelineData({ + type: 'updateActiveDocument', + payload: { + config: { + selectedDocumentIndex: index, + }, + }, + }); + }; + + useEffect( + () => { + onOpen(); + }, + [] /* eslint-disable-line react-hooks/exhaustive-deps */ + ); + + const [activeTab, setActiveTab] = useState('configuration'); + + let flyoutContent: React.ReactNode; + + if (activeTab === 'output') { + flyoutContent = ( + + ); + } else { + flyoutContent = ; + } + + return ( +
+ { + resetProcessors(); + closeFlyout(); + }} + > + + + +
+ +

{getFlyoutTitle(isOnFailure)}

+
+
+
+ + + {({ type }) => { + const formDescriptor = getProcessorDescriptor(type as any); + + if (formDescriptor) { + return ( + + ); + } + return null; + }} + + +
+
+ + + {tabs.map((tab) => ( + { + if (tab.id === 'output') { + await handleSubmit(false); + } else { + form.reset({ defaultValue: { fields: processor.options } }); + } + setActiveTab(tab.id); + }} + isSelected={tab.id === activeTab} + key={tab.id} + data-test-subj={`${tab.id}Tab`} + disabled={ + tab.id === 'output' && + (Boolean(testOutputPerProcessor) === false || Boolean(processorOutput) === false) + } + > + {tab.name} + + ))} + + + + + {flyoutContent} + + + + + { + resetProcessors(); + closeFlyout(); + }} + > + {cancelButtonLabel} + + + + { + if (activeTab === 'output') { + return closeFlyout(); + } + await handleSubmit(); + }} + > + {updateButtonLabel} + + + + +
+
+ ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/field_components/index.ts similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/index.ts rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/field_components/index.ts diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/text_editor.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/field_components/text_editor.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/text_editor.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/field_components/text_editor.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/xjson_editor.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/field_components/xjson_editor.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/xjson_editor.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/field_components/xjson_editor.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/index.ts similarity index 71% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/index.ts rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/index.ts index 986bd52e911bf..5a8d2522f1376 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/index.ts @@ -5,7 +5,7 @@ */ export { - ManageProcessorForm, - ManageProcessorFormOnSubmitArg, + ProcessorFormContainer as ProcessorForm, + ProcessorFormOnSubmitArg, OnSubmitHandler, -} from './manage_processor_form.container'; +} from './processor_form.container'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_form.container.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_form.container.tsx new file mode 100644 index 0000000000000..332908d0756f2 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_form.container.tsx @@ -0,0 +1,127 @@ +/* + * 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, useCallback, useEffect, useRef } from 'react'; + +import { useForm, OnFormUpdateArg, FormData, useKibana } from '../../../../../shared_imports'; +import { ProcessorInternal } from '../../types'; + +import { EditProcessorForm } from './edit_processor_form'; +import { AddProcessorForm } from './add_processor_form'; + +export type ProcessorFormOnSubmitArg = Omit; + +export type OnSubmitHandler = (processor: ProcessorFormOnSubmitArg) => void; + +export type OnFormUpdateHandler = (form: OnFormUpdateArg) => void; + +export interface Fields { + fields: { [key: string]: any }; +} + +interface Props { + onFormUpdate: OnFormUpdateHandler; + onSubmit: OnSubmitHandler; + isOnFailure: boolean; + onOpen: () => void; + onClose: () => void; + processor?: ProcessorInternal; +} + +export const ProcessorFormContainer: FunctionComponent = ({ + processor, + onFormUpdate, + onSubmit, + onClose, + ...rest +}) => { + const { services } = useKibana(); + + // We need to keep track of the processor form state if the user + // has made config changes, navigated between tabs (Configuration vs. Output) + // and has not yet submitted the form + const unsavedFormState = useRef(); + + const getProcessor = useCallback((): ProcessorInternal => { + let options; + + if (unsavedFormState?.current) { + options = unsavedFormState.current; + } else { + options = processor?.options ?? {}; + } + + return { ...processor, options } as ProcessorInternal; + }, [processor, unsavedFormState]); + + const { form } = useForm({ + defaultValue: { fields: getProcessor().options }, + }); + + const handleSubmit = useCallback( + async (shouldCloseFlyout: boolean = true) => { + const { isValid, data } = await form.submit(); + + if (isValid) { + const { type, customOptions, fields } = data as FormData; + const options = customOptions ? customOptions : fields; + + unsavedFormState.current = options; + + onSubmit({ + type, + options, + }); + + if (shouldCloseFlyout) { + onClose(); + } + } + }, + [form, onClose, onSubmit] + ); + + const resetProcessors = useCallback(() => { + onSubmit({ + type: processor!.type, + options: processor?.options || {}, + }); + }, [onSubmit, processor]); + + useEffect(() => { + const subscription = form.subscribe(onFormUpdate); + return subscription.unsubscribe; + + // TODO: Address this issue + // For some reason adding `form` object to the dependencies array here is causing an + // infinite update loop. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [onFormUpdate]); + + if (processor) { + return ( + + ); + } else { + return ( + + ); + } +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/index.ts new file mode 100644 index 0000000000000..3b506fc9296e3 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/index.ts @@ -0,0 +1,7 @@ +/* + * 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 { ProcessorOutput } from './processor_output'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/processor_output.scss b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/processor_output.scss new file mode 100644 index 0000000000000..e1b5eb83584ff --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/processor_output.scss @@ -0,0 +1,12 @@ +.processorOutput { + &__callOut { + &--customIcon { + .euiCallOutHeader { + align-items: center; + } + } + &__codeBlock > pre { + background: transparent; + } + } +} diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/processor_output.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/processor_output.tsx new file mode 100644 index 0000000000000..bd0ce6ca2cd52 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/processor_output.tsx @@ -0,0 +1,240 @@ +/* + * 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 { i18n } from '@kbn/i18n'; + +import { + EuiAccordion, + EuiCallOut, + EuiCodeBlock, + EuiText, + EuiSpacer, + EuiSelect, +} from '@elastic/eui'; + +import { SectionLoading } from '../../../../../../shared_imports'; +import { ProcessorResult, Document } from '../../../types'; +import { ErrorIcon, ErrorIgnoredIcon, SkippedIcon } from '../../shared'; + +import './processor_output.scss'; + +export interface Props { + processorOutput?: ProcessorResult; + documents: Document[]; + selectedDocumentIndex: number; + updateSelectedDocument: (index: number) => void; + isExecuting?: boolean; +} + +const i18nTexts = { + tabDescription: i18n.translate('xpack.ingestPipelines.processorOutput.descriptionText', { + defaultMessage: + 'View how the processor affects the ingest document as it passes through the pipeline.', + }), + skippedCalloutTitle: i18n.translate('xpack.ingestPipelines.processorOutput.skippedCalloutTitle', { + defaultMessage: 'The processor was not run.', + }), + droppedCalloutTitle: i18n.translate('xpack.ingestPipelines.processorOutput.droppedCalloutTitle', { + defaultMessage: 'The document was dropped.', + }), + noOutputCalloutTitle: i18n.translate( + 'xpack.ingestPipelines.processorOutput.noOutputCalloutTitle', + { + defaultMessage: 'Output is not available for this processor.', + } + ), + processorOutputLabel: i18n.translate( + 'xpack.ingestPipelines.processorOutput.processorOutputCodeBlockLabel', + { + defaultMessage: 'Data out', + } + ), + processorErrorTitle: i18n.translate( + 'xpack.ingestPipelines.processorOutput.processorErrorCodeBlockLabel', + { + defaultMessage: 'There was an error', + } + ), + prevProcessorLabel: i18n.translate( + 'xpack.ingestPipelines.processorOutput.processorInputCodeBlockLabel', + { + defaultMessage: 'Data in', + } + ), + processorIgnoredErrorTitle: i18n.translate( + 'xpack.ingestPipelines.processorOutput.ignoredErrorCodeBlockLabel', + { + defaultMessage: 'There was an error that was ignored', + } + ), + documentsDropdownLabel: i18n.translate( + 'xpack.ingestPipelines.processorOutput.documentsDropdownLabel', + { + defaultMessage: 'Test data:', + } + ), + loadingMessage: i18n.translate('xpack.ingestPipelines.processorOutput.loadingMessage', { + defaultMessage: 'Loading processor output…', + }), +}; + +export const ProcessorOutput: FunctionComponent = ({ + processorOutput, + documents, + selectedDocumentIndex, + updateSelectedDocument, + isExecuting, +}) => { + if (isExecuting) { + return {i18nTexts.loadingMessage}; + } + + if (!processorOutput) { + return ; + } + + const { + processorInput, + doc: currentResult, + ignored_error: ignoredError, + error, + status, + } = processorOutput!; + + const NoOutputCallOut: FunctionComponent = () => ( + + ); + + const getOutputContent = () => { + switch (status) { + case 'skipped': + return ( + + ); + case 'dropped': + return ; + case 'success': + if (currentResult) { + return ( + + {JSON.stringify(currentResult, null, 2)} + + ); + } + + return ; + case 'error': + return ( + + + {JSON.stringify(error, null, 2)} + + + ); + case 'error_ignored': + return ( + + + {JSON.stringify(ignoredError, null, 2)} + + + ); + default: + return ; + } + }; + + return ( +
+ +

{i18nTexts.tabDescription}

+
+ + + + {/* Documents dropdown */} + ({ + value: index, + text: i18n.translate('xpack.ingestPipelines.processorOutput.documentLabel', { + defaultMessage: 'Document {number}', + values: { + number: index + 1, + }, + }), + }))} + value={selectedDocumentIndex} + onChange={(e) => { + updateSelectedDocument(Number(e.target.value)); + }} + aria-label={i18nTexts.documentsDropdownLabel} + prepend={i18nTexts.documentsDropdownLabel} + /> + + + + {/* Data-in accordion */} + +

{i18nTexts.prevProcessorLabel}

+ + } + > + <> + + + + {/* If there is no processorInput defined (i.e., it's the first processor), we provide the sample document */} + {JSON.stringify( + processorInput ? processorInput : documents[selectedDocumentIndex], + null, + 2 + )} + + +
+ + + + {/* Data-out content */} + + {i18nTexts.processorOutputLabel} + + + + + {getOutputContent()} +
+ ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_settings_fields.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_settings_fields.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/append.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/append.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/append.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/append.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/bytes.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/bytes.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/bytes.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/bytes.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/circle.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/circle.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/circle.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/circle.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/common_processor_fields.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/common_processor_fields.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/common_processor_fields.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/common_processor_fields.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/field_name_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/field_name_field.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/field_name_field.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/field_name_field.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/ignore_missing_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/ignore_missing_field.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/ignore_missing_field.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/ignore_missing_field.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/index.ts similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/index.ts rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/index.ts diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/processor_type_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/processor_type_field.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/processor_type_field.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/processor_type_field.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/properties_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/properties_field.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/properties_field.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/properties_field.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/target_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/target_field.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/target_field.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/common_fields/target_field.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/convert.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/convert.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/convert.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/convert.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/csv.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/csv.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/csv.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/csv.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/custom.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/custom.tsx similarity index 96% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/custom.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/custom.tsx index c2aab62cf8933..f49e77501f931 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/custom.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/custom.tsx @@ -17,6 +17,7 @@ import { const { emptyField, isJsonField } = fieldValidators; import { XJsonEditor } from '../field_components'; +import { Fields } from '../processor_form.container'; import { EDITOR_PX_HEIGHT } from './shared'; const customConfig: FieldConfig = { @@ -60,7 +61,7 @@ const customConfig: FieldConfig = { }; interface Props { - defaultOptions?: any; + defaultOptions?: Fields['fields']; } /** diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/date.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/date.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date_index_name.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/date_index_name.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date_index_name.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/date_index_name.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/dissect.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/dissect.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/dissect.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/dissect.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/dot_expander.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/dot_expander.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/dot_expander.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/dot_expander.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/drop.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/drop.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/drop.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/drop.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/enrich.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/enrich.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/enrich.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/enrich.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/fail.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/fail.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/fail.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/fail.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/foreach.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/foreach.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/foreach.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/foreach.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/geoip.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/geoip.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/geoip.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/geoip.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/grok.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/grok.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/grok.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/grok.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/gsub.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/gsub.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/gsub.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/gsub.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/html_strip.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/html_strip.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/html_strip.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/html_strip.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/index.ts similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/index.ts rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/index.ts diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/inference.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/inference.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/inference.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/inference.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/join.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/join.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/join.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/join.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/json.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/json.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/json.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/json.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/kv.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/kv.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/kv.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/kv.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/lowercase.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/lowercase.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/lowercase.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/lowercase.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/pipeline.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/pipeline.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/pipeline.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/pipeline.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/remove.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/remove.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/remove.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/remove.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/rename.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/rename.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/rename.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/rename.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/script.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/script.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/script.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/script.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/set.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/set.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set_security_user.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/set_security_user.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set_security_user.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/set_security_user.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/shared.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/shared.ts similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/shared.ts rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/shared.ts diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/sort.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/sort.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/sort.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/sort.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/split.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/split.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/split.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/split.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/trim.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/trim.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/trim.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/trim.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/uppercase.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/uppercase.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/uppercase.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/uppercase.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/url_decode.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/url_decode.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/url_decode.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/url_decode.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/user_agent.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/user_agent.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/user_agent.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processors/user_agent.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/index.ts index 1b4b975b5305e..3f258bf279e42 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/index.ts @@ -9,3 +9,5 @@ export { mapProcessorTypeToDescriptor, ProcessorType, } from './map_processor_type_to_form'; + +export { ErrorIcon, ErrorIgnoredIcon, SkippedIcon } from './status_icons'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx index 95a8d35c119a6..8d9260f3c822c 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx @@ -46,7 +46,7 @@ import { UrlDecode, UserAgent, FormFieldsComponent, -} from '../manage_processor_form/processors'; +} from '../processor_form/processors'; interface FieldDescriptor { FieldsComponent?: FormFieldsComponent; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/status_icons/error_icon.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/status_icons/error_icon.tsx new file mode 100644 index 0000000000000..58cb56d4f768d --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/status_icons/error_icon.tsx @@ -0,0 +1,18 @@ +/* + * 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'; + +export const ErrorIcon: FunctionComponent = () => ( + + + +); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/status_icons/error_ignored_icon.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/status_icons/error_ignored_icon.tsx new file mode 100644 index 0000000000000..74ceda7687f02 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/status_icons/error_ignored_icon.tsx @@ -0,0 +1,24 @@ +/* + * 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'; + +export const ErrorIgnoredIcon: FunctionComponent = () => ( + + + + +); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/status_icons/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/status_icons/index.ts new file mode 100644 index 0000000000000..9fe0871e445eb --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/status_icons/index.ts @@ -0,0 +1,9 @@ +/* + * 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 { ErrorIcon } from './error_icon'; +export { ErrorIgnoredIcon } from './error_ignored_icon'; +export { SkippedIcon } from './skipped_icon'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/status_icons/skipped_icon.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/status_icons/skipped_icon.tsx new file mode 100644 index 0000000000000..c540bd3790fb0 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/status_icons/skipped_icon.tsx @@ -0,0 +1,18 @@ +/* + * 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'; + +export const SkippedIcon: FunctionComponent = () => ( + + + +); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/add_documents_button.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/add_documents_button.tsx index e3ef9a9ee5390..26492454cbcf5 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/add_documents_button.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/add_documents_button.tsx @@ -6,6 +6,7 @@ import { i18n } from '@kbn/i18n'; import React, { FunctionComponent } from 'react'; import { EuiButtonEmpty } from '@elastic/eui'; +import { TestPipelineFlyoutTab } from './test_pipeline_flyout_tabs'; const i18nTexts = { buttonLabel: i18n.translate('xpack.ingestPipelines.pipelineEditor.testPipeline.buttonLabel', { @@ -14,16 +15,15 @@ const i18nTexts = { }; interface Props { - openTestPipelineFlyout: () => void; + openFlyout: (activeFlyoutTab: TestPipelineFlyoutTab) => void; } -export const AddDocumentsButton: FunctionComponent = ({ openTestPipelineFlyout }) => { +export const AddDocumentsButton: FunctionComponent = ({ openFlyout }) => { return ( openFlyout('documents')} data-test-subj="addDocumentsButton" - iconType="plusInCircleFilled" > {i18nTexts.buttonLabel} diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/documents_dropdown/documents_dropdown.scss b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/documents_dropdown/documents_dropdown.scss new file mode 100644 index 0000000000000..5deb48a2f01a7 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/documents_dropdown/documents_dropdown.scss @@ -0,0 +1,3 @@ +.documentsDropdownPanel { + min-width: 200px; +} diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/documents_dropdown/documents_dropdown.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/documents_dropdown/documents_dropdown.tsx new file mode 100644 index 0000000000000..269a697a33c17 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/documents_dropdown/documents_dropdown.tsx @@ -0,0 +1,138 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import React, { FunctionComponent, useState } from 'react'; +import { + EuiButton, + EuiPopover, + EuiButtonEmpty, + EuiPopoverTitle, + EuiSelectable, + EuiHorizontalRule, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, +} from '@elastic/eui'; + +import { Document } from '../../../types'; + +import { TestPipelineFlyoutTab } from '../test_pipeline_flyout_tabs'; + +import './documents_dropdown.scss'; + +const i18nTexts = { + dropdownLabel: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.testPipeline.documentsdropdown.dropdownLabel', + { + defaultMessage: 'Documents:', + } + ), + addDocumentsButtonLabel: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.testPipeline.documentsDropdown.buttonLabel', + { + defaultMessage: 'Add documents', + } + ), + popoverTitle: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.testPipeline.documentsDropdown.popoverTitle', + { + defaultMessage: 'Test documents', + } + ), +}; + +interface Props { + documents: Document[]; + selectedDocumentIndex: number; + updateSelectedDocument: (index: number) => void; + openFlyout: (activeFlyoutTab: TestPipelineFlyoutTab) => void; +} + +export const DocumentsDropdown: FunctionComponent = ({ + documents, + selectedDocumentIndex, + updateSelectedDocument, + openFlyout, +}) => { + const [showPopover, setShowPopover] = useState(false); + + const managePipelineButton = ( + setShowPopover((previousBool) => !previousBool)} + iconType="arrowDown" + iconSide="right" + > + {i18n.translate('xpack.ingestPipelines.pipelineEditor.testPipeline.selectedDocumentLabel', { + defaultMessage: 'Document {selectedDocument}', + values: { + selectedDocument: selectedDocumentIndex + 1, + }, + })} + + ); + + return ( + setShowPopover(false)} + button={managePipelineButton} + panelPaddingSize="none" + withTitle + repositionOnScroll + data-test-subj="documentsDropdown" + panelClassName="documentsDropdownPanel" + > + ({ + key: index.toString(), + checked: selectedDocumentIndex === index ? 'on' : undefined, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.testPipeline.documentLabel', { + defaultMessage: 'Document {documentNumber}', + values: { + documentNumber: index + 1, + }, + }), + }))} + onChange={(newOptions) => { + const selectedOption = newOptions.find((option) => option.checked === 'on'); + if (selectedOption) { + updateSelectedDocument(Number(selectedOption.key!)); + } + + setShowPopover(false); + }} + > + {(list, search) => ( +
+ {i18nTexts.popoverTitle} + {list} +
+ )} +
+ + + + + + { + openFlyout('documents'); + setShowPopover(false); + }} + data-test-subj="addDocumentsButton" + > + {i18nTexts.addDocumentsButtonLabel} + + + + + +
+ ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/documents_dropdown/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/documents_dropdown/index.ts similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/documents_dropdown/index.ts rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/documents_dropdown/index.ts diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_output_button.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_output_button.tsx index 6fd1adad54f84..9018042229590 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_output_button.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_output_button.tsx @@ -5,7 +5,8 @@ */ import { i18n } from '@kbn/i18n'; import React, { FunctionComponent } from 'react'; -import { EuiButton, EuiToolTip } from '@elastic/eui'; +import { EuiButton } from '@elastic/eui'; +import { TestPipelineFlyoutTab } from './test_pipeline_flyout_tabs'; const i18nTexts = { buttonLabel: i18n.translate( @@ -14,46 +15,15 @@ const i18nTexts = { defaultMessage: 'View output', } ), - disabledButtonTooltipLabel: i18n.translate( - 'xpack.ingestPipelines.pipelineEditor.testPipeline.outputButtonTooltipLabel', - { - defaultMessage: 'Add documents to view the output', - } - ), }; interface Props { - isDisabled: boolean; - openTestPipelineFlyout: () => void; + openFlyout: (activeFlyoutTab: TestPipelineFlyoutTab) => void; } -export const TestOutputButton: FunctionComponent = ({ - isDisabled, - openTestPipelineFlyout, -}) => { - if (isDisabled) { - return ( - {i18nTexts.disabledButtonTooltipLabel}

}> - - {i18nTexts.buttonLabel} - -
- ); - } - +export const TestOutputButton: FunctionComponent = ({ openFlyout }) => { return ( - + openFlyout('output')} data-test-subj="viewOutputButton"> {i18nTexts.buttonLabel} ); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_actions.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_actions.tsx index eb9d9352e4b90..cec02db26729d 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_actions.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_actions.tsx @@ -4,15 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { FunctionComponent, useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { useTestPipelineContext, usePipelineProcessorsContext } from '../../context'; - -import { DocumentsDropdown } from '../documents_dropdown'; +import { DocumentsDropdown } from './documents_dropdown'; import { TestPipelineFlyoutTab } from './test_pipeline_flyout_tabs'; import { AddDocumentsButton } from './add_documents_button'; import { TestOutputButton } from './test_output_button'; -import { TestPipelineFlyout } from './test_pipeline_flyout'; +import { TestPipelineFlyout } from './test_pipeline_flyout.container'; + +const i18nTexts = { + testPipelineActionsLabel: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.testPipeline.testPipelineActionsLabel', + { + defaultMessage: 'Test pipeline:', + } + ), +}; export const TestPipelineActions: FunctionComponent = () => { const { testPipelineData, setCurrentTestPipelineData } = useTestPipelineContext(); @@ -40,35 +49,42 @@ export const TestPipelineActions: FunctionComponent = () => { }); }; + const openFlyout = (activeTab: TestPipelineFlyoutTab) => { + setOpenTestPipelineFlyout(true); + setActiveFlyoutTab(activeTab); + }; + return ( <> - + + + + + {i18nTexts.testPipelineActionsLabel} + + + + {documents ? ( ) : ( - { - setOpenTestPipelineFlyout(true); - setActiveFlyoutTab('documents'); - }} - /> + )} - - { - setOpenTestPipelineFlyout(true); - setActiveFlyoutTab('output'); - }} - /> - + + {testOutputPerProcessor && ( + + + + )} + {openTestPipelineFlyout && ( void; + processors: DeserializeResult; +} + +export interface TestPipelineConfig { + documents: Document[]; + verbose?: boolean; +} + +export const TestPipelineFlyout: React.FunctionComponent = ({ + onClose, + activeTab, + processors, +}) => { + const { services } = useKibana(); + + const { + testPipelineData, + setCurrentTestPipelineData, + updateTestOutputPerProcessor, + } = useTestPipelineContext(); + + const { + config: { documents: cachedDocuments, verbose: cachedVerbose }, + } = testPipelineData; + + const { form } = useForm({ + schema: documentsSchema, + defaultValue: { + documents: cachedDocuments || '', + }, + }); + + const [selectedTab, setSelectedTab] = useState(activeTab); + + const [isRunningTest, setIsRunningTest] = useState(false); + const [testingError, setTestingError] = useState(null); + const [testOutput, setTestOutput] = useState(undefined); + + const handleTestPipeline = useCallback( + async ( + { documents, verbose }: TestPipelineConfig, + updateProcessorOutput?: boolean + ): Promise<{ isSuccessful: boolean }> => { + const serializedProcessors = serialize({ pipeline: processors }); + + setIsRunningTest(true); + setTestingError(null); + + const { error, data: currentTestOutput } = await services.api.simulatePipeline({ + documents, + verbose, + pipeline: { ...serializedProcessors }, + }); + + setIsRunningTest(false); + + if (error) { + setTestingError(error); + + // reset the per-processor output + // this is needed in the scenario where the pipeline has already executed, + // but you modified the sample documents and there was an error on re-execution + setCurrentTestPipelineData({ + type: 'updateOutputPerProcessor', + payload: { + isExecutingPipeline: false, + testOutputPerProcessor: undefined, + }, + }); + + return { isSuccessful: false }; + } + + setCurrentTestPipelineData({ + type: 'updateConfig', + payload: { + config: { + documents, + verbose, + }, + }, + }); + + // We sometimes need to manually refresh the per-processor output + // e.g., when clicking the "Refresh output" button and there have been no state changes + if (updateProcessorOutput) { + updateTestOutputPerProcessor(documents, processors); + } + + setTestOutput(currentTestOutput); + + services.notifications.toasts.addSuccess( + i18n.translate('xpack.ingestPipelines.testPipelineFlyout.successNotificationText', { + defaultMessage: 'Pipeline executed', + }), + { + toastLifeTimeMs: 1000, + } + ); + + return { isSuccessful: true }; + }, + [ + processors, + services.api, + services.notifications.toasts, + setCurrentTestPipelineData, + updateTestOutputPerProcessor, + ] + ); + + const validateAndTestPipeline = async () => { + const { isValid, data } = await form.submit(); + + if (!isValid) { + return; + } + + const { documents } = data as { documents: Document[] }; + + const { isSuccessful } = await handleTestPipeline({ + documents: documents!, + verbose: cachedVerbose, + }); + + if (isSuccessful) { + setSelectedTab('output'); + } + }; + + useEffect(() => { + if (cachedDocuments && activeTab === 'output') { + handleTestPipeline({ documents: cachedDocuments, verbose: cachedVerbose }, true); + } + // We only want to know on initial mount if + // there are cached documents and we are on the output tab + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout.tsx index b26c6f536366d..46271a6bce51c 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout.tsx @@ -4,9 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useState, useCallback, useEffect } from 'react'; +import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; import { EuiFlyout, @@ -17,112 +16,46 @@ import { EuiCallOut, } from '@elastic/eui'; -import { useKibana } from '../../../../../shared_imports'; -import { useTestPipelineContext } from '../../context'; -import { serialize } from '../../serialize'; -import { DeserializeResult } from '../../deserialize'; +import { Form, FormHook } from '../../../../../shared_imports'; import { Document } from '../../types'; import { Tabs, TestPipelineFlyoutTab, OutputTab, DocumentsTab } from './test_pipeline_flyout_tabs'; export interface Props { - activeTab: TestPipelineFlyoutTab; onClose: () => void; - processors: DeserializeResult; + handleTestPipeline: ( + testPipelineConfig: TestPipelineConfig, + refreshOutputPerProcessor?: boolean + ) => Promise<{ isSuccessful: boolean }>; + isRunningTest: boolean; + cachedVerbose?: boolean; + cachedDocuments?: Document[]; + testOutput?: any; + form: FormHook; + validateAndTestPipeline: () => Promise; + selectedTab: TestPipelineFlyoutTab; + setSelectedTab: (selectedTa: TestPipelineFlyoutTab) => void; + testingError: any; } -export interface HandleTestPipelineArgs { +export interface TestPipelineConfig { documents: Document[]; verbose?: boolean; } export const TestPipelineFlyout: React.FunctionComponent = ({ + handleTestPipeline, + isRunningTest, + cachedVerbose, + cachedDocuments, + testOutput, + form, + validateAndTestPipeline, + selectedTab, + setSelectedTab, + testingError, onClose, - activeTab, - processors, }) => { - const { services } = useKibana(); - - const { - testPipelineData, - setCurrentTestPipelineData, - updateTestOutputPerProcessor, - } = useTestPipelineContext(); - - const { - config: { documents: cachedDocuments, verbose: cachedVerbose }, - } = testPipelineData; - - const [selectedTab, setSelectedTab] = useState(activeTab); - - const [shouldTestImmediately, setShouldTestImmediately] = useState(false); - const [isRunningTest, setIsRunningTest] = useState(false); - const [testingError, setTestingError] = useState(null); - const [testOutput, setTestOutput] = useState(undefined); - - const handleTestPipeline = useCallback( - async ({ documents, verbose }: HandleTestPipelineArgs) => { - const serializedProcessors = serialize({ pipeline: processors }); - - setIsRunningTest(true); - setTestingError(null); - - const { error, data: currentTestOutput } = await services.api.simulatePipeline({ - documents, - verbose, - pipeline: { ...serializedProcessors }, - }); - - setIsRunningTest(false); - - if (error) { - setTestingError(error); - return; - } - - setCurrentTestPipelineData({ - type: 'updateConfig', - payload: { - config: { - documents, - verbose, - }, - }, - }); - - setTestOutput(currentTestOutput); - - services.notifications.toasts.addSuccess( - i18n.translate('xpack.ingestPipelines.testPipelineFlyout.successNotificationText', { - defaultMessage: 'Pipeline executed', - }), - { - toastLifeTimeMs: 1000, - } - ); - - setSelectedTab('output'); - }, - [services.api, processors, setCurrentTestPipelineData, services.notifications.toasts] - ); - - useEffect(() => { - if (cachedDocuments) { - setShouldTestImmediately(true); - } - // We only want to know on initial mount if there are cached documents - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - useEffect(() => { - // If the user has already tested the pipeline once, - // use the cached test config and automatically execute the pipeline - if (shouldTestImmediately) { - setShouldTestImmediately(false); - handleTestPipeline({ documents: cachedDocuments!, verbose: cachedVerbose }); - } - }, [handleTestPipeline, cachedDocuments, cachedVerbose, shouldTestImmediately]); - let tabContent; if (selectedTab === 'output') { @@ -138,13 +71,19 @@ export const TestPipelineFlyout: React.FunctionComponent = ({ } else { // default to "Documents" tab tabContent = ( - +
+ + ); } @@ -163,9 +102,17 @@ export const TestPipelineFlyout: React.FunctionComponent = ({ { + if (nextTab === 'output') { + // When switching to the output tab, + // we automatically run the pipeline if documents are defined + validateAndTestPipeline(); + } else { + form.reset({ defaultValue: { documents: cachedDocuments! } }); + setSelectedTab(nextTab); + } + }} selectedTab={selectedTab} - getIsDisabled={(tabId) => !testOutput && tabId === 'output'} /> diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_documents.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_documents.tsx index dd12cdab0c934..b2326644340a7 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_documents.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_documents.tsx @@ -10,67 +10,23 @@ import { i18n } from '@kbn/i18n'; import { EuiSpacer, EuiText, EuiButton, EuiLink } from '@elastic/eui'; -import { - getUseField, - Field, - JsonEditorField, - Form, - useForm, - useKibana, -} from '../../../../../../shared_imports'; - -import { TestPipelineContext } from '../../../context'; -import { Document } from '../../../types'; -import { DeserializeResult } from '../../../deserialize'; -import { HandleTestPipelineArgs } from '../test_pipeline_flyout'; -import { documentsSchema } from './documents_schema'; +import { getUseField, Field, JsonEditorField, useKibana } from '../../../../../../shared_imports'; const UseField = getUseField({ component: Field }); interface Props { - handleTestPipeline: (data: HandleTestPipelineArgs) => void; - setPerProcessorOutput: (documents: Document[] | undefined, processors: DeserializeResult) => void; + validateAndTestPipeline: () => Promise; isRunningTest: boolean; - processors: DeserializeResult; - testPipelineData: TestPipelineContext['testPipelineData']; + isSubmitButtonDisabled: boolean; } export const DocumentsTab: React.FunctionComponent = ({ - handleTestPipeline, + validateAndTestPipeline, + isSubmitButtonDisabled, isRunningTest, - setPerProcessorOutput, - processors, - testPipelineData, }) => { const { services } = useKibana(); - const { - config: { documents: cachedDocuments, verbose: cachedVerbose }, - } = testPipelineData; - - const testPipeline = async () => { - const { isValid, data } = await form.submit(); - - if (!isValid) { - return; - } - - const { documents } = data as { documents: Document[] }; - - await handleTestPipeline({ documents: documents!, verbose: cachedVerbose }); - - // This is necessary to update the status and output of each processor - // as verbose may not be enabled - setPerProcessorOutput(documents, processors); - }; - - const { form } = useForm({ - schema: documentsSchema, - defaultValue: { - documents: cachedDocuments || '', - }, - }); - return (
@@ -100,53 +56,46 @@ export const DocumentsTab: React.FunctionComponent = ({ -
- {/* Documents editor */} - + {/* Documents editor */} + - + - - {isRunningTest ? ( - - ) : ( - - )} - - + + {isRunningTest ? ( + + ) : ( + + )} +
); }; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_output.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_output.tsx index 926bab6da993c..db6a020e307a5 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_output.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_output.tsx @@ -18,10 +18,13 @@ import { } from '@elastic/eui'; import { Document } from '../../../types'; -import { HandleTestPipelineArgs } from '../test_pipeline_flyout'; +import { TestPipelineConfig } from '../test_pipeline_flyout.container'; interface Props { - handleTestPipeline: (data: HandleTestPipelineArgs) => void; + handleTestPipeline: ( + testPipelineConfig: TestPipelineConfig, + refreshOutputPerProcessor?: boolean + ) => Promise<{ isSuccessful: boolean }>; isRunningTest: boolean; cachedVerbose?: boolean; cachedDocuments: Document[]; @@ -37,12 +40,6 @@ export const OutputTab: React.FunctionComponent = ({ }) => { const [isVerboseEnabled, setIsVerboseEnabled] = useState(Boolean(cachedVerbose)); - const onEnableVerbose = (isVerbose: boolean) => { - setIsVerboseEnabled(isVerbose); - - handleTestPipeline({ documents: cachedDocuments!, verbose: isVerbose }); - }; - let content: React.ReactNode | undefined; if (isRunningTest) { @@ -78,15 +75,23 @@ export const OutputTab: React.FunctionComponent = ({ /> } checked={isVerboseEnabled} - onChange={(e) => onEnableVerbose(e.target.checked)} data-test-subj="verboseOutputToggle" + onChange={async (e) => { + const isVerbose = e.target.checked; + setIsVerboseEnabled(isVerbose); + + await handleTestPipeline({ documents: cachedDocuments!, verbose: isVerbose }); + }} /> - handleTestPipeline({ documents: cachedDocuments!, verbose: isVerboseEnabled }) + onClick={async () => + await handleTestPipeline( + { documents: cachedDocuments!, verbose: isVerboseEnabled }, + true + ) } iconType="refresh" data-test-subj="refreshOutputButton" diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/test_pipeline_tabs.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/test_pipeline_tabs.tsx index abfb86c2afda1..b13fb2df90984 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/test_pipeline_tabs.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/test_pipeline_tabs.tsx @@ -13,14 +13,9 @@ export type TestPipelineFlyoutTab = 'documents' | 'output'; interface Props { onTabChange: (tab: TestPipelineFlyoutTab) => void; selectedTab: TestPipelineFlyoutTab; - getIsDisabled: (tab: TestPipelineFlyoutTab) => boolean; } -export const Tabs: React.FunctionComponent = ({ - onTabChange, - selectedTab, - getIsDisabled, -}) => { +export const Tabs: React.FunctionComponent = ({ onTabChange, selectedTab }) => { const tabs: Array<{ id: TestPipelineFlyoutTab; name: React.ReactNode; @@ -29,8 +24,8 @@ export const Tabs: React.FunctionComponent = ({ id: 'documents', name: ( ), }, @@ -49,7 +44,6 @@ export const Tabs: React.FunctionComponent = ({ onClick={() => onTabChange(tab.id)} isSelected={tab.id === selectedTab} key={tab.id} - disabled={getIsDisabled(tab.id)} data-test-subj={tab.id.toLowerCase() + 'Tab'} > {tab.name} diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/processors_context.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/processors_context.tsx index 8c59d484acd08..6595437c01810 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/processors_context.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/processors_context.tsx @@ -38,7 +38,7 @@ import { OnActionHandler } from '../components/processors_tree'; import { ProcessorRemoveModal, PipelineProcessorsItemTooltip, - ManageProcessorForm, + ProcessorForm, OnSubmitHandler, } from '../components'; @@ -159,12 +159,12 @@ export const PipelineProcessorsContextProvider: FunctionComponent = ({ selector: mode.arg.selector, }, }); + break; default: } - setMode({ id: 'idle' }); }, - [processorsDispatch, mode, setMode] + [processorsDispatch, mode] ); const onCloseSettingsForm = useCallback(() => { @@ -208,8 +208,8 @@ export const PipelineProcessorsContextProvider: FunctionComponent = ({ }; }, [mode, setMode, processorsState, processorsDispatch]); - // Update the test output whenever the processorsState changes (e.g., on move, update, delete) - // Note: updateTestOutputPerProcessor() will only simulate if the user has added sample documents + // Make a request to the simulate API and update the processor output + // whenever the documents or processorsState changes (e.g., on move, update, delete) useEffect(() => { updateTestOutputPerProcessor(documents, processorsState); }, [documents, processorsState, updateTestOutputPerProcessor]); @@ -233,7 +233,7 @@ export const PipelineProcessorsContextProvider: FunctionComponent = ({ )} {mode.id === 'managingProcessor' || mode.id === 'creatingProcessor' ? ( - { + const previousProcessorIndex = processorIndex - count; + + if (previousProcessorIndex >= 0) { + const processorResult = document.processor_results[previousProcessorIndex]; + + if (!processorResult.doc) { + const newCount = count + 1; + return getProcessorInput(processorIndex, document, newCount); + } + + return processorResult.doc; + } + + return undefined; +}; + /** * This function takes the verbose response of the simulate API * and maps the results to each processor in the pipeline by the "tag" field @@ -81,11 +114,9 @@ export const deserializeVerboseTestOutput = ( const result = { ...currentResult }; const resultId = result.tag; + // We skip index 0, as the first processor will not have a previous result if (index !== 0) { - // Add the result from the previous processor so that the user - // can easily compare current output to the previous output - // This may be a result from an on_failure processor - result.prevProcessorResult = doc.processor_results[index - 1]; + result.processorInput = getProcessorInput(index, doc); } // The tag is added programatically as a way to map diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/index.ts index 71b2e2fa8f7f1..c462b19c79327 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/index.ts @@ -14,9 +14,4 @@ export { OnUpdateHandlerArg, OnUpdateHandler } from './types'; export { SerializeResult } from './serialize'; -export { - LoadFromJsonButton, - OnDoneLoadJsonHandler, - TestPipelineActions, - DocumentsDropdown, -} from './components'; +export { LoadFromJsonButton, OnDoneLoadJsonHandler, TestPipelineActions } from './components'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/types.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/types.ts index 5229f5eb0bb21..42201b3102c28 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/types.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/types.ts @@ -94,7 +94,7 @@ export interface ProcessorResult { tag: string; ignored_error?: any; error?: any; - prevProcessorResult?: ProcessorResult; + processorInput?: Document; [key: string]: any; } diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 6e1a91884d325..ad74a35b4f9e0 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -9504,9 +9504,6 @@ "xpack.ingestPipelines.requestFlyout.descriptionText": "このElasticsearchリクエストは、このパイプラインを作成または更新します。", "xpack.ingestPipelines.requestFlyout.namedTitle": "「{name}」のリクエスト", "xpack.ingestPipelines.requestFlyout.unnamedTitle": "リクエスト", - "xpack.ingestPipelines.settingsFormOnFailureFlyout.addButtonLabel": "追加", - "xpack.ingestPipelines.settingsFormOnFailureFlyout.cancelButtonLabel": "キャンセル", - "xpack.ingestPipelines.settingsFormOnFailureFlyout.updateButtonLabel": "更新", "xpack.ingestPipelines.tabs.outputTabTitle": "アウトプット", "xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsFieldLabel": "ドキュメント", "xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsJsonError": "ドキュメントJSONが無効です。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 27611bbb7db6c..164d83aa85948 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9510,9 +9510,6 @@ "xpack.ingestPipelines.requestFlyout.descriptionText": "此 Elasticsearch 请求将创建或更新管道。", "xpack.ingestPipelines.requestFlyout.namedTitle": "对“{name}”的请求", "xpack.ingestPipelines.requestFlyout.unnamedTitle": "请求", - "xpack.ingestPipelines.settingsFormOnFailureFlyout.addButtonLabel": "添加", - "xpack.ingestPipelines.settingsFormOnFailureFlyout.cancelButtonLabel": "取消", - "xpack.ingestPipelines.settingsFormOnFailureFlyout.updateButtonLabel": "更新", "xpack.ingestPipelines.tabs.outputTabTitle": "输出", "xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsFieldLabel": "文档", "xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsJsonError": "文档 JSON 无效。",