Skip to content

feat(agentflow) - create array input component and add test cases#5887

Merged
j-sanaa merged 9 commits intomainfrom
feat/agentflow-array-input
Mar 6, 2026
Merged

feat(agentflow) - create array input component and add test cases#5887
j-sanaa merged 9 commits intomainfrom
feat/agentflow-array-input

Conversation

@j-sanaa
Copy link
Contributor

@j-sanaa j-sanaa commented Mar 3, 2026

  • Create array input component as per requirements outlined in JIRA [[FLOWISE-234]]
  • Added unit test cases for ArrayInput and integration test cases for EditNodeDialog
  • Added minItems constraint for array inputs to prevent deletion below minimum count like that required by conditional agent node (Shown in Recording 1)
  • Fixed bug where connection edges connected to the top of dynamically added nodes instead of center (Shown in recording 2)
  • Added functionality to show/hide fields in ArrayInput (Recording 3)

Recording 1 - Behavior of Array Input component:

Array.Input.component.behavior.mov

Recording 2 -
Bug in position of connection edge (Before)

Before.Fix.mov

Resolved bug in position of connection edge (After)

After.fix.mov

Recording 3 - Recording of Show/Hide in ArrayInput

Hide.Show.fields.in.ArrayInput.mov

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the user interface for configuring nodes by introducing a flexible array input component. It allows for dynamic management of structured data within node parameters, complete with a new constraint to maintain minimum item counts. Additionally, a critical visual bug affecting connection edge positioning on dynamically sized nodes has been rectified, leading to a more stable and intuitive canvas experience.

Highlights

  • New Array Input Component: Introduced a new ArrayInput component to handle complex array-type inputs within node configurations, allowing users to dynamically add and remove items, each with its own set of configurable fields.
  • Minimum Items Constraint: Implemented a minItems constraint for array inputs, preventing users from deleting items if the current count falls below a specified minimum. This is particularly useful for nodes like 'conditionAgentflow' that require a certain number of array elements.
  • Connection Edge Positioning Fix: Resolved a bug where connection edges were incorrectly attaching to the top of dynamically added nodes instead of their intended center, improving the visual accuracy and usability of the canvas.
  • Comprehensive Testing: Added extensive unit tests for the new ArrayInput component and integration tests for its interaction within the EditNodeDialog, ensuring robustness and correct behavior.
Changelog
  • packages/agentflow/jest.config.js
    • Added coverage threshold for the new ArrayInput.tsx component.
  • packages/agentflow/src/atoms/ArrayInput.test.tsx
    • Added comprehensive unit tests for the ArrayInput component, covering rendering, adding, deleting, and updating items, as well as minItems constraint and disabled states.
  • packages/agentflow/src/atoms/ArrayInput.tsx
    • Created the ArrayInput component, providing functionality to manage arrays of complex objects with dynamic fields.
    • Implemented state management for array items and their parameters.
    • Added handlers for adding new items with default values and deleting existing items.
    • Integrated minItems prop to control the minimum number of deletable items.
    • Rendered nested NodeInputHandler components for individual fields within each array item.
  • packages/agentflow/src/atoms/NodeInputHandler.tsx
    • Imported the new ArrayInput component.
    • Extended NodeInputHandlerProps to include an optional minItems prop.
    • Added a new case to render ArrayInput when inputParam.type is 'array', passing relevant props including minItems.
  • packages/agentflow/src/atoms/index.ts
    • Exported ArrayInput and its ArrayInputProps from the atoms module.
  • packages/agentflow/src/core/types/index.ts
    • Extended the InputParam interface with an optional array?: InputParam[] property to define the structure of array items.
  • packages/agentflow/src/features/canvas/components/NodeOutputHandles.tsx
    • Modified getAnchorPosition to use an effectiveHeight calculation, ensuring correct positioning of output handles even before node height is fully measured, resolving the connection edge bug.
  • packages/agentflow/src/features/node-editor/EditNodeDialog.test.tsx
    • Updated the mock for NodeInputHandler to correctly simulate array input behavior (add, delete, change items).
    • Added new integration tests for EditNodeDialog to verify the rendering and data flow of array-type inputs, including adding and deleting items.
  • packages/agentflow/src/features/node-editor/EditNodeDialog.tsx
    • Implemented business logic to dynamically set the minItems prop for array inputs based on the node's name (e.g., 'conditionAgentflow' nodes require at least one item).
    • Passed the calculated minItems prop to the NodeInputHandler component.
Activity
  • j-sanaa created the ArrayInput component to fulfill requirements from JIRA FLOWISE-234.
  • j-sanaa added unit tests for the new ArrayInput and integration tests for EditNodeDialog to ensure functionality.
  • j-sanaa implemented the minItems constraint to prevent deletion of essential array items.
  • j-sanaa fixed a bug related to connection edge positioning on dynamically added nodes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new ArrayInput component, adds comprehensive unit and integration tests, and fixes a bug related to connection edge positioning. The implementation is solid, but I've identified a critical state management issue in the new ArrayInput component that could lead to race conditions. I've also suggested an improvement in EditNodeDialog to enhance maintainability by decoupling business logic from the component. My feedback aims to improve the robustness and long-term maintainability of the new features.

@j-sanaa
Copy link
Contributor Author

j-sanaa commented Mar 4, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new ArrayInput component designed to manage lists of structured data within node inputs. Key changes include extending the InputParam and INodeParams interfaces with array, minItems, and maxItems properties to define array input structures and constraints. The ArrayInput component is integrated into NodeInputHandler to render it for 'array' type inputs, supporting operations like adding and deleting items, handling nested field changes, applying default values, and respecting minItems constraints. Comprehensive unit tests for ArrayInput and integration tests within EditNodeDialog were added to validate its functionality. A minor adjustment was also made to NodeOutputHandles.tsx to improve anchor positioning. The review comment suggests an optimization for the ArrayInput component by removing an inefficient itemParameters useMemo and directly using inputParam.array in the render method to enhance performance and readability.

Comment on lines +37 to +40
const itemParameters = useMemo(
() => arrayItems.map(() => inputParam.array?.map((field) => ({ ...field })) || []),
[arrayItems, inputParam.array]
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The itemParameters useMemo is inefficient as it creates a deep copy of inputParam.array for every item in arrayItems. This can be simplified by removing this useMemo and using inputParam.array directly in the render loop. This improves performance and readability.

After removing this useMemo, you should modify the render logic around line 137 to use inputParam.array instead of itemParameters[index], like this:

{inputParam.array
    ?.filter((param) => param.display !== false)
    .map((param, paramIndex) => (
        <NodeInputHandler
            key={paramIndex}
            inputParam={param}
            data={itemData}
            disabled={disabled}
            isAdditionalParams={true}
            disablePadding={false}
            onDataChange={({ inputParam: changedParam, newValue }) => {
                handleItemInputChange(index, changedParam, newValue)
            }}
        />
    ))}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need itemParameters for per-item field visibility tracking when PR #5890 merges

@j-sanaa j-sanaa marked this pull request as ready for review March 4, 2026 16:17
@j-sanaa j-sanaa marked this pull request as draft March 4, 2026 21:47
- Add ArrayInput component for managing lists of structured data

- Implement field visibility engine with show/hide conditions

- Add minItems constraint support for array inputs

- Add comprehensive test coverage for ArrayInput and EditNodeDialog

- Update NodeInputHandler to support array type inputs

- Update types to include array-related input parameters
@j-sanaa j-sanaa force-pushed the feat/agentflow-array-input branch from 0572f4f to 026ae25 Compare March 4, 2026 21:58
@j-sanaa
Copy link
Contributor Author

j-sanaa commented Mar 4, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new ArrayInput component for handling array-based inputs, along with associated tests and type definition updates. It also includes a fix for a bug related to connection edge positioning. My review focuses on the new ArrayInput component's logic and the related test implementations. I have two suggestions: one to improve the handling of default values in the ArrayInput component to prevent potential type mismatches, and another to enhance the maintainability of the integration tests by simplifying a mock implementation. Please see the detailed comments below.

Comment on lines +47 to +51
const newItem = inputParam.array?.reduce((acc, field) => {
acc[field.name] = field.default ?? ''
return acc
}, {} as Record<string, unknown>)
onDataChange({ inputParam, newValue: [...currentArray, newItem || {}] })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The mock for NodeInputHandler replicates the logic for creating a new item with default values from the ArrayInput component. This tight coupling makes the test brittle, as any change to the default value logic in ArrayInput will require a corresponding change here.

Since ArrayInput.test.tsx already covers the default value logic in detail, this integration test could be simplified. Consider having the mock add a static, predictable object. The test assertion would then verify that the onDataChange callback is invoked with an array containing this new static object. This would decouple the test from the implementation details of ArrayInput and make it more robust.

References
  1. To avoid flaky tests, prefer making logic deterministic (e.g., using sequential IDs) over mocking non-deterministic dependencies (e.g., Date.now()).

@j-sanaa j-sanaa marked this pull request as ready for review March 4, 2026 23:18

return (
<Box
key={index}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: key={index} for array items will cause subtle bugs when items are deleted from the middle. React will reuse the wrong DOM/state for remaining items. Is there any other field we could combine with to make this more robust?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array items are plain Record<string, unknown> objects and their fields are entirely user-defined data due to which none of them are usable as a stable key. Another option is to have a key field added onto each arrayItems during load but this requires more testing. Can add this change in a separate PR

display?: boolean
array?: InputParam[]
minItems?: number
maxItems?: number
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: doesn't look like we access this field or add any logic to enforce the constraint, is this something to be used in the future?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The minItems is used for conditionalAgent as it requires a minimum of 1 scenario to always be present. MaxItems is not used anywhere in the existing nodes but can be used in the future if required

disabled={disabled}
isAdditionalParams={true}
disablePadding={false}
onDataChange={({ inputParam: changedParam, newValue }) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: This creates a new closure on every render for every field in every item. For small arrays this is fine, but for larger arrays it defeats the useCallback memoization of handleItemInputChange. Consider wrapping this with a memoized callback or accepting the index as part of the handler pattern.

const [arrayItemParameters, setArrayItemParameters] = useState<Record<string, InputParam[][]>>({})

// Evaluate field visibility for each item in every array-type param.
const computeArrayItemParameters = useCallback(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this function seems stable and is added to the useEffect deps at line 88 ([dialogProps, computeArrayItemParameters]). Since the callback is stable (empty deps), this is technically fine but the callback itself could simply be a plain function outside the component.

?.filter((param) => param.display !== false)
.map((param, paramIndex) => (
<NodeInputHandler
key={paramIndex}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: key={paramIndex} is used for the field renderers within each item. Since these params are from a static definition and don't reorder, this is acceptable but using param.name or param.id could be more robust.

@j-sanaa j-sanaa merged commit a2451e2 into main Mar 6, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants