Skip to content

MudTreeViewItem: make Items two-way for returning server-loaded children#10684

Merged
henon merged 6 commits intoMudBlazor:devfrom
henon:treeview-serverdata-plus-items
Jan 24, 2025
Merged

MudTreeViewItem: make Items two-way for returning server-loaded children#10684
henon merged 6 commits intoMudBlazor:devfrom
henon:treeview-serverdata-plus-items

Conversation

@henon
Copy link
Copy Markdown
Contributor

@henon henon commented Jan 22, 2025

Description

This change fixes two problems at once.

  1. In MudTreeViewItem the parameter Items was overwritten from within the component which is forbidden by our own rules
  2. It allows people to have an initial tree of items which can be extended with server loading. fixes MudTreeView: Using ServerData and Items at the same time not possible #9939

The example has been improved to show how an existing initial tree can be extended with server loading. Initial view of the example:
image

After clicking Promotions:
image

After clicking More Spam:
image

How Has This Been Tested?

Type of Changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation (fix or improvement to the website or code docs)

Checklist

  • The PR is submitted to the correct branch (dev).
  • My code follows the code style of this project.
  • I've added relevant tests.

@github-actions github-actions Bot added bug Unexpected behavior or functionality not working as intended PR: needs review labels Jan 22, 2025
@henon henon marked this pull request as draft January 22, 2025 04:18
@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 22, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 91.81%. Comparing base (f20e5ff) to head (0e410c1).
Report is 7 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #10684      +/-   ##
==========================================
+ Coverage   91.79%   91.81%   +0.01%     
==========================================
  Files         426      426              
  Lines       13389    13406      +17     
  Branches     2577     2579       +2     
==========================================
+ Hits        12291    12309      +18     
  Misses        527      527              
+ Partials      571      570       -1     

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

@henon henon marked this pull request as ready for review January 22, 2025 10:13
<MudTreeViewItem
Value="@context.Value"
Items="@context.Children"
ItemsChanged="@(new Action<IReadOnlyCollection<TreeItemData<string>>>(items => OnItemsLoaded(context, items)))"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@ScarletKuro I do not understand why I must wrap the lambda in an Action<> here in order to get it to compile. Do you?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

By the way, this is kind of a two-way binding from List<> to IReadOnlyCollection<>, that's why it is not possible to do @bind-Items. Guess it was a mistake to make TreeItemData.Children of type List.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

By the way, this is kind of a two-way binding from List<> to IReadOnlyCollection<>, that's why it is not possible to do @bind-Items. Guess it was a mistake to make TreeItemData.Children of type List.

We probably can queue this change for v9.

@sonarqubecloud
Copy link
Copy Markdown

@henon henon requested a review from ScarletKuro January 22, 2025 13:20
@henon
Copy link
Copy Markdown
Contributor Author

henon commented Jan 22, 2025

@Taylan2020 Please share your opinion on the modified server loading example:

@using System.Collections.ObjectModel

<MudPaper Width="300px" Elevation="0">
    <MudTreeView ServerData="@LoadServerData" Items="@InitialTreeItems">
        <ItemTemplate>
            <MudTreeViewItem 
                Value="@context.Value" 
                Items="@context.Children" 
                ItemsChanged="@(new Action<IReadOnlyCollection<TreeItemData<string>>>(items => OnItemsLoaded(context, items)))" 
                @bind-Expanded="@context.Expanded"
                CanExpand="@context.Expandable"
                Icon="@context.Icon" 
                LoadingIconColor="Color.Info" 
                />
        </ItemTemplate>
    </MudTreeView>
</MudPaper>
@code {

    private List<TreeItemData<string>> InitialTreeItems { get; set; } = new();
    private int _idCounter=1; // <- the counter makes sure the generated items are unique

    protected override void OnInitialized()
    {
        // MudTreeView initially only gets these top-level items
        InitialTreeItems.Add(new TreeItemData<string> {
            Value = "All Mail", Icon = Icons.Material.Filled.Label,
            Expanded = true,
            Children = [
                new TreeItemData<string> { Value = "Promotions", Icon = Icons.Material.Filled.Group, },
                new TreeItemData<string> { Value = "Updates", Icon = Icons.Material.Filled.Info, },
                new TreeItemData<string> { Value = "Forums", Icon = Icons.Material.Filled.QuestionAnswer, Expandable = false },
                new TreeItemData<string> { Value = "Social", Icon = Icons.Material.Filled.LocalOffer, Expandable = false }
            ] });
        InitialTreeItems.Add(new TreeItemData<string> { Value = "Trash", Icon = Icons.Material.Filled.Delete });
    }

    public async Task<IReadOnlyCollection<TreeItemData<string>>> LoadServerData(string parentValue)
    {
        // wait 500ms to simulate a server load
        await Task.Delay(500);
        // normally you would use the parentValue to query your server for the children of the given parent
        // but for the sake of this example we will just return some hardcoded children
        return [
            new TreeItemData<string> { Value = $"More Spam ({_idCounter++})", Icon = Icons.Material.Filled.Group, },
            new TreeItemData<string> { Value = $"L.E.D Door Mats ({_idCounter++})", Icon = Icons.Material.Outlined.Lightbulb, Expandable = false },
            new TreeItemData<string> { Value = $"Car Beauty Salon ({_idCounter++})", Icon = Icons.Material.Filled.CarRepair, Expandable = false },
            new TreeItemData<string> { Value = $"Fakedoors.com ({_idCounter++})", Icon = Icons.Material.Outlined.DoorFront, Expandable = false },
            new TreeItemData<string> { Value = $"Bluetooth Toilet ({_idCounter++})", Icon = Icons.Material.Filled.Wc, Expandable = false }
        ];        
    }

    private void OnItemsLoaded(TreeItemData<string> treeItemData, IReadOnlyCollection<TreeItemData<string>> children)
    {
        // here we store the server-loaded children in the treeItemData so that they are available in the InitialTreeItems
        // if you don't do this you loose already loaded children on next render update
        treeItemData.Children = children?.ToList();
    }

}

Copy link
Copy Markdown
Member

@ScarletKuro ScarletKuro left a comment

Choose a reason for hiding this comment

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

LGTM. Feel free to merge whenever.

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

Labels

bug Unexpected behavior or functionality not working as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MudTreeView: Using ServerData and Items at the same time not possible

2 participants