UI/BuildingPanel.razor
@using Sandbox
@using Sandbox.UI
@using System
@using HC3.UI

@inherits SingletonWindow<BuildingPanel>
@namespace HC3

<root class="column gap">
    <div class="row groups no-shrink">
        <button class="@(CurrentGroup == "Building" ? "selected" : "") square-button" tooltip="Buildings" onclick=@(() => SetGroup("Building"))>
            <img src="textures/hud/ferris_wheel.png" />
        </button>
    </div>

    <div class="row grow">
        <column class="tree">
            @foreach (var group in Items
                        .GroupBy(x => x.Group.SecondaryGroup)
                        .OrderBy(g => g.Key))
            {
                var isSelected = group.Key == CurrentSecondaryGroup;
                <button class="tree-root @(isSelected ? "selected" : "")" onclick=@(() => SetSecondaryGroup(group.Key))>@(group.Key) (@group.Count())</button>
            }
        </column>

        <div class="window-container">
            <div class="items">
                @foreach (var item in CurrentItems.OrderBy(x => x.GetOrder()))
                {
                    <CatalogItemPanel Item=@item />
                }
            </div>
        </div>
    </div>
</root>

@code
{
    public override string Title => $"{CurrentGroup} Catalog";
    public override string Icon => "bug";

    public string CurrentGroup { get; set; } = "Building";

    public string? CurrentSecondaryGroup { get; set; } = null;

    public IEnumerable<IPlacementObject> Items => IPlacementObject.GetAllPrefabs( CurrentGroup )
            .Where( x => x.Group.SecondaryGroup != "Special" );

    public IEnumerable<IPlacementObject> CurrentItems => Items
            .Where( x => string.IsNullOrEmpty( CurrentSecondaryGroup ) || x.Group.SecondaryGroup == CurrentSecondaryGroup );
           

    public void SetGroup(string group)
    {
        CurrentGroup = group;
        CurrentSecondaryGroup = null; // reset sub-group on group switch
        StateHasChanged();
    }

    public void SetSecondaryGroup(string group)
    {
        CurrentSecondaryGroup = group;
        StateHasChanged();
    }

    protected override int BuildHash() => System.HashCode.Combine(base.BuildHash(), BuildingPlacer.Instance?.IsDestroying);

    public override void Tick()
    {
        SetClass("visible", IsVisible);
    }
}