Open Closed

Best Practice for Overriding LeptonTheme Components #2155


User avatar
0
z2lai created
  • ABP Framework version: v4.4.2
  • UI type: Blazor Server
  • DB provider: EF Core

I'm trying to override the MainHeader component in LeptonTheme to add conditional logic for rendering the MainSidebar and I'm looking for the best approach to use.

One approach I've tried is downloading the LeptonTheme module source code, customizing it and including it in my solution. However, we don't want to use this approach as we use are using a private NuGet feed and the cycle for customizing UI, packaging, deploying and verifying it in our application is too long.

The second approach I'm trying is overriding the MainHeader Razor component and its code-behind file using this documentation: https://docs.abp.io/en/abp/latest/UI/Blazor/Customization-Overriding-Components#example-replacing-with-the-code-behind-file. I've copied the code from the LeptonTheme MainHeader Razor compoonent and code-behind file into a MyMainHeader component in my application and added the isSidebarNavRendered flag (set within OnLocationChanged method) to conditionally render the sidebar in the Razor component. Is this the right way to override the LeptonTheme components or is there a better way?

Below is the file structure within my Blazor project and the code-behind file for my custom MyMainHeader component:

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components.ApplicationLayout.Navigation;
using Volo.Abp.LeptonTheme.Management;
using Volo.Abp.AspNetCore.Components.Web.LeptonTheme.Components.ApplicationLayout.MainHeader;
using Volo.Abp.DependencyInjection;

namespace MyOrg.MyApp.Blazor.Components.ApplicationLayout.MyMainHeader
{
    [ExposeServices(typeof(MainHeader))]
    [Dependency(ReplaceServices = true)]
    public partial class MyMainHeader
    {
        //public bool IsToolbarNavShown { get; set; }
        //public bool IsSidebarNavShown { get; set; }
        public bool isSidebarNavRendered { get; set; }

        [Inject]
        private NavigationManager NavigationManager { get; set; }

        //[Inject]
        //protected MainMenuProvider MainMenuProvider { get; set; }

        [Inject]
        private IAbpUtilsService UtilsService { get; set; }

        //protected MenuViewModel Menu { get; set; }

        protected override async Task OnInitializedAsync()
        {
            Menu = await MainMenuProvider.GetMenuAsync();
            await SetBodyClassesAsync();
            Menu.StateChanged += RefreshMenu;
            NavigationManager.LocationChanged += OnLocationChanged;
        }

        private void OnLocationChanged(object sender, LocationChangedEventArgs e)
        {
            Console.WriteLine(NavigationManager.Uri);
            if (NavigationManager.Uri == "https://localhost:44313/" || NavigationManager.Uri == "https://localhost:44313/Account/SecurityLogs")
            {
                Console.WriteLine("Hide Sidebar!!!");
                isSidebarNavRendered = false;
            }
            else
            {
                Console.WriteLine("Show Sidebar!!!");
                isSidebarNavRendered = true;
            }
            IsSidebarNavShown = false;
        }

        private void ToggleToolbarNav()
        {
            IsToolbarNavShown = !IsToolbarNavShown;
        }

        private void ToggleSidebarNav()
        {
            IsSidebarNavShown = !IsSidebarNavShown;
        }

        private async Task SetBodyClassesAsync()
        {
            //TODO: Does setting body classes so frequently effects performance?
            if (Menu.Placement == MenuPlacement.Top)
            {
                await UtilsService.AddClassToTagAsync("body", "lp-topmenu");
            }
            else if (isSidebarNavRendered)
            {
                if (Menu.NavBarStatus == MenuStatus.OpenOnHover)
                {
                    await UtilsService.AddClassToTagAsync("body", "lp-closed");
                    await UtilsService.RemoveClassFromTagAsync("body", "lp-opened-sidebar");
                    await UtilsService.RemoveClassFromTagAsync("body", "lp-body-fixed");
                }
                else
                {
                    await UtilsService.RemoveClassFromTagAsync("body", "lp-closed");
                    await UtilsService.AddClassToTagAsync("body", "lp-opened-sidebar");
                    await UtilsService.AddClassToTagAsync("body", "lp-body-fixed");
                }
            }
        }

        //public void Dispose()
        //{
        //    Menu.StateChanged -= RefreshMenu;
        //    NavigationManager.LocationChanged -= OnLocationChanged;
        //}

        private async Task ToggleNavbarStatusAsync()
        {
            Menu.ToggleNavbarStatus();
            await SetBodyClassesAsync();
        }

        private async Task OnNavBarMouseOverAsync()
        {
            //TODO: MOUSEOVER IS NOT PERFORMANT, WE SHOULD USE MOUSEENTER/MOUSELEAVE

            if (Menu.NavBarStatus == MenuStatus.OpenOnHover)
            {
                if (await UtilsService.HasClassOnTagAsync("body", "lp-closed"))
                {
                    await UtilsService.AddClassToTagAsync("body", "lp-extended");
                }
            }
        }

        private async Task OnNavbarMouseOutAsync()
        {
            if (Menu.NavBarStatus == MenuStatus.OpenOnHover)
            {
                if (await UtilsService.HasClassOnTagAsync("body", "lp-closed"))
                {
                    await UtilsService.RemoveClassFromTagAsync("body", "lp-extended");
                }
            }
        }

        private void RefreshMenu(object sender, EventArgs e)
        {
            InvokeAsync(StateHasChanged);
        }
    }
}

The other thing is that the OnLocationChanged method seems to only be called when going to the home page, but not when going to any other page.


2 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    The second way is the best.

    The other thing is that the OnLocationChanged method seems to only be called when going to the home page, but not when going to any other page.

    Sorry , I didn't get it.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Reopen if still question.

Made with ❤️ on ABP v9.1.0-preview. Updated on December 12, 2024, 07:15