diff --git a/docs/en/Multi-Tenancy.md b/docs/en/Multi-Tenancy.md index f5510a82db..0ad3c66b26 100644 --- a/docs/en/Multi-Tenancy.md +++ b/docs/en/Multi-Tenancy.md @@ -114,7 +114,7 @@ namespace MyCompany.MyProject { Configure(options => { - options.TenantResolvers.Add(new MyCustomTenantResolver()); + options.TenantResolvers.Add(new MyCustomTenantResolveContributor()); }); //... @@ -123,14 +123,14 @@ namespace MyCompany.MyProject } ```` -MyCustomTenantResolver must implement **ITenantResolver** as shown below: +`MyCustomTenantResolveContributor` must implement **ITenantResolveContributor** as shown below: ````C# using Volo.Abp.MultiTenancy; namespace MyCompany.MyProject { - public class MyCustomTenantResolver : ITenantResolver + public class MyCustomTenantResolveContributor : ITenantResolveContributor { public void Resolve(ITenantResolveContext context) { diff --git a/docs/zh-Hans/Multi-Tenancy.md b/docs/zh-Hans/Multi-Tenancy.md index 911803b1be..352190d5cd 100644 --- a/docs/zh-Hans/Multi-Tenancy.md +++ b/docs/zh-Hans/Multi-Tenancy.md @@ -115,7 +115,7 @@ namespace MyCompany.MyProject { Configure(options => { - options.TenantResolvers.Add(new MyCustomTenantResolver()); + options.TenantResolvers.Add(new MyCustomTenantResolveContributor()); }); //... @@ -124,14 +124,14 @@ namespace MyCompany.MyProject } ```` -MyCustomTenantResolver必须像下面这样实现**ITenantResolver**接口: +`MyCustomTenantResolveContributor`必须像下面这样实现**ITenantResolveContributor**接口: ````C# using Volo.Abp.MultiTenancy; namespace MyCompany.MyProject { - public class MyCustomTenantResolver : ITenantResolver + public class MyCustomTenantResolveContributor : ITenantResolveContributor { public void Resolve(ITenantResolveContext context) { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs index 056f87f897..d7dbb70d14 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs @@ -171,31 +171,32 @@ namespace Volo.Abp.Cli private void LogNewVersionInfo(UpdateChannel updateChannel, SemanticVersion latestVersion, string toolPath) { - Logger.LogWarning( - $"ABP CLI has a newer {updateChannel.ToString().ToLowerInvariant()} version {latestVersion}, please update to get the latest features and fixes."); - Logger.LogWarning(""); + Logger.LogWarning($"ABP CLI has a newer {updateChannel.ToString().ToLowerInvariant()} version {latestVersion}, please update to get the latest features and fixes."); + Logger.LogWarning(string.Empty); Logger.LogWarning("Update Command: "); // Update command doesn't support prerelease versions https://github.com/dotnet/sdk/issues/2551 workaround is to uninstall & install switch (updateChannel) { case UpdateChannel.Stable: - Logger.LogWarning($" dotnet tool update --tool-path {toolPath} Volo.Abp.Cli"); + Logger.LogWarning("dotnet tool update -g Volo.Abp.Cli"); break; case UpdateChannel.Prerelease: - Logger.LogWarning($" dotnet tool uninstall --tool-path {toolPath} Volo.Abp.Cli"); - Logger.LogWarning($" dotnet tool install --tool-path {toolPath} --version {latestVersion} Volo.Abp.Cli"); + Logger.LogWarning("dotnet tool uninstall -g Volo.Abp.Cli"); + Logger.LogWarning($"dotnet tool install -g Volo.Abp.Cli --version {latestVersion}"); break; case UpdateChannel.Nightly: - Logger.LogWarning($" dotnet tool uninstall --tool-path {toolPath} Volo.Abp.Cli"); - Logger.LogWarning( - $" dotnet tool install --tool-path {toolPath} --add-source https://www.myget.org/F/abp-nightly/api/v3/index.json --version {latestVersion} Volo.Abp.Cli"); + case UpdateChannel.Development: + Logger.LogWarning("dotnet tool uninstall -g Volo.Abp.Cli"); + Logger.LogWarning($"dotnet tool install -g Volo.Abp.Cli --add-source https://www.myget.org/F/abp-nightly/api/v3/index.json --version {latestVersion}"); break; + default: + throw new ArgumentOutOfRangeException(nameof(updateChannel), updateChannel, null); } - Logger.LogWarning(""); + Logger.LogWarning(string.Empty); } protected enum UpdateChannel diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json index 68af08b6a1..2e8812968d 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json @@ -1,6 +1,7 @@ { "culture": "en", "texts": { - "Features": "Features" + "Features": "Features", + "NoFeatureFoundMessage": "There is't any available feature." } } \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml index b52ea264b4..59e80e236c 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml @@ -12,49 +12,58 @@
- - - - @for (var i = 0; i < Model.FeatureListDto.Features.Count; i++) - { - var feature = Model.FeatureListDto.Features[i]; -
+ @if (Model.FeatureListDto?.Features != null && Model.FeatureListDto.Features.Any()) + { + + + + @for (var i = 0; i < Model.FeatureListDto.Features.Count; i++) + { + var feature = Model.FeatureListDto.Features[i]; +
- @feature.Name + @feature.Name - - @if (feature.ValueType is FreeTextStringValueType) - { - - - } - @if (feature.ValueType is SelectionStringValueType) - { - - + @if (feature.ValueType is FreeTextStringValueType) + { + + + } + @if (feature.ValueType is SelectionStringValueType) + { + + - } - @if (feature.ValueType is ToggleStringValueType) - { - - - } -
- } -
- + + } + @if (feature.ValueType is ToggleStringValueType) + { + + + } +
+ } +
+ + } + else + { + + @L["NoFeatureFoundMessage"] + + }
diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo.Abp.IdentityServer.Domain.Shared.csproj b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo.Abp.IdentityServer.Domain.Shared.csproj index 6894c3f60b..bcd99cd524 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo.Abp.IdentityServer.Domain.Shared.csproj +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo.Abp.IdentityServer.Domain.Shared.csproj @@ -13,6 +13,14 @@ + + + + + + + + diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/AbpIdentityServerDomainSharedModule.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/AbpIdentityServerDomainSharedModule.cs index 141bd1a5fb..8d2bf66576 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/AbpIdentityServerDomainSharedModule.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/AbpIdentityServerDomainSharedModule.cs @@ -1,6 +1,9 @@ using Volo.Abp.IdentityServer.Localization; using Volo.Abp.Localization; +using Volo.Abp.Localization.ExceptionHandling; +using Volo.Abp.Localization.Resources.AbpValidation; using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.IdentityServer { @@ -11,9 +14,22 @@ namespace Volo.Abp.IdentityServer { public override void ConfigureServices(ServiceConfigurationContext context) { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + Configure(options => { - options.Resources.Add("en"); + options.Resources.Add("en") + .AddBaseTypes( + typeof(AbpValidationResource) + ).AddVirtualJson("/Volo/Abp/IdentityServer/Localization/Resources"); + }); + + Configure(options => + { + options.MapCodeNamespace("Volo.IdentityServer", typeof(AbpIdentityServerResource)); }); } } diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/en.json b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/en.json new file mode 100644 index 0000000000..89ffea534c --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/en.json @@ -0,0 +1,7 @@ +{ + "culture": "en", + "texts": { + "Volo.IdentityServer:DuplicateIdentityResourceName": "Identity Resource name already exist: {Name}", + "Volo.IdentityServer:DuplicateApiResourceName": "Api Resource name already exist: {Name}" + } +} \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs index e229f361d5..6eead2f2dd 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/IApiResourceRepository.cs @@ -32,5 +32,10 @@ namespace Volo.Abp.IdentityServer.ApiResources bool includeDetails = false, CancellationToken cancellationToken = default ); + + Task CheckNameExistAsync( + string name, + Guid? expectedId = null + ); } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs index 0ae9754b91..2b569a84e4 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IIdentityResourceRepository.cs @@ -27,5 +27,10 @@ namespace Volo.Abp.IdentityServer.IdentityResources bool includeDetails = true, CancellationToken cancellationToken = default ); + + Task CheckNameExistAsync( + string name, + Guid? expectedId = null + ); } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiResources/ApiResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiResources/ApiResourceRepository.cs index 7b6acd495a..9ba8f19b14 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiResources/ApiResourceRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiResources/ApiResourceRepository.cs @@ -61,6 +61,11 @@ namespace Volo.Abp.IdentityServer.ApiResources .ToListAsync(GetCancellationToken(cancellationToken)); } + public async Task CheckNameExistAsync(string name, Guid? expectedId = null) + { + return await DbSet.AnyAsync(ar => ar.Id != expectedId && ar.Name == name); + } + public override async Task DeleteAsync(Guid id, bool autoSave = false, CancellationToken cancellationToken = default) { var scopeClaims = DbContext.Set().Where(sc => sc.ApiResourceId == id); diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceRepository.cs index a5237a6cc8..5c6de3ffac 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceRepository.cs @@ -56,5 +56,10 @@ namespace Volo.Abp.IdentityServer.IdentityResources .Where(x => x.Name == name) .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); } + + public async Task CheckNameExistAsync(string name, Guid? expectedId = null) + { + return await DbSet.AnyAsync(ir => ir.Id != expectedId && ir.Name == name); + } } } diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs index 81ea680720..7cd9147889 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs @@ -47,5 +47,10 @@ namespace Volo.Abp.IdentityServer.MongoDB { return await GetCountAsync(); } + + public async Task CheckNameExistAsync(string name, Guid? expectedId = null) + { + return await GetMongoQueryable().AnyAsync(ar => ar.Id != expectedId && ar.Name == name); + } } } diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs index 85505c2987..4ab1ee91c0 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs @@ -50,5 +50,10 @@ namespace Volo.Abp.IdentityServer.MongoDB { return await GetCountAsync(); } + + public async Task CheckNameExistAsync(string name, Guid? expectedId = null) + { + return await GetMongoQueryable().AnyAsync(ir => ir.Id != expectedId && ir.Name == name); + } } } diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html index ea954c55be..949c6619ec 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html @@ -83,100 +83,98 @@ - -
- - - -
-
- * - -
+ + + + +
+
+ * + +
-
- - -
+
+ + +
-
- - -
+
+ + +
-
- * - -
+
+ * + +
-
- * - -
+
+ * + +
-
- - -
+
+ + +
-
- - -
+
+ + +
-
- - -
+
+ +
- - - - -
-
- - -
+
+
+
+ + +
+
+ +
- - - - - +
+
+
+ + diff --git a/npm/ng-packs/packages/identity/src/lib/identity.module.ts b/npm/ng-packs/packages/identity/src/lib/identity.module.ts index e39385e5f5..d94ba410d9 100644 --- a/npm/ng-packs/packages/identity/src/lib/identity.module.ts +++ b/npm/ng-packs/packages/identity/src/lib/identity.module.ts @@ -10,7 +10,6 @@ import { UsersComponent } from './components/users/users.component'; import { PermissionManagementModule } from '@abp/ng.permission-management'; import { TableModule } from 'primeng/table'; import { NgxValidateCoreModule } from '@ngx-validate/core'; -import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; @NgModule({ declarations: [RolesComponent, UsersComponent], @@ -24,7 +23,6 @@ import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; NgbDropdownModule, PermissionManagementModule, NgxValidateCoreModule, - PerfectScrollbarModule, ], }) export class IdentityModule {} diff --git a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html index 3f6a47eabd..fbac3ae354 100644 --- a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html +++ b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html @@ -22,16 +22,14 @@
@@ -52,32 +50,30 @@ }}

- -
+ + - - -
-
+
diff --git a/npm/ng-packs/packages/permission-management/src/lib/permission-management.module.ts b/npm/ng-packs/packages/permission-management/src/lib/permission-management.module.ts index 3986689c41..73c3455828 100644 --- a/npm/ng-packs/packages/permission-management/src/lib/permission-management.module.ts +++ b/npm/ng-packs/packages/permission-management/src/lib/permission-management.module.ts @@ -4,11 +4,10 @@ import { NgModule } from '@angular/core'; import { NgxsModule } from '@ngxs/store'; import { PermissionManagementComponent } from './components/permission-management.component'; import { PermissionManagementState } from './states/permission-management.state'; -import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; @NgModule({ declarations: [PermissionManagementComponent], - imports: [CoreModule, ThemeSharedModule, NgxsModule.forFeature([PermissionManagementState]), PerfectScrollbarModule], + imports: [CoreModule, ThemeSharedModule, NgxsModule.forFeature([PermissionManagementState])], exports: [PermissionManagementComponent], }) export class PermissionManagementModule {} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts index 917e981338..39cf9b73a2 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts @@ -11,26 +11,25 @@ import { Toaster } from '../../models/toaster'; (onClose)="close(dismiss)" [modal]="true" [baseZIndex]="1000" - styleClass="" + styleClass="abp-confirm" > - diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts index dd66eec05c..e2646b5128 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts @@ -119,11 +119,16 @@ export class ModalComponent implements OnDestroy { this.visibleChange.emit(value); this.showModal = value; - value - ? timer(ANIMATION_TIMEOUT + 100) - .pipe(take(1)) - .subscribe(_ => (this.closable = true)) - : (this.closable = false); + if (value) { + timer(ANIMATION_TIMEOUT + 100) + .pipe(take(1)) + .subscribe(_ => (this.closable = true)); + + this.renderer.addClass(document.body, 'modal-open'); + } else { + this.closable = false; + this.renderer.removeClass(document.body, 'modal-open'); + } } listen() { diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.ts index 12005e4935..382b18974b 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.ts @@ -3,7 +3,7 @@ import { Component } from '@angular/core'; @Component({ selector: 'abp-toast', template: ` - + { + const fn = function() { + const lazyLoadService: LazyLoadService = injector.get(LazyLoadService); - return forkJoin( - lazyLoadService.load( - null, - 'style', - styles, - 'head', - 'afterbegin', - ) /* lazyLoadService.load(null, 'script', scripts) */, - ).pipe(take(1)); + return forkJoin( + lazyLoadService.load( + null, + 'style', + styles, + 'head', + 'afterbegin', + ) /* lazyLoadService.load(null, 'script', scripts) */, + ).pipe(take(1)); + }; + + return fn; }; - return fn; + return higher; } @NgModule({ @@ -87,7 +91,7 @@ export class ThemeSharedModule { provide: APP_INITIALIZER, multi: true, deps: [Injector, ErrorHandler], - useFactory: appendScript, + useFactory: appendScript(styles), }, { provide: MessageService, useClass: MessageService }, ],