Skip to content

Conversation

@ArgoZhang
Copy link
Member

@ArgoZhang ArgoZhang commented Sep 18, 2025

Link issues

fixes #6751

Summary By Copilot

Regression?

  • Yes
  • No

Risk

  • High
  • Medium
  • Low

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

☑️ Self Check before Merge

⚠️ Please check all items below before review. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • Merge the latest code from the main branch

Summary by Sourcery

Fix the close button in MultiSelectGeneric by refactoring and unifying the toggle logic, and correctly wiring JS-invokable handlers to update the selected items.

Bug Fixes:

  • Restore functionality of the close button in popover mode by passing the correct item index via data attribute and invoking the toggle handler.

Enhancements:

  • Extract common add/remove behavior into a new ToggleItem method and overload ToggleRow for JS-invokable calls.
  • Introduce GetValueString helper and data-bb-val attribute to support popover item identification.
  • Update Razor markup to use ToggleItem for row clicks and wire close button clicks to the new toggle implementation.

Copilot AI review requested due to automatic review settings September 18, 2025 04:47
@bb-auto bb-auto bot added the bug Something isn't working label Sep 18, 2025
@bb-auto bb-auto bot added this to the 9.10.0 milestone Sep 18, 2025
@ArgoZhang ArgoZhang merged commit a8dd255 into main Sep 18, 2025
4 checks passed
@ArgoZhang ArgoZhang deleted the fix-multi branch September 18, 2025 04:47
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Sep 18, 2025

Reviewer's Guide

This PR refactors the toggle logic for multi-select items by introducing a dedicated ToggleItem method, overloading ToggleRow to accept an index string for JS interop, and updating the component markup to pass item indices via data attributes, thereby restoring close-button functionality.

Sequence diagram for close button click interaction in MultiSelectGeneric

sequenceDiagram
    participant User as actor User
    participant UI as "MultiSelectGeneric UI"
    participant Component as "MultiSelectGeneric Component"
    User->>UI: Click close button on item
    UI->>Component: ToggleRow(item index as string)
    Component->>Component: ToggleRow(SelectedItem) (internal)
    Component->>Component: Remove item from SelectedItems
    Component->>Component: SetValue()
    Component->>UI: StateHasChanged()
Loading

Class diagram for updated MultiSelectGeneric component toggle logic

classDiagram
    class MultiSelectGeneric {
        +Task ConfirmSelectedItem(int index)
        +Task ToggleRow(string val)
        -Task ToggleRow(SelectedItem<TValue> item)
        -string? GetValueString(SelectedItem<TValue> item)
        -Task ToggleItem(SelectedItem<TValue> val)
        -int _min
        -List<SelectedItem<TValue>> SelectedItems
        -List<SelectedItem<TValue>> Rows
        -bool _isToggle
        -bool IsPopover
        -bool IsDisabled
        +Task SetValue()
    }
    MultiSelectGeneric o-- SelectedItem
    class SelectedItem {
        +TValue Value
    }
Loading

File-Level Changes

Change Details Files
Refactor toggle logic and JS interop
  • Changed JSInvokable ToggleRow to accept a string index and parse it to locate the item
  • Added private ToggleRow(item) overload to centralize add/remove and SetValue logic
  • Introduced ToggleItem to handle user-triggered toggles and call SetValue
  • Added GetValueString to generate data-bb-val attribute based on item index
MultiSelectGeneric.razor.cs
Update component markup for item toggles
  • Close-button element now includes data-bb-val attribute for index-based toggling
  • Changed OnClick handlers: close button calls JSInvokable ToggleRow via index, rows call ToggleItem
  • Ensured TriggerClick settings align with popover vs inline modes
MultiSelectGeneric.razor

Assessment against linked issues

Issue Objective Addressed Explanation
#6751 Fix the bug where clicking the 'X' (close button) on a selected item in MultiSelectGeneric does not remove the item.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes an issue where the close button in the MultiSelectGeneric component was not working properly. The fix introduces a new overloaded ToggleRow method that accepts a string parameter for JavaScript invocation and separates the toggle functionality for different use cases.

  • Introduces a new ToggleRow(string val) method that can be called from JavaScript
  • Separates row toggling logic into ToggleRow and ToggleItem methods for different contexts
  • Adds GetValueString method to provide string representation of item indices for popover scenarios

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
MultiSelectGeneric.razor.cs Refactors toggle functionality with new overloaded methods and fixes close button behavior
MultiSelectGeneric.razor Updates template to use correct toggle methods and adds data attribute for close button

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +403 to +407
await ToggleRow(item);
}
}

private async Task ToggleRow(SelectedItem<TValue> item)
Copy link

Copilot AI Sep 18, 2025

Choose a reason for hiding this comment

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

This creates infinite recursion. The method ToggleRow(string val) calls ToggleRow(item) which should be calling the private ToggleRow(SelectedItem<TValue> item) method instead.

Suggested change
await ToggleRow(item);
}
}
private async Task ToggleRow(SelectedItem<TValue> item)
await ToggleRowInternal(item);
}
}
private async Task ToggleRowInternal(SelectedItem<TValue> item)

Copilot uses AI. Check for mistakes.
Comment on lines +407 to +414
private async Task ToggleRow(SelectedItem<TValue> item)
{
SelectedItems.Remove(item);

_isToggle = true;
// 更新选中值
await SetValue();
}
Copy link

Copilot AI Sep 18, 2025

Choose a reason for hiding this comment

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

This method only removes items and doesn't check the IsDisabled state, unlike the original ToggleRow implementation. Consider adding the disabled check for consistency.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `src/BootstrapBlazor/Components/SelectGeneric/MultiSelectGeneric.razor.cs:400` </location>
<code_context>
+    public async Task ToggleRow(string val)
     {
-        if (!IsDisabled)
+        if (int.TryParse(val, out var index) && index >= 0 && index < SelectedItems.Count)
         {
-            var item = SelectedItems.FirstOrDefault(i => Equals(i.Value, val.Value));
</code_context>

<issue_to_address>
**suggestion:** Handle non-integer or out-of-range values more explicitly.

Consider adding error handling or logging for invalid or out-of-range values to prevent silent failures and aid debugging.
</issue_to_address>

### Comment 2
<location> `src/BootstrapBlazor/Components/SelectGeneric/MultiSelectGeneric.razor.cs:416` </location>
<code_context>
+        await SetValue();
+    }
+
+    private string? GetValueString(SelectedItem<TValue> item) => IsPopover ? SelectedItems.IndexOf(item).ToString() : null;
+
+    private async Task ToggleItem(SelectedItem<TValue> val)
</code_context>

<issue_to_address>
**suggestion:** Consider handling case where item is not in SelectedItems.

IndexOf returns -1 if the item is not found, which may not be appropriate for GetValueString. Consider returning null or a different sentinel value instead.

```suggestion
    private string? GetValueString(SelectedItem<TValue> item)
    {
        if (!IsPopover)
        {
            return null;
        }
        var index = SelectedItems.IndexOf(item);
        return index >= 0 ? index.ToString() : null;
    }
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

await SetValue();
}

private string? GetValueString(SelectedItem<TValue> item) => IsPopover ? SelectedItems.IndexOf(item).ToString() : null;
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Consider handling case where item is not in SelectedItems.

IndexOf returns -1 if the item is not found, which may not be appropriate for GetValueString. Consider returning null or a different sentinel value instead.

Suggested change
private string? GetValueString(SelectedItem<TValue> item) => IsPopover ? SelectedItems.IndexOf(item).ToString() : null;
private string? GetValueString(SelectedItem<TValue> item)
{
if (!IsPopover)
{
return null;
}
var index = SelectedItems.IndexOf(item);
return index >= 0 ? index.ToString() : null;
}

@codecov
Copy link

codecov bot commented Sep 18, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (20fba89) to head (3d2ebf7).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #6754   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          739       739           
  Lines        31713     31713           
  Branches      4462      4462           
=========================================
  Hits         31713     31713           
Flag Coverage Δ
BB 100.00% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(MultiSelectGeneric): 无法通过点击X去掉已选项目

2 participants