diff --git a/.github/lock.yml b/.github/lock.yml new file mode 100644 index 0000000000..2e36a791b6 --- /dev/null +++ b/.github/lock.yml @@ -0,0 +1,38 @@ +# Configuration for Lock Threads - https://github.com/dessant/lock-threads-app + +# Number of days of inactivity before a closed issue or pull request is locked +daysUntilLock: 30 + +# Skip issues and pull requests created before a given timestamp. Timestamp must +# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable +skipCreatedBefore: false + +# Issues and pull requests with these labels will be ignored. Set to `[]` to disable +exemptLabels: [] + +# Label to add before locking, such as `outdated`. Set to `false` to disable +lockLabel: false + +# Comment to post before locking. Set to `false` to disable +lockComment: > + This thread has been automatically locked since there has not been + any recent activity after it was closed. Please open a new issue for + related bugs. + +# Assign `resolved` as the reason for locking. Set to `false` to disable +setLockReason: true + +# Limit to only `issues` or `pulls` +# only: issues + +# Optionally, specify configuration settings just for `issues` or `pulls` +# issues: +# exemptLabels: +# - help-wanted +# lockLabel: outdated + +# pulls: +# daysUntilLock: 30 + +# Repository to extend settings from +# _extends: repo \ No newline at end of file diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 0000000000..c1133728da --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,15 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 60 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: true +# Label to use when marking an issue as stale +staleLabel: inactive +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false \ No newline at end of file diff --git a/.github/workflows/angular.yml b/.github/workflows/angular.yml index 3f576ee9c1..60051c2dc1 100644 --- a/.github/workflows/angular.yml +++ b/.github/workflows/angular.yml @@ -3,15 +3,6 @@ on: pull_request: paths: - 'npm/ng-packs/**' - branches: - #- master - - dev - push: - paths: - - 'npm/ng-packs/**' - branches: - #- master - - dev jobs: build-test-lint: runs-on: ubuntu-18.04 @@ -19,6 +10,6 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: - node-version: '10.x' + node-version: '12.x' - run: yarn && yarn ci working-directory: npm/ng-packs diff --git a/docs/en/API/Application-Configuration.md b/docs/en/API/Application-Configuration.md index db624987c5..1465f0fd24 100644 --- a/docs/en/API/Application-Configuration.md +++ b/docs/en/API/Application-Configuration.md @@ -2,12 +2,12 @@ ABP Framework provides a pre-built and standard endpoint that contains some useful information about the application/service. Here, the list of some fundamental information at this endpoint: -* [Localization](Localization.md) values, supported and the current language of the application. -* Available and granted [policies](Authorization.md) (permissions) for the current user. -* [Setting](Settings.md) values for the current user. -* Info about the [current user](CurrentUser.md) (like id and user name). -* Info about the current [tenant](Multi-Tenancy.md) (like id and name). -* [Time zone](Timing.md) information for the current user and the [clock](Timing.md) type of the application. +* [Localization](../Localization.md) values, supported and the current language of the application. +* Available and granted [policies](../Authorization.md) (permissions) for the current user. +* [Setting](../Settings.md) values for the current user. +* Info about the [current user](../CurrentUser.md) (like id and user name). +* Info about the current [tenant](../Multi-Tenancy.md) (like id and name). +* [Time zone](../Timing.md) information for the current user and the [clock](Timing.md) type of the application. ## HTTP API diff --git a/docs/en/Authorization.md b/docs/en/Authorization.md index 1ede9f7577..4b7502f437 100644 --- a/docs/en/Authorization.md +++ b/docs/en/Authorization.md @@ -284,8 +284,6 @@ You may need to check a policy/permission on the client side. For ASP.NET Core M abp.auth.isGranted('MyPermissionName'); ``` -See [abp.auth](UI/AspNetCore/JavaScript-API/Index.md) API documentation for details. - ## Permission Management Permission management is normally done by an admin user using the permission management modal: diff --git a/docs/en/Background-Workers-Quartz.md b/docs/en/Background-Workers-Quartz.md index f8495b27a4..9b419d6c27 100644 --- a/docs/en/Background-Workers-Quartz.md +++ b/docs/en/Background-Workers-Quartz.md @@ -1,6 +1,6 @@ # Quartz Background Worker Manager -[Quartz](https://www.quartz-scheduler.net/) is an advanced background worker manager. You can integrate Quartz with the ABP Framework to use it instead of the [default background worker manager](Background-Worker.md). ABP simply integrates quartz. +[Quartz](https://www.quartz-scheduler.net/) is an advanced background worker manager. You can integrate Quartz with the ABP Framework to use it instead of the [default background worker manager](Background-Workers.md). ABP simply integrates quartz. ## Installation diff --git a/docs/en/Best-Practices/Application-Services.md b/docs/en/Best-Practices/Application-Services.md index 876105c214..3332ce08ea 100644 --- a/docs/en/Best-Practices/Application-Services.md +++ b/docs/en/Best-Practices/Application-Services.md @@ -206,7 +206,7 @@ This method votes a question and returns the current score of the question. #### Extra Properties -* **Do** use either `MapExtraPropertiesTo` extension method ([see](Object-Extensions.md)) or configure the object mapper (`MapExtraProperties`) to allow application developers to be able to extend the objects and services. +* **Do** use either `MapExtraPropertiesTo` extension method ([see](../Object-Extensions.md)) or configure the object mapper (`MapExtraProperties`) to allow application developers to be able to extend the objects and services. #### Manipulating / Deleting Entities diff --git a/docs/en/Blob-Storing-Database.md b/docs/en/Blob-Storing-Database.md index 69b9232ee8..c14086a2f4 100644 --- a/docs/en/Blob-Storing-Database.md +++ b/docs/en/Blob-Storing-Database.md @@ -27,7 +27,7 @@ This command adds all the NuGet packages to corresponding layers of your solutio Here, all the NuGet packages defined by this provider; -* [Volo.Abp.BlobStoring.Database.Domain.Shared](https://www.nuget.org/packages/Volo.Abp.BlobStoring.Domain.Shared) +* [Volo.Abp.BlobStoring.Database.Domain.Shared](https://www.nuget.org/packages/Volo.Abp.BlobStoring.Database.Domain.Shared) * [Volo.Abp.BlobStoring.Database.Domain](https://www.nuget.org/packages/Volo.Abp.BlobStoring.Database.Domain) * [Volo.Abp.BlobStoring.Database.EntityFrameworkCore](https://www.nuget.org/packages/Volo.Abp.BlobStoring.Database.EntityFrameworkCore) * [Volo.Abp.BlobStoring.Database.MongoDB](https://www.nuget.org/packages/Volo.Abp.BlobStoring.Database.MongoDB) diff --git a/docs/en/Entity-Framework-Core-Migrations.md b/docs/en/Entity-Framework-Core-Migrations.md index 00e791a94e..d59f9f96c7 100644 --- a/docs/en/Entity-Framework-Core-Migrations.md +++ b/docs/en/Entity-Framework-Core-Migrations.md @@ -2,7 +2,7 @@ This document begins by **introducing the default structure** provided by [the application startup template](Startup-Templates/Application.md) and **discusses various scenarios** you may want to implement for your own application. -> This document is for who want to fully understand and customize the database structure comes with [the application startup template](Startup-Templates/Application.md). If you simply want to create entities and manage your code first migrations, just follow [the startup tutorials](Tutorials/Index.md). +> This document is for who want to fully understand and customize the database structure comes with [the application startup template](Startup-Templates/Application.md). If you simply want to create entities and manage your code first migrations, just follow [the startup tutorials](Tutorials/Part-1.md). ### Source Code diff --git a/docs/en/Modules/Docs.md b/docs/en/Modules/Docs.md index b8f678dc48..e788a4c0f8 100644 --- a/docs/en/Modules/Docs.md +++ b/docs/en/Modules/Docs.md @@ -613,7 +613,7 @@ Configure(options => The `Index` is automatically created after the application starts if the `Index` does not exist. `DefaultElasticClientProvider` is responsible for creating `IElasticClient`. By default, it reads Elastic Search's `Url` from `IConfiguration`. -If your `IElasticClient` needs additional configuration, please use override `IElasticClientProvider` service and replace it in the [dependency injection](Dependency-Injection.md) system. +If your `IElasticClient` needs additional configuration, please use override `IElasticClientProvider` service and replace it in the [dependency injection](../Dependency-Injection.md) system. ``` { diff --git a/docs/en/Startup-Templates/Module.md b/docs/en/Startup-Templates/Module.md index 45e123971b..ea2fe5acca 100644 --- a/docs/en/Startup-Templates/Module.md +++ b/docs/en/Startup-Templates/Module.md @@ -56,7 +56,7 @@ An `IssueType` enum and an `IssueConsts` class (which may have some constant fie ### .Domain Project -This is the domain layer of the solution. It mainly contains [entities, aggregate roots](../Entities.md), [domain services](../Domain-Services.md), [value types](../Value-Types.md), [repository interfaces](../Repositories.md) and other domain objects. +This is the domain layer of the solution. It mainly contains [entities, aggregate roots](../Entities.md), [domain services](../Domain-Services.md), value types, [repository interfaces](../Repositories.md) and other domain objects. An `Issue` entity, an `IssueManager` domain service and an `IIssueRepository` interface are good candidates for this project. diff --git a/docs/en/Tutorials/Part-1.md b/docs/en/Tutorials/Part-1.md index 11b608b0eb..bb41fd678e 100644 --- a/docs/en/Tutorials/Part-1.md +++ b/docs/en/Tutorials/Part-1.md @@ -233,32 +233,30 @@ namespace Acme.BookStore public async Task SeedAsync(DataSeedContext context) { - if (await _bookRepository.GetCountAsync() > 0) + if (await _bookRepository.GetCountAsync() <= 0) { - return; + await _bookRepository.InsertAsync( + new Book + { + Name = "1984", + Type = BookType.Dystopia, + PublishDate = new DateTime(1949, 6, 8), + Price = 19.84f + }, + autoSave: true + ); + + await _bookRepository.InsertAsync( + new Book + { + Name = "The Hitchhiker's Guide to the Galaxy", + Type = BookType.ScienceFiction, + PublishDate = new DateTime(1995, 9, 27), + Price = 42.0f + }, + autoSave: true + ); } - - await _bookRepository.InsertAsync( - new Book - { - Name = "1984", - Type = BookType.Dystopia, - PublishDate = new DateTime(1949, 6, 8), - Price = 19.84f - }, - autoSave: true - ); - - await _bookRepository.InsertAsync( - new Book - { - Name = "The Hitchhiker's Guide to the Galaxy", - Type = BookType.ScienceFiction, - PublishDate = new DateTime(1995, 9, 27), - Price = 42.0f - }, - autoSave: true - ); } } } diff --git a/docs/en/Tutorials/Part-10.md b/docs/en/Tutorials/Part-10.md index fbecf39b86..0fa4892298 100644 --- a/docs/en/Tutorials/Part-10.md +++ b/docs/en/Tutorials/Part-10.md @@ -80,7 +80,7 @@ This is a typical migration problem and the decision depends on your case; * You can do it programmatically on data migration or seed phase. * You can manually handle it on the database. -We prefer to delete the database {{if DB=="EF"}}(run the `Drop-Database` in the *Package Manager Console*){{end}} since this is just an example project and data loss is not important. Since this topic is not related to the ABP Framework, we don't go deeper for all the scenarios. +We prefer to **delete the database** {{if DB=="EF"}}(run the `Drop-Database` in the *Package Manager Console*){{end}} since this is just an example project and data loss is not important. Since this topic is not related to the ABP Framework, we don't go deeper for all the scenarios. {{if DB=="EF"}} diff --git a/docs/en/Tutorials/Part-8.md b/docs/en/Tutorials/Part-8.md index 38e5b6013f..cf75994c14 100644 --- a/docs/en/Tutorials/Part-8.md +++ b/docs/en/Tutorials/Part-8.md @@ -439,50 +439,51 @@ namespace Acme.BookStore public async Task SeedAsync(DataSeedContext context) { - if (await _bookRepository.GetCountAsync() > 0) + if (await _bookRepository.GetCountAsync() <= 0) { - return; + await _bookRepository.InsertAsync( + new Book + { + Name = "1984", + Type = BookType.Dystopia, + PublishDate = new DateTime(1949, 6, 8), + Price = 19.84f + }, + autoSave: true + ); + + await _bookRepository.InsertAsync( + new Book + { + Name = "The Hitchhiker's Guide to the Galaxy", + Type = BookType.ScienceFiction, + PublishDate = new DateTime(1995, 9, 27), + Price = 42.0f + }, + autoSave: true + ); } // ADDED SEED DATA FOR AUTHORS - - await _authorRepository.InsertAsync( - await _authorManager.CreateAsync( - "George Orwell", - new DateTime(1903, 06, 25), - "Orwell produced literary criticism and poetry, fiction and polemical journalism; and is best known for the allegorical novella Animal Farm (1945) and the dystopian novel Nineteen Eighty-Four (1949)." - ) - ); - - await _authorRepository.InsertAsync( - await _authorManager.CreateAsync( - "Douglas Adams", - new DateTime(1952, 03, 11), - "Douglas Adams was an English author, screenwriter, essayist, humorist, satirist and dramatist. Adams was an advocate for environmentalism and conservation, a lover of fast cars, technological innovation and the Apple Macintosh, and a self-proclaimed 'radical atheist'." - ) - ); - await _bookRepository.InsertAsync( - new Book - { - Name = "1984", - Type = BookType.Dystopia, - PublishDate = new DateTime(1949, 6, 8), - Price = 19.84f - }, - autoSave: true - ); + if (await _authorRepository.GetCountAsync() <= 0) + { + await _authorRepository.InsertAsync( + await _authorManager.CreateAsync( + "George Orwell", + new DateTime(1903, 06, 25), + "Orwell produced literary criticism and poetry, fiction and polemical journalism; and is best known for the allegorical novella Animal Farm (1945) and the dystopian novel Nineteen Eighty-Four (1949)." + ) + ); - await _bookRepository.InsertAsync( - new Book - { - Name = "The Hitchhiker's Guide to the Galaxy", - Type = BookType.ScienceFiction, - PublishDate = new DateTime(1995, 9, 27), - Price = 42.0f - }, - autoSave: true - ); + await _authorRepository.InsertAsync( + await _authorManager.CreateAsync( + "Douglas Adams", + new DateTime(1952, 03, 11), + "Douglas Adams was an English author, screenwriter, essayist, humorist, satirist and dramatist. Adams was an advocate for environmentalism and conservation, a lover of fast cars, technological innovation and the Apple Macintosh, and a self-proclaimed 'radical atheist'." + ) + ); + } } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmApplicationType.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmApplicationType.cs index 9f58aa52e9..0e05a1ffb0 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmApplicationType.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmApplicationType.cs @@ -5,6 +5,7 @@ namespace Volo.Abp.Cli.ProjectModification [Flags] public enum NpmApplicationType { - Mvc = 1 + Mvc = 1, + Angular = 2 } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs index acf4231520..a19af6f52c 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs @@ -39,7 +39,7 @@ namespace Volo.Abp.Cli.ProjectModification EfCoreMigrationAdder efCoreMigrationAdder, DerivedClassFinder derivedClassFinder, ProjectNpmPackageAdder projectNpmPackageAdder, - NpmGlobalPackagesChecker npmGlobalPackagesChecker, + NpmGlobalPackagesChecker npmGlobalPackagesChecker, IRemoteServiceExceptionHandler remoteServiceExceptionHandler, SourceCodeDownloadService sourceCodeDownloadService, SolutionFileModifier solutionFileModifier, @@ -159,7 +159,7 @@ namespace Volo.Abp.Cli.ProjectModification { Directory.Delete(demoFolder, true); } - + var hostFolder = Path.Combine(targetModuleFolder, "host"); if (Directory.Exists(hostFolder)) { @@ -186,7 +186,9 @@ namespace Volo.Abp.Cli.ProjectModification await ProjectNugetPackageAdder.AddAsync(targetProjectFile, nugetPackage); } - if (!module.NpmPackages.IsNullOrEmpty()) + var mvcNpmPackages = module.NpmPackages?.Where(p => p.ApplicationType.HasFlag(NpmApplicationType.Mvc)).ToList(); + + if (!mvcNpmPackages.IsNullOrEmpty()) { var targetProjects = ProjectFinder.FindNpmTargetProjectFile(projectFiles); if (targetProjects.Any()) @@ -195,8 +197,7 @@ namespace Volo.Abp.Cli.ProjectModification foreach (var targetProject in targetProjects) { - foreach (var npmPackage in module.NpmPackages.Where(p => - p.ApplicationType.HasFlag(NpmApplicationType.Mvc))) + foreach (var npmPackage in mvcNpmPackages) { await ProjectNpmPackageAdder.AddAsync(Path.GetDirectoryName(targetProject), npmPackage); } @@ -222,7 +223,7 @@ namespace Volo.Abp.Cli.ProjectModification } var dbMigrationsProject = projectFiles.FirstOrDefault(p => p.EndsWith(".DbMigrations.csproj")); - + if (dbMigrationsProject == null) { Logger.LogDebug("Solution doesn't have a \".DbMigrations\" project."); @@ -241,7 +242,7 @@ namespace Volo.Abp.Cli.ProjectModification if (addedNewBuilder && !skipDbMigrations) { - EfCoreMigrationAdder.AddMigration(dbMigrationsProject, module.Name, startupProject); + EfCoreMigrationAdder.AddMigration(dbMigrationsProject, module.Name, startupProject); } } @@ -274,4 +275,4 @@ namespace Volo.Abp.Cli.ProjectModification .Any(p => p.EndsWith(".IdentityServer") || p.EndsWith(".HttpApi.Host")); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpListExtensions.cs b/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpListExtensions.cs index ec7a640a39..ac71649793 100644 --- a/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpListExtensions.cs +++ b/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpListExtensions.cs @@ -9,6 +9,14 @@ namespace System.Collections.Generic /// public static class AbpListExtensions { + public static void InsertRange(this IList source, int index, IEnumerable items) + { + foreach (var item in items) + { + source.Insert(index++, item); + } + } + public static int FindIndex(this IList source, Predicate selector) { for (var i = 0; i < source.Count; ++i) @@ -182,7 +190,7 @@ namespace System.Collections.Generic /// Function to resolve the dependencies /// /// Returns a new list ordered by dependencies. - /// If A depends on B, then B will come before than A in the resulting list. + /// If A depends on B, then B will come before than A in the resulting list. /// public static List SortByDependencies(this IEnumerable source, Func> getDependencies) { @@ -202,14 +210,15 @@ namespace System.Collections.Generic } /// - /// + /// /// /// The type of the members of values. /// Item to resolve /// Function to resolve the dependencies /// List with the sortet items /// Dictionary with the visited items - private static void SortByDependenciesVisit(T item, Func> getDependencies, List sorted, Dictionary visited) + private static void SortByDependenciesVisit(T item, Func> getDependencies, List sorted, + Dictionary visited) { bool inProcess; var alreadyVisited = visited.TryGetValue(item, out inProcess); diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EntityHistory/EntityHistoryHelper.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EntityHistory/EntityHistoryHelper.cs index 796c6e20fb..50de4f1b56 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EntityHistory/EntityHistoryHelper.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EntityHistory/EntityHistoryHelper.cs @@ -242,7 +242,7 @@ namespace Volo.Abp.EntityFrameworkCore.EntityHistory } } - if (IsBaseAuditProperty(propertyInfo, entityType)) + if (propertyInfo != null && IsBaseAuditProperty(propertyInfo, entityType)) { return false; } diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs index 533b76aa6c..af9eb59b7f 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs @@ -17,7 +17,6 @@ using Volo.Abp.Http.Modeling; using Volo.Abp.Http.ProxyScripting.Generators; using Volo.Abp.Json; using Volo.Abp.MultiTenancy; -using Volo.Abp.Reflection; using Volo.Abp.Threading; using Volo.Abp.Tracing; diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs index dcb8f28dff..c3ea13da43 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Modularity; +using Volo.Abp.Json.Newtonsoft; +using Volo.Abp.Modularity; using Volo.Abp.Timing; namespace Volo.Abp.Json @@ -6,6 +7,12 @@ namespace Volo.Abp.Json [DependsOn(typeof(AbpTimingModule))] public class AbpJsonModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Converters.Add(); + }); + } } } diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs new file mode 100644 index 0000000000..cb1c3d9f65 --- /dev/null +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json; +using Volo.Abp.Collections; + +namespace Volo.Abp.Json.Newtonsoft +{ + public class AbpNewtonsoftJsonSerializerOptions + { + public ITypeList Converters { get; } + + public AbpNewtonsoftJsonSerializerOptions() + { + Converters = new TypeList(); + } + } +} diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs index 99252b8448..20e49ac817 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs @@ -1,4 +1,8 @@ using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Volo.Abp.DependencyInjection; @@ -7,14 +11,19 @@ namespace Volo.Abp.Json.Newtonsoft { public class NewtonsoftJsonSerializer : IJsonSerializer, ITransientDependency { - private readonly AbpJsonIsoDateTimeConverter _dateTimeConverter; - private static readonly CamelCaseExceptDictionaryKeysResolver SharedCamelCaseExceptDictionaryKeysResolver = new CamelCaseExceptDictionaryKeysResolver(); - public NewtonsoftJsonSerializer(AbpJsonIsoDateTimeConverter dateTimeConverter) + protected List Converters { get; } + + public NewtonsoftJsonSerializer( + IOptions options, + IServiceProvider serviceProvider) { - _dateTimeConverter = dateTimeConverter; + Converters = options.Value + .Converters + .Select(c => (JsonConverter) serviceProvider.GetRequiredService(c)) + .ToList(); } public string Serialize(object obj, bool camelCase = true, bool indented = false) @@ -36,8 +45,8 @@ namespace Volo.Abp.Json.Newtonsoft { var settings = new JsonSerializerSettings(); - settings.Converters.Insert(0, _dateTimeConverter); - + settings.Converters.InsertRange(0, Converters); + if (camelCase) { settings.ContractResolver = SharedCamelCaseExceptDictionaryKeysResolver; @@ -47,7 +56,7 @@ namespace Volo.Abp.Json.Newtonsoft { settings.Formatting = Formatting.Indented; } - + return settings; } @@ -63,4 +72,4 @@ namespace Volo.Abp.Json.Newtonsoft } } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PeopleAppService_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PeopleAppService_Tests.cs index 96a79d8971..aae7345908 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PeopleAppService_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PeopleAppService_Tests.cs @@ -83,7 +83,6 @@ namespace Volo.Abp.AspNetCore.Mvc (await _personRepository.FindAsync(resultDto.Id)).ShouldNotBeNull(); } - [Fact] public async Task Update_Test() { @@ -170,4 +169,4 @@ namespace Volo.Abp.AspNetCore.Mvc douglas.Phones.Any(p => p.Number == firstPhone.Number).ShouldBeFalse(); } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.Core.Tests/System/Collections/Generic/AbpListExtensions_Tests.cs b/framework/test/Volo.Abp.Core.Tests/System/Collections/Generic/AbpListExtensions_Tests.cs index 9c8926f38a..618b8769dc 100644 --- a/framework/test/Volo.Abp.Core.Tests/System/Collections/Generic/AbpListExtensions_Tests.cs +++ b/framework/test/Volo.Abp.Core.Tests/System/Collections/Generic/AbpListExtensions_Tests.cs @@ -7,6 +7,20 @@ namespace System.Collections.Generic { public class AbpListExtensions_Tests { + [Fact] + public void InsertRange() + { + var list = Enumerable.Range(1, 3).ToList(); + list.InsertRange(1, new[] {7, 8, 9}); + + list[0].ShouldBe(1); + list[1].ShouldBe(7); + list[2].ShouldBe(8); + list[3].ShouldBe(9); + list[4].ShouldBe(2); + list[5].ShouldBe(3); + } + [Fact] public void InsertAfter() { @@ -191,7 +205,7 @@ namespace System.Collections.Generic { var list = RandomHelper .GenerateRandomizedList(new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G'}); - + list = list.SortByDependencies(c => dependencies[c]); foreach (var dependency in dependencies) @@ -204,4 +218,4 @@ namespace System.Collections.Generic } } } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/AbpFeatureManagementApplicationContractsModule.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/AbpFeatureManagementApplicationContractsModule.cs index 8b71e3f85b..37b49f2d8a 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/AbpFeatureManagementApplicationContractsModule.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/AbpFeatureManagementApplicationContractsModule.cs @@ -1,4 +1,5 @@ using Volo.Abp.Application; +using Volo.Abp.Json.Newtonsoft; using Volo.Abp.Modularity; using Volo.Abp.VirtualFileSystem; @@ -16,6 +17,11 @@ namespace Volo.Abp.FeatureManagement { options.FileSets.AddEmbedded(); }); + + Configure(options => + { + options.Converters.Add(); + }); } } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/StringValueTypeJsonConverter.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/StringValueTypeJsonConverter.cs new file mode 100644 index 0000000000..0ee276cce1 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/StringValueTypeJsonConverter.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Validation.StringValues; + +namespace Volo.Abp.FeatureManagement +{ + public class StringValueTypeJsonConverter : JsonConverter, ITransientDependency + { + public override bool CanWrite => false; + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(IStringValueType); + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + throw new NotImplementedException("This method should not be called to write (since CanWrite is false)."); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType != JsonToken.StartObject) + { + return null; + } + + var jsonObject = JObject.Load(reader); + + var stringValue = CreateStringValueTypeByName(jsonObject, jsonObject["name"].ToString()); + foreach (var o in serializer.Deserialize>( + new JsonTextReader(new StringReader(jsonObject["properties"].ToString())))) + { + stringValue[o.Key] = o.Value; + } + + stringValue.Validator = CreateValueValidatorByName(jsonObject["validator"], jsonObject["validator"]["name"].ToString()); + foreach (var o in serializer.Deserialize>( + new JsonTextReader(new StringReader(jsonObject["validator"]["properties"].ToString())))) + { + stringValue.Validator[o.Key] = o.Value; + } + + return stringValue; + } + + protected virtual IStringValueType CreateStringValueTypeByName(JObject jObject, string name) + { + if (name == "SelectionStringValueType") + { + var selectionStringValueType = new SelectionStringValueType(); + if (jObject["itemSource"].HasValues) + { + selectionStringValueType.ItemSource = new StaticSelectionStringValueItemSource(jObject["itemSource"]["items"] + .Select(item => new LocalizableSelectionStringValueItem() + { + Value = item["value"].ToString(), + DisplayText = new LocalizableStringInfo(item["displayText"]["resourceName"].ToString(), item["displayText"]["name"].ToString()) + }).ToArray()); + } + + return selectionStringValueType; + } + + return name switch + { + "FreeTextStringValueType" => new FreeTextStringValueType(), + "ToggleStringValueType" => new ToggleStringValueType(), + _ => throw new ArgumentException($"{nameof(IStringValueType)} named {name} was not found!") + }; + } + + protected virtual IValueValidator CreateValueValidatorByName(JToken jObject, string name) + { + return name switch + { + "NULL" => new AlwaysValidValueValidator(), + "BOOLEAN" => new BooleanValueValidator(), + "NUMERIC" => new NumericValueValidator(), + "STRING" => new StringValueValidator(), + _ => throw new ArgumentException($"{nameof(IValueValidator)} named {name} was not found!") + }; + } + } +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/UpdateFeatureDto.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/UpdateFeatureDto.cs index 26b351ee9e..7fc367b0d2 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/UpdateFeatureDto.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/UpdateFeatureDto.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Volo.Abp.FeatureManagement +namespace Volo.Abp.FeatureManagement { public class UpdateFeatureDto { diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs index 6c9db9bade..ab097a54a6 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs @@ -1,13 +1,9 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.AspNetCore.Authorization; -using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; -using Volo.Abp.Application.Services; using Volo.Abp.Features; namespace Volo.Abp.FeatureManagement diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureAppService_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureAppService_Tests.cs index b86e6be013..b257f873cd 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureAppService_Tests.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureAppService_Tests.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using NSubstitute; diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/StringValueJsonConverter_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/StringValueJsonConverter_Tests.cs new file mode 100644 index 0000000000..528e0de5e8 --- /dev/null +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/StringValueJsonConverter_Tests.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Shouldly; +using Volo.Abp.Json; +using Volo.Abp.Validation.StringValues; +using Xunit; + +namespace Volo.Abp.FeatureManagement +{ + public class StringValueJsonConverter_Tests : FeatureManagementApplicationTestBase + { + private readonly IJsonSerializer _jsonSerializer; + + public StringValueJsonConverter_Tests() + { + _jsonSerializer = GetRequiredService(); + } + + [Fact] + public void Should_Serialize_And_Deserialize() + { + var featureListDto = new FeatureListDto + { + Features = new List + { + new FeatureDto + { + ValueType = new FreeTextStringValueType + { + Validator = new BooleanValueValidator() + } + }, + new FeatureDto + { + ValueType = new SelectionStringValueType + { + ItemSource = new StaticSelectionStringValueItemSource( + new LocalizableSelectionStringValueItem + { + Value = "TestValue", + DisplayText = new LocalizableStringInfo("TestResourceName", "TestName") + }), + Validator = new AlwaysValidValueValidator() + } + }, + new FeatureDto + { + ValueType = new ToggleStringValueType + { + Validator = new NumericValueValidator + { + MaxValue = 1000, + MinValue = 10 + } + } + } + } + }; + + var serialized = _jsonSerializer.Serialize(featureListDto, indented: true); + var featureListDto2 = _jsonSerializer.Deserialize(serialized); + + featureListDto2.Features[0].ValueType.ShouldBeOfType(); + featureListDto2.Features[0].ValueType.Validator.ShouldBeOfType(); + + featureListDto2.Features[1].ValueType.ShouldBeOfType(); + featureListDto2.Features[1].ValueType.Validator.ShouldBeOfType(); + featureListDto2.Features[1].ValueType.As().ItemSource.Items.ShouldBeOfType(); + featureListDto2.Features[1].ValueType.As().ItemSource.Items.ShouldContain(x => + x.Value == "TestValue" && x.DisplayText.ResourceName == "TestResourceName" && + x.DisplayText.Name == "TestName"); + + featureListDto2.Features[2].ValueType.ShouldBeOfType(); + featureListDto2.Features[2].ValueType.Validator.ShouldBeOfType(); + featureListDto2.Features[2].ValueType.Validator.As().MaxValue.ShouldBe(1000); + featureListDto2.Features[2].ValueType.Validator.As().MinValue.ShouldBe(10); + } + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs index 137341a25e..0b1dbe9e3b 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs @@ -95,8 +95,8 @@ namespace Volo.Abp.Identity.EntityFrameworkCore string correlationId = null) { return DbSet.AsNoTracking() - .WhereIf(startTime.HasValue, securityLog => securityLog.CreationTime >= startTime) - .WhereIf(endTime.HasValue, securityLog => securityLog.CreationTime >= endTime) + .WhereIf(startTime.HasValue, securityLog => securityLog.CreationTime >= startTime.Value) + .WhereIf(endTime.HasValue, securityLog => securityLog.CreationTime < endTime.Value.AddDays(1).Date) .WhereIf(!applicationName.IsNullOrWhiteSpace(), securityLog => securityLog.ApplicationName == applicationName) .WhereIf(!identity.IsNullOrWhiteSpace(), securityLog => securityLog.Identity == identity) .WhereIf(!action.IsNullOrWhiteSpace(), securityLog => securityLog.Action == action) diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs index 4336abaaae..cbf20e0393 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs @@ -101,8 +101,8 @@ namespace Volo.Abp.Identity.MongoDB string correlationId = null) { return GetMongoQueryable() - .WhereIf(startTime.HasValue, securityLog => securityLog.CreationTime >= startTime) - .WhereIf(endTime.HasValue, securityLog => securityLog.CreationTime >= endTime) + .WhereIf(startTime.HasValue, securityLog => securityLog.CreationTime >= startTime.Value) + .WhereIf(endTime.HasValue, securityLog => securityLog.CreationTime < endTime.Value.AddDays(1).Date) .WhereIf(!applicationName.IsNullOrWhiteSpace(), securityLog => securityLog.ApplicationName == applicationName) .WhereIf(!identity.IsNullOrWhiteSpace(), securityLog => securityLog.Identity == identity) diff --git a/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo.Abp.Users.EntityFrameworkCore.Tests.csproj b/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo.Abp.Users.EntityFrameworkCore.Tests.csproj deleted file mode 100644 index 912daad74d..0000000000 --- a/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo.Abp.Users.EntityFrameworkCore.Tests.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - netcoreapp2.2 - Volo.Abp.Users.EntityFrameworkCore.Tests - Volo.Abp.Users.EntityFrameworkCore.Tests - latest - true - false - false - false - - - - - - - - - - - - - - diff --git a/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo.Abp.Users.EntityFrameworkCore.Tests.csproj.DotSettings b/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo.Abp.Users.EntityFrameworkCore.Tests.csproj.DotSettings deleted file mode 100644 index 58ad6c8854..0000000000 --- a/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo.Abp.Users.EntityFrameworkCore.Tests.csproj.DotSettings +++ /dev/null @@ -1,2 +0,0 @@ - - CSharp71 \ No newline at end of file diff --git a/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo/Abp/Users/EntityFrameworkCore/AbpUserRepository_Tests.cs b/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo/Abp/Users/EntityFrameworkCore/AbpUserRepository_Tests.cs deleted file mode 100644 index 7f92ae7483..0000000000 --- a/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo/Abp/Users/EntityFrameworkCore/AbpUserRepository_Tests.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Volo.Abp.Users.EntityFrameworkCore -{ - public class AbpUserRepository_Tests : AbpUserRepository_Tests - { - - } -} diff --git a/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo/Abp/Users/EntityFrameworkCore/AbpUsersEntityFrameworkCoreTestModule.cs b/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo/Abp/Users/EntityFrameworkCore/AbpUsersEntityFrameworkCoreTestModule.cs deleted file mode 100644 index 7a19077afe..0000000000 --- a/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo/Abp/Users/EntityFrameworkCore/AbpUsersEntityFrameworkCoreTestModule.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.Modularity; -using Volo.Abp.Uow; - -namespace Volo.Abp.Users.EntityFrameworkCore -{ - [DependsOn( - typeof(AbpUsersTestsSharedModule), - typeof(AbpUsersEntityFrameworkCoreModule) - )] - public class AbpUsersEntityFrameworkCoreTestModule : AbpModule - { - public override void ConfigureServices(IServiceCollection services) - { - services.AddEntityFrameworkInMemoryDatabase(); - - var databaseName = Guid.NewGuid().ToString(); - - services.Configure(options => - { - options.Configure(context => - { - context.DbContextOptions.UseInMemoryDatabase(databaseName); - }); - }); - - services.Configure(options => - { - options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; //EF in-memory database does not support transactions - }); - - services.AddAssemblyOf(); - } - } -} diff --git a/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo/Abp/Users/EntityFrameworkCore/ExternalUserLookupService_Tests.cs b/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo/Abp/Users/EntityFrameworkCore/ExternalUserLookupService_Tests.cs deleted file mode 100644 index 26fd633808..0000000000 --- a/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo/Abp/Users/EntityFrameworkCore/ExternalUserLookupService_Tests.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Volo.Abp.Users.EntityFrameworkCore -{ - public class ExternalUserLookupService_Tests : ExternalUserLookupService_Tests - { - - } -} \ No newline at end of file diff --git a/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo/Abp/Users/EntityFrameworkCore/LocalUserLookupService_Tests.cs b/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo/Abp/Users/EntityFrameworkCore/LocalUserLookupService_Tests.cs deleted file mode 100644 index 089fd35dbe..0000000000 --- a/modules/users/test/Volo.Abp.Users.EntityFrameworkCore.Tests/Volo/Abp/Users/EntityFrameworkCore/LocalUserLookupService_Tests.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Volo.Abp.Users.EntityFrameworkCore -{ - public class LocalUserLookupService_Tests : LocalUserLookupService_Tests - { - - } -} \ No newline at end of file diff --git a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo.Abp.Users.MongoDB.Tests.csproj b/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo.Abp.Users.MongoDB.Tests.csproj deleted file mode 100644 index 06b92ffd34..0000000000 --- a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo.Abp.Users.MongoDB.Tests.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - netcoreapp2.2 - Volo.Abp.Users.MongoDB.Tests - Volo.Abp.Users.MongoDB.Tests - latest - true - false - false - false - - - - - - - - - - - - - - diff --git a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/AbpUserRepository_Tests.cs b/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/AbpUserRepository_Tests.cs deleted file mode 100644 index a54790410e..0000000000 --- a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/AbpUserRepository_Tests.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Volo.Abp.Users.MongoDB -{ - [Collection(MongoTestCollection.Name)] - public class AbpUserRepository_Tests : AbpUserRepository_Tests - { - - } -} diff --git a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/AbpUsersMongoDbTestModule.cs b/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/AbpUsersMongoDbTestModule.cs deleted file mode 100644 index 560d6287d7..0000000000 --- a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/AbpUsersMongoDbTestModule.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using Microsoft.Extensions.DependencyInjection; -using Mongo2Go; -using Volo.Abp.Data; -using Volo.Abp.Modularity; - -namespace Volo.Abp.Users.MongoDB -{ - [DependsOn( - typeof(AbpUsersMongoDbModule), - typeof(AbpUsersTestsSharedModule) - )] - public class AbpUsersMongoDbTestModule : AbpModule - { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - - public override void ConfigureServices(IServiceCollection services) - { - var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + - "Db_" + - Guid.NewGuid().ToString("N"); - - Configure(options => - { - options.ConnectionStrings.Default = connectionString; - }); - - services.AddAssemblyOf(); - } - } -} diff --git a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/ExternalUserLookupService_Tests.cs b/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/ExternalUserLookupService_Tests.cs deleted file mode 100644 index 764cadedf4..0000000000 --- a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/ExternalUserLookupService_Tests.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Volo.Abp.Users.MongoDB -{ - [Collection(MongoTestCollection.Name)] - public class ExternalUserLookupService_Tests : ExternalUserLookupService_Tests - { - - } -} diff --git a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/LocalUserLookupService_Tests.cs b/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/LocalUserLookupService_Tests.cs deleted file mode 100644 index b52af21d3e..0000000000 --- a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/LocalUserLookupService_Tests.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Volo.Abp.Users.MongoDB -{ - [Collection(MongoTestCollection.Name)] - public class LocalUserLookupService_Tests : LocalUserLookupService_Tests - { - - } -} diff --git a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/MongoDbFixture.cs b/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/MongoDbFixture.cs deleted file mode 100644 index 4f8c6eea2f..0000000000 --- a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/MongoDbFixture.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using Mongo2Go; - -namespace Volo.Abp.Users.MongoDB -{ - public class MongoDbFixture : IDisposable - { - private static readonly MongoDbRunner MongoDbRunner; - public static readonly string ConnectionString; - - static MongoDbFixture() - { - MongoDbRunner = MongoDbRunner.Start(); - ConnectionString = MongoDbRunner.ConnectionString; - } - - public void Dispose() - { - MongoDbRunner?.Dispose(); - } - } -} diff --git a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/MongoTestCollection.cs b/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/MongoTestCollection.cs deleted file mode 100644 index d8b6a718d8..0000000000 --- a/modules/users/test/Volo.Abp.Users.MongoDB.Tests/Volo/Abp/Users/MongoDB/MongoTestCollection.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Xunit; - -namespace Volo.Abp.Users.MongoDB -{ - [CollectionDefinition(Name)] - public class MongoTestCollection : ICollectionFixture - { - public const string Name = "MongoDB Collection"; - } -} diff --git a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo.Abp.Users.Tests.Shared.csproj b/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo.Abp.Users.Tests.Shared.csproj deleted file mode 100644 index ececb4eddd..0000000000 --- a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo.Abp.Users.Tests.Shared.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - netcoreapp2.2 - Volo.Abp.Users.Tests.Shared - Volo.Abp.Users.Tests.Shared - latest - true - false - false - false - - - - - - - - - - - - - - - - - - - - diff --git a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo.Abp.Users.Tests.Shared.csproj.DotSettings b/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo.Abp.Users.Tests.Shared.csproj.DotSettings deleted file mode 100644 index 58ad6c8854..0000000000 --- a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo.Abp.Users.Tests.Shared.csproj.DotSettings +++ /dev/null @@ -1,2 +0,0 @@ - - CSharp71 \ No newline at end of file diff --git a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUserRepository_Tests.cs b/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUserRepository_Tests.cs deleted file mode 100644 index 40d8de9572..0000000000 --- a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUserRepository_Tests.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Shouldly; -using Volo.Abp.Modularity; -using Xunit; - -namespace Volo.Abp.Users -{ - public abstract class AbpUserRepository_Tests : AbpUsersTestBase - where TStartupModule : IAbpModule - { - private readonly AbpUsersLocalTestData _localTestData; - private readonly IAbpUserRepository _userRepository; - - protected AbpUserRepository_Tests() - { - _userRepository = GetRequiredService(); - _localTestData = GetRequiredService(); - } - - [Fact] - public async Task FindAsync() - { - var john = await _userRepository.FindAsync(_localTestData.John.Id); - john.ShouldNotBeNull(); - john.UserName.ShouldBe(_localTestData.John.UserName); - - //Undefined user - (await _userRepository.FindAsync(Guid.NewGuid())).ShouldBeNull(); - } - - [Fact] - public async Task FindByUserNameAsync() - { - var john = await _userRepository.FindByUserNameAsync(_localTestData.John.UserName); - john.ShouldNotBeNull(); - john.Id.ShouldBe(_localTestData.John.Id); - - //Undefined user - (await _userRepository.FindByUserNameAsync("undefined-user")).ShouldBeNull(); - } - - [Fact] - public async Task GetListAsync() - { - (await _userRepository.GetListAsync(new Guid[0])).Any().ShouldBeFalse(); - (await _userRepository.GetListAsync(new[] { _localTestData.John.Id })).Count.ShouldBe(1); - (await _userRepository.GetListAsync(new[] { _localTestData.John.Id, _localTestData.David.Id })).Count.ShouldBe(2); - (await _userRepository.GetListAsync(new[] { _localTestData.John.Id, _localTestData.David.Id, Guid.NewGuid() })).Count.ShouldBe(2); - } - } -} diff --git a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersExternalTestData.cs b/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersExternalTestData.cs deleted file mode 100644 index dba3c573de..0000000000 --- a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersExternalTestData.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Users -{ - public class AbpUsersExternalTestData : ISingletonDependency - { - public IAbpUserData David { get; } - public IAbpUserData Neo { get; } - - public AbpUsersExternalTestData(AbpUsersLocalTestData localTestData) - { - Neo = new AbpUserData(Guid.NewGuid(), "neo"); - David = localTestData.David.ToAbpUserData(); - } - - public List GetAllUsers() - { - return new List - { - David, - Neo - }; - } - } -} \ No newline at end of file diff --git a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersLocalTestData.cs b/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersLocalTestData.cs deleted file mode 100644 index 2382a3f93e..0000000000 --- a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersLocalTestData.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Users -{ - public class AbpUsersLocalTestData : ISingletonDependency - { - public AbpUser John { get; } - public AbpUser David { get; } - - public AbpUsersLocalTestData() - { - John = new AbpUser(Guid.NewGuid(), "john"); - David = new AbpUser(Guid.NewGuid(), "david", "david@abp.io"); - } - } -} \ No newline at end of file diff --git a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersTestBase.cs b/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersTestBase.cs deleted file mode 100644 index e36f485a70..0000000000 --- a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersTestBase.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Volo.Abp.Modularity; -using Volo.Abp.Testing; - -namespace Volo.Abp.Users -{ - public abstract class AbpUsersTestBase : AbpIntegratedTest - where TStartupModule : IAbpModule - { - protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) - { - options.UseAutofac(); - } - } -} diff --git a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersTestDataBuilder.cs b/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersTestDataBuilder.cs deleted file mode 100644 index a3602491be..0000000000 --- a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersTestDataBuilder.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Users -{ - public class AbpUsersTestDataBuilder : ITransientDependency - { - private readonly IAbpUserRepository _userRepository; - private readonly AbpUsersLocalTestData _localTestData; - - public AbpUsersTestDataBuilder( - IAbpUserRepository userRepository, - AbpUsersLocalTestData localTestData) - { - _userRepository = userRepository; - _localTestData = localTestData; - } - - public void Build() - { - AddUsers(); - } - - private void AddUsers() - { - _userRepository.Insert(_localTestData.John); - _userRepository.Insert(_localTestData.David); - } - } -} \ No newline at end of file diff --git a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersTestsSharedModule.cs b/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersTestsSharedModule.cs deleted file mode 100644 index 50da79183d..0000000000 --- a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/AbpUsersTestsSharedModule.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Autofac; -using Volo.Abp.Modularity; - -namespace Volo.Abp.Users -{ - [DependsOn( - typeof(AbpUsersDomainModule), - typeof(AbpTestBaseModule), - typeof(AbpAutofacModule) - )] - public class AbpUsersTestsSharedModule : AbpModule - { - public override void ConfigureServices(IServiceCollection services) - { - services.AddAssemblyOf(); - } - - public override void OnApplicationInitialization(ApplicationInitializationContext context) - { - SeedTestData(context); - } - - private static void SeedTestData(ApplicationInitializationContext context) - { - using (var scope = context.ServiceProvider.CreateScope()) - { - scope.ServiceProvider - .GetRequiredService() - .Build(); - } - } - } -} diff --git a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/ExternalUserLookupService_Tests.cs b/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/ExternalUserLookupService_Tests.cs deleted file mode 100644 index 8916607ea7..0000000000 --- a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/ExternalUserLookupService_Tests.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Shouldly; -using Volo.Abp.Modularity; -using Xunit; - -namespace Volo.Abp.Users -{ - public abstract class ExternalUserLookupService_Tests : AbpUsersTestBase - where TStartupModule : IAbpModule - { - private readonly IAbpUserLookupService _lookupService; - private readonly AbpUsersLocalTestData _localTestData; - private readonly AbpUsersExternalTestData _externalTestData; - - protected ExternalUserLookupService_Tests() - { - _lookupService = GetRequiredService(); - _localTestData = GetRequiredService(); - _externalTestData = GetRequiredService(); - } - - protected override void AfterAddApplication(IServiceCollection services) - { - services.AddTransient(); - } - - [Fact] - public async Task FindByUserNameAsync() - { - (await GetRequiredService().FindByUserNameAsync(_localTestData.John.UserName)).ShouldNotBeNull(); - - (await _lookupService.FindByUserNameAsync("undefined-user")).ShouldBeNull(); - (await _lookupService.FindByUserNameAsync(_localTestData.John.UserName)).ShouldBeNull(); //Because it's not available in the external provider. And this will delete the user! - (await _lookupService.FindByUserNameAsync(_localTestData.David.UserName)).ShouldNotBeNull(); - (await _lookupService.FindByUserNameAsync(_externalTestData.Neo.UserName)).ShouldNotBeNull(); - - (await GetRequiredService().FindByUserNameAsync(_localTestData.John.UserName)).ShouldBeNull(); - } - - [Fact] - public async Task FindByIdAsync() - { - (await GetRequiredService().FindAsync(_localTestData.John.Id)).ShouldNotBeNull(); - - (await _lookupService.FindByIdAsync(Guid.NewGuid())).ShouldBeNull(); - (await _lookupService.FindByIdAsync(_localTestData.John.Id)).ShouldBeNull(); //Because it's not available in the external provider. And this will delete the user! - (await _lookupService.FindByIdAsync(_localTestData.David.Id)).ShouldNotBeNull(); - (await _lookupService.FindByIdAsync(_externalTestData.Neo.Id)).ShouldNotBeNull(); - - (await GetRequiredService().FindAsync(_localTestData.John.Id)).ShouldBeNull(); - } - - public class TestExternalAbpUserLookupServiceProvider : IExternalAbpUserLookupServiceProvider - { - private readonly AbpUsersExternalTestData _externalTestData; - - public TestExternalAbpUserLookupServiceProvider(AbpUsersExternalTestData externalTestData) - { - _externalTestData = externalTestData; - } - - public Task FindByIdAsync(Guid id, CancellationToken cancellationToken = default) - { - return Task.FromResult(_externalTestData.GetAllUsers().FirstOrDefault(u => u.Id == id)); - } - - public Task FindByUserNameAsync(string userName, CancellationToken cancellationToken = default) - { - return Task.FromResult(_externalTestData.GetAllUsers().FirstOrDefault(u => u.UserName == userName)); - } - } - } -} \ No newline at end of file diff --git a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/LocalUserLookupService_Tests.cs b/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/LocalUserLookupService_Tests.cs deleted file mode 100644 index 9e128f14cc..0000000000 --- a/modules/users/test/Volo.Abp.Users.Tests.Shared/Volo/Abp/Users/LocalUserLookupService_Tests.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Threading.Tasks; -using Shouldly; -using Volo.Abp.Modularity; -using Xunit; - -namespace Volo.Abp.Users -{ - public abstract class LocalUserLookupService_Tests : AbpUsersTestBase - where TStartupModule : IAbpModule - { - private readonly IAbpUserLookupService _lookupService; - private readonly AbpUsersLocalTestData _localTestData; - - protected LocalUserLookupService_Tests() - { - _lookupService = GetRequiredService(); - _localTestData = GetRequiredService(); - } - - [Fact] - public async Task FindByUserNameAsync() - { - (await _lookupService.FindByUserNameAsync(_localTestData.John.UserName)).ShouldNotBeNull(); - (await _lookupService.FindByUserNameAsync(_localTestData.David.UserName)).ShouldNotBeNull(); - (await _lookupService.FindByUserNameAsync("undefined-user")).ShouldBeNull(); - } - } -} diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index 4b28ca5849..4098c8813d 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -16,7 +16,7 @@ "scripts:build": "cd scripts && yarn && yarn build", "prepare:workspace": "yarn scripts:build --noInstall", "ci": "yarn ng lint && yarn prepare:workspace && yarn ci:test && yarn ci:build", - "ci:test": "ng test --coverage=false", + "ci:test": "ng test --coverage=false --silent", "ci:build": "cd scripts && yarn build:prod", "lerna": "lerna", "compile:ivy": "yarn ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points --tsconfig './tsconfig.prod.json' --source node_modules --async false", @@ -51,7 +51,7 @@ "@fortawesome/fontawesome-free": "^5.13.0", "@ng-bootstrap/ng-bootstrap": "^6.1.0", "@ngneat/spectator": "^5.11.0", - "@ngx-validate/core": "^0.0.9", + "@ngx-validate/core": "^0.0.10", "@ngxs/devtools-plugin": "^3.6.2", "@ngxs/logger-plugin": "^3.6.2", "@ngxs/router-plugin": "^3.6.2", diff --git a/npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts index 553fcc6d7e..9a4166e7cc 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts @@ -77,7 +77,8 @@ describe('InitialUtils', () => { const injectorSpy = jest.spyOn(injector, 'get'); const store = spectator.inject(Store); store.selectSnapshot.andCallFake(selector => selector({ SessionState: { language: 'tr' } })); - injectorSpy.mockReturnValue(store); + injectorSpy.mockReturnValueOnce(store); + injectorSpy.mockReturnValueOnce({ cultureNameToLocaleFileNameMapping: {} }); expect(typeof localeInitializer(injector)).toBe('function'); expect(await localeInitializer(injector)()).toBe('resolved'); }); diff --git a/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts index 4dc9d51771..963610cdfd 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/localization.service.spec.ts @@ -1,3 +1,4 @@ +import { CORE_OPTIONS } from '../tokens/options.token'; import { Router } from '@angular/router'; import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest'; import { Actions, Store } from '@ngxs/store'; @@ -13,7 +14,10 @@ describe('LocalizationService', () => { service: LocalizationService, entryComponents: [], mocks: [Store, Router], - providers: [{ provide: Actions, useValue: new Subject() }], + providers: [ + { provide: Actions, useValue: new Subject() }, + { provide: CORE_OPTIONS, useValue: { cultureNameToLocaleFileNameMapping: {} } }, + ], }); beforeEach(() => { diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html index ef1647b540..30d115216b 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html @@ -1,15 +1,13 @@
- + @@ -19,28 +17,26 @@ {{ prop.displayName | abpLocalization }} {{ asterisk }}
- + - + - + - + diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts index f796c2d5fe..4a28b14f22 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts @@ -1,14 +1,17 @@ -import { TrackByService } from '@abp/ng.core'; +import { ABP, TrackByService } from '@abp/ng.core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, Optional, + SimpleChanges, SkipSelf, + OnChanges, } from '@angular/core'; -import { ControlContainer, Validators } from '@angular/forms'; +import { ControlContainer, Validators, ValidatorFn } from '@angular/forms'; import { NgbDateAdapter, NgbTimeAdapter } from '@ng-bootstrap/ng-bootstrap'; +import { Observable, of } from 'rxjs'; import { DateAdapter } from '../../adapters/date.adapter'; import { TimeAdapter } from '../../adapters/time.adapter'; import { ePropType } from '../../enums/props.enum'; @@ -30,15 +33,23 @@ import { selfFactory } from '../../utils/factory.util'; { provide: NgbTimeAdapter, useClass: TimeAdapter }, ], }) -export class ExtensibleFormPropComponent { +export class ExtensibleFormPropComponent implements OnChanges { @Input() data: PropData; @Input() prop: FormProp; + options$: Observable[]> = of([]); + + validators: ValidatorFn[] = []; + + readonly: boolean; + + disabled: boolean; + constructor(public readonly cdRef: ChangeDetectorRef, public readonly track: TrackByService) {} - getAsterisk(prop: FormProp, data: PropData): string { - return prop.validators(data).some(validator => validator === Validators.required) ? '*' : ''; + get asterisk(): string { + return this.validators.some(validator => validator === Validators.required) ? '*' : ''; } getComponent(prop: FormProp): string { @@ -77,4 +88,16 @@ export class ExtensibleFormPropComponent { return 'hidden'; } } + + ngOnChanges({ prop }: SimpleChanges) { + const options = prop.currentValue.options; + const readonly = prop.currentValue.readonly; + const disabled = prop.currentValue.disabled; + const validators = prop.currentValue.validators; + + if (options) this.options$ = options(this.data); + if (readonly) this.readonly = readonly(this.data); + if (disabled) this.disabled = disabled(this.data); + if (validators) this.validators = validators(this.data); + } } diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form.component.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form.component.ts index 995b29b8d1..f15f173faa 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form.component.ts +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form.component.ts @@ -1,20 +1,16 @@ import { TrackByService } from '@abp/ng.core'; import { - AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Input, - OnDestroy, Optional, QueryList, SkipSelf, ViewChildren, } from '@angular/core'; import { ControlContainer, FormGroup } from '@angular/forms'; -import { Subscription } from 'rxjs'; -import { debounceTime } from 'rxjs/operators'; import { EXTRA_PROPERTIES_KEY } from '../../constants/extra-properties'; import { FormPropList } from '../../models/form-props'; import { ExtensionsService } from '../../services/extensions.service'; @@ -35,7 +31,7 @@ import { ExtensibleFormPropComponent } from './extensible-form-prop.component'; }, ], }) -export class ExtensibleFormComponent implements AfterViewInit, OnDestroy { +export class ExtensibleFormComponent { @ViewChildren(ExtensibleFormPropComponent) formProps: QueryList; @@ -46,7 +42,6 @@ export class ExtensibleFormComponent implements AfterViewInit, OnDestro this.record = record; } - private subscription = new Subscription(); extraPropertiesKey = EXTRA_PROPERTIES_KEY; propList: FormPropList; record: R; @@ -66,17 +61,4 @@ export class ExtensibleFormComponent implements AfterViewInit, OnDestro private extensions: ExtensionsService, @Inject(EXTENSIONS_IDENTIFIER) private identifier: string, ) {} - - ngAfterViewInit() { - this.subscription.add( - this.form.statusChanges.pipe(debounceTime(0)).subscribe(() => { - this.formProps.forEach(prop => prop.cdRef.markForCheck()); - this.cdRef.detectChanges(); - }), - ); - } - - ngOnDestroy() { - this.subscription.unsubscribe(); - } } diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.html b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.html index d30b005a98..dc09088430 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.html +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.html @@ -27,11 +27,11 @@ [sortable]="prop.sortable" > - -
+ +
diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts index 7768d70c2c..adacc4efa8 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts @@ -9,6 +9,11 @@ import { LOCALE_ID, TemplateRef, TrackByFunction, + Type, + InjectionToken, + InjectFlags, + SimpleChanges, + OnChanges, } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -25,7 +30,7 @@ const DEFAULT_ACTIONS_COLUMN_WIDTH = 150; templateUrl: './extensible-table.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) -export class ExtensibleTableComponent { +export class ExtensibleTableComponent implements OnChanges { @Input() actionsText: string; @Input() data: R[]; @Input() list: ListService; @@ -35,6 +40,8 @@ export class ExtensibleTableComponent { } @Input() actionsTemplate: TemplateRef; + getInjected: (token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags) => T; + readonly columnWidths: number[]; readonly propList: EntityPropList; @@ -42,6 +49,8 @@ export class ExtensibleTableComponent { readonly trackByFn: TrackByFunction> = (_, item) => item.name; constructor(@Inject(LOCALE_ID) private locale: string, injector: Injector) { + // tslint:disable-next-line + this.getInjected = injector.get.bind(injector); const extensions = injector.get(ExtensionsService); const name = injector.get(EXTENSIONS_IDENTIFIER); this.propList = extensions.entityProps.get(name).props; @@ -85,4 +94,20 @@ export class ExtensibleTableComponent { }), ); } + + ngOnChanges({ data }: SimpleChanges) { + if (!data?.currentValue) return; + + this.data = data.currentValue.map((record, index) => { + this.propList.forEach(prop => { + const propData = { getInjected: this.getInjected, record, index } as any; + record[`_${prop.value.name}`] = { + visible: prop.value.visible(propData), + value: this.getContent(prop.value, propData), + }; + }); + + return record; + }); + } } diff --git a/npm/ng-packs/packages/theme-shared/package.json b/npm/ng-packs/packages/theme-shared/package.json index 542dd18d5f..d1b4be2dd7 100644 --- a/npm/ng-packs/packages/theme-shared/package.json +++ b/npm/ng-packs/packages/theme-shared/package.json @@ -10,7 +10,7 @@ "@abp/ng.core": "~3.0.4", "@fortawesome/fontawesome-free": "^5.13.1", "@ng-bootstrap/ng-bootstrap": "^6.1.0", - "@ngx-validate/core": "^0.0.9", + "@ngx-validate/core": "^0.0.10", "@swimlane/ngx-datatable": "^17.0.0", "bootstrap": "^4.5.0", "chart.js": "^2.9.3",