Skip to content

Conversation

@ArgoZhang
Copy link
Member

@ArgoZhang ArgoZhang commented Mar 24, 2025

Link issues

fixes #5686

Summary By Copilot

This pull request includes several changes to the BootstrapBlazor.Server project, focusing on theme management and dependency updates. The most important changes include updating package versions, refactoring theme handling, and modifying various components to support dynamic theme changes.

Dependency Updates:

  • Updated BootstrapBlazor.DockView package version from 9.1.5 to 9.1.7 in BootstrapBlazor.Server.csproj.

Theme Handling Refactor:

  • Removed the OnThemeChangedAsync method and its usage from Header.razor and Header.razor.cs. [1] [2]
  • Refactored Pre.razor.cs to inject IThemeProvider and handle theme changes using the OnThemeChanged method. [1] [2] [3]
  • Updated ThemeMode.razor and ThemeMode.razor.cs to use JSObjectReference and handle theme changes with OnThemeChanged method. [1] [2] [3] [4]
  • Modified BaseDockView.cs to inject IThemeProvider and handle theme changes by updating the Theme property. [1] [2] [3] [4]

Component Updates:

  • Added Theme parameter to various DockViewV2 components in different .razor files to support dynamic theme changes. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]

JavaScript Changes:

  • Removed the updateTheme function and its usage from Header.razor.js. [1] [2]
  • Simplified the switchTheme function in Pre.razor.js by removing the assetPath parameter.
  • Updated ThemeMode.razor.js to invoke the OnThemeChanged method when the theme changes. [1] [2]

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

Fixes an issue where the theme parameter was not working in the DockView component. This is achieved by refactoring theme handling to use the IThemeProvider service and updating components to support dynamic theme changes.

Bug Fixes:

  • Fixes an issue where the theme parameter was not working in the DockView component.
  • The theme parameter was not being correctly passed to the DockView component, preventing it from rendering with the correct theme.
  • The theme was not updating when the user changed the theme in the application.

Enhancements:

  • Refactors theme handling to use the IThemeProvider service.
  • Updates components to support dynamic theme changes.

Tests:

  • Adds a test to verify that the theme is correctly applied to the DockView component.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Mar 24, 2025

Reviewer's Guide by Sourcery

This pull request addresses an issue where the theme parameter was not functioning correctly in the DockView component. The changes involve refactoring theme handling to use the IThemeProvider service, updating components to support dynamic theme changes, and updating the BootstrapBlazor.DockView package version.

Sequence diagram for Theme Change

sequenceDiagram
    participant User
    participant ThemeMode
    participant IThemeProvider
    participant BaseDockView

    User->ThemeMode: Click to change theme
    ThemeMode->IThemeProvider: SetThemeAsync(themeName)
    activate IThemeProvider
    IThemeProvider->IThemeProvider: Store theme
    IThemeProvider-->>ThemeMode: Return
    deactivate IThemeProvider
    IThemeProvider->BaseDockView: ThemeChangedAsync(themeName)
    activate BaseDockView
    BaseDockView->BaseDockView: Update Theme property
    BaseDockView->BaseDockView: StateHasChanged()
    BaseDockView-->>IThemeProvider: Return
    deactivate BaseDockView
Loading

File-Level Changes

Change Details Files
Refactored theme handling across multiple components to utilize the IThemeProvider service for dynamic theme changes.
  • Injected IThemeProvider into Pre.razor.cs and handled theme changes using the OnThemeChanged method.
  • Updated ThemeMode.razor and ThemeMode.razor.cs to use JSObjectReference and handle theme changes with OnThemeChanged method.
  • Modified BaseDockView.cs to inject IThemeProvider and handle theme changes by updating the Theme property.
  • Removed the OnThemeChangedAsync method and its usage from Header.razor and Header.razor.cs.
  • Removed the updateTheme function and its usage from Header.razor.js.
  • Simplified the switchTheme function in Pre.razor.js by removing the assetPath parameter.
  • Updated ThemeMode.razor.js to invoke the OnThemeChanged method when the theme changes.
src/BootstrapBlazor.Server/Components/Components/Pre.razor.cs
src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.cs
src/BootstrapBlazor.Server/Components/Samples/DockViews2/BaseDockView.cs
src/BootstrapBlazor.Server/Components/Components/Header.razor
src/BootstrapBlazor.Server/Components/Components/Header.razor.cs
src/BootstrapBlazor.Server/Components/Components/Header.razor.js
src/BootstrapBlazor.Server/Components/Components/Pre.razor.js
src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.js
Added a Theme parameter to various DockViewV2 components to support dynamic theme changes.
  • Added Theme parameter to DockViewV2 components in .razor files.
src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewNest.razor
src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewCol.razor
src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewComplex.razor
src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewGroup.razor
src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewLayout.razor
src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewLock.razor
src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewRow.razor
src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewTitle.razor
src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewVisible.razor
Updated the BootstrapBlazor.DockView package version.
  • Updated BootstrapBlazor.DockView package version from 9.1.5 to 9.1.7.
src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj

Assessment against linked issues

Issue Objective Addressed Explanation
#5686 The DockView component should respect the selected theme (light or dark) and display accordingly.

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!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

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 bug Something isn't working label Mar 24, 2025
@bb-auto bb-auto bot added this to the v9.4.0 milestone Mar 24, 2025
@ArgoZhang ArgoZhang merged commit 8860c4b into main Mar 24, 2025
3 checks passed
@ArgoZhang ArgoZhang deleted the refactor-theme branch March 24, 2025 12:19
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:

Overall Comments:

  • Consider adding a guard to DefaultThemeProvider.cs to prevent ThemeChangedAsync from being called if it's null.
  • The asset path is hardcoded in Pre.razor.js; consider making this configurable.
Here's what I looked at during the review
  • 🟡 General issues: 3 issues found
  • 🟢 Security: all looks good
  • 🟡 Testing: 2 issues 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.


DataTableDynamicContext = DataTableDynamicService.CreateContext();

ThemeProviderService.ThemeChangedAsync += OnThemeChanged;
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Unsubscribe from ThemeChangedAsync to prevent potential memory leaks.

Since the component registers for theme change notifications during OnInitialized, consider unsubscribing in Dispose to ensure that disposed instances do not remain referenced through the delegate.

Suggested implementation:

        base.OnInitialized();

        ThemeProviderService.ThemeChangedAsync += OnThemeChanged;
    // Unsubscribe from the ThemeChangedAsync event to avoid memory leaks
    public void Dispose()
    {
        if (ThemeProviderService != null)
        {
            ThemeProviderService.ThemeChangedAsync -= OnThemeChanged;
        }
        GC.SuppressFinalize(this);
    }

If your class already overrides a Dispose(bool disposing) method, then incorporate the unsubscription logic there instead of creating a new Dispose() method. Additionally, ensure that the class implements IDisposable if it isn’t already.

{
base.OnInitialized();

ThemeProviderService.ThemeChangedAsync += OnThemeChanged;
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Manage event subscription lifecycle in Pre component.

Just as in other components, ensure that the event handler registered to ThemeProviderService.ThemeChangedAsync is removed when the component is disposed. This helps avoid unintended behavior and memory retention.

Suggested implementation:

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        ThemeProviderService.ThemeChangedAsync -= OnThemeChanged;
    }
    base.Dispose(disposing);
}

Ensure that the method OnThemeChanged exists in the component. If not, implement it accordingly.

Comment on lines +26 to +29
/// <summary>
/// The callback when theme changed
/// </summary>
Func<string, Task>? ThemeChangedAsync { get; set; }
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 using an event instead of a delegate property for theme changes.

Using the event keyword and following the .NET event pattern could make subscribing and unsubscribing more natural, especially if multiple components might listen to theme change notifications.

Suggested change
/// <summary>
/// The callback when theme changed
/// </summary>
Func<string, Task>? ThemeChangedAsync { get; set; }
/// <summary>
/// Occurs when the theme is changed.
/// </summary>
event Func<string, Task>? ThemeChangedAsync;

await Task.CompletedTask;
};
await themeProviderService.SetThemeAsync("light");
Assert.Equal("light", themeName);
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): Add test for the ThemeChangedAsync event with "dark" theme

It would be beneficial to add a test case that specifically checks the behavior of the ThemeChangedAsync event when the "dark" theme is set. This ensures that the event is triggered correctly and the theme name is passed accurately in both light and dark scenarios.

public async Task SetTheme_Ok()
{
var themeName = "";
var themeProviderService = Context.Services.GetRequiredService<IThemeProvider>();
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): Add test for GetThemeAsync

A test is missing to verify the functionality of the GetThemeAsync method. This test should set a theme using SetThemeAsync and then retrieve it using GetThemeAsync, asserting that the retrieved theme matches the set theme.

Suggested implementation:

    [Fact]
    public async Task SetTheme_Ok()
    {
        var themeName = "";
        var themeProviderService = Context.Services.GetRequiredService<IThemeProvider>();
        themeProviderService.ThemeChangedAsync = async theme =>
        {
            themeName = theme;
            await Task.CompletedTask;
        };
        await themeProviderService.SetThemeAsync("light");
        Assert.Equal("light", themeName);
    }

    [Fact]
    public async Task GetTheme_Ok()
    {
        // Arrange
        var themeProviderService = Context.Services.GetRequiredService<IThemeProvider>();
        await themeProviderService.SetThemeAsync("light");

        // Act
        var theme = await themeProviderService.GetThemeAsync();

        // Assert
        Assert.Equal("light", theme);
    }

This change assumes that the IThemeProvider interface includes a GetThemeAsync method that functions synchronously after setting the theme. If additional setup is required in your test fixture or dependency injection container, please ensure to update that accordingly.

@codecov
Copy link

codecov bot commented Mar 24, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (7d4606e) to head (3ed83cd).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #5705   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          657       657           
  Lines        29818     29825    +7     
  Branches      4225      4226    +1     
=========================================
+ Hits         29818     29825    +7     

☔ 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(DockView): theme parameter not work

2 participants