more apis

This commit is contained in:
2021-12-01 14:26:54 +01:00
parent 595738fa06
commit 19eabe22a9
55 changed files with 370 additions and 112 deletions
@@ -0,0 +1,21 @@
using Raven.Client.Documents.Indexes;
namespace zero.Api.Endpoints.Mails;
public class zero_Api_MailTemplates_Listing : ZeroIndex<MailTemplate>
{
protected override void Create()
{
Map = items => items.Select(item => new
{
item.Name,
item.Key,
item.Subject,
item.CreatedDate
});
Index(x => x.Name, FieldIndexing.Search);
Index(x => x.Key, FieldIndexing.Search);
Index(x => x.Subject, FieldIndexing.Search);
}
}
+18
View File
@@ -0,0 +1,18 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace zero.Api.Endpoints.Mails;
public class MailModule : ZeroModule
{
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services.AddSingleton<IPermissionProvider, MailPermissions>();
services.AddSingleton<IMapperProfile, MailMapperProfile>();
services.Configure<RavenOptions>(opts =>
{
opts.Indexes.Add<zero_Api_MailTemplates_Listing>();
});
}
}
@@ -0,0 +1,29 @@
namespace zero.Api.Endpoints.Mails;
public class MailPermissions : PermissionProvider
{
public const string Create = "zero.settings.mail.create";
public const string Read = "zero.settings.mail.read";
public const string Update = "zero.settings.mail.update";
public const string Delete = "zero.settings.mail.delete";
public override Task Configure(IPermissionContext context)
{
if (!context.TryGetGroup(Constants.Permissions.Groups.Settings, out PermissionGroup group))
{
group.Permissions.Add(new Permission("zero.settings.mail", "@settings.application.mails.name")
{
Children = new()
{
new(Create, "@permission.states.create"),
new(Read, "@permission.states.read"),
new(Update, "@permission.states.update"),
new(Delete, "@permission.states.delete")
}
});
}
return Task.CompletedTask;
}
}
@@ -0,0 +1,45 @@
using Microsoft.AspNetCore.Mvc;
namespace zero.Api.Endpoints.Mails;
public class MailTemplatesController : ZeroApiEntityStoreController<MailTemplate, IMailTemplatesStore>
{
public MailTemplatesController(IMailTemplatesStore store) : base(store)
{
}
[HttpGet("empty")]
[ZeroAuthorize(MailPermissions.Create)]
public virtual Task<ActionResult<MailEdit>> Empty() => EmptyModel<MailEdit>();
[HttpGet("{id}")]
[ZeroAuthorize(MailPermissions.Read)]
public virtual Task<ActionResult<MailEdit>> Get(string id, string changeVector = null) => GetModel<MailEdit>(id, changeVector);
[HttpGet("")]
[ZeroAuthorize(MailPermissions.Read)]
public virtual Task<ActionResult<Paged>> Get([FromQuery] ListQuery<MailTemplate> query)
{
query.SearchFor(entity => entity.Name, entity => entity.Key, entity => entity.Subject);
return GetModels<MailBasic, zero_Api_MailTemplates_Listing>(query);
}
[HttpPost("")]
[ZeroAuthorize(MailPermissions.Create)]
public virtual Task<ActionResult<Result>> Create(MailSave saveModel) => CreateModel<MailSave, MailEdit>(saveModel);
[HttpPut("{id}")]
[ZeroAuthorize(MailPermissions.Update)]
public virtual Task<ActionResult<Result>> Update(string id, MailSave updateModel, [FromQuery] string changeToken = null) => UpdateModel<MailSave, MailEdit>(id, updateModel, changeToken);
[HttpDelete("{id}")]
[ZeroAuthorize(MailPermissions.Delete)]
public virtual Task<ActionResult<Result>> Delete(string id) => DeleteModel(id);
}
@@ -0,0 +1,6 @@
namespace zero.Api.Endpoints.Mails;
public class MailBasic : BasicModel<MailTemplate>
{
public string Subject { get; set; }
}
+20
View File
@@ -0,0 +1,20 @@
namespace zero.Api.Endpoints.Mails;
public class MailEdit : DisplayModel<MailTemplate>
{
public string SenderEmail { get; set; }
public string SenderName { get; set; }
public string RecipientEmail { get; set; }
public string Cc { get; set; }
public string Bcc { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public string Preheader { get; set; }
}
@@ -0,0 +1,44 @@
namespace zero.Api.Endpoints.Mails;
public class MailMapperProfile : ZeroMapperProfile
{
public override void Configure(IZeroMapper mapper)
{
mapper.Define<MailTemplate, MailBasic>((source, ctx) => new(), Map);
mapper.Define<MailTemplate, MailEdit>((source, ctx) => new(), Map);
mapper.Define<MailSave, MailTemplate>((source, ctx) => new(), Map);
}
protected virtual void Map(MailTemplate source, MailBasic target, IZeroMapperContext ctx)
{
this.MapBasicData(source, target);
target.Subject = source.Subject;
}
protected virtual void Map(MailTemplate source, MailEdit target, IZeroMapperContext ctx)
{
this.MapDisplayData(source, target);
target.Subject = source.Subject;
target.SenderEmail = source.SenderEmail;
target.SenderName = source.SenderName;
target.RecipientEmail = source.RecipientEmail;
target.Cc = source.Cc;
target.Bcc = source.Bcc;
target.Body = source.Body;
target.Preheader = source.Preheader;
}
protected virtual void Map(MailSave source, MailTemplate target, IZeroMapperContext ctx)
{
this.MapSaveData(source, target);
target.Subject = source.Subject;
target.SenderEmail = source.SenderEmail;
target.SenderName = source.SenderName;
target.RecipientEmail = source.RecipientEmail;
target.Cc = source.Cc;
target.Bcc = source.Bcc;
target.Body = source.Body;
target.Preheader = source.Preheader;
}
}
+20
View File
@@ -0,0 +1,20 @@
namespace zero.Api.Endpoints.Mails;
public class MailSave : SaveModel<MailTemplate>
{
public string SenderEmail { get; set; }
public string SenderName { get; set; }
public string RecipientEmail { get; set; }
public string Cc { get; set; }
public string Bcc { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public string Preheader { get; set; }
}
@@ -1,19 +1,21 @@
using Raven.Client.Documents.Indexes;
namespace zero.Backoffice.Modules;
namespace zero.Api.Endpoints.Translations;
public class zero_Backoffice_Translations : ZeroIndex<Translation>
public class zero_Api_Translations_Listing : ZeroIndex<Translation>
{
protected override void Create()
{
Map = items => items.Select(item => new
{
Key = item.Key,
Name = item.Name,
Value = item.Value,
Key = item.Key,
CreatedDate = item.CreatedDate
});
Index(x => x.Name, FieldIndexing.Search);
Index(x => x.Key, FieldIndexing.Search);
Index(x => x.Value, FieldIndexing.Search);
}
};
}
@@ -0,0 +1,33 @@
namespace zero.Api.Endpoints.Translations;
public class TranslationMapperProfile : ZeroMapperProfile
{
public override void Configure(IZeroMapper mapper)
{
mapper.Define<Translation, TranslationBasic>((source, ctx) => new(), Map);
mapper.Define<Translation, TranslationEdit>((source, ctx) => new(), Map);
mapper.Define<TranslationSave, Translation>((source, ctx) => new(), Map);
}
protected virtual void Map(Translation source, TranslationBasic target, IZeroMapperContext ctx)
{
this.MapBasicData(source, target);
target.Value = source.Value;
target.Display = source.Display;
}
protected virtual void Map(Translation source, TranslationEdit target, IZeroMapperContext ctx)
{
this.MapDisplayData(source, target);
target.Value = source.Value;
target.Display = source.Display;
}
protected virtual void Map(TranslationSave source, Translation target, IZeroMapperContext ctx)
{
this.MapSaveData(source, target);
target.Value = source.Value;
target.Display = source.Display;
}
}
@@ -0,0 +1,8 @@
namespace zero.Api.Endpoints.Translations;
public class TranslationBasic : BasicModel<Translation>
{
public string Value { get; set; }
public TranslationDisplay Display { get; set; }
}
@@ -0,0 +1,8 @@
namespace zero.Api.Endpoints.Translations;
public class TranslationEdit : DisplayModel<Translation>
{
public string Value { get; set; }
public TranslationDisplay Display { get; set; }
}
@@ -0,0 +1,8 @@
namespace zero.Api.Endpoints.Translations;
public class TranslationSave : SaveModel<Translation>
{
public string Value { get; set; }
public TranslationDisplay Display { get; set; }
}
@@ -0,0 +1,18 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace zero.Api.Endpoints.Translations;
public class TranslationModule : ZeroModule
{
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services.AddSingleton<IPermissionProvider, TranslationPermissions>();
services.AddSingleton<IMapperProfile, TranslationMapperProfile>();
services.Configure<RavenOptions>(opts =>
{
opts.Indexes.Add<zero_Api_Translations_Listing>();
});
}
}
@@ -0,0 +1,29 @@
namespace zero.Api.Endpoints.Translations;
public class TranslationPermissions : PermissionProvider
{
public const string Create = "zero.settings.translation.create";
public const string Read = "zero.settings.translation.read";
public const string Update = "zero.settings.translation.update";
public const string Delete = "zero.settings.translation.delete";
public override Task Configure(IPermissionContext context)
{
if (!context.TryGetGroup(Constants.Permissions.Groups.Settings, out PermissionGroup group))
{
group.Permissions.Add(new Permission("zero.settings.translation", "@settings.application.translations.name")
{
Children = new()
{
new(Create, "@permission.states.create"),
new(Read, "@permission.states.read"),
new(Update, "@permission.states.update"),
new(Delete, "@permission.states.delete")
}
});
}
return Task.CompletedTask;
}
}
@@ -0,0 +1,45 @@
using Microsoft.AspNetCore.Mvc;
namespace zero.Api.Endpoints.Translations;
public class TranslationsController : ZeroApiEntityStoreController<Translation, ITranslationStore>
{
public TranslationsController(ITranslationStore store) : base(store)
{
}
[HttpGet("empty")]
[ZeroAuthorize(TranslationPermissions.Create)]
public virtual Task<ActionResult<TranslationEdit>> Empty() => EmptyModel<TranslationEdit>();
[HttpGet("{id}")]
[ZeroAuthorize(TranslationPermissions.Read)]
public virtual Task<ActionResult<TranslationEdit>> Get(string id, string changeVector = null) => GetModel<TranslationEdit>(id, changeVector);
[HttpGet("")]
[ZeroAuthorize(TranslationPermissions.Read)]
public virtual Task<ActionResult<Paged>> Get([FromQuery] ListQuery<Translation> query)
{
query.SearchFor(x => x.Key, x => x.Value);
return GetModels<TranslationBasic, zero_Api_Translations_Listing>(query);
}
[HttpPost("")]
[ZeroAuthorize(TranslationPermissions.Create)]
public virtual Task<ActionResult<Result>> Create(TranslationSave saveModel) => CreateModel<TranslationSave, TranslationEdit>(saveModel);
[HttpPut("{id}")]
[ZeroAuthorize(TranslationPermissions.Update)]
public virtual Task<ActionResult<Result>> Update(string id, TranslationSave updateModel, [FromQuery] string changeToken = null) => UpdateModel<TranslationSave, TranslationEdit>(id, updateModel, changeToken);
[HttpDelete("{id}")]
[ZeroAuthorize(TranslationPermissions.Delete)]
public virtual Task<ActionResult<Result>> Delete(string id) => DeleteModel(id);
}
+5 -7
View File
@@ -1,13 +1,9 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using zero.Api.Endpoints.Countries;
using zero.Api.Endpoints.Languages;
using zero.Api.Endpoints.Search;
namespace zero.Api;
@@ -30,9 +26,11 @@ public class ZeroApiPlugin : ZeroPlugin
services.AddScoped<IZeroMapper, ZeroMapper>();
ZeroModuleCollection.AddModule<Endpoints.Applications.ApplicationModule>(services, configuration);
ZeroModuleCollection.AddModule<CountryModule>(services, configuration);
ZeroModuleCollection.AddModule<LanguageModule>(services, configuration);
ZeroModuleCollection.AddModule<SearchModule>(services, configuration);
ZeroModuleCollection.AddModule<Endpoints.Countries.CountryModule>(services, configuration);
ZeroModuleCollection.AddModule<Endpoints.Languages.LanguageModule>(services, configuration);
ZeroModuleCollection.AddModule<Endpoints.Search.SearchModule>(services, configuration);
ZeroModuleCollection.AddModule<Endpoints.Translations.TranslationModule>(services, configuration);
ZeroModuleCollection.AddModule<Endpoints.Mails.MailModule>(services, configuration);
PostConfigureServices?.Invoke(services, configuration);
}
+1
View File
@@ -16,6 +16,7 @@ global using zero.FileStorage;
global using zero.Identity;
global using zero.Localization;
global using zero.Mapper;
global using zero.Mails;
global using zero.Media;
global using zero.Models;
global using zero.Pages;
+5 -3
View File
@@ -78,13 +78,15 @@ public abstract class ZeroApiEntityStoreController<TModel, TStore> : ZeroApiCont
TModel model = Mapper.Map<T, TModel>(saveModel);
Result<TModel> result = await Store.Create(model);
bool minimalResponse = Hints.ResponsePreference == ApiResponsePreference.Minimal;
if (result.IsSuccess)
{
Result<T> mappedResult = Mapper.Map<TModel, T>(result);
return Created(GetAction(model), mappedResult);
Result<TEdit> mappedResult = Mapper.Map<TModel, TEdit>(result);
return Created(GetAction(model), minimalResponse ? null : mappedResult);
}
if (Hints.ResponsePreference == ApiResponsePreference.Minimal)
if (minimalResponse)
{
return result.WithoutModel();
}
@@ -1,25 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Raven.Client.Documents.Session;
using System.Threading.Tasks;
using zero.Core.Database;
using zero.Core.Entities;
namespace zero.Web.Controllers
{
public class BlueprintController : BackofficeController
{
IZeroStore Store;
public BlueprintController(IZeroStore store)
{
Store = store;
}
public async Task<ZeroEntity> GetById([FromQuery] string id)
{
IAsyncDocumentSession session = Store.Session(global: true);
return await session.LoadAsync<ZeroEntity>(id);
}
}
}
@@ -1,20 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
namespace zero.Backoffice.Modules;
internal class TranslationsModule : ZeroModule
{
/// <inheritdoc />
public override void Register(IZeroModuleConfiguration config)
{
config.Services.AddOptions<SearchOptions>().Bind(config.Configuration.GetSection(SearchOptions.KEY));
config.Services.AddScoped<IBackofficeSearchService, BackofficeSearchService>();
}
/// <inheritdoc />
public override void Configure(IZeroOptions options)
{
options.For<RavenOptions>().Indexes.Add<zero_Backoffice_Search>();
}
}
@@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using zero.Core.Entities;
namespace zero.Web.Models
{
public class TranslationEditModel : ObsoleteEditModel
{
public string Key { get; set; }
public string Value { get; set; }
public TranslationDisplay Display { get; set; }
}
}
@@ -1,13 +0,0 @@
using System;
namespace zero.Web.Models
{
public class TranslationListModel : ListModel
{
public string Key { get; set; }
public string Value { get; set; }
public DateTimeOffset CreatedDate { get; set; }
}
}
@@ -1,24 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Raven.Client.Documents.Linq;
using System.Linq;
using System.Threading.Tasks;
using zero.Core.Collections;
using zero.Core.Database.Indexes;
using zero.Core.Entities;
using zero.Core.Identity;
namespace zero.Web.Controllers
{
[ZeroAuthorize(Permissions.Settings.Translations, PermissionsValue.Read)]
public class TranslationsController : ZeroBackofficeCollectionController<Translation, ITranslationsStore>
{
public TranslationsController(ITranslationsStore collection) : base(collection) { }
public override async Task<Paged<Translation>> GetByQuery([FromQuery] ListQuery<Translation> query)
{
query.SearchFor(entity => entity.Key, entity => entity.Value);
query.OrderQuery = q => q.OrderByDescending(x => x.CreatedDate);
return await Collection.Load<zero_Translations>(query);
}
}
}
+1 -1
View File
@@ -16,7 +16,7 @@ public class TranslationStore : EntityStore<Translation>, ITranslationStore
protected override void ValidationRules(ZeroValidator<Translation> validator)
{
validator.RuleFor(x => x.Key).Length(2, 300).Unique(Context.Store);
validator.RuleFor(x => x.Key).NotEmpty().Length(2, 300).Unique(Context.Store);
validator.RuleFor(x => x.Value).MaximumLength(10 * 1000);
}
}