diff --git a/public/pages/workflow_detail/workflow_inputs/processors_list.tsx b/public/pages/workflow_detail/workflow_inputs/processors_list.tsx index 6584aa91..2bc0a9da 100644 --- a/public/pages/workflow_detail/workflow_inputs/processors_list.tsx +++ b/public/pages/workflow_detail/workflow_inputs/processors_list.tsx @@ -17,7 +17,8 @@ import { EuiAccordion, EuiSpacer, EuiText, - EuiIconTip, + EuiIcon, + EuiCallOut, } from '@elastic/eui'; import { cloneDeep, isEmpty } from 'lodash'; import { getIn, useFormikContext } from 'formik'; @@ -85,6 +86,11 @@ export function ProcessorsList(props: ProcessorsListProps) { const [isPopoverOpen, setPopover] = useState(false); const [processors, setProcessors] = useState([]); + // Accordions do not persist an open/closed state, so we manually persist + const [processorOpenState, setProcessorOpenState] = useState<{ + [processorId: string]: boolean; + }>({}); + function clearProcessorErrors(): void { if (props.context === PROCESSOR_CONTEXT.INGEST) { dispatch(setIngestPipelineErrors({ errors: {} })); @@ -379,31 +385,60 @@ export function ProcessorsList(props: ProcessorsListProps) { `${processorIndex}.errorMsg`, undefined ); + const errorFound = + processorFormError !== undefined || + processorRuntimeError !== undefined; + const isAddedProcessor = + processorAdded && processorIndex === processors.length - 1; + const processorOpen = + processorOpenState[processor.id] ?? isAddedProcessor; + const errorMsg = processorFormError + ? 'Form error(s) detected' + : 'Runtime error(s) detected'; return ( { + setProcessorOpenState({ + ...processorOpenState, + [processor.id]: isOpen, + }); + }} buttonContent={ - + {`${processor.name || 'Processor'}`} - {(processorFormError !== undefined || - processorRuntimeError !== undefined) && ( + {errorFound && !processorOpen && ( - + + + + + + + {errorMsg} + + + )} @@ -421,6 +456,21 @@ export function ProcessorsList(props: ProcessorsListProps) { > + {errorFound && processorOpen && ( + <> + + + {processorFormError || processorRuntimeError} + + + + + )}