flavors work with API now
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user