Käyttäjän "berkansasmaz" toiminnot

Hello, first of all, thank you very much for the information you have provided. I have conveyed to my related teammates how they can reproduce the problem.


Thank you again for your understanding.

Hello again, you stated that you encountered the following error while customizing:

I've got it partially working but have run into some issues due to the javascript for the general settings menu. I don't have much insight into what's happening under the hood, but I'm getting an exception which prevents the user menu from loading.

Uncaught TypeError: Cannot read properties of null (reading 'parentElement')
    at t.initChildren (lepton-x.bundle.min.js?_v=638261408440000000:2:43721)
    at new t (lepton-x.bundle.min.js?_v=638261408440000000:2:41474)
    at t.create (lepton-x.bundle.min.js?_v=638261408440000000:2:41563)
    at t.createSettingGroupWithMenu (lepton-x.bundle.min.js?_v=638261408440000000:2:86551)
    at e [as constructor] (lepton-x.bundle.min.js?_v=638261408440000000:2:68837)
    at new e (lepton-x.bundle.min.js?_v=638261408440000000:2:71613)
    at e.create (lepton-x.bundle.min.js?_v=638261408440000000:2:71708)
    at t.createSettingGroups (lepton-x.bundle.min.js?_v=638261408440000000:2:73132)
    at t.create (lepton-x.bundle.min.js?_v=638261408440000000:2:72833)
    at NodeList.forEach ()

We have intuitive guesses as to where this error might be, but we want to reproduce the error just to be sure. Could you please tell us the steps by which we can reproduce the error?

As an alternative, I thought it would be possible to move the appearance and language menus to the top toolbar like this:

Hello, I have examined your problem in detail, the alternative solution looks good, but I am sorry for the error you have received. We are already aware of the problem and will work to solve it in future versions.

To briefly talk about the problem, LeptonX traverses the DOM elements in order while it is initializing, and if it cannot find an element it expects while it is traversing, it gives an error. So, you may have removed an element in the existing structure, for example, removing General Settings menu will cause this error. Likewise, removing Appearance under General Settings menu or changing its order will cause an error. If you are removing an element from the DOM, instead of removing it, I can recommend you set the visible property to hidden in the style as a workaround for now.

Hello, sorry for the late reply.

I will create an internal issue on the subject.

I can suggest the following code as a workaround. It's not a workaround that will meet all your needs, but it still works:

1-) Create menu.js in wwwroot folder as follow:

$(function () {
    // Function to toggle the settings menu visibility
    function toggleSettingsMenu() {
        const settingsMenu = document.querySelector('[data-lpx-context-menu="settings-context-menu"]');
        settingsMenu.classList.toggle('show');
    }

    // Function to handle keyboard events on the settings menu item
    function handleSettingsMenuItemKeydown(event) {
        if (event.key === 'Enter') {
            event.preventDefault(); // Prevent default action for "Enter" key
            toggleSettingsMenu(); // Toggle the settings menu visibility
        }
    }

    // Function to add keyboard accessibility to the settings menu
    function addKeyboardAccessibilityToSettingsMenu() {
        const settingsMenuItem = document.getElementById('lpx-settings');
        settingsMenuItem.setAttribute('tabindex', '0');
        settingsMenuItem.addEventListener('keydown', handleSettingsMenuItemKeydown);
        settingsMenuItem.addEventListener('blur', () => {
            const settingsMenu = document.querySelector('[data-lpx-context-menu="settings-context-menu"]');
            settingsMenu.classList.remove('show');
        }); // Close the settings menu when focus is lost

        const settingIcons = document.querySelectorAll('.setting-icon');
        settingIcons.forEach(item => {
            item.setAttribute('tabindex', '0');
            item.addEventListener('keydown', handleSubMenuItemKeydown);
        });
    }

    addKeyboardAccessibilityToSettingsMenu();

    function handleMenuItemKeydown(event) {
        if (event.key === 'Enter') {
            event.preventDefault(); // Prevent default action for "Enter" key
            // Toggle the sub-menu visibility
            const subMenu = event.currentTarget.querySelector('.lpx-inner-menu');
            if (subMenu) {
                subMenu.classList.toggle('show');
                if (subMenu.classList.contains('show')) {
                    const subMenuItems = subMenu.querySelectorAll('.lpx-menu-item-link');
                    subMenuItems.forEach(item => item.setAttribute('tabindex', '0'));
                } else {
                    const subMenuItems = subMenu.querySelectorAll('.lpx-menu-item-link');
                    subMenuItems.forEach(item => item.removeAttribute('tabindex'));
                }
            }
        } else if (event.key === 'ArrowDown') {
            event.preventDefault(); // Prevent default action for "ArrowDown" key
            // Focus on the next menu item
            const nextMenuItem = event.currentTarget.nextElementSibling;
            if (nextMenuItem) {
                nextMenuItem.querySelector('.lpx-menu-item-link').focus();
            }
        } else if (event.key === 'ArrowUp') {
            event.preventDefault(); // Prevent default action for "ArrowUp" key
            // Focus on the previous menu item
            const prevMenuItem = event.currentTarget.previousElementSibling;
            if (prevMenuItem) {
                prevMenuItem.querySelector('.lpx-menu-item-link').focus();
            }
        }
    }

    // Function to handle keyboard events on sub-menu items
    function handleSubMenuItemKeydown(event) {
        if (event.key === 'Enter') {
            event.preventDefault(); // Prevent default action for "Enter" key
            // Perform the desired action for the sub-menu item (you can open sub-menus here)
            const linkElement = event.target.closest('.lpx-menu-item-link');
            if (linkElement) {
                window.location.href = linkElement.getAttribute('href');
            }
        } else if (event.key === 'ArrowDown') {
            event.preventDefault(); // Prevent default action for "ArrowDown" key
            // Focus on the next sub-menu item
            const nextSubMenuItem = event.currentTarget.nextElementSibling;
            if (nextSubMenuItem) {
                nextSubMenuItem.querySelector('.lpx-menu-item-link').focus();
            }
        } else if (event.key === 'ArrowUp') {
            event.preventDefault(); // Prevent default action for "ArrowUp" key
            // Focus on the previous sub-menu item
            const prevSubMenuItem = event.currentTarget.previousElementSibling;
            if (prevSubMenuItem) {
                prevSubMenuItem.querySelector('.lpx-menu-item-link').focus();
            }
        }
    }

    // Function to add keyboard accessibility to the menu
    function addKeyboardAccessibilityToMenu() {
        const menuItems = document.querySelectorAll('.lpx-menu-item');
        menuItems.forEach(item => {
            item.setAttribute('tabindex', '0');
            item.addEventListener('keydown', handleMenuItemKeydown);
        });

        const subMenuItems = document.querySelectorAll('.lpx-inner-menu-item');
        subMenuItems.forEach(item => {
            item.setAttribute('tabindex', '-1');
            item.addEventListener('keydown', handleSubMenuItemKeydown);
        });
    }

    // Call the function to enable keyboard accessibility for the menu
    addKeyboardAccessibilityToMenu();
});

2-) Configure AbpBundlingOptions in the module class of your web project as follow:


      Configure<AbpBundlingOptions>(options =>
        {
            options.StyleBundles.Configure(
                LeptonXThemeBundles.Styles.Global,
                bundle =>
                {
                    ...
                }
            );

            options.ScriptBundles.Configure(
                LeptonXThemeBundles.Styles.Global,
                bundle =>
                {
                    ...
                    bundle.AddFiles("/menu.js");
                    ...
                });
        });

Hello, @enis and I have done a lot of research to be able to recommend you a workaround, but unfortunately, we could not find a suitable workaround. In order not to encounter similar problems in future versions, we have made the relevant parts of LeptonX overridable. The issue was resolved in version 7.2.* and with 7.4.* we will make it possible to override it if desired, but unfortunately, this is not possible in version 6.0.1.

Sorry for the late reply.

This problem has already been solved in version 7.2.*. You can upgrade your application.

You are welcome :)

Instead of getting the XSRF-TOKEN from the cookie, you can get it as follows?

AntiForgeryManager.GenerateToken()

Full code example:

@page "/Upload"
@using Volo.Abp.AspNetCore.Mvc.AntiForgery
@inject NavigationManager NavigationManager
@inject IAbpAntiForgeryManager AntiForgeryManager // added
<div id="overviewDemoDropZone" class="card custom-drop-zone bg-light rounded-3 w-100 m-0">
    <span class="drop-file-icon mb-3"></span>
    <span>Drag and Drop File Here</span><span class="m-1">or</span>
    <button id="overviewDemoSelectButton" class="btn border-primary btn-primary m-1">Select File</button>
</div>
<DxUpload Name="myFile"
          Visible="@UploadVisible"
          ExternalSelectButtonCssSelector="#overviewDemoSelectButton"
          ExternalDropZoneCssSelector="#overviewDemoDropZone"
          ExternalDropZoneDragOverCssClass="bg-light border-secondary text-dark"
          MaxFileSize="15000000"
          UploadUrl="@GetUploadUrl("api/Upload/Upload/")"
          SelectedFilesChanged="@SelectedFilesChanged"
          FileUploadStart="FileUploadStart"
          CssClass="w-100">
    

</DxUpload>

@code {
    bool UploadVisible { get; set; } = false;

    protected void SelectedFilesChanged(IEnumerable<UploadFileInfo> files) {
        UploadVisible = files.ToList().Count > 0;
        InvokeAsync(StateHasChanged);
    }
    protected string GetUploadUrl(string url) {
        return NavigationManager.ToAbsoluteUri(url).AbsoluteUri;
    }
    
    protected void FileUploadStart(FileUploadStartEventArgs args) {
        args.RequestHeaders.Add("RequestVerificationToken", AntiForgeryManager.GenerateToken()); // changed
    }
}

Yes, I can reproduce the problem. I am opening an internal issue for this.

2023-06-02 09:35:45.969 +03:00 [ERR] An unhandled exception has occurred while executing the request.
System.NullReferenceException: Object reference not set to an instance of an object.
   at Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Themes.LeptonX.Components.SideMenu.Toolbar.LanguageSwitch.ThemeLanguageInfoProvider.GetLanguageSwitchViewComponentModel()
   at Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Themes.LeptonX.Components.Common.MobileGeneralSettings.MobileGeneralSettingsViewComponent.InvokeAsync()
   at Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentInvoker.InvokeAsyncCore(ObjectMethodExecutor executor, Object component, ViewComponentContext context)
   at Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentInvoker.InvokeAsync(ViewComponentContext context)
   at Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentInvoker.InvokeAsync(ViewComponentContext context)
   at Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentHelper.InvokeCoreAsync(ViewComponentDescriptor descriptor, Object arguments)
   at Volo.Abp.AspNetCore.Mvc.UI.Widgets.AbpViewComponentHelper.InvokeAsync(Type componentType, Object arguments)
   at AYVEhCp6iK4h4mmxeYR.Oi2jqVpmF6RLaW8Jp6X.ExecuteAsync()
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
   at Microsoft.AspNetCore.Mvc.ViewComponents.ViewViewComponentResult.ExecuteAsync(ViewComponentContext context)
   at Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentInvoker.InvokeAsync(ViewComponentContext context)
   at Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentHelper.InvokeCoreAsync(ViewComponentDescriptor descriptor, Object arguments)
   at Volo.Abp.AspNetCore.Mvc.UI.Widgets.AbpViewComponentHelper.InvokeAsync(Type componentType, Object arguments)
   at ERWIIxOFYGRoT95Rbss.n2uEpTO8cMNabKx1lh2.<>c__DisplayClass19_0.LOH71gICjA7wiGBOaY3.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync()
   at ERWIIxOFYGRoT95Rbss.n2uEpTO8cMNabKx1lh2.ExecuteAsync()
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderLayoutAsync(ViewContext context, ViewBufferTextWriter bodyWriter)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultFilters>g__Awaited|28_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Volo.Abp.AspNetCore.Serilog.AbpSerilogMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at Volo.Abp.AspNetCore.Auditing.AbpAuditingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Volo.Abp.AspNetCore.Auditing.AbpAuditingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Volo.Abp.AspNetCore.Uow.AbpUnitOfWorkMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Builder.ApplicationBuilderAbpOpenIddictMiddlewareExtension.<>c__DisplayClass0_0.<<UseAbpOpenIddictValidation>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Volo.Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at Volo.Abp.AspNetCore.Tracing.AbpCorrelationIdMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

The problem will be solved as soon as possible.

Do you need a workaround?

I will test your problem more but before that I have a small request.

If you haven't tried to get the Antiforgery token as follows, do you have a chance to try it?

@(Html.DevExtreme().FileUploader()  
    .OnInitialized("OnInitialized")  
...  
function OnInitialized(s, e) {  
    var _createFormData = s.component._uploadStrategy._createFormData;  
    s.component._uploadStrategy._createFormData = (fieldName, fieldValue) => {  
        var formData = _createFormData.call(this, fieldName, fieldValue);  
        formData.append('__RequestVerificationToken', document.getElementsByName("__RequestVerificationToken")[0].value);  
        return formData;  
    }  
}  

The codes I suggest are excerpts from here, so if you need more information on this, you can check it out here.

The reason I want you to try this is because I think you might have a similar situation with someone who is experiencing the same problem as you in different ways.

Please let me know the result :)

Näytetään 21 - 30/318 tietueesta
Made with ❤️ on ABP v8.2.0-preview Updated on maaliskuuta 25, 2024, 15.11