Activities of "enisn"

Yeah sure,

You can use following files to override:

  • /Pages/Identity/Users/EditModal.cshtml
@page
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@using Volo.Abp.Data
@using Volo.Abp.Identity.Localization
@using Volo.Abp.Identity.Web.Pages.Identity.Users
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@model EditModalModel
@inject IHtmlLocalizer<IdentityResource> L
@inject IStringLocalizerFactory StringLocalizerFactory
@{
    Layout = null;
}
<form method="post" asp-page="/Identity/Users/EditModal">
    <abp-modal>
        <abp-modal-header title="@L["Edit"].Value"></abp-modal-header>
        <abp-modal-body>
            <abp-tabs name="create-user-modal-tabs">
                <abp-tab title="@L["UserInformation"].Value">
                    <input asp-for="UserInfo.Id" />
                    <input asp-for="UserInfo.ConcurrencyStamp" />
                    <abp-input asp-for="UserInfo.UserName" />
                    <abp-input asp-for="UserInfo.Name" />
                    <abp-input asp-for="UserInfo.Surname" />
                    <abp-input asp-for="UserInfo.Email" label="@(L["EmailAddress"].Value + " * ")" />
                    @foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<EditModalModel.UserInfoViewModel>())
                    {
                        if (!propertyInfo.Name.EndsWith("_Text"))
                        {
                            if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
                            {
                                if (propertyInfo.Type.IsEnum)
                                {
                                    Model.UserInfo.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
                                }
                                <abp-select asp-for="UserInfo.ExtraProperties[propertyInfo.Name]"
                                            label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
                                            autocomplete-api-url="@propertyInfo.Lookup.Url"
                                            autocomplete-selected-item-name="@Model.UserInfo.GetProperty(propertyInfo.Name+"_Text")"
                                            autocomplete-selected-item-value="@Model.UserInfo.GetProperty(propertyInfo.Name)"
                                            autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
                                            autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
                                            autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
                                            autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"></abp-select>
                            }
                            else
                            {
                                <abp-input type="@propertyInfo.GetInputType()"
                                           asp-for="UserInfo.ExtraProperties[propertyInfo.Name]"
                                           label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
                                           asp-format="@propertyInfo.GetInputFormatOrNull()"
                                           value="@propertyInfo.GetInputValueOrNull(Model.UserInfo.GetProperty(propertyInfo.Name))" />
                            }
                        }
                    }
                    <abp-input asp-for="UserInfo.PhoneNumber" />
                    <abp-input asp-for="UserInfo.IsActive" />
                    <abp-input asp-for="UserInfo.LockoutEnabled" />
                </abp-tab>
                @if (Model.Roles.Any())
                {
                    <abp-tab name="Roles" title="@L.GetString("Roles{0}", Model.Roles.Count(r => r.IsAssigned))">
                        @for (var i = 0; i < Model.Roles.Length; i++)
                        {
                            var role = Model.Roles[i];
                            <abp-input asp-for="@role.IsAssigned"
                                       abp-id-name="@Model.Roles[i].IsAssigned"
                                       label="@role.GetShownName(HtmlEncoder, L.GetString("OU"))"
                                       disabled="@role.IsInheritedFromOu" />
                            <input asp-for="@role.Name" abp-id-name="@Model.Roles[i].Name" />
                        }
                    </abp-tab>
                }

                @if (Model.OrganizationUnits.Any())
                {
                    <abp-tab name="OrganizationUnits" title="@L.GetString("OrganizationUnits{0}", Model.OrganizationUnits.Count(r => r.IsAssigned))">

                        <div id="JsTreeCheckable" class="tree jstree jstree-2 jstree-default jstree-checkbox-no-clicked jstree-checkbox-selection" role="tree" aria-multiselectable="true" tabindex="0" aria-activedescendant="j2_1" aria-busy="false" aria-selected="false">
                            <ul class="jstree-container-ul jstree-children" role="group">
                                @for (int i = 0; i < Model.OrganizationUnitTreeRootNode.Children.Count; i++)
                                {
                                    @await Html.PartialAsync("OrganizationUnitTreeNode", new OrganizationUnitTreeNodeModel
                                    {
                                        Depth = 0,
                                        Node = Model.OrganizationUnitTreeRootNode.Children[i],
                                        OrganizationUnits = Model.OrganizationUnits
                                    })
                                }
                            </ul>
                        </div>
                        @for (var i = 0; i < Model.OrganizationUnits.Length; i++)
                        {
                            var organizationUnits = Model.OrganizationUnits[i];
                            <input asp-for="@organizationUnits.IsAssigned" abp-id-name="@Model.OrganizationUnits[i].IsAssigned" />
                            <input asp-for="@organizationUnits.DisplayName" abp-id-name="@Model.OrganizationUnits[i].DisplayName" />
                            <input asp-for="@organizationUnits.Id" abp-id-name="@Model.OrganizationUnits[i].Id" />
                        }
                    </abp-tab>
                }
            </abp-tabs>
        </abp-modal-body>
        <abp-modal-footer buttons="@(AbpModalButtons.Cancel | AbpModalButtons.Save)"></abp-modal-footer>
    </abp-modal>
</form>
<input hidden id="RolesCount" value="@Model.Roles.Count(r => r.IsAssigned)" />

For the models, you can just inherit from IdentityUserModalPageModel, IdentityUserModalPageModel and add your custom logic instead of writing all the model again.


using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.Identity.Web.Pages.Identity.Users;

[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(CreateModalModel))]
public class MyCreateModalModel : CreateModalModel
{
    public MyCreateModalModel(IIdentityUserAppService identityUserAppService) : base(identityUserAppService)
    {
    }

    public override async Task OnGetAsync()
    {
        await base.OnGetAsync(); // Keep base operations.

        // your own logic here
    }

    public override async Task<NoContentResult> OnPostAsync()
    {
        var result = await base.OnPostAsync();

        // your own logic here
		
        return result;
    }
}

We solved that problem and it'll be released in the next version of LeptonX.

You can use the following footer override in your application to fix it until the next release.

  • Create a razor file in your blazor project. Let's say it's MyFooter.razor

  • Content of this file should be as following:

@using Volo.Abp.DependencyInjection
@using Microsoft.Extensions.DependencyInjection
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.TopMenu
@inherits Footer

@attribute [ExposeServices(typeof(Footer))]
@attribute [Dependency(ReplaceServices = true)]

<div class="lpx-footer">
    <div class="d-flex justify-content-between px-4 py-3">
        <div>
            <span>2022©</span>
            <a href="#"> LeptonX Theme</a>
        </div>
        <div>
            <a href="#">About</a>
            <a href="#">Contact</a>
        </div>
    </div>
</div> 

You can override the existing cshtml file of the modal via following this documentation: https://docs.abp.io/en/abp/latest/UI/AspNetCore/Customization-User-Interface#overriding-a-razor-page-cshtml

To achieve that, create a file in this path:

  • /Pages/Identity/Users/CreateModal.cshtml

  • And content of this newly created file should be:

@page
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@using Volo.Abp.Data
@using Volo.Abp.Identity
@using Volo.Abp.Identity.Localization
@using Volo.Abp.Identity.Settings
@using Volo.Abp.Identity.Web.Pages.Identity.Users
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@using Volo.Abp.Settings
@model Volo.Abp.Identity.Web.Pages.Identity.Users.CreateModalModel
@inject ISettingProvider SettingProvider
@inject IHtmlLocalizer<IdentityResource> L
@inject IStringLocalizerFactory StringLocalizerFactory
@{
    Layout = null;
}
<form method="post" asp-page="/Identity/Users/CreateModal">
    <abp-modal>
        <abp-modal-header title="@L["NewUser"].Value"></abp-modal-header>
        <abp-modal-body>
            <abp-tabs name="create-user-modal-tabs">
                <abp-tab title="@L["UserInformations"].Value">
                    <abp-input asp-for="UserInfo.UserName" />
                    <abp-input asp-for="UserInfo.Name" />
                    <abp-input asp-for="UserInfo.Surname" />
                    <div class="mb-3">
                        <label asp-for="UserInfo.Password" class="form-label">@L["Password"] *</label>
                        <div class="input-group">
                            <input type="password" class="form-control" maxlength="@IdentityUserConsts.MaxPasswordLength" asp-for="UserInfo.Password" />
                            <button class="btn btn-secondary" type="button" id="PasswordVisibilityButton"><i class="fa fa-eye-slash" aria-hidden="true"></i></button>
                        </div>
                        <span asp-validation-for="UserInfo.Password"></span>
                    </div>
                    <abp-input asp-for="UserInfo.Email" label="@(L["EmailAddress"].Value + " * ")" />
                    @foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<CreateModalModel.UserInfoViewModel>())
                    {
                        if (!propertyInfo.Name.EndsWith("_Text"))
                        {
                            if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
                            {
                                if (propertyInfo.Type.IsEnum)
                                {
                                    Model.UserInfo.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
                                }
                                <abp-select asp-for="UserInfo.ExtraProperties[propertyInfo.Name]"
                                            label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
                                            autocomplete-api-url="@propertyInfo.Lookup.Url"
                                            autocomplete-selected-item-name="@Model.UserInfo.GetProperty(propertyInfo.Name+"_Text")"
                                            autocomplete-selected-item-value="@Model.UserInfo.GetProperty(propertyInfo.Name)"
                                            autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
                                            autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
                                            autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
                                            autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"></abp-select>
                            }
                            else
                            {
                                <abp-input type="@propertyInfo.GetInputType()"
                                           asp-for="UserInfo.ExtraProperties[propertyInfo.Name]"
                                           label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
                                           asp-format="@propertyInfo.GetInputFormatOrNull()"
                                           value="@propertyInfo.GetInputValueOrNull(Model.UserInfo.GetProperty(propertyInfo.Name))" />
                            }
                        }
                    }
                    <abp-input asp-for="UserInfo.PhoneNumber" />
                    <abp-input asp-for="UserInfo.IsActive" />
                    <abp-input asp-for="UserInfo.LockoutEnabled" />
                    @if (await SettingProvider.IsTrueAsync(IdentitySettingNames.SignIn.RequireConfirmedEmail))
                    {
                        <abp-input asp-for="UserInfo.SendConfirmationEmail" />
                    }
                </abp-tab>
                <abp-tab name="Roles" title="@L.GetString("Roles{0}", Model.Roles.Count(r => r.IsAssigned))">
                    @for (var i = 0; i < Model.Roles.Length; i++)
                    {
                        var role = Model.Roles[i];
                        if (role.IsDefault)
                        {

                            <abp-input asp-for="@role.IsAssigned" abp-id-name="@Model.Roles[i].IsAssigned" label="@HtmlEncoder.Encode(role.Name)" checked="checked" />
                        }
                        else
                        {
                            <abp-input asp-for="@role.IsAssigned" abp-id-name="@Model.Roles[i].IsAssigned" label="@HtmlEncoder.Encode(role.Name)" />
                        }

                        <input asp-for="@role.Name" abp-id-name="@Model.Roles[i].Name" />
                    }
                </abp-tab>
                @if (Model.OrganizationUnits.Any())
                {
                    <abp-tab name="OrganizationUnits" title="@L.GetString("OrganizationUnits{0}", Model.OrganizationUnits.Count(r => r.IsAssigned))">
                        <div id="JsTreeCheckable" class="tree jstree jstree-2 jstree-default jstree-checkbox-no-clicked jstree-checkbox-selection" role="tree" aria-multiselectable="true" tabindex="0" aria-activedescendant="j2_1" aria-busy="false" aria-selected="false">
                            <ul class="jstree-container-ul jstree-children" role="group">
                                @for (int i = 0; i < Model.OrganizationUnitTreeRootNode.Children.Count; i++)
                                {
                                    @await Html.PartialAsync("OrganizationUnitTreeNode", new OrganizationUnitTreeNodeModel
                                    {
                                        Depth = 0,
                                        Node = Model.OrganizationUnitTreeRootNode.Children[i],
                                        OrganizationUnits = Model.OrganizationUnits
                                    })
                                }
                            </ul>
                        </div>
                        @for (var i = 0; i < Model.OrganizationUnits.Length; i++)
                        {
                            var organizationUnits = Model.OrganizationUnits[i];
                            <input asp-for="@organizationUnits.IsAssigned" abp-id-name="@Model.OrganizationUnits[i].IsAssigned" />
                            <input asp-for="@organizationUnits.DisplayName" abp-id-name="@Model.OrganizationUnits[i].DisplayName" />
                            <input asp-for="@organizationUnits.Id" abp-id-name="@Model.OrganizationUnits[i].Id" />
                        }
                    </abp-tab>
                }
                
                <abp-tab name="your-custom-tab" title="Your Custom Tab">
                    YOUR TAB CONTENT HERE 👈
                </abp-tab>
            </abp-tabs>
        </abp-modal-body>
        <abp-modal-footer buttons="@(AbpModalButtons.Cancel | AbpModalButtons.Save)"></abp-modal-footer>
    </abp-modal>
</form>
<input hidden id="RolesCount" value="@Model.Roles.Count(r => r.IsAssigned)" />

Have you checked Tenant-Edition Subscription? Before doing that, you have to configure Payment Configuration properly.

You can use Edition Features to turn on/off tenant features according to the subscription.

Also you can check this out: https://support.abp.io/QA/Questions/3726/Questions-Regarding-Recurring-Stripe-Payment--Retrieval#answer-f874d726-d096-90e6-d993-3a0671092939

Hi christophe.baille

That search feature is written as a plain script in javascript. It shouldn't be dependent on redis. Can you provide Browser Console log if there is an error?

We're still investigating this issue. Since this is a kind of bug, your ticket has been refunded.

The HandleErrorAsync(ex); is only in the BLazor component though. The issue I am having is getting the error from the server and actually getting all the way to the component. It is getting lost somewhere and not making it to the client to be handled by the HandleErrorAsync method.

Global Error handling isn't possible currently for blazor-server: https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/handle-errors?view=aspnetcore-6.0 You have to use try-catch blocks to handle exceptions. Otherwise, the following error view will be displayed and your application execution won't continue.

<div id="blazor-error-ui">
    <environment include="Staging,Production">
        An error has occurred. This application may no longer respond until reloaded.
    </environment>
    <environment include="Development">
        An unhandled exception has occurred. See browser dev tools for details.
    </environment>
    <a href="" class="reload">Reload</a>
    <a class="dismiss">🗙</a>
</div>

Hi We've solved the problem, it'll be released in the next patch version of LeptonX. But you can use the following component in your project to overcome the problem as a workaround.

  • Create a razor page in your blazor application. Let say it's MyMainHeader.razor
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.SideMenu.Navigation
@using Volo.Abp.DependencyInjection;
@using Volo.Abp.LeptonX.Shared.Localization
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.SideMenu.MainHeader

@inherits MainHeader
@attribute [ExposeServices(typeof(MainHeader))]
@attribute [Dependency(ReplaceServices = true)]
@{
	LocalizationResource = typeof(LeptonXResource);
}

<div class="lpx-sidebar-container">
	<div class="lpx-sidebar" id="lpx-sidebar">
		<nav class="lpx-nav">
			<div class="lpx-logo-container">
				<MainHeaderBranding />
				<i class="lpx-icon bi bi-filter-left menu-collapse-icon hidden-in-hover-trigger"
				   aria-hidden="true"
				   data-lpx-toggle="sidebar">
				</i>
			</div>

			<div class="lpx-menu-filter hidden-in-hover-trigger" data-lpx-menu-filter="sidebar">
				<i class="lpx-icon bi bi-filter menu-filter-icon" aria-hidden="true"></i>
				<input class="menu-filter-input hidden-in-hover-trigger" type="text" placeholder="@L["FilterMenu"]" />
				<span class="menu-filter-clear hidden">
					<i class="lpx-icon bi bi-x clear-icon" aria-hidden="true"></i>
				</span>
			</div>
			<ul class="lpx-nav-menu" id="desktop-sidebar">
				<MainMenu />
			</ul>
		</nav>
	</div>
</div>

Then you'll see it'll start to be scrolled

Sorry for your inconvenient experience. We'll update related documentations about it as soon as possible.

Also your credit was refunded.

How did you deploy? Docker, filesystem,..etc?

Make sure you run abp install-libs before building the docker image. Those wwwroot files should be included in the docker image.

Showing 161 to 170 of 496 entries
Made with ❤️ on ABP v9.1.0-preview. Updated on November 11, 2024, 11:11