Skip to content

Conversation

@ArgoZhang
Copy link
Member

@ArgoZhang ArgoZhang commented May 10, 2025

Link issues

fixes #6008

Summary By Copilot

This pull request introduces improvements to the filtering functionality in the MultiFilter component and refactors how filtered items are handled in the TablesFilter component. The most important changes include adding support for customizable string comparison in MultiFilter, updating the filtering logic to use this new feature, and modifying test cases to ensure compatibility.

Enhancements to filtering functionality:

Refactoring and test updates:

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

Add customizable string comparison support to MultiFilter component, improving filtering flexibility

New Features:

  • Added StringComparison parameter to MultiFilter to customize string comparison during filtering

Enhancements:

  • Updated filtering logic to use the new StringComparison parameter
  • Simplified item filtering and selection using collection expressions

Tests:

  • Updated unit test for MultiFilter to include StringComparison parameter

@ArgoZhang ArgoZhang requested a review from Copilot May 10, 2025 01:35
@ArgoZhang ArgoZhang self-assigned this May 10, 2025
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented May 10, 2025

Reviewer's Guide

This pull request implements customizable string comparison in the MultiFilter component by adding a StringComparison parameter (defaulting to OrdinalIgnoreCase), which is then utilized in the OnSearchValueChanged method for filtering. Additionally, list creation in TablesFilter.razor.cs was refactored using the spread operator, and corresponding unit tests in TableFilterTest.cs were updated to accommodate the new parameter.

Sequence Diagram: Filtering Logic in MultiFilter.OnSearchValueChanged

sequenceDiagram
  actor User
  participant MF as "MultiFilter Component"
  participant Item as "SelectedItem (from internal list)"

  User->>MF: Inputs/modifies search text (searchText)
  activate MF
  MF->>MF: Calls OnSearchValueChanged(searchText)
  alt searchText is not empty
    MF->>MF: Iterates over its internal list of items (_source)
    loop For each item in _source
      MF->>Item: Checks if item.Text.Contains(searchText, StringComparison)
      note right of Item: Filtering uses the configured StringComparison property
    end
    MF->>MF: Updates its display list (_items) with filtered results
  else searchText is empty
    MF->>MF: Updates its display list (_items) with all original items from _source
  end
  deactivate MF
Loading

Class Diagram: Update to MultiFilter Component

classDiagram
  class MultiFilter {
    +StringComparison StringComparison
    +OnSearchValueChanged(string? val) Task
    %% Other existing members are not shown for brevity %%
  }
  note for MultiFilter "Added: StringComparison property (default: StringComparison.OrdinalIgnoreCase).\nOnSearchValueChanged: Method logic updated to use the StringComparison property during text filtering."
Loading

File-Level Changes

Change Details Files
Added StringComparison parameter to MultiFilter and integrated it into the filtering logic.
  • Introduced new StringComparison parameter with a default value of StringComparison.OrdinalIgnoreCase.
  • Utilized the StringComparison parameter in the OnSearchValueChanged method for filtering.
  • Adopted spread operator for list creation from filtered results in OnSearchValueChanged.
src/BootstrapBlazor/Components/Filters/MultiFilter.razor.cs
Refactored list creation in TablesFilter sample.
  • Updated OnGetAddressItemsAsync to use the spread operator [..] for returning selected items.
src/BootstrapBlazor.Server/Components/Samples/Table/TablesFilter.razor.cs
Updated MultiFilter unit tests.
  • Incorporated the new StringComparison parameter in the MultiFilter_Ok test setup.
  • Adjusted component attribute ordering in the test.
test/UnitTest/Components/TableFilterTest.cs

Assessment against linked issues

Issue Objective Addressed Explanation
#6008 Allow users to modify the search function of the MultiFilter component to enable case-insensitive comparison or other custom search logic.

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

@bb-auto bb-auto bot added the enhancement New feature or request label May 10, 2025
@bb-auto bb-auto bot added this to the v9.6.0 milestone May 10, 2025
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 enhances the filtering functionality of the MultiFilter component by adding a customizable StringComparison parameter and refactoring relevant filtering logic, including updating test cases and simplifying filtered item returns.

  • Introduces a new StringComparison parameter in MultiFilter with a default value of StringComparison.OrdinalIgnoreCase.
  • Updates filtering logic in MultiFilter to use the new parameter.
  • Refactors the TablesFilter component and its test to use the C# 12 collection expression (spread operator) for returning filtered items.

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
test/UnitTest/Components/TableFilterTest.cs Updates attribute ordering in the test for MultiFilter to include the new StringComparison parameter.
src/BootstrapBlazor/Components/Filters/MultiFilter.razor.cs Adds the StringComparison parameter and updates filtering logic to use it.
src/BootstrapBlazor.Server/Components/Samples/Table/TablesFilter.razor.cs Simplifies the return of filtered items via the C# 12 spread operator.
Comments suppressed due to low confidence (2)

src/BootstrapBlazor/Components/Filters/MultiFilter.razor.cs:235

  • Consider verifying that the C# 12 collection expression syntax used here produces a list type compatible with _items in all intended target frameworks.
_items = [.. _source.Where(i => i.Text.Contains(_searchText, StringComparison))];

src/BootstrapBlazor.Server/Components/Samples/Table/TablesFilter.razor.cs:49

  • Ensure that the use of the collection expression reliably returns the expected list type across all target environments, matching the method's return type.
return [.. Items.Select(i => new SelectedItem(i.Address!, i.Address!)).DistinctBy(i => i.Value)];

@codecov
Copy link

codecov bot commented May 10, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (d86aa37) to head (91a33af).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #6010   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          670       670           
  Lines        30645     30646    +1     
  Branches      4361      4361           
=========================================
+ Hits         30645     30646    +1     

☔ 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.

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 @ArgoZhang - I've reviewed your changes - here's some feedback:

  • Consider extending StringComparison parameter support to other relevant filter components for API consistency across the library.
  • Evaluate if CurrentCultureIgnoreCase might be a more suitable default for the StringComparison parameter in typical UI filtering scenarios, instead of OrdinalIgnoreCase.
Here's what I looked at during the review
  • 🟢 General issues: all looks good
  • 🟢 Security: all looks good
  • 🟡 Testing: 1 issue found
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

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.

b.AddAttribute(1, nameof(MultiFilter.ShowSearch), true);
b.AddAttribute(2, nameof(MultiFilter.OnGetItemsAsync), () => Task.FromResult(new List<SelectedItem>() { new("test1", "test1") }));
b.AddAttribute(1, nameof(MultiFilter.AlwaysTriggerGetItems), true);
b.AddAttribute(2, nameof(MultiFilter.StringComparison), StringComparison.OrdinalIgnoreCase);
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion (testing): Consider adding tests to verify different StringComparison behaviors.

Add tests covering each StringComparison mode. For each (e.g. Ordinal, CurrentCulture, OrdinalIgnoreCase), use items with varied casing (e.g., “Apple”, “apple”, “APPLE”), perform a search, and assert that results match the expected case-sensitive or case-insensitive behavior.

Suggested implementation:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;

public class TableFilterStringComparisonTests
{
    [Fact]
    public async Task Test_StringComparison_Ordinal()
    {
         // Arrange: Ordinal comparison is case-sensitive so only the exact match should be returned.
         var filter = new MultiFilter
         {
             StringComparison = StringComparison.Ordinal
         };
         var items = new List<SelectedItem>
         {
             new SelectedItem("Apple", "Apple"),
             new SelectedItem("apple", "apple"),
             new SelectedItem("APPLE", "APPLE")
         };

         // Act: Perform search using "Apple" as query.
         var result = await filter.GetItemsAsync("Apple", items);

         // Assert: Only "Apple" should match.
         Assert.Single(result);
         Assert.Equal("Apple", result.First().Text);
    }

    [Fact]
    public async Task Test_StringComparison_OrdinalIgnoreCase()
    {
         // Arrange: OrdinalIgnoreCase comparison returns matches regardless of casing.
         var filter = new MultiFilter
         {
             StringComparison = StringComparison.OrdinalIgnoreCase
         };
         var items = new List<SelectedItem>
         {
             new SelectedItem("Apple", "Apple"),
             new SelectedItem("apple", "apple"),
             new SelectedItem("APPLE", "APPLE")
         };

         // Act: Perform search using "Apple" as query.
         var result = await filter.GetItemsAsync("Apple", items);

         // Assert: All three items should match.
         Assert.Equal(3, result.Count);
    }

    [Fact]
    public async Task Test_StringComparison_CurrentCulture()
    {
         // Arrange: CurrentCulture comparison is typically case-sensitive.
         var filter = new MultiFilter
         {
             StringComparison = StringComparison.CurrentCulture
         };
         var items = new List<SelectedItem>
         {
             new SelectedItem("Apple", "Apple"),
             new SelectedItem("apple", "apple"),
             new SelectedItem("APPLE", "APPLE")
         };

         // Act: Perform search using "Apple" as query.
         var result = await filter.GetItemsAsync("Apple", items);

         // Assert: Only the item with exact casing "Apple" should be returned.
         Assert.Single(result);
         Assert.Equal("Apple", result.First().Text);
    }
}

// End of file

Make sure that:

  1. The MultiFilter class has a GetItemsAsync(searchQuery, items) method or a similar method to perform the filtering, otherwise adjust the test to correctly call the filtering functionality.
  2. The SelectedItem class exposes a property (e.g., Text) that contains the string to be compared.
  3. The necessary using directives are present at the top of the file if they are not already included in your codebase.

@ArgoZhang ArgoZhang merged commit f89a1fa into main May 10, 2025
5 checks passed
@ArgoZhang ArgoZhang deleted the feat-filter branch May 10, 2025 01:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(MultiFilter): Customize search evaluation in MultiFilter component

2 participants