Activities of "Spospisil"

Hi,

Ok, I've implemented the changes in your last commit and that has resolved the issue I'm having with the stylesheets loading multiple times as well as the user menu not being clickable. I appreciate your help in resolving this issue.

Curious though if with abp9+ there is a better way of implementing custom layouts on a page by page basis while utilizing all the underlying leptonx components, etc. We have purchased the full source code and I see abp developer comments indicating that there should be a better way of doing this in the future.

Thanks again.

checking it now, but any resolution to the js function that does not exist in 7.3.0-rc.3?

Hi,

You have not address the issue with the stylesheets loading multiple times as stated in bullet point #1 in my previous response. Additionally when I apply these fixes to my actual project which is based on ABP 7.3.0-rc.3 I get the following error when my blazor app launches.

Hi,

So the sample has been updated completely now it Git to show you the problems I'm having.

  1. The CSS styles are loading multiple times as you navigate from Sample1, 2 and 3.
  2. On the Sample3 page (the one that uses ABP's SideMenuLayout component), the user menu in the upper right corner of the page does not work.

Thanks.

I've updated the solution in git for you

Hi,

For starters change the .RequiredPermissions on sample1, sample2 and sample3 in the menu contribution to host

        context.Menu.AddItem(
            new ApplicationMenuItem(
                "Sample1",
                "Sample1",
                "/Sample1",
                icon: "fa fa-chart-line",
                order: 3
            ).RequirePermissions(ABPSamplePermissions.Dashboard.Host)
        );

        context.Menu.AddItem(
            new ApplicationMenuItem(
                "Sample2",
                "Sample2",
                "/Sample2",
                icon: "fa fa-chart-line",
                order: 4
            ).RequirePermissions(ABPSamplePermissions.Dashboard.Host)
        );

        context.Menu.AddItem(
            new ApplicationMenuItem(
                "Sample3",
                "Sample3",
                "/Sample3",
                icon: "fa fa-chart-line",
                order: 5
            ).RequirePermissions(ABPSamplePermissions.Dashboard.Host)
        );

and then start gong to them. you'll see the css stylesheet files bein loaded several times.

Any update?

Hi,

I have created a private repo on github for you to view, however currently it's not working/running as typically a generated solution using abp tools does not work without coding changes. I have made my specific changes to demostrate the issue but can't really go any further with it until you tell me why I can run this solution that was produced by abp studio.

You should have received an invite to the repo.

Any update on this?

  • ABP Framework version: v7.3.0
  • UI Type: Blazor WASM
  • Database System: EF Core (PostgreSQL)
  • Tiered (for MVC) or Auth Server Separated (for Angular): yes

I had previously created a ticket on loading a pages layout dynamically which is now working for me, however when set the layout to the default 'SideMenuLayout' the user menu in the upper right does not seem to be able to be clicked on. I have experimented with overriding the OnAferRenderAsync of the SideMenuLayout class and when invoke 'initleptonX' and 'AfterLeptonXInitialization' functions every time that seems to fix the click issue, but then it causes the stylesheets to load multiple times.

I have 3 different layouts that I switch between (see DynamicLayoutPicker.razor.cs), so I have the same OnAfterRenderAsync method on my other two layouts defined the same way I have the SideMenuLayout.cs

Any idea how I can resolve this?

DynamicLayoutPicker.razor

@inherits LayoutComponentBase

<LayoutView Layout="@CurrentLayout">
    @Body
</LayoutView>

DynamicLayoutPicker.razor.cs

using CFDataSystems.StructureCloud.Blazor.Themes.LeptonX.Layouts.TenantLayout;
using CFDataSystems.StructureCloud.Components.Layouts;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using System.Threading.Tasks;
using System;
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout;

namespace CFDataSystems.StructureCloud.Blazor.Themes.LeptonX.Layouts;

public partial class DynamicLayoutPicker : LayoutComponentBase, IDisposable
{
    [Inject] private NavigationManager _navManager { get; set; }
    public Type CurrentLayout { get; set; } = typeof(SideMenuLayout);

    protected override Task OnInitializedAsync()
    {
        _navManager.LocationChanged += OnLocationChanged;
        SetLayout(_navManager.Uri);
        return base.OnInitializedAsync();
    }

    public void Dispose()
    {
        _navManager.LocationChanged -= OnLocationChanged;
    }

    private void OnLocationChanged(object sender, LocationChangedEventArgs e)
    {
        SetLayout(e.Location);
    }

    private void SetLayout(string location)
    {
        if (location.Contains("tenant-procedure-list"))
        {
            CurrentLayout = typeof(ProceduresPageLayout);
       }
        else if (location.Contains("SampleTenantDefault"))
        {
            CurrentLayout = typeof(TenantDefaultLayout);
        }
        else
        {
            CurrentLayout = typeof(SideMenuLayout);
        }

        StateHasChanged();
    }
}

ToolbarContributor.cs

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Threading.Tasks;
using System;
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme;
using Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars;
using SideMenuUserMenu = Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXTheme.Components.ApplicationLayout.SideMenu.MainHeader.MainHeaderToolbarUserMenu;
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout;
using CFDataSystems.StructureCloud.Blazor.Themes.LeptonX.Layouts;

namespace CFDataSystems.StructureCloud.Blazor.Toolbars;


public class StructureToolbarContributor : IToolbarContributor
{
    public Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
    {
        if (context.Toolbar.Name == StandardToolbars.Main)
        {
            var options = context.ServiceProvider.GetRequiredService<IOptions<LeptonXThemeBlazorOptions>>().Value;

            if (options.Layout == typeof(DynamicLayoutPicker))
            {
                context.Toolbar.Items.Add(new ToolbarItem(typeof(SideMenuUserMenu)));
            }

        }
        return Task.CompletedTask;
    }
}

Abp Module Setting Toolbar options

        Configure<AbpToolbarOptions>(options =>
        {
            //Add the standard toolbar contributors as we are using the leptonX theme
            options.Contributors.Add(new LeptonXThemeToolbarContributor());

            //Add our own toolbar contributor as we are using the DynamicLayoutPicker component to dynamically change the layout
            //based on specific changes and we need to explicitly add the TopMenuUserMenu component to the toolbar.items collection since
            //the base LeptonX theme toolbar contributor does not factor in out custom layout.
            var layoutOptions = context.Services.GetRequiredService<IOptions<LeptonXThemeBlazorOptions>>().Value;
            if (layoutOptions.Layout == typeof(DynamicLayoutPicker))
            {
                options.Contributors.Add(new StructureToolbarContributor());
            }   
            //This is going to be used to receiving the messages coming from cobol to fire off popup's etc coming from
            //the Acu2Web pages
            //options.Contributors.Add(new MessageToolBarContributor());
        });
        

    private void ConfigureTheme()
    {
        Configure<LeptonXThemeBlazorOptions>(options =>
        {
            //options.Layout = LeptonXBlazorLayouts.SideMenu;
            options.Layout = typeof(DynamicLayoutPicker);
        });

        //https://abp.io/docs/latest/ui-themes/lepton-x/blazor?UI=Blazor#customization
        Configure<LeptonXThemeOptions>(options =>
        {
            options.Styles.Add("structurecloud",
                    new LeptonXThemeStyle(
                    LocalizableString.Create<StructureCloudResource>("Theme:StructueCloud"),
            "bi bi-circle-fill"));

            options.Styles.Remove(LeptonXStyleNames.System);
            options.Styles.Remove(LeptonXStyleNames.Light);
            options.Styles.Remove(LeptonXStyleNames.Dark);
            options.Styles.Remove(LeptonXStyleNames.Dim);


            options.DefaultStyle = "structurecloud";

        });
    }

SideMenuLayoutOverride.cs (I seem to have to do this to prevent the css stylesheets from loading muliple times)

using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Options;
using Microsoft.JSInterop;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout;
using Volo.Abp.DependencyInjection;
using Volo.Abp.LeptonX.Shared;

namespace CFDataSystems.StructureCloud.Blazor.Themes.LeptonX.Layouts.TenantLayout;

[ExposeServices(typeof(SideMenuLayout))]
[Dependency(ReplaceServices = true)]
public partial class SideMenuLayoutOverride : SideMenuLayout
{

    [Inject]
    IJSRuntime JSRuntime { get; set; }


    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        var bExists = await UtilsService.HasClassOnTagAsync("body", "lpx-theme-" + Options.Value.DefaultStyle);

        if (!bExists)
        {
            await UtilsService.AddClassToTagAsync("body", GetBodyClassName());
            await JSRuntime.InvokeVoidAsync("initLeptonX", new[] { "side-menu", Options.Value.DefaultStyle });
            await JSRuntime.InvokeVoidAsync("afterLeptonXInitialization", new[] { "side-menu", Options.Value.DefaultStyle });
        }
    }

    private string GetBodyClassName()
    {
        return "lpx-theme-" + Options.Value.DefaultStyle;
    }
}

Showing 1 to 10 of 302 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
Do you need assistance from an ABP expert?
Schedule a Meeting
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v9.3.0-preview. Updated on April 16, 2025, 12:13