Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tenant modals validation #6035

Merged
merged 3 commits into from
Nov 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
using JetBrains.Annotations;
using Microsoft.Extensions.Localization;

namespace Volo.Abp.Identity.Blazor
namespace Volo.Abp.AspNetCore.Components.WebAssembly
{
public class AbpIdentityBlazorMessageLocalizerHelper<T>
public class AbpBlazorMessageLocalizerHelper<T>
{
private readonly IStringLocalizer<T> stringLocalizer;

public AbpIdentityBlazorMessageLocalizerHelper(IStringLocalizer<T> stringLocalizer)
public AbpBlazorMessageLocalizerHelper(IStringLocalizer<T> stringLocalizer)
{
this.stringLocalizer = stringLocalizer;
}
Expand Down
3 changes: 3 additions & 0 deletions framework/src/Volo.Abp.BlazoriseUI/AbpBlazoriseModule.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Blazorise;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Components.WebAssembly;
using Volo.Abp.Modularity;

Expand All @@ -18,6 +19,8 @@ private void ConfigureBlazorise(ServiceConfigurationContext context)
{
context.Services
.AddBlazorise();

context.Services.AddSingleton(typeof(AbpBlazorMessageLocalizerHelper<>));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing;
using Volo.Abp.AutoMapper;
using Volo.Abp.BlazoriseUI;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.Blazor;
using Volo.Abp.UI.Navigation;
Expand All @@ -10,7 +11,8 @@ namespace Volo.Abp.Identity.Blazor
[DependsOn(
typeof(AbpIdentityHttpApiClientModule),
typeof(AbpAutoMapperModule),
typeof(AbpPermissionManagementBlazorModule)
typeof(AbpPermissionManagementBlazorModule),
typeof(AbpBlazoriseUIModule)
)]
public class AbpIdentityBlazorModule : AbpModule
{
Expand All @@ -32,8 +34,6 @@ public override void ConfigureServices(ServiceConfigurationContext context)
{
options.AdditionalAssemblies.Add(typeof(AbpIdentityBlazorModule).Assembly);
});

context.Services.AddSingleton(typeof(AbpIdentityBlazorMessageLocalizerHelper<>));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
@using Volo.Abp.PermissionManagement.Blazor.Components
@using Microsoft.Extensions.Localization
@using Volo.Abp.Identity.Localization
@inject AbpIdentityBlazorMessageLocalizerHelper<IdentityResource> LH
@inject AbpBlazorMessageLocalizerHelper<IdentityResource> LH

@inherits AbpCrudPageBase<IIdentityRoleAppService, IdentityRoleDto, Guid, GetIdentityRolesInput, IdentityRoleCreateDto, IdentityRoleUpdateDto>

@* ************************* PAGE HEADER ************************* *@
<Row>
<Column ColumnSize="ColumnSize.Is6">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
@page "/identity/users"
@attribute [Authorize(IdentityPermissions.Users.Default)]
@attribute [Authorize( IdentityPermissions.Users.Default )]
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Volo.Abp.PermissionManagement.Blazor.Components
@using Microsoft.Extensions.Localization
@using Volo.Abp.Identity.Localization
@inject AbpBlazorMessageLocalizerHelper<IdentityResource> LH

@inherits AbpCrudPageBase<IIdentityUserAppService, IdentityUserDto, Guid, GetIdentityUsersInput, IdentityUserCreateDto, IdentityUserUpdateDto>

@inject AbpIdentityBlazorMessageLocalizerHelper<IdentityResource> LH
@* ************************* PAGE HEADER ************************* *@
<Row>
<Column ColumnSize="ColumnSize.Is6">
Expand Down Expand Up @@ -187,7 +186,7 @@
<CloseButton Clicked="CloseEditModalAsync" />
</ModalHeader>
<ModalBody>
<Validations @ref="@EditValidationsRef" Model="@NewEntity" ValidateOnLoad="false">
<Validations @ref="@EditValidationsRef" Model="@EditingEntity" ValidateOnLoad="false">
<input type="hidden" name="ConcurrencyStamp" @bind-value="EditingEntity.ConcurrencyStamp" />

<Tabs @bind-SelectedTab="@EditModalSelectedTab">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ public abstract class TenantCreateOrUpdateDtoBase : ExtensibleObject
{
[Required]
[DynamicStringLength(typeof(TenantConsts), nameof(TenantConsts.MaxNameLength))]
[Display(Name = "TenantName")]
public string Name { get; set; }

public TenantCreateOrUpdateDtoBase() : base(false)
{

}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
@page "/tenant-management/tenants"
@attribute [Authorize(TenantManagementPermissions.Tenants.Default)]
@attribute [Authorize( TenantManagementPermissions.Tenants.Default )]
@using Microsoft.AspNetCore.Authorization
@using Volo.Abp.FeatureManagement.Blazor.Components
@using Microsoft.AspNetCore.Components.Forms

@using Volo.Abp.TenantManagement.Localization
@inject AbpBlazorMessageLocalizerHelper<AbpTenantManagementResource> LH
@inherits AbpCrudPageBase<ITenantAppService, TenantDto, Guid, GetTenantsInput, TenantCreateDto, TenantUpdateDto>

@* ************************* PAGE HEADER ************************* *@
<Row>
<Column ColumnSize="ColumnSize.Is6">
<h1>@L["Tenants"]</h1>
<Heading Size="HeadingSize.Is1">@L["Tenants"]</Heading>
</Column>
<Column ColumnSize="ColumnSize.Is6">
@if (HasCreatePermission)
Expand Down Expand Up @@ -65,31 +65,52 @@
{
<Modal @ref="CreateModal">
<ModalBackdrop />
<ModalContent IsCentered="true">
<ModalHeader>
<ModalTitle>@L["NewTenant"]</ModalTitle>
<CloseButton Clicked="CloseCreateModalAsync" />
</ModalHeader>
<ModalBody>
<EditForm id="TenantCreateForm" Model="@NewEntity" OnValidSubmit="CreateEntityAsync">
<Field>
<FieldLabel>@L["TenantName"]</FieldLabel>
<TextEdit @bind-text="@NewEntity.Name" />
</Field>
<Field>
<FieldLabel>@L["DisplayName:AdminEmailAddress"]</FieldLabel>
<TextEdit Role="@TextRole.Email" @bind-text="@NewEntity.AdminEmailAddress" />
</Field>
<Field>
<FieldLabel>@L["DisplayName:AdminPassword"]</FieldLabel>
<TextEdit Role="@TextRole.Password" @bind-text="@NewEntity.AdminPassword" />
</Field>
</EditForm>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary" Clicked="CloseCreateModalAsync">@L["Cancel"]</Button>
<Button form="TenantCreateForm" Color="Color.Primary" Clicked="CreateEntityAsync">@L["Save"]</Button>
</ModalFooter>
<ModalContent Centered="true">
<Form id="TenantCreateForm">
<ModalHeader>
<ModalTitle>@L["NewTenant"]</ModalTitle>
<CloseButton Clicked="CloseCreateModalAsync" />
</ModalHeader>
<ModalBody>

<Validations @ref="@CreateValidationsRef" Model="@NewEntity" ValidateOnLoad="false">
<Validation MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@L["TenantName"]</FieldLabel>
<TextEdit @bind-Text="@NewEntity.Name">
<Feedback>
<ValidationError />
</Feedback>
</TextEdit>
</Field>
</Validation>
<Validation MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@L["DisplayName:AdminEmailAddress"]</FieldLabel>
<TextEdit Role="@TextRole.Email" @bind-Text="@NewEntity.AdminEmailAddress">
<Feedback>
<ValidationError />
</Feedback>
</TextEdit>
</Field>
</Validation>
<Validation MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@L["DisplayName:AdminPassword"]</FieldLabel>
<TextEdit Role="@TextRole.Password" @bind-Text="@NewEntity.AdminPassword">
<Feedback>
<ValidationError />
</Feedback>
</TextEdit>
</Field>
</Validation>
</Validations>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary" Clicked="CloseCreateModalAsync">@L["Cancel"]</Button>
<Button form="TenantCreateForm" Type="ButtonType.Submit" PreventDefaultOnSubmit="true" Color="Color.Primary" Clicked="CreateEntityAsync">@L["Save"]</Button>
</ModalFooter>
</Form>
</ModalContent>
</Modal>
}
Expand All @@ -99,23 +120,31 @@
{
<Modal @ref="EditModal">
<ModalBackdrop />
<ModalContent IsCentered="true">
<ModalHeader>
<ModalTitle>@L["Edit"]</ModalTitle>
<CloseButton Clicked="CloseEditModalAsync" />
</ModalHeader>
<ModalBody>
<EditForm id="TenantEditForm" Model="@EditingEntity" OnValidSubmit="UpdateEntityAsync">
<Field>
<FieldLabel>@L["TenantName"]</FieldLabel>
<TextEdit @bind-text="@EditingEntity.Name" />
</Field>
</EditForm>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary" Clicked="CloseEditModalAsync">@L["Cancel"]</Button>
<Button form="TenantEditForm" Color="Color.Primary" Clicked="UpdateEntityAsync">@L["Save"]</Button>
</ModalFooter>
<ModalContent Centered="true">
<Form id="TenantEditForm">
<ModalHeader>
<ModalTitle>@L["Edit"]</ModalTitle>
<CloseButton Clicked="CloseEditModalAsync" />
</ModalHeader>
<ModalBody>
<Validations @ref="@EditValidationsRef" Model="@EditingEntity" ValidateOnLoad="false">
<Validation MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@L["TenantName"]</FieldLabel>
<TextEdit @bind-Text="@EditingEntity.Name">
<Feedback>
<ValidationError />
</Feedback>
</TextEdit>
</Field>
</Validation>
</Validations>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary" Clicked="CloseEditModalAsync">@L["Cancel"]</Button>
<Button form="TenantEditForm" Type="ButtonType.Submit" PreventDefaultOnSubmit="true" Color="Color.Primary" Clicked="UpdateEntityAsync">@L["Save"]</Button>
</ModalFooter>
</Form>
</ModalContent>
</Modal>
}
Expand All @@ -125,30 +154,36 @@
{
<Modal @ref="@ManageConnectionStringModal">
<ModalBackdrop />
<ModalContent IsCentered="true">
<ModalHeader>
<ModalTitle>@L["ConnectionStrings"]</ModalTitle>
<CloseButton Clicked="CloseEditConnectionStringModal" />
</ModalHeader>
<ModalBody>
<EditForm id="ConnectionStringEditForm" Model="@TenantInfo" OnValidSubmit="UpdateConnectionStringAsync">
<Field>
<FieldLabel>@L["DisplayName:DefaultConnectionString"]</FieldLabel>
<Check TValue="bool" @bind-Checked="@TenantInfo.UseSharedDatabase" Cursor="@Cursor.Pointer" />
</Field>
@if (!TenantInfo.UseSharedDatabase)
{
<Field>
<FieldLabel>@L["DisplayName:DefaultConnectionString"]</FieldLabel>
<TextEdit @bind-text="@TenantInfo.DefaultConnectionString" />
</Field>
}
</EditForm>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary" Clicked="CloseEditConnectionStringModal">@L["Cancel"]</Button>
<Button form="ConnectionStringEditForm" Color="Color.Primary" Clicked="UpdateConnectionStringAsync">@L["Save"]</Button>
</ModalFooter>
<ModalContent Centered="true">
<Form id="ConnectionStringEditForm">
<ModalHeader>
<ModalTitle>@L["ConnectionStrings"]</ModalTitle>
<CloseButton Clicked="CloseEditConnectionStringModal" />
</ModalHeader>
<ModalBody>
<Validations @ref="@ManageConnectionStringValidations" Model="@TenantInfo" ValidateOnLoad="false">
<Validation MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@L["DisplayName:DefaultConnectionString"]</FieldLabel>
<Check TValue="bool" @bind-Checked="@TenantInfo.UseSharedDatabase" Cursor="@Cursor.Pointer" />
</Field>
</Validation>
@if (!TenantInfo.UseSharedDatabase)
{
<Validation MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@L["DisplayName:DefaultConnectionString"]</FieldLabel>
<TextEdit @bind-Text="@TenantInfo.DefaultConnectionString" />
</Field>
</Validation>
}
</Validations>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary" Clicked="CloseEditConnectionStringModal">@L["Cancel"]</Button>
<Button form="ConnectionStringEditForm" Type="ButtonType.Submit" PreventDefaultOnSubmit="true" Color="Color.Primary" Clicked="UpdateConnectionStringAsync">@L["Save"]</Button>
</ModalFooter>
</Form>
</ModalContent>
</Modal>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Blazorise;
using Microsoft.AspNetCore.Authorization;
Expand All @@ -20,9 +21,10 @@ public partial class TenantManagement
protected FeatureManagementModal FeatureManagementModal;

protected Modal ManageConnectionStringModal;
protected Validations ManageConnectionStringValidations;

protected TenantInfoModel TenantInfo;

public TenantManagement()
{
LocalizationResource = typeof(AbpTenantManagementResource);
Expand All @@ -36,7 +38,7 @@ public TenantManagement()

TenantInfo = new TenantInfoModel();
}

protected async override Task SetPermissionsAsync()
{
await base.SetPermissionsAsync();
Expand All @@ -47,6 +49,8 @@ protected async override Task SetPermissionsAsync()

protected virtual async Task OpenEditConnectionStringModalAsync(Guid id)
{
ManageConnectionStringValidations.ClearAll();

var tenantConnectionString = await AppService.GetDefaultConnectionStringAsync(id);

TenantInfo = new TenantInfoModel
Expand All @@ -67,18 +71,21 @@ protected virtual Task CloseEditConnectionStringModal()

protected virtual async Task UpdateConnectionStringAsync()
{
await CheckPolicyAsync(ManageConnectionStringsPolicyName);

if (TenantInfo.UseSharedDatabase || TenantInfo.DefaultConnectionString.IsNullOrWhiteSpace())
if (ManageConnectionStringValidations.ValidateAll())
{
await AppService.DeleteDefaultConnectionStringAsync(TenantInfo.Id);
await CheckPolicyAsync(ManageConnectionStringsPolicyName);

if (TenantInfo.UseSharedDatabase || TenantInfo.DefaultConnectionString.IsNullOrWhiteSpace())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You define as [Required] for TenantInfoModel.DefaultConnectionString, but here we control is that null or empty.

{
await AppService.DeleteDefaultConnectionStringAsync(TenantInfo.Id);
}
else
{
await AppService.UpdateDefaultConnectionStringAsync(TenantInfo.Id, TenantInfo.DefaultConnectionString);
}

ManageConnectionStringModal.Hide();
}
else
{
await AppService.UpdateDefaultConnectionStringAsync(TenantInfo.Id, TenantInfo.DefaultConnectionString);
}

ManageConnectionStringModal.Hide();
}

protected override string GetDeleteConfirmationMessage(TenantDto entity)
Expand All @@ -93,6 +100,7 @@ public class TenantInfoModel

public bool UseSharedDatabase { get; set; }

[Required]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be nullable. Does not required.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only run if the checkbox is ticked so I think it's best to be Required in this case

public string DefaultConnectionString { get; set; }
}
}