Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: group identifier for dropdown form controls #39256

Merged
merged 69 commits into from
Feb 14, 2025

Conversation

ayushpahwa
Copy link
Contributor

@ayushpahwa ayushpahwa commented Feb 13, 2025

Description

This PR enhances the DropDownControl component to support storing group information along with selected values. When enabled, this feature allows consumers to track which group an option belongs to in the stored value, making it easier to handle cases where different groups might have options with identical values.

Key Changes

  • Added new prop appendGroupIdentfierToValue to control the feature
  • Modified value handling to store values in format groupType:value when enabled
  • Updated selection and removal logic to handle group-prefixed values
  • Added comprehensive test coverage for the new functionality

Value Format

When appendGroupIdentfierToValue is enabled:

  • Single Select: "groupType:optionValue"
  • Multi Select: ["groupType1:optionValue1", "groupType2:optionValue2", ...]
  • Options without explicit groups use "others" as the group identifier

Example Usage

<DropDownControl
   options={[
      { label: "Option 1", value: "1", optionGroupType: "group1" },
      { label: "Option 2", value: "2" }, // Will use "others" group
   ]}
   optionGroupConfig={{
      group1: { label: "Group 1", children: [] }
   }}
   appendGroupIdentfierToValue={true}
   // ... other props
/>

Notes

  • Feature is opt-in via the appendGroupIdentfierToValue prop
  • When disabled or when optionGroupConfig is not provided, behavior remains unchanged
  • Existing code using the component without the new prop continues to work as before
  • The feature only takes effect when both appendGroupIdentfierToValue is true AND optionGroupConfig is provided
  • Options without an explicit group are assigned to the "others" group
  • The group identifier is added at selection time and handled transparently during removal

Fixes #39259

Automation

/ok-to-test tags="@tag.Sanity, @tag.IDE"

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/13315296499
Commit: 7a0184b
Cypress dashboard.
Tags: @tag.Sanity, @tag.IDE
Spec:


Thu, 13 Feb 2025 20:07:54 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Introduced an option to include group identifiers with dropdown selections, allowing grouped options to be managed and stored accurately.
  • Tests

    • Expanded test coverage to validate the proper rendering, selection, and removal of grouped options, including edge cases and integration with Redux actions.

Copy link
Contributor

coderabbitai bot commented Feb 13, 2025

Walkthrough

The pull request updates the DropDownControl component and its corresponding tests. The changes introduce a new optional property that allows appending a group identifier to selected values. Both the component logic and the tests have been modified to support this feature, ensuring that grouped options are handled correctly through updated value comparisons, action payloads, and test assertions.

Changes

File(s) Change Summary
app/client/src/components/formControls/DropDownControl.tsx Added the optional property appendGroupIdentifierToValue to DropDownControlProps and modified the renderDropdown function along with selection/removal logic to append the group identifier to the value when needed.
app/client/src/components/formControls/DropDownControl.test.tsx Introduced a new type import ReduxAction, updated the beforeEach setup to reflect the new form value structure, and added tests to verify that selected options correctly include group identifiers in dispatched actions and that grouped options render properly.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant D as DropDownControl
    participant R as Redux Store
    U->>D: Select option
    D->>D: Check if appendGroupIdentifierToValue is true
    D->>D: Append group identifier to the option value
    D->>R: Dispatch Redux action with modified payload
    R-->>D: Update store state
    D-->>U: Update displayed selection
Loading

Possibly related PRs

Suggested labels

Task, Query & Widgets Pod

Suggested reviewers

  • AmanAgarwal041
  • ApekshaBhosale
  • jsartisan

Poem

In the code's bustling bazaar, a tweak takes flight,
Group identifiers join the dance, shining bright.
Options now twirl with clarity in view,
Redux listens as each change rings true.
A nod to tests and production’s art,
Crafting grouped magic—a piece of smart code's heart!


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 369367d and 7a0184b.

📒 Files selected for processing (2)
  • app/client/src/components/formControls/DropDownControl.test.tsx (3 hunks)
  • app/client/src/components/formControls/DropDownControl.tsx (9 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/src/components/formControls/DropDownControl.tsx
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-build / client-build
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (5)
app/client/src/components/formControls/DropDownControl.test.tsx (5)

9-9: LGTM! Type safety enhancement.

The addition of the ReduxAction type import improves type safety when handling Redux actions in the tests.


303-369: LGTM! Comprehensive test coverage for single-select with group identifiers.

The test thoroughly verifies:

  • Group identifier appending for items in groups
  • Default 'others' group for items without a group
  • Redux action payloads

371-444: LGTM! Thorough multi-select test coverage.

The test effectively covers:

  • Multiple selection with group identifiers
  • Removal of selected options
  • Correct Redux action payloads

446-515: LGTM! Edge cases well covered.

Excellent coverage of edge cases:

  • Values containing colons
  • Items without groups
  • Multi-select behavior

225-235:

❓ Verification inconclusive

Verify store initialization structure.

The store initialization has been updated to use a dynamic form name and a nested data structure. While this matches the new requirements, we should verify this matches the actual Redux state shape used in the application.


🏁 Script executed:

#!/bin/bash
# Search for other test files that might show the expected Redux state shape
rg -l "mockStore\({" --type ts | xargs rg -A 5 "form: {" --type ts

Length of output: 234


Action Required: Verify Redux State Shape in Store Initialization

The modified test now initializes the store using a dynamic form name with a nested data structure. However, our initial attempt to auto-detect the expected Redux state shape via regex produced errors due to regex syntax issues. Please verify manually that the Redux state shape defined in the test at app/client/src/components/formControls/DropDownControl.test.tsx (lines 225–235) aligns with the actual state expected by the application.

To assist with further verification, you can re-run the search using fixed-string matching with the following command:

If the output still doesn't provide clarity, please perform manual verification of the store structure across the relevant parts of the codebase.


🏁 Script executed:

[run_scripts]
#!/bin/bash
# Using fixed-string search (-F) for reliable matching
rg -l -F "mockStore({" --type ts | xargs rg -A 5 -F "form: {" --type ts

Length of output: 1715


Ensure Consistent Redux Store State Structure

The test now initializes the store using a dynamic form name ([formName]) with a nested state shape (values: { actionConfiguration: { testPath: { data: "" } } }). However, the search results indicate that some tests use literal form names (e.g., "TestForm") while others use the dynamic notation. Please verify that the Redux state shape in this test is consistent with the overall application state. In particular:

  • Confirm that the reducer or state initialization logic expects the nested structure used here.
  • Reconcile any differences between tests using dynamic form names and those using fixed names.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@ayushpahwa
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions github-actions bot added the Enhancement New feature or request label Feb 13, 2025
Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/13312354447.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 39256.
recreate: .

Copy link

Deploy-Preview-URL: https://ce-39256.dp.appsmith.com

When trying to do multi select on the dropdown with the append option
enabled, the check for group type identifier was being appended
incorrectly. Fixed the same
We are not getting store updates, but the store actions launched are
realiable and hence used in the test
@github-actions github-actions bot added the Frontend This label marks the issue or pull request to reference client code label Feb 13, 2025
@ayushpahwa ayushpahwa marked this pull request as ready for review February 13, 2025 19:04
@ayushpahwa ayushpahwa requested review from jsartisan and sneha122 and removed request for jsartisan February 13, 2025 19:05
@github-actions github-actions bot added Workflows Pod Issues that the workflows team owns Workflows Product Issues related to the workflows product labels Feb 13, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d64eab6 and 2814dff.

📒 Files selected for processing (2)
  • app/client/src/components/formControls/DropDownControl.test.tsx (3 hunks)
  • app/client/src/components/formControls/DropDownControl.tsx (8 hunks)
🔇 Additional comments (7)
app/client/src/components/formControls/DropDownControl.test.tsx (4)

9-9: LGTM! Test setup changes look good.

The changes improve type safety and properly initialize the form state for testing the new group identifier feature.

Also applies to: 225-233


303-369: LGTM! Comprehensive test coverage for group identifier feature.

The test case thoroughly verifies:

  • Group identifier appending for grouped options
  • Handling of ungrouped options (others group)
  • Correct Redux action payloads

371-444: LGTM! Multi-select test coverage is thorough.

The test case effectively verifies:

  • Array handling with group identifiers
  • Selection and removal of multiple options
  • Correct Redux action payloads for array values

446-515: LGTM! Edge cases are well covered.

The test case effectively handles:

  • Values containing colons
  • Options without group assignments
  • Correct Redux action payloads for edge cases
app/client/src/components/formControls/DropDownControl.tsx (3)

294-304: LGTM! Selected options filtering logic is robust.

The implementation correctly:

  • Handles both grouped and ungrouped options
  • Performs appropriate value comparisons based on configuration

355-368: LGTM! Option selection logic handles group identifiers correctly.

The implementation properly:

  • Appends group identifiers when configured
  • Handles ungrouped options with "others" group
  • Maintains existing functionality when feature is disabled

402-412: LGTM! Option removal logic handles group identifiers correctly.

The implementation effectively:

  • Handles group identifiers during removal
  • Correctly compares values by splitting on colon
  • Maintains array integrity

app/client/src/components/formControls/DropDownControl.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
app/client/src/components/formControls/DropDownControl.tsx (2)

294-308: Optimize the filtering logic.

The filtering logic can be simplified using array methods and early returns.

-  const selectedOptions = options.filter((opt) => {
-    const checkGroupIdentifier =
-      appendGroupIdentfierToValue && optionGroupConfig;
-    const valueToCompare = checkGroupIdentifier
-      ? opt.optionGroupType + ":" + opt.value
-      : opt.value;
-
-    return isMultiSelect
-      ? (selectedValue as string[]).includes(valueToCompare)
-      : selectedValue === valueToCompare;
-  });
+  const checkGroupIdentifier = appendGroupIdentfierToValue && optionGroupConfig;
+  const getValueToCompare = (opt: SelectOptionProps) =>
+    checkGroupIdentifier ? `${opt.optionGroupType || "others"}:${opt.value}` : opt.value;
+  const selectedOptions = options.filter((opt) =>
+    isMultiSelect
+      ? (selectedValue as string[]).includes(getValueToCompare(opt))
+      : selectedValue === getValueToCompare(opt)
+  );

411-421: Simplify the removal logic.

The removal logic can be simplified by extracting the group identifier parsing into a helper function.

+  function parseGroupedValue(value: string): string {
+    return appendGroupIdentfierToValue && optionGroupConfig ? value.split(":")[1] : value;
+  }
+
   const filtered = currentArray.filter((v) => {
-    let selectedValueToCheck = v;
-
-    if (appendGroupIdentfierToValue && optionGroupConfig) {
-      selectedValueToCheck = v.split(":")[1];
-    }
-
-    return selectedValueToCheck !== optionValueToRemove;
+    return parseGroupedValue(v) !== optionValueToRemove;
   });
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2814dff and 369367d.

📒 Files selected for processing (1)
  • app/client/src/components/formControls/DropDownControl.tsx (9 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-prettier / prettier-check
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-build / client-build
🔇 Additional comments (2)
app/client/src/components/formControls/DropDownControl.tsx (2)

120-120: Fix typo in property name.

The property name has a typo: "Identfier" should be "Identifier".


458-458: LGTM: Clear button visibility logic is correct.

The clear button visibility logic correctly handles both multi-select and single-select cases.

app/client/src/components/formControls/DropDownControl.tsx Outdated Show resolved Hide resolved
@ayushpahwa ayushpahwa added the ok-to-test Required label for CI label Feb 13, 2025
@ayushpahwa ayushpahwa merged commit 400f894 into release Feb 14, 2025
48 checks passed
@ayushpahwa ayushpahwa deleted the feat/dropdown-value-with-group branch February 14, 2025 07:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement New feature or request Frontend This label marks the issue or pull request to reference client code ok-to-test Required label for CI Workflows Pod Issues that the workflows team owns Workflows Product Issues related to the workflows product
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature]: append group type identifier to dropdown component
2 participants