diff --git a/zero.Core/Api/CountriesApi.cs b/zero.Core/Api/CountriesApi.cs index 822b5c0e..a84d4da6 100644 --- a/zero.Core/Api/CountriesApi.cs +++ b/zero.Core/Api/CountriesApi.cs @@ -1,4 +1,5 @@ -using FluentValidation.Results; +using FluentValidation; +using FluentValidation.Results; using Raven.Client.Documents; using Raven.Client.Documents.Linq; using Raven.Client.Documents.Session; @@ -7,28 +8,33 @@ using System.Collections.Generic; using System.Threading.Tasks; using zero.Core.Entities; using zero.Core.Extensions; -using zero.Core.Validation; namespace zero.Core.Api { - public class CountriesApi : BackofficeApi, ICountriesApi + public class CountriesApi : BackofficeApi, ICountriesApi where T : ICountry { - public CountriesApi(IBackofficeStore store) : base(store) { } + IValidator Validator; - /// - public async Task GetById(string id) + public CountriesApi(IBackofficeStore store, IValidator validator) : base(store) { - return await GetById(id); + Validator = validator; } /// - public async Task> GetAll(string languageId) + public async Task GetById(string id) + { + return await GetById(id); + } + + + /// + public async Task> GetAll(string languageId) { using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { - return await session.Query() + return await session.Query() .Where(x => x.LanguageId == languageId) .OrderByDescending(x => x.IsPreferred) .ThenBy(x => x.Name) @@ -38,13 +44,13 @@ namespace zero.Core.Api /// - public async Task> GetByQuery(string languageId, ListQuery query) + public async Task> GetByQuery(string languageId, ListQuery query) { query.SearchSelector = country => country.Name; using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { - return await session.Query() + return await session.Query() .Where(x => x.LanguageId == languageId) .OrderByDescending(x => x.IsPreferred) .ThenBy(x => x.Name) @@ -54,13 +60,13 @@ namespace zero.Core.Api /// - public async Task> Save(Country model) + public async Task> Save(T model) { - ValidationResult validation = await new CountryValidator().ValidateAsync(model); + ValidationResult validation = await Validator.ValidateAsync(model); if (!validation.IsValid) { - return EntityResult.Fail(validation); + return EntityResult.Fail(validation); } if (model.Id.IsNullOrEmpty()) @@ -84,20 +90,20 @@ namespace zero.Core.Api } } - return EntityResult.Success(model); + return EntityResult.Success(model); } /// - public async Task> Delete(string id) + public async Task> Delete(string id) { using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { - Country country = await session.LoadAsync(id); + T country = await session.LoadAsync(id); if (country == null) { - return EntityResult.Fail("@errors.ondelete.idnotfound"); + return EntityResult.Fail("@errors.ondelete.idnotfound"); } session.Delete(country); @@ -105,36 +111,36 @@ namespace zero.Core.Api await session.SaveChangesAsync(); } - return EntityResult.Success(); + return EntityResult.Success(); } } - public interface ICountriesApi + public interface ICountriesApi where T : ICountry { /// /// Get country by Id /// - Task GetById(string id); + Task GetById(string id); /// /// Get all available countries /// - Task> GetAll(string languageId); + Task> GetAll(string languageId); /// /// Get all available countries (with query) /// - Task> GetByQuery(string languageId, ListQuery query); + Task> GetByQuery(string languageId, ListQuery query); /// /// Creates or updates a country /// - Task> Save(Country model); + Task> Save(T model); /// /// Deletes a country by Id /// - Task> Delete(string id); + Task> Delete(string id); } } diff --git a/zero.Core/Api/SetupApi.cs b/zero.Core/Api/SetupApi.cs index 5110b002..0f9ec01d 100644 --- a/zero.Core/Api/SetupApi.cs +++ b/zero.Core/Api/SetupApi.cs @@ -209,9 +209,9 @@ namespace zero.Core.Api { CreatedDate = DateTimeOffset.Now, IsActive = true, - Alias = Alias.Generate(country.Key), + Alias = Alias.Generate(country.Value), LanguageId = defaultLanguage.Id, - Code = country.Key, + Code = country.Key.ToLowerInvariant(), Name = country.Value }).ToList()); } diff --git a/zero.Core/Entities/Country.cs b/zero.Core/Entities/Country.cs index 2530bc23..f63e434b 100644 --- a/zero.Core/Entities/Country.cs +++ b/zero.Core/Entities/Country.cs @@ -1,12 +1,20 @@ namespace zero.Core.Entities { - public class Country : ZeroEntity, ILanguageAwareEntity, IZeroDbConventions + public class Country : ZeroEntity, ICountry { - /// - /// Language variant - /// - public class Variant : LanguageVariant { } + /// + public bool IsPreferred { get; set; } + /// + public string Code { get; set; } + + /// + public string LanguageId { get; set; } + } + + + public interface ICountry : IZeroEntity, ILanguageAwareEntity, IZeroDbConventions + { /// /// Preferred countries are displayed on top in lists /// @@ -16,8 +24,5 @@ /// Country code (ISO 3166-1) /// public string Code { get; set; } - - /// - public string LanguageId { get; set; } } } diff --git a/zero.Core/ServiceCollectionExtensions.cs b/zero.Core/ServiceCollectionExtensions.cs index 643a27b0..431a8efb 100644 --- a/zero.Core/ServiceCollectionExtensions.cs +++ b/zero.Core/ServiceCollectionExtensions.cs @@ -16,6 +16,9 @@ namespace zero.Core.Entities services.AddTransient(); services.AddTransient(typeof(IApplicationsApi<>), typeof(ApplicationsApi<>)); + + services.AddTransient(); + services.AddTransient(typeof(ICountriesApi<>), typeof(CountriesApi<>)); } diff --git a/zero.Web.UI/App/pages/settings/country.vue b/zero.Web.UI/App/pages/settings/country.vue index 25e7bdea..9395e830 100644 --- a/zero.Web.UI/App/pages/settings/country.vue +++ b/zero.Web.UI/App/pages/settings/country.vue @@ -79,7 +79,7 @@ { form.load(!this.id ? CountriesApi.getEmpty() : CountriesApi.getById(this.id)).then(response => { - this.model = response; + this.model = response.entity; }); }, diff --git a/zero.Web/Controllers/CountriesController.cs b/zero.Web/Controllers/CountriesController.cs index 09343416..0035dd5c 100644 --- a/zero.Web/Controllers/CountriesController.cs +++ b/zero.Web/Controllers/CountriesController.cs @@ -3,16 +3,15 @@ using System.Threading.Tasks; using zero.Core.Api; using zero.Core.Entities; using zero.Core.Identity; -using zero.Web.Models; namespace zero.Web.Controllers { [ZeroAuthorize(Permissions.Settings.Countries, PermissionsValue.Read)] - public class CountriesController : BackofficeController + public class CountriesController : BackofficeController where T : ICountry, new() { - ICountriesApi Api; + ICountriesApi Api; - public CountriesController(ICountriesApi api) + public CountriesController(ICountriesApi api) { Api = api; } @@ -21,48 +20,32 @@ namespace zero.Web.Controllers /// /// Get country by id /// - public async Task GetById([FromQuery] string id) - { - return await As(await Api.GetById(id)); - } + public async Task GetById([FromQuery] string id) => JsonEdit(await Api.GetById(id)); /// /// Get new country /// - public IActionResult GetEmpty() - { - return Json(new CountryEditModel()); - } + public IActionResult GetEmpty() => Json(new T()); /// /// Get all countries /// - public async Task GetAll([FromQuery] ListQuery query) - { - return await As(await Api.GetByQuery("en-US", query)); - } + public async Task GetAll([FromQuery] ListQuery query) => Json(await Api.GetByQuery("languages.1-A", query)); // TODO correct language /// /// Save country /// [ZeroAuthorize(Permissions.Settings.Countries, PermissionsValue.Write)] - public async Task Save([FromBody] CountryEditModel model) - { - Country country = await Mapper.Map(model, await Api.GetById(model.Id)); - return Json(await Api.Save(country)); - } + public async Task Save([FromBody] T model) => Json(await Api.Save(model)); /// /// Deletes a country /// [ZeroAuthorize(Permissions.Settings.Countries, PermissionsValue.Write)] - public async Task Delete([FromQuery] string id) - { - return Json(await Api.Delete(id)); - } + public async Task Delete([FromQuery] string id) => Json(await Api.Delete(id)); } } diff --git a/zero.Web/Defaults/DefaultBackofficePlugin.cs b/zero.Web/Defaults/DefaultBackofficePlugin.cs index 1fbb4cd1..0ca99e25 100644 --- a/zero.Web/Defaults/DefaultBackofficePlugin.cs +++ b/zero.Web/Defaults/DefaultBackofficePlugin.cs @@ -1,4 +1,6 @@ using Microsoft.Extensions.DependencyInjection; +using zero.Core; +using zero.Core.Entities; using zero.Core.Options; using zero.Core.Plugins; using zero.Web.Mapper; @@ -8,7 +10,11 @@ namespace zero.Web.Defaults { internal class DefaultBackofficePlugin : IZeroPlugin { - public void ConfigureServices(IServiceCollection services) { } + public void ConfigureServices(IServiceCollection services) + { + EntityMap.Use(); + EntityMap.Use(); + } public void Configure(IZeroPluginOptions plugin, IZeroOptions zero) { diff --git a/zero.Web/ZeroBuilder.cs b/zero.Web/ZeroBuilder.cs index 16d641de..ce9d3153 100644 --- a/zero.Web/ZeroBuilder.cs +++ b/zero.Web/ZeroBuilder.cs @@ -100,7 +100,6 @@ namespace zero.Web Services.AddTransient(); Services.AddTransient(); Services.AddTransient(); - Services.AddTransient(); Services.AddTransient(); Services.AddTransient(); Services.AddTransient();