flavors work with API now

This commit is contained in:
2021-12-02 14:44:48 +01:00
parent 2536c46fc7
commit 3853dbfdb9
12 changed files with 74 additions and 11 deletions
@@ -12,7 +12,7 @@ public class CountriesController : ZeroApiEntityStoreController<Country, ICountr
[HttpGet("empty")]
[ZeroAuthorize(CountryPermissions.Create)]
public virtual Task<ActionResult<CountryEdit>> Empty() => EmptyModel<CountryEdit>();
public virtual Task<ActionResult<CountryEdit>> Empty(string flavor = null) => EmptyModel<CountryEdit>(flavor);
[HttpGet("{id}")]
@@ -12,7 +12,7 @@ public class LanguagesController : ZeroApiEntityStoreController<Language, ILangu
[HttpGet("empty")]
[ZeroAuthorize(LanguagePermissions.Create)]
public virtual Task<ActionResult<LanguageEdit>> Empty() => EmptyModel<LanguageEdit>();
public virtual Task<ActionResult<LanguageEdit>> Empty(string flavor = null) => EmptyModel<LanguageEdit>(flavor);
[HttpGet("{id}")]
@@ -12,7 +12,7 @@ public class MailTemplatesController : ZeroApiEntityStoreController<MailTemplate
[HttpGet("empty")]
[ZeroAuthorize(MailPermissions.Create)]
public virtual Task<ActionResult<MailEdit>> Empty() => EmptyModel<MailEdit>();
public virtual Task<ActionResult<MailEdit>> Empty(string flavor = null) => EmptyModel<MailEdit>(flavor);
[HttpGet("{id}")]
@@ -12,7 +12,7 @@ public class TranslationsController : ZeroApiEntityStoreController<Translation,
[HttpGet("empty")]
[ZeroAuthorize(TranslationPermissions.Create)]
public virtual Task<ActionResult<TranslationEdit>> Empty() => EmptyModel<TranslationEdit>();
public virtual Task<ActionResult<TranslationEdit>> Empty(string flavor = null) => EmptyModel<TranslationEdit>(flavor);
[HttpGet("{id}")]
@@ -15,6 +15,7 @@ public static class IMapperProfileExtensions
target.Key = source.Key;
target.IsActive = source.IsActive;
target.CreatedDate = source.CreatedDate;
target.Flavor = source.Flavor;
}
@@ -31,6 +32,7 @@ public static class IMapperProfileExtensions
target.Key = source.Key;
target.IsActive = source.IsActive;
target.CreatedDate = source.CreatedDate;
target.Flavor = source.Flavor;
target.Sort = source.Sort;
target.Hash = source.Hash;
@@ -53,5 +55,6 @@ public static class IMapperProfileExtensions
target.Key = source.Key;
target.Sort = source.Sort;
target.IsActive = source.IsActive;
target.Flavor = source.Flavor;
}
}
+6 -1
View File
@@ -1,6 +1,6 @@
namespace zero.Api.Models;
public abstract class BasicModel<T> : ZeroIdEntity where T : ZeroEntity
public abstract class BasicModel<T> : ZeroIdEntity, ISupportsFlavors where T : ZeroEntity
{
/// <summary>
/// Full name of the entity
@@ -32,4 +32,9 @@ public abstract class BasicModel<T> : ZeroIdEntity where T : ZeroEntity
/// </summary>
[JsonPropertyName("@link")]
public string Link { get; set; }
/// <summary>
/// Configured flavor of this entity
/// </summary>
public string Flavor { get; set; }
}
+6 -1
View File
@@ -1,7 +1,7 @@
namespace zero.Api.Models;
public abstract class DisplayModel<T> : ZeroIdEntity where T : ZeroEntity
public abstract class DisplayModel<T> : ZeroIdEntity, ISupportsFlavors where T : ZeroEntity
{
/// <summary>
/// Full name of the entity
@@ -57,4 +57,9 @@ public abstract class DisplayModel<T> : ZeroIdEntity where T : ZeroEntity
/// Language of the entity
/// </summary>
public string LanguageId { get; set; }
/// <summary>
/// Configured flavor of this entity
/// </summary>
public string Flavor { get; set; }
}
+6 -1
View File
@@ -1,6 +1,6 @@
namespace zero.Api.Models;
public abstract class SaveModel<T> : ZeroIdEntity where T : ZeroEntity
public abstract class SaveModel<T> : ZeroIdEntity, ISupportsFlavors where T : ZeroEntity
{
/// <summary>
/// Full name of the entity
@@ -26,4 +26,9 @@ public abstract class SaveModel<T> : ZeroIdEntity where T : ZeroEntity
/// Whether the entity is visible in the frontend
/// </summary>
public bool IsActive { get; set; }
/// <summary>
/// Configured flavor of this entity
/// </summary>
public string Flavor { get; set; }
}
+15 -1
View File
@@ -34,6 +34,19 @@ public abstract class ZeroApiEntityStoreController<TModel, TStore> : ZeroApiCont
}
protected async Task<ActionResult<T>> EmptyModel<T>(string flavor) where T : DisplayModel<TModel>
{
TModel model = await Store.Empty(flavor);
if (model == null)
{
return NotFound();
}
return Mapper.Map<TModel, T>(model);
}
protected async Task<ActionResult<T>> GetModel<T>(string id, string changeVector = null) where T : DisplayModel<TModel>
{
TModel model = await Store.Load(id, changeVector);
@@ -75,7 +88,8 @@ public abstract class ZeroApiEntityStoreController<TModel, TStore> : ZeroApiCont
protected async Task<ActionResult<Result>> CreateModel<T, TEdit>(T saveModel) where T : SaveModel<TModel> where TEdit : DisplayModel<TModel>
{
TModel model = Mapper.Map<T, TModel>(saveModel);
TModel emptyModel = saveModel.Flavor.IsNullOrEmpty() ? await Store.Empty() : await Store.Empty(saveModel.Flavor);
TModel model = Mapper.Map(saveModel, emptyModel);
Result<TModel> result = await Store.Create(model);
bool minimalResponse = Hints.ResponsePreference == ApiResponsePreference.Minimal;
@@ -178,7 +178,9 @@
"idnotfound": "Could not find an entity for the given ID",
"onsave": {
"notallowed": "You are not allowed to edit this resource",
"empty": "You need to pass a model"
"empty": "You need to pass a model",
"noidmatch": "Do not fill out the Id field when creating a resource",
"flavornotfound": "Could not find a registration for this resource flavor"
},
"ondelete": {
"idnotfound": "Could not find an entity for the given ID"
+8 -1
View File
@@ -1,6 +1,6 @@
using System.Collections.Concurrent;
namespace zero.Pages;
namespace zero.Stores;
public class FlavorOptions
{
@@ -45,6 +45,13 @@ public class FlavorOptions
}
public bool Exists<TEntity>(string alias)
{
List<FlavorConfig> flavors = Flavors.GetValueOrDefault(typeof(TEntity), new());
return flavors.Any(x => x.Alias == alias);
}
public void Provide<TEntity>()
where TEntity : ISupportsFlavors, new()
{
+23 -1
View File
@@ -18,7 +18,29 @@ public partial class StoreOperations : IStoreOperations
return Result<T>.Fail("@errors.onsave.empty");
}
bool isUpdate = !model.Id.IsNullOrEmpty() && await Session.Advanced.ExistsAsync(model.Id);
bool isUpdate = false;
// check if the Id for a model already exists
if (!model.Id.IsNullOrEmpty())
{
bool exists = await Session.Advanced.ExistsAsync(model.Id);
if (!exists)
{
return Result<T>.Fail("@errors.onsave.noidmatch");
}
isUpdate = true;
}
// validate flavor
if (model is ISupportsFlavors flavorModel && !flavorModel.Flavor.IsNullOrEmpty())
{
if (!Flavors.Exists<T>(flavorModel.Flavor))
{
return Result<T>.Fail("@errors.onsave.flavornotfound");
}
}
// prepare model
PrepareForSave(model);