remove other stuff
This commit is contained in:
@@ -1,24 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace zero.Api.Abstractions;
|
||||
|
||||
[ApiController]
|
||||
[ZeroAuthorize]
|
||||
[ApiMetadataFilter]
|
||||
[ApiResponseFilter]
|
||||
[TypeFilter(typeof(ApiExceptionFilter))]
|
||||
//[MiddlewareFilter(typeof(ApiUnhandledExceptionMiddlewareFilter))]
|
||||
//[ServiceFilter(typeof(ModelStateValidationFilterAttribute))]
|
||||
//[ServiceFilter(typeof(BackofficeFilterAttribute))]
|
||||
public abstract class ZeroApiController : ControllerBase
|
||||
{
|
||||
IZeroMapper _mapper;
|
||||
protected IZeroMapper Mapper => _mapper ?? (_mapper = HttpContext?.RequestServices?.GetService<IZeroMapper>());
|
||||
|
||||
IZeroContext _context;
|
||||
protected IZeroContext ZeroContext => _context ?? (_context = HttpContext?.RequestServices?.GetService<IZeroContext>());
|
||||
|
||||
|
||||
public ApiRequestHints Hints { get; protected set; } = new();
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Abstractions;
|
||||
|
||||
public abstract class ZeroApiEntityStoreController<TModel, TStore> : ZeroApiController
|
||||
where TModel : ZeroEntity, new()
|
||||
where TStore : IEntityStore<TModel>
|
||||
{
|
||||
protected TStore Store { get; set; }
|
||||
|
||||
protected ZeroApiEntityStoreOperations<TModel, TStore> Ops { get; set; }
|
||||
|
||||
public ZeroApiEntityStoreController(TStore store)
|
||||
{
|
||||
Store = store;
|
||||
Ops = new ZeroApiEntityStoreOperations<TModel, TStore>(this, store);
|
||||
}
|
||||
|
||||
|
||||
protected Task<ActionResult<T>> EmptyModel<T>(string flavorAlias = null, Action<T> modify = null) => Ops.EmptyModel<T>(flavorAlias, modify);
|
||||
protected Task<ActionResult<TModel>> EmptyModel(string flavorAlias = null, Action<TModel> modify = null) => Ops.EmptyModel(flavorAlias, modify);
|
||||
protected Task<ActionResult<T>> GetModel<T>(string id, string changeVector = null) => Ops.GetModel<T>(id, changeVector);
|
||||
protected Task<ActionResult<TModel>> GetModel(string id, string changeVector = null) => Ops.GetModel(id, changeVector);
|
||||
protected Task<ActionResult<Paged>> GetModels<T>(ListQuery<TModel> query) => Ops.GetModels<T>(query);
|
||||
protected Task<ActionResult<Paged>> GetModels(ListQuery<TModel> query) => Ops.GetModels(query);
|
||||
protected Task<ActionResult<Paged>> GetModelsByIndex<T, TIndex>(ListQuery<TModel> query) where TIndex : AbstractCommonApiForIndexes, new() => Ops.GetModelsByIndex<T, TIndex>(query);
|
||||
protected Task<ActionResult<Paged>> GetModelsByIndex<TIndex>(ListQuery<TModel> query) where TIndex : AbstractCommonApiForIndexes, new() => Ops.GetModelsByIndex<TIndex>(query);
|
||||
protected Task<ActionResult<Result>> CreateModel<T, TEdit>(T saveModel) where T : ISupportsFlavors => Ops.CreateModel<T, TEdit>(saveModel);
|
||||
protected Task<ActionResult<Result>> CreateModel(TModel saveModel) => Ops.CreateModel(saveModel);
|
||||
protected Task<ActionResult<Result>> UpdateModel<T, TEdit>(string id, T updateModel, string changeToken = null) where T : ZeroIdEntity => Ops.UpdateModel<T, TEdit>(id, updateModel, changeToken);
|
||||
protected Task<ActionResult<Result>> UpdateModel(string id, TModel updateModel, string changeToken = null) => Ops.UpdateModel(id, updateModel, changeToken);
|
||||
protected Task<ActionResult<Result>> SortModels(string[] ids) => Ops.SortModels(ids);
|
||||
protected Task<ActionResult<Result>> DeleteModel(string id) => Ops.DeleteModel(id);
|
||||
}
|
||||
@@ -1,255 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Abstractions;
|
||||
|
||||
public class ZeroApiEntityStoreOperations<TModel, TStore>
|
||||
where TModel : ZeroEntity, new()
|
||||
where TStore : IEntityStore<TModel>
|
||||
{
|
||||
public TStore Store { get; set; }
|
||||
|
||||
IZeroMapper _mapper;
|
||||
protected IZeroMapper Mapper => _mapper ?? (_mapper = Controller.HttpContext?.RequestServices?.GetService<IZeroMapper>());
|
||||
|
||||
protected ZeroApiController Controller { get; private set; }
|
||||
|
||||
public ZeroApiEntityStoreOperations(ZeroApiController controller, TStore store)
|
||||
{
|
||||
Controller = controller;
|
||||
Store = store;
|
||||
Store.Config.IncludeInactive = true;
|
||||
}
|
||||
|
||||
|
||||
protected string GetActionMethod { get; set; } = "Get";
|
||||
|
||||
protected virtual string GetAction(TModel model)
|
||||
{
|
||||
return "/"; // TODO Url.Action does not work anymore,
|
||||
// probably due to ZeroApiControllerModelConvention, which rewrites AttributeRouteModel
|
||||
//return Url.Action(GetActionMethod, ControllerContext.ActionDescriptor.ControllerName, new { id = model.Id, changeVector = default(string) });
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<T>> EmptyModel<T>(string flavorAlias = null, Action<T> modify = null)
|
||||
{
|
||||
TModel model = await Store.Empty(flavorAlias);
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
return Controller.NotFound();
|
||||
}
|
||||
|
||||
T result = Mapper.Map<TModel, T>(model);
|
||||
modify?.Invoke(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<TModel>> EmptyModel(string flavorAlias = null, Action<TModel> modify = null)
|
||||
{
|
||||
TModel model = await Store.Empty(flavorAlias);
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
return Controller.NotFound();
|
||||
}
|
||||
|
||||
modify?.Invoke(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<T>> GetModel<T>(string id, string changeVector = null)
|
||||
{
|
||||
TModel model = await Store.Load(id, changeVector);
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
return Controller.NotFound();
|
||||
}
|
||||
|
||||
Controller.HttpContext.Items[ApiConstants.ChangeToken] = Store.GetChangeToken(model);
|
||||
|
||||
return Mapper.Map<TModel, T>(model);
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<TModel>> GetModel(string id, string changeVector = null)
|
||||
{
|
||||
TModel model = await Store.Load(id, changeVector);
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
return Controller.NotFound();
|
||||
}
|
||||
|
||||
Controller.HttpContext.Items[ApiConstants.ChangeToken] = Store.GetChangeToken(model);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<Paged>> GetModels<T>(ListQuery<TModel> query)
|
||||
{
|
||||
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
|
||||
query.SearchSelector ??= x => x.Name;
|
||||
Paged<TModel> result = await Store.Load(query.Page, query.PageSize, q => q.Filter(query));
|
||||
|
||||
return Mapper.Map<TModel, T>(result);
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<Paged>> GetModels(ListQuery<TModel> query)
|
||||
{
|
||||
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
|
||||
query.SearchSelector ??= x => x.Name;
|
||||
Paged<TModel> result = await Store.Load(query.Page, query.PageSize, q => q.Filter(query));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<Paged>> GetModelsByIndex<T, TIndex>(ListQuery<TModel> query) where TIndex : AbstractCommonApiForIndexes, new()
|
||||
{
|
||||
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
|
||||
query.SearchSelector ??= x => x.Name;
|
||||
Paged<TModel> result = await Store.Load<TIndex>(query.Page, query.PageSize, q => q.Filter(query));
|
||||
|
||||
return Mapper.Map<TModel, T>(result);
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<Paged>> GetModelsByIndex<TIndex>(ListQuery<TModel> query) where TIndex : AbstractCommonApiForIndexes, new()
|
||||
{
|
||||
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
|
||||
query.SearchSelector ??= x => x.Name;
|
||||
Paged<TModel> result = await Store.Load<TIndex>(query.Page, query.PageSize, q => q.Filter(query));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<Result>> CreateModel<T, TEdit>(T saveModel) where T : ISupportsFlavors
|
||||
{
|
||||
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 = false && Controller.Hints.ResponsePreference == ApiResponsePreference.Minimal;
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
Result<TEdit> mappedResult = Mapper.Map<TModel, TEdit>(result);
|
||||
return Controller.Created(GetAction(model), minimalResponse ? null : mappedResult);
|
||||
}
|
||||
|
||||
return result.WithoutModel();
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<Result>> CreateModel(TModel saveModel)
|
||||
{
|
||||
Result<TModel> result = await Store.Create(saveModel);
|
||||
|
||||
bool minimalResponse = false && Controller.Hints.ResponsePreference == ApiResponsePreference.Minimal;
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
return Controller.Created(GetAction(saveModel), minimalResponse ? null : saveModel);
|
||||
}
|
||||
|
||||
return result.WithoutModel();
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<Result>> UpdateModel<T, TEdit>(string id, T updateModel, string changeToken = null) where T : ZeroIdEntity
|
||||
{
|
||||
if (id != updateModel.Id)
|
||||
{
|
||||
return Controller.BadRequest(Result.Fail(nameof(id), "@errors.onupdate.noidmatch"));
|
||||
}
|
||||
|
||||
TModel model = await Store.Load(id);
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
return Controller.BadRequest(Result.Fail(nameof(id), "@errors.idnotfound"));
|
||||
}
|
||||
|
||||
string storedChangeToken = Store.GetChangeToken(model);
|
||||
|
||||
if (!changeToken.IsNullOrEmpty() && storedChangeToken != changeToken)
|
||||
{
|
||||
return Controller.BadRequest(Result.Fail("@errors.onupdate.changetokenmismatch"));
|
||||
}
|
||||
|
||||
Mapper.Map(updateModel, model);
|
||||
|
||||
Result<TModel> result = await Store.Update(model);
|
||||
|
||||
if (false && Controller.Hints.ResponsePreference == ApiResponsePreference.Minimal)
|
||||
{
|
||||
return result.WithoutModel();
|
||||
}
|
||||
|
||||
// TODO add Preference-Applied header, see https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md#76-standard-response-headers
|
||||
return Mapper.Map<TModel, TEdit>(result);
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<Result>> UpdateModel(string id, TModel updateModel, string changeToken = null)
|
||||
{
|
||||
if (id != updateModel.Id)
|
||||
{
|
||||
return Controller.BadRequest(Result.Fail(nameof(id), "@errors.onupdate.noidmatch"));
|
||||
}
|
||||
|
||||
// TODO throws error on save: Attempted to associate a different object with id ...
|
||||
// we need to map props to new object
|
||||
//TModel model = await Store.Load(id);
|
||||
|
||||
//if (model == null)
|
||||
//{
|
||||
// return BadRequest(Result.Fail(nameof(id), "@errors.idnotfound"));
|
||||
//}
|
||||
|
||||
//string storedChangeToken = Store.GetChangeToken(model);
|
||||
|
||||
//if (!changeToken.IsNullOrEmpty() && storedChangeToken != changeToken)
|
||||
//{
|
||||
// return BadRequest(Result.Fail("@errors.onupdate.changetokenmismatch"));
|
||||
//}
|
||||
|
||||
Result<TModel> result = await Store.Update(updateModel);
|
||||
|
||||
if (false && Controller.Hints.ResponsePreference == ApiResponsePreference.Minimal)
|
||||
{
|
||||
return result.WithoutModel();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<Result>> SortModels(string[] ids)
|
||||
{
|
||||
return await Store.Sort(ids);
|
||||
}
|
||||
|
||||
|
||||
public async Task<ActionResult<Result>> DeleteModel(string id)
|
||||
{
|
||||
TModel model = await Store.Load(id);
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
return Controller.NotFound();
|
||||
}
|
||||
|
||||
Result<TModel> result = await Store.Delete(model);
|
||||
|
||||
return result.WithoutModel();
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Abstractions;
|
||||
|
||||
public abstract class ZeroApiTreeEntityStoreController<TModel, TStore> : ZeroApiEntityStoreController<TModel, TStore>
|
||||
where TModel : ZeroEntity, ISupportsTrees, new()
|
||||
where TStore : ITreeEntityStore<TModel>
|
||||
{
|
||||
public ZeroApiTreeEntityStoreController(TStore store) : base(store) { }
|
||||
|
||||
|
||||
protected async Task<ActionResult<Paged>> GetChildModels<T>(string parentId, ListQuery<TModel> query)
|
||||
{
|
||||
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
|
||||
Paged<TModel> result = await Store.LoadChildren(NormalizeParentId(parentId), query.Page, query.PageSize, q => q.Filter(query));
|
||||
|
||||
return Mapper.Map<TModel, T>(result);
|
||||
}
|
||||
|
||||
|
||||
protected async Task<ActionResult<Paged>> GetChildModels(string parentId, ListQuery<TModel> query)
|
||||
{
|
||||
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
|
||||
Paged<TModel> result = await Store.LoadChildren(NormalizeParentId(parentId), query.Page, query.PageSize, q => q.Filter(query));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
protected async Task<ActionResult<Paged>> GetChildModelsByIndex<T, TIndex>(string parentId, ListQuery<TModel> query) where TIndex : AbstractCommonApiForIndexes, new()
|
||||
{
|
||||
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
|
||||
Paged<TModel> result = await Store.LoadChildren<TIndex>(NormalizeParentId(parentId), query.Page, query.PageSize, q => q.Filter(query));
|
||||
|
||||
return Mapper.Map<TModel, T>(result);
|
||||
}
|
||||
|
||||
|
||||
protected async Task<ActionResult<Paged>> GetChildModelsByIndex<TIndex>(string parentId, ListQuery<TModel> query) where TIndex : AbstractCommonApiForIndexes, new()
|
||||
{
|
||||
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
|
||||
Paged<TModel> result = await Store.LoadChildren<TIndex>(NormalizeParentId(parentId), query.Page, query.PageSize, q => q.Filter(query));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
protected async Task<ActionResult<Result>> MoveModel<TEdit>(string id, string newParentId)
|
||||
{
|
||||
return await PutOperation<TEdit>(async () => await Store.Move(id, NormalizeParentId(newParentId)));
|
||||
}
|
||||
|
||||
|
||||
protected async Task<ActionResult<Result>> MoveModel(string id, string newParentId)
|
||||
{
|
||||
return await PutOperation(async () => await Store.Move(id, NormalizeParentId(newParentId)));
|
||||
}
|
||||
|
||||
|
||||
protected async Task<ActionResult<Result>> CopyModel<TEdit>(string id, string newParentId)
|
||||
{
|
||||
return await PutOperation<TEdit>(async () => await Store.Copy(id, NormalizeParentId(newParentId)));
|
||||
}
|
||||
|
||||
|
||||
protected async Task<ActionResult<Result>> CopyModel(string id, string newParentId)
|
||||
{
|
||||
return await PutOperation(async () => await Store.Copy(id, NormalizeParentId(newParentId)));
|
||||
}
|
||||
|
||||
|
||||
protected async Task<ActionResult<Result>> CopyModelWithDescendants<TEdit>(string id, string newParentId)
|
||||
{
|
||||
return await PutOperation<TEdit>(async () => await Store.CopyWithDescendants(id, NormalizeParentId(newParentId)));
|
||||
}
|
||||
|
||||
|
||||
protected async Task<ActionResult<Result>> CopyModelWithDescendants(string id, string newParentId)
|
||||
{
|
||||
return await PutOperation(async () => await Store.CopyWithDescendants(id, NormalizeParentId(newParentId)));
|
||||
}
|
||||
|
||||
|
||||
protected async Task<ActionResult<Result<string[]>>> DeleteModelWithDescendants(string id)
|
||||
{
|
||||
TModel model = await Store.Load(id);
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
Result<string[]> result = await Store.DeleteWithDescendants(model);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
async Task<ActionResult<Result>> PutOperation<TEdit>(Func<Task<Result<TModel>>> action)
|
||||
{
|
||||
Result<TModel> result = await action();
|
||||
|
||||
if (false && Hints.ResponsePreference == ApiResponsePreference.Minimal)
|
||||
{
|
||||
return result.WithoutModel();
|
||||
}
|
||||
|
||||
return Mapper.Map<TModel, TEdit>(result);
|
||||
}
|
||||
|
||||
|
||||
async Task<ActionResult<Result>> PutOperation(Func<Task<Result<TModel>>> action)
|
||||
{
|
||||
Result<TModel> result = await action();
|
||||
|
||||
if (false && Hints.ResponsePreference == ApiResponsePreference.Minimal)
|
||||
{
|
||||
return result.WithoutModel();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
protected string NormalizeParentId(string id)
|
||||
{
|
||||
return id == "root" ? null : id;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace zero.Api;
|
||||
|
||||
public class ApiApplicationResolverHandler : IBackofficeApplicationResolverHandler
|
||||
{
|
||||
readonly IZeroOptions options;
|
||||
|
||||
public ApiApplicationResolverHandler(IZeroOptions options)
|
||||
{
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
|
||||
public bool TryResolve(HttpContext context, IEnumerable<Application> applications, ZeroUser user, out Application resolved)
|
||||
{
|
||||
string path = options.ZeroPath.EnsureStartsWith('/').TrimEnd('/');
|
||||
|
||||
if (!context.Request.Path.ToString().StartsWith(path))
|
||||
{
|
||||
resolved = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
resolved = applications.FirstOrDefault();
|
||||
return resolved != null;
|
||||
|
||||
//string appKey = context.Request.Path.Value.Substring(path.Length).TrimStart('/').Split('/').ElementAtOrDefault(1);
|
||||
|
||||
//if (appKey.HasValue())
|
||||
//{
|
||||
// resolved = applications.FirstOrDefault(x => x.Alias == appKey);
|
||||
// return resolved != null;
|
||||
//}
|
||||
|
||||
//resolved = null;
|
||||
//return false;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
namespace zero.Api;
|
||||
|
||||
public static class ApiErrorCodes
|
||||
{
|
||||
public static class Categories
|
||||
{
|
||||
public const string Server = "server";
|
||||
public const string Validation = "validation";
|
||||
}
|
||||
|
||||
public static class Server
|
||||
{
|
||||
public const string Exception = "server.error";
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
|
||||
namespace zero.Api;
|
||||
|
||||
public class ApiParameterTransformer : IOutboundParameterTransformer
|
||||
{
|
||||
public string TransformOutbound(object value)
|
||||
{
|
||||
return value == null ? null : Safenames.Alias(value);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
namespace zero.Api;
|
||||
|
||||
public struct ApiRequestHints
|
||||
{
|
||||
public ApiRequestHints(ApiResponsePreference responsePreference)
|
||||
{
|
||||
ResponsePreference = responsePreference;
|
||||
}
|
||||
|
||||
public ApiResponsePreference ResponsePreference { get; set; } = ApiResponsePreference.Representation;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Preference for POST + PUT requests
|
||||
/// see https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md#75-standard-request-headers
|
||||
/// </summary>
|
||||
public enum ApiResponsePreference
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a minimal repsonse for inserts and updates
|
||||
/// </summary>
|
||||
Minimal = 0,
|
||||
/// <summary>
|
||||
/// Returns status as well as model for inserts and updates
|
||||
/// </summary>
|
||||
Representation = 1
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace zero.Api;
|
||||
|
||||
public static class ApplicationBuilderExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseZeroApi(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
namespace zero.Api.Attributes;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
||||
public class ZeroSystemApiAttribute : Attribute { }
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace zero.Api.Configuration;
|
||||
|
||||
public static class ApiConstants
|
||||
{
|
||||
public const string ChangeToken = "zero.api.change_vector";
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace zero.Api;
|
||||
|
||||
|
||||
public class ConfigureApiJsonOptions : IConfigureOptions<JsonOptions>
|
||||
{
|
||||
public void Configure(JsonOptions options)
|
||||
{
|
||||
// TODO this matches all serialization, not limited to API
|
||||
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace zero.Api.Endpoints.Applications;
|
||||
|
||||
public class ApplicationModule : ZeroModule
|
||||
{
|
||||
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddSingleton<IPermissionProvider, ApplicationPermissions>();
|
||||
services.AddSingleton<IMapperProfile, ApplicationMapperProfile>();
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Applications;
|
||||
|
||||
public class ApplicationPermissions : PermissionProvider
|
||||
{
|
||||
// TODO wrong
|
||||
public const string Create = "zero.settings.country.create";
|
||||
public const string Read = "zero.settings.country.read";
|
||||
public const string Update = "zero.settings.country.update";
|
||||
public const string Delete = "zero.settings.country.delete";
|
||||
|
||||
|
||||
public override Task Configure(IPermissionContext context)
|
||||
{
|
||||
if (!context.TryGetGroup(Constants.Permissions.Groups.Settings, out PermissionGroup group))
|
||||
{
|
||||
group.Permissions.Add(new Permission("zero.settings.country", "@settings.application.countries.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;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace zero.Api.Endpoints.Applications;
|
||||
|
||||
[ZeroSystemApi]
|
||||
public class ApplicationsController : ZeroApiEntityStoreController<Application, IApplicationStore>
|
||||
{
|
||||
public ApplicationsController(IApplicationStore store) : base(store) { }
|
||||
|
||||
|
||||
[HttpGet("empty")]
|
||||
[ZeroAuthorize(ApplicationPermissions.Create)]
|
||||
public virtual Task<ActionResult<Application>> Empty(string flavor = null) => EmptyModel(flavor);
|
||||
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[ZeroAuthorize(ApplicationPermissions.Read)]
|
||||
public virtual Task<ActionResult<Application>> Get(string id, string changeVector = null) => GetModel(id, changeVector);
|
||||
|
||||
|
||||
[HttpGet("")]
|
||||
[ZeroAuthorize(ApplicationPermissions.Read)]
|
||||
public virtual Task<ActionResult<Paged>> Get([FromQuery] ListQuery<Application> query) => GetModels<ApplicationBasic>(query);
|
||||
|
||||
|
||||
[HttpPost("")]
|
||||
[ZeroAuthorize(ApplicationPermissions.Create)]
|
||||
public virtual Task<ActionResult<Result>> Create(Application saveModel) => CreateModel(saveModel);
|
||||
|
||||
|
||||
[HttpPut("{id}")]
|
||||
[ZeroAuthorize(ApplicationPermissions.Update)]
|
||||
public virtual Task<ActionResult<Result>> Update(string id, Application updateModel, [FromQuery] string changeToken = null) => UpdateModel(id, updateModel, changeToken);
|
||||
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[ZeroAuthorize(ApplicationPermissions.Delete)]
|
||||
public virtual Task<ActionResult<Result>> Delete(string id) => DeleteModel(id);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Applications;
|
||||
|
||||
public class ApplicationBasic : BasicModel<Application>
|
||||
{
|
||||
public string FullName { get; set; }
|
||||
|
||||
public string ImageId { get; set; }
|
||||
|
||||
public Uri[] Domains { get; set; }
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Applications;
|
||||
|
||||
public class ApplicationEdit : DisplayModel<Application>
|
||||
{
|
||||
public string ImageId { get; set; }
|
||||
|
||||
public string IconId { get; set; }
|
||||
|
||||
public Uri[] Domains { get; set; } = Array.Empty<Uri>();
|
||||
|
||||
public string FullName { get; set; }
|
||||
|
||||
public string Email { get; set; }
|
||||
|
||||
public List<string> Features { get; set; } = new();
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Applications;
|
||||
|
||||
public class ApplicationMapperProfile : ZeroMapperProfile
|
||||
{
|
||||
public override void Configure(IZeroMapper mapper)
|
||||
{
|
||||
mapper.Define<Application, ApplicationBasic>((source, ctx) => new(), Map);
|
||||
mapper.Define<Application, ApplicationEdit>((source, ctx) => new(), Map);
|
||||
mapper.Define<ApplicationSave, Application>((source, ctx) => new(), Map);
|
||||
}
|
||||
|
||||
|
||||
protected virtual void Map(Application source, ApplicationBasic target, IZeroMapperContext ctx)
|
||||
{
|
||||
this.MapBasicData(source, target);
|
||||
target.ImageId = source.ImageId;
|
||||
target.Domains = source.Domains;
|
||||
target.FullName = source.FullName;
|
||||
}
|
||||
|
||||
protected virtual void Map(Application source, ApplicationEdit target, IZeroMapperContext ctx)
|
||||
{
|
||||
this.MapDisplayData(source, target);
|
||||
target.ImageId = source.ImageId;
|
||||
target.IconId = source.IconId;
|
||||
target.Domains = source.Domains;
|
||||
target.FullName = source.FullName;
|
||||
target.Email = source.Email;
|
||||
target.Features = source.Features;
|
||||
}
|
||||
|
||||
protected virtual void Map(ApplicationSave source, Application target, IZeroMapperContext ctx)
|
||||
{
|
||||
this.MapSaveData(source, target);
|
||||
target.ImageId = source.ImageId;
|
||||
target.IconId = source.IconId;
|
||||
target.Domains = source.Domains;
|
||||
target.FullName = source.FullName;
|
||||
target.Email = source.Email;
|
||||
target.Features = source.Features;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Applications;
|
||||
|
||||
public class ApplicationSave : SaveModel<Application>
|
||||
{
|
||||
public string ImageId { get; set; }
|
||||
|
||||
public string IconId { get; set; }
|
||||
|
||||
public Uri[] Domains { get; set; } = Array.Empty<Uri>();
|
||||
|
||||
public string FullName { get; set; }
|
||||
|
||||
public string Email { get; set; }
|
||||
|
||||
public List<string> Features { get; set; } = new();
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace zero.Api.Endpoints.Countries;
|
||||
|
||||
public class CountriesController : ZeroApiEntityStoreController<Country, ICountryStore>
|
||||
{
|
||||
public CountriesController(ICountryStore store) : base(store) { }
|
||||
|
||||
|
||||
[HttpGet("empty")]
|
||||
[ZeroAuthorize(CountryPermissions.Create)]
|
||||
public virtual Task<ActionResult<Country>> Empty(string flavor = null) => EmptyModel(flavor);
|
||||
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[ZeroAuthorize(CountryPermissions.Read)]
|
||||
public virtual Task<ActionResult<Country>> Get(string id, string changeVector = null) => GetModel(id, changeVector);
|
||||
|
||||
|
||||
[HttpGet("")]
|
||||
[ZeroAuthorize(CountryPermissions.Read)]
|
||||
public virtual Task<ActionResult<Paged>> Get([FromQuery] ListQuery<Country> query)
|
||||
{
|
||||
query.OrderQuery = q => q.OrderByDescending(x => x.IsPreferred).ThenBy(x => x.Name);
|
||||
return GetModelsByIndex<CountryBasic, zero_Api_Countries_Listing>(query);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("")]
|
||||
[ZeroAuthorize(CountryPermissions.Create)]
|
||||
public virtual Task<ActionResult<Result>> Create(Country saveModel) => CreateModel(saveModel);
|
||||
|
||||
|
||||
[HttpPut("{id}")]
|
||||
[ZeroAuthorize(CountryPermissions.Update)]
|
||||
public virtual Task<ActionResult<Result>> Update(string id, Country updateModel, [FromQuery] string changeToken = null) => UpdateModel(id, updateModel, changeToken);
|
||||
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[ZeroAuthorize(CountryPermissions.Delete)]
|
||||
public virtual Task<ActionResult<Result>> Delete(string id) => DeleteModel(id);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace zero.Api.Endpoints.Countries;
|
||||
|
||||
public class CountryModule : ZeroModule
|
||||
{
|
||||
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddSingleton<IPermissionProvider, CountryPermissions>();
|
||||
services.AddSingleton<IMapperProfile, CountryMapperProfile>();
|
||||
|
||||
services.Configure<RavenOptions>(opts =>
|
||||
{
|
||||
opts.Indexes.Add<zero_Api_Countries_Listing>();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Countries;
|
||||
|
||||
public class CountryPermissions : PermissionProvider
|
||||
{
|
||||
public const string Create = "zero.settings.country.create";
|
||||
public const string Read = "zero.settings.country.read";
|
||||
public const string Update = "zero.settings.country.update";
|
||||
public const string Delete = "zero.settings.country.delete";
|
||||
|
||||
|
||||
public override Task Configure(IPermissionContext context)
|
||||
{
|
||||
if (!context.TryGetGroup(Constants.Permissions.Groups.Settings, out PermissionGroup group))
|
||||
{
|
||||
group.Permissions.Add(new Permission("zero.settings.country", "@settings.application.countries.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;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Endpoints.Countries;
|
||||
|
||||
public class zero_Api_Countries_Listing : ZeroIndex<Country>
|
||||
{
|
||||
protected override void Create()
|
||||
{
|
||||
Map = items => items.Select(item => new
|
||||
{
|
||||
Name = item.Name,
|
||||
IsPreferred = item.IsPreferred
|
||||
});
|
||||
|
||||
Index(x => x.Name, FieldIndexing.Search);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Countries;
|
||||
|
||||
public class CountryBasic : BasicModel<Country>
|
||||
{
|
||||
public bool IsPreferred { get; set; }
|
||||
|
||||
public string Code { get; set; }
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Countries;
|
||||
|
||||
public class CountryEdit : DisplayModel<Country>
|
||||
{
|
||||
public bool IsPreferred { get; set; }
|
||||
|
||||
public string Code { get; set; }
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Countries;
|
||||
|
||||
public class CountryMapperProfile : ZeroMapperProfile
|
||||
{
|
||||
public override void Configure(IZeroMapper mapper)
|
||||
{
|
||||
mapper.Define<Country, CountryBasic>((source, ctx) => new(), Map);
|
||||
mapper.Define<Country, CountryEdit>((source, ctx) => new(), Map);
|
||||
mapper.Define<CountrySave, Country>((source, ctx) => new(), Map);
|
||||
}
|
||||
|
||||
|
||||
protected virtual void Map(Country source, CountryBasic target, IZeroMapperContext ctx)
|
||||
{
|
||||
this.MapBasicData(source, target);
|
||||
target.Code = source.Code;
|
||||
target.IsPreferred = source.IsPreferred;
|
||||
}
|
||||
|
||||
protected virtual void Map(Country source, CountryEdit target, IZeroMapperContext ctx)
|
||||
{
|
||||
this.MapDisplayData(source, target);
|
||||
target.Code = source.Code;
|
||||
target.IsPreferred = source.IsPreferred;
|
||||
}
|
||||
|
||||
protected virtual void Map(CountrySave source, Country target, IZeroMapperContext ctx)
|
||||
{
|
||||
this.MapSaveData(source, target);
|
||||
target.Code = source.Code;
|
||||
target.IsPreferred = source.IsPreferred;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Countries;
|
||||
|
||||
public class CountrySave : SaveModel<Country>
|
||||
{
|
||||
public bool IsPreferred { get; set; }
|
||||
|
||||
public string Code { get; set; }
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using Microsoft.AspNetCore.Diagnostics;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace zero.Api.Endpoints.Error;
|
||||
|
||||
public class ErrorController : ZeroApiController
|
||||
{
|
||||
[HttpGet("")]
|
||||
public virtual ActionResult<ApiResponse> Index()
|
||||
{
|
||||
return new ErrorApiResponse()
|
||||
{
|
||||
Success = false,
|
||||
Status = HttpContext.Response.StatusCode
|
||||
};
|
||||
|
||||
//IExceptionHandlerFeature exception = HttpContext.Features.Get<IExceptionHandlerFeature>();
|
||||
|
||||
//return new ErrorApiResponse()
|
||||
//{
|
||||
// Success = false,
|
||||
// Status = HttpContext.Response.StatusCode,
|
||||
// Error = new()
|
||||
// {
|
||||
// ApiPath = exception.Path,
|
||||
// Message = exception.Error.Message
|
||||
// }
|
||||
//};
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace zero.Api.Endpoints.Error;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddZeroBackofficeErrorHandler(this IServiceCollection services)
|
||||
{
|
||||
return services;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace zero.Api.Endpoints.Integrations;
|
||||
|
||||
public class IntegrationModule : ZeroModule
|
||||
{
|
||||
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddSingleton<IMapperProfile, IntegrationMapperProfile>();
|
||||
|
||||
//services.Configure<RavenOptions>(opts =>
|
||||
//{
|
||||
// opts.Indexes.Add<zero_Api_Languages_Listing>();
|
||||
//});
|
||||
}
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections;
|
||||
using zero.Mapper;
|
||||
|
||||
namespace zero.Api.Endpoints.Integrations;
|
||||
|
||||
public class IntegrationsController : ZeroApiController
|
||||
{
|
||||
readonly IIntegrationTypeService IntegrationTypes;
|
||||
readonly IIntegrationStore Store;
|
||||
|
||||
public IntegrationsController(IIntegrationTypeService integrationTypes, IIntegrationStore store)
|
||||
{
|
||||
IntegrationTypes = integrationTypes;
|
||||
Store = store;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpGet("types")]
|
||||
//[ZeroAuthorize(SpacePermissions.Read)]
|
||||
public virtual async Task<ActionResult<IEnumerable>> GetTypes()
|
||||
{
|
||||
IEnumerable<IntegrationTypeDisplay> result = Mapper.Map<IntegrationType, IntegrationTypeDisplay>(IntegrationTypes.GetAll()).ToList();
|
||||
|
||||
foreach (IntegrationTypeDisplay display in result)
|
||||
{
|
||||
Integration model = await Store.Load(display.Alias);
|
||||
|
||||
if (model != null)
|
||||
{
|
||||
display.IsConfigured = true;
|
||||
display.IsActivated = model.IsActive;
|
||||
display.ModelId = model.Id;
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("types/{alias}")]
|
||||
//[ZeroAuthorize(SpacePermissions.Read)]
|
||||
public virtual async Task<ActionResult<IntegrationTypeDisplay>> GetType(string alias)
|
||||
{
|
||||
IntegrationTypeDisplay result = Mapper.Map<IntegrationType, IntegrationTypeDisplay>(IntegrationTypes.GetByAlias(alias));
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
Integration model = await Store.Load(result.Alias);
|
||||
|
||||
if (model != null)
|
||||
{
|
||||
result.IsConfigured = true;
|
||||
result.IsActivated = model.IsActive;
|
||||
result.ModelId = model.Id;
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("empty/{alias}")]
|
||||
//[ZeroAuthorize(CountryPermissions.Create)]
|
||||
public virtual async Task<ActionResult<Integration>> Empty(string alias)
|
||||
{
|
||||
Integration model = await Store.Empty(alias);
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("{alias}")]
|
||||
//[ZeroAuthorize(CountryPermissions.Read)]
|
||||
public virtual async Task<ActionResult<Integration>> Get(string alias)
|
||||
{
|
||||
Integration model = await Store.Load(alias);
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
HttpContext.Items[ApiConstants.ChangeToken] = Store.GetChangeToken(model);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("")]
|
||||
//[ZeroAuthorize(CountryPermissions.Create)]
|
||||
public virtual async Task<ActionResult<Result>> Create(Integration saveModel)
|
||||
{
|
||||
Result<Integration> result = await Store.Create(saveModel);
|
||||
|
||||
bool minimalResponse = Hints.ResponsePreference == ApiResponsePreference.Minimal;
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
return Created("/", minimalResponse ? null : saveModel);
|
||||
}
|
||||
|
||||
return result.WithoutModel();
|
||||
}
|
||||
|
||||
|
||||
[HttpPut("{alias}")]
|
||||
//[ZeroAuthorize(CountryPermissions.Update)]
|
||||
public virtual async Task<ActionResult<Result>> Update(string alias, Integration updateModel, [FromQuery] string changeToken = null)
|
||||
{
|
||||
if (alias != updateModel.Flavor)
|
||||
{
|
||||
return BadRequest(Result.Fail(nameof(alias), "@integration.errors.noaliasmatch"));
|
||||
}
|
||||
|
||||
Result<Integration> result = await Store.Update(updateModel);
|
||||
|
||||
if (Hints.ResponsePreference == ApiResponsePreference.Minimal)
|
||||
{
|
||||
return result.WithoutModel();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
[HttpPut("{alias}/activate")]
|
||||
//[ZeroAuthorize(CountryPermissions.Update)]
|
||||
public virtual async Task<ActionResult<Result>> Activate(string alias)
|
||||
{
|
||||
Result<Integration> result = await Store.Activate(alias);
|
||||
|
||||
if (Hints.ResponsePreference == ApiResponsePreference.Minimal)
|
||||
{
|
||||
return result.WithoutModel();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
[HttpPut("{alias}/deactivate")]
|
||||
//[ZeroAuthorize(CountryPermissions.Update)]
|
||||
public virtual async Task<ActionResult<Result>> Deactivate(string alias)
|
||||
{
|
||||
Result<Integration> result = await Store.Deactivate(alias);
|
||||
|
||||
if (Hints.ResponsePreference == ApiResponsePreference.Minimal)
|
||||
{
|
||||
return result.WithoutModel();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete("{alias}")]
|
||||
//[ZeroAuthorize(CountryPermissions.Delete)]
|
||||
public virtual async Task<ActionResult<Result>> Delete(string alias)
|
||||
{
|
||||
Result<Integration> result = await Store.Delete(alias);
|
||||
return result.WithoutModel();
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Integrations;
|
||||
|
||||
public class IntegrationMapperProfile : ZeroMapperProfile
|
||||
{
|
||||
public override void Configure(IZeroMapper mapper)
|
||||
{
|
||||
mapper.Define<IntegrationType, IntegrationTypeDisplay>((source, ctx) => new(), Map);
|
||||
}
|
||||
|
||||
|
||||
protected virtual void Map(IntegrationType source, IntegrationTypeDisplay target, IZeroMapperContext ctx)
|
||||
{
|
||||
target.Description = source.Description;
|
||||
target.Name = source.Name;
|
||||
target.Alias = source.Alias;
|
||||
target.EditorAlias = source.EditorAlias;
|
||||
target.ImagePath = source.ImagePath;
|
||||
target.Tags = source.Tags;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Integrations;
|
||||
|
||||
public class IntegrationTypeDisplay
|
||||
{
|
||||
public string EditorAlias { get; set; }
|
||||
|
||||
public string Alias { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public List<string> Tags { get; set; } = new();
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
public string ImagePath { get; set; }
|
||||
|
||||
public bool IsActivated { get; set; }
|
||||
|
||||
public bool IsConfigured { get; set; }
|
||||
|
||||
public string ModelId { get; set; }
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Endpoints.Languages;
|
||||
|
||||
public class zero_Api_Languages_Listing : ZeroIndex<Language>
|
||||
{
|
||||
protected override void Create()
|
||||
{
|
||||
Map = items => items.Select(item => new
|
||||
{
|
||||
Name = item.Name,
|
||||
CreatedDate = item.CreatedDate,
|
||||
IsDefault = item.IsDefault
|
||||
});
|
||||
|
||||
Index(x => x.Name, FieldIndexing.Search);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace zero.Api.Endpoints.Languages;
|
||||
|
||||
public class LanguageModule : ZeroModule
|
||||
{
|
||||
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddSingleton<IPermissionProvider, LanguagePermissions>();
|
||||
services.AddSingleton<IMapperProfile, LanguageMapperProfile>();
|
||||
|
||||
services.Configure<RavenOptions>(opts =>
|
||||
{
|
||||
opts.Indexes.Add<zero_Api_Languages_Listing>();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Languages;
|
||||
|
||||
public class LanguagePermissions : PermissionProvider
|
||||
{
|
||||
public const string Create = "zero.settings.language.create";
|
||||
public const string Read = "zero.settings.language.read";
|
||||
public const string Update = "zero.settings.language.update";
|
||||
public const string Delete = "zero.settings.language.delete";
|
||||
|
||||
|
||||
public override Task Configure(IPermissionContext context)
|
||||
{
|
||||
if (!context.TryGetGroup(Constants.Permissions.Groups.Settings, out PermissionGroup group))
|
||||
{
|
||||
group.Permissions.Add(new Permission("zero.settings.language", "@settings.application.languages.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;
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace zero.Api.Endpoints.Languages;
|
||||
|
||||
public class LanguagesController : ZeroApiEntityStoreController<Language, ILanguageStore>
|
||||
{
|
||||
public LanguagesController(ILanguageStore store) : base(store)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("empty")]
|
||||
[ZeroAuthorize(LanguagePermissions.Create)]
|
||||
public virtual Task<ActionResult<Language>> Empty(string flavor = null) => EmptyModel(flavor);
|
||||
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[ZeroAuthorize(LanguagePermissions.Read)]
|
||||
public virtual Task<ActionResult<Language>> Get(string id, string changeVector = null) => GetModel(id, changeVector);
|
||||
|
||||
|
||||
[HttpGet("")]
|
||||
[ZeroAuthorize(LanguagePermissions.Read)]
|
||||
public virtual Task<ActionResult<Paged>> Get([FromQuery] ListQuery<Language> query) => GetModelsByIndex<LanguageBasic, zero_Api_Languages_Listing>(query);
|
||||
|
||||
|
||||
[HttpPost("")]
|
||||
[ZeroAuthorize(LanguagePermissions.Create)]
|
||||
public virtual Task<ActionResult<Result>> Create(Language saveModel) => CreateModel(saveModel);
|
||||
|
||||
|
||||
[HttpPut("{id}")]
|
||||
[ZeroAuthorize(LanguagePermissions.Update)]
|
||||
public virtual Task<ActionResult<Result>> Update(string id, Language updateModel, [FromQuery] string changeToken = null) => UpdateModel(id, updateModel, changeToken);
|
||||
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[ZeroAuthorize(LanguagePermissions.Delete)]
|
||||
public virtual Task<ActionResult<Result>> Delete(string id) => DeleteModel(id);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Languages;
|
||||
|
||||
public class LanguageBasic : BasicModel<Language>
|
||||
{
|
||||
public string Code { get; set; }
|
||||
|
||||
public bool IsDefault { get; set; }
|
||||
|
||||
public string InheritedLanguageId { get; set; }
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Languages;
|
||||
|
||||
public class LanguageEdit : DisplayModel<Language>
|
||||
{
|
||||
public string Code { get; set; }
|
||||
|
||||
public bool IsDefault { get; set; }
|
||||
|
||||
public string InheritedLanguageId { get; set; }
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Languages;
|
||||
|
||||
public class LanguageMapperProfile : ZeroMapperProfile
|
||||
{
|
||||
public override void Configure(IZeroMapper mapper)
|
||||
{
|
||||
mapper.Define<Language, LanguageBasic>((source, ctx) => new(), Map);
|
||||
mapper.Define<Language, LanguageEdit>((source, ctx) => new(), Map);
|
||||
mapper.Define<LanguageSave, Language>((source, ctx) => new(), Map);
|
||||
}
|
||||
|
||||
|
||||
protected virtual void Map(Language source, LanguageBasic target, IZeroMapperContext ctx)
|
||||
{
|
||||
this.MapBasicData(source, target);
|
||||
target.Code = source.Code;
|
||||
target.IsDefault = source.IsDefault;
|
||||
target.InheritedLanguageId = source.InheritedLanguageId;
|
||||
}
|
||||
|
||||
protected virtual void Map(Language source, LanguageEdit target, IZeroMapperContext ctx)
|
||||
{
|
||||
this.MapDisplayData(source, target);
|
||||
target.Code = source.Code;
|
||||
target.IsDefault = source.IsDefault;
|
||||
target.InheritedLanguageId = source.InheritedLanguageId;
|
||||
}
|
||||
|
||||
protected virtual void Map(LanguageSave source, Language target, IZeroMapperContext ctx)
|
||||
{
|
||||
this.MapSaveData(source, target);
|
||||
target.Code = source.Code;
|
||||
target.IsDefault = source.IsDefault;
|
||||
target.InheritedLanguageId = source.InheritedLanguageId;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Languages;
|
||||
|
||||
public class LanguageSave : SaveModel<Language>
|
||||
{
|
||||
public string Code { get; set; }
|
||||
|
||||
public bool IsDefault { get; set; }
|
||||
|
||||
public string InheritedLanguageId { get; set; }
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
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>();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
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(string flavor = null) => EmptyModel<MailEdit>(flavor);
|
||||
|
||||
|
||||
[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 GetModelsByIndex<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);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Mails;
|
||||
|
||||
public class MailBasic : BasicModel<MailTemplate>
|
||||
{
|
||||
public string Subject { get; set; }
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
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,32 +0,0 @@
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class zero_Api_Media_ChildCounts : ZeroIndex<zero.Media.Media, zero_Api_Media_ChildCounts.Result>
|
||||
{
|
||||
public class Result : ZeroIdEntity
|
||||
{
|
||||
public int ChildCount { get; set; }
|
||||
|
||||
public int ChildFolderCount { get; set; }
|
||||
}
|
||||
|
||||
protected override void Create()
|
||||
{
|
||||
Map = items => items.Where(x => x.ParentId != null).Select(item => new Result
|
||||
{
|
||||
Id = item.ParentId,
|
||||
ChildCount = 1,
|
||||
ChildFolderCount = item.IsFolder ? 1 : 0
|
||||
});
|
||||
|
||||
Reduce = results => results.GroupBy(x => new { x.Id }).Select(group => new Result()
|
||||
{
|
||||
Id = group.Key.Id,
|
||||
ChildCount = group.Sum(x => x.ChildCount),
|
||||
ChildFolderCount = group.Sum(x => x.ChildFolderCount)
|
||||
});
|
||||
|
||||
StoreAllFields(FieldStorage.Yes);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
|
||||
public class MediaTreeHierarchyIndexResult : ZeroTreeHierarchyIndexResult
|
||||
{
|
||||
public bool IsFolder { get; set; }
|
||||
}
|
||||
|
||||
public class zero_Api_Media_Hierarchy : ZeroTreeHierarchyIndex<zero.Media.Media>
|
||||
{
|
||||
protected override void Create()
|
||||
{
|
||||
Map = items => items.Select(item => new MediaTreeHierarchyIndexResult
|
||||
{
|
||||
Id = item.Id,
|
||||
IsFolder = item.IsFolder,
|
||||
Path = Recurse(item, x => LoadDocument<zero.Media.Media>(x.ParentId))
|
||||
.Where(x => x != null && x.Id != null && x.Id != item.Id)
|
||||
.Reverse()
|
||||
.Select(current => current.Id)
|
||||
.ToList()
|
||||
});
|
||||
|
||||
StoreAllFields(FieldStorage.Yes);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class zero_Api_Media_Listing : ZeroIndex<zero.Media.Media>
|
||||
{
|
||||
protected override void Create()
|
||||
{
|
||||
Map = items => items.Select(item => new
|
||||
{
|
||||
Name = item.Name,
|
||||
ParentId = item.ParentId,
|
||||
CreatedDate = item.CreatedDate,
|
||||
IsFolder = item.IsFolder
|
||||
});
|
||||
|
||||
Index(x => x.Name, FieldIndexing.Search);
|
||||
Index(x => x.ParentId, FieldIndexing.Exact);
|
||||
Index(x => x.CreatedDate, FieldIndexing.Exact);
|
||||
Index(x => x.IsFolder, FieldIndexing.Exact);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class MediaBasic : ZeroIdEntity
|
||||
{
|
||||
public string ParentId { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public bool IsFolder { get; set; }
|
||||
|
||||
public string Source { get; set; }
|
||||
|
||||
public string Preview { get; set; }
|
||||
|
||||
public int Children { get; set; }
|
||||
|
||||
public long Size { get; set; }
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class MediaBulkDeleteOperation
|
||||
{
|
||||
public string[] Ids { get; set; }
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class MediaBulkMoveOperation
|
||||
{
|
||||
public string ParentId { get; set; }
|
||||
|
||||
public string[] Ids { get; set; }
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class MediaDescendantStatistics
|
||||
{
|
||||
public int Folders { get; set; }
|
||||
|
||||
public int Files { get; set; }
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class MediaEdit : DisplayModel<zero.Media.Media>
|
||||
{
|
||||
public bool IsFolder { get; set; }
|
||||
|
||||
public string ParentId { get; set; }
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class MediaFileEdit : MediaEdit
|
||||
{
|
||||
public string AlternativeText { get; set; }
|
||||
|
||||
public string Caption { get; set; }
|
||||
|
||||
public string Path { get; set; }
|
||||
|
||||
public Dictionary<string, string> Thumbnails { get; set; } = new();
|
||||
|
||||
public long Size { get; set; }
|
||||
|
||||
public MediaImageMetadata ImageMeta { get; set; }
|
||||
|
||||
public MediaFocalPoint FocalPoint { get; set; }
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class MediaFolderEdit : MediaEdit
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class MediaMapperProfile : ZeroMapperProfile
|
||||
{
|
||||
protected IMediaFileSystem FileSystem { get; private set; }
|
||||
|
||||
|
||||
public MediaMapperProfile(IMediaFileSystem fileSystem)
|
||||
{
|
||||
FileSystem = fileSystem;
|
||||
}
|
||||
|
||||
|
||||
public override void Configure(IZeroMapper mapper)
|
||||
{
|
||||
mapper.Define<zero.Media.Media, MediaBasic>((source, ctx) => new(), Map);
|
||||
mapper.Define<zero.Media.Media, MediaEdit>((source, ctx) => new(), Map);
|
||||
mapper.Define<zero.Media.Media, MediaFileEdit>((source, ctx) => new(), Map);
|
||||
mapper.Define<zero.Media.Media, MediaFolderEdit>((source, ctx) => new(), Map);
|
||||
mapper.Define<MediaSave, zero.Media.Media>((source, ctx) => new(), Map);
|
||||
}
|
||||
|
||||
|
||||
protected virtual void Map(zero.Media.Media source, MediaBasic target, IZeroMapperContext ctx)
|
||||
{
|
||||
target.Id = source.Id;
|
||||
target.Name = source.Name;
|
||||
target.ParentId = source.ParentId;
|
||||
target.IsFolder = source.IsFolder;
|
||||
target.Children = 0;
|
||||
target.Size = source.Size;
|
||||
|
||||
if (source.Path.HasValue())
|
||||
{
|
||||
target.Source = FileSystem.MapToPublicPath(source.Path);
|
||||
}
|
||||
|
||||
if (source.ImageMeta != null && source.ImageMeta.Thumbnails.Any())
|
||||
{
|
||||
string path = source.ImageMeta.Thumbnails.GetValueOrDefault("preview");
|
||||
target.Preview = path.IsNullOrEmpty() ? null : FileSystem.MapToPublicPath(path);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Map(zero.Media.Media source, MediaEdit target, IZeroMapperContext ctx)
|
||||
{
|
||||
this.MapDisplayData(source, target);
|
||||
target.IsFolder = source.IsFolder;
|
||||
target.ParentId = source.ParentId;
|
||||
}
|
||||
|
||||
|
||||
protected virtual void Map(zero.Media.Media source, MediaFolderEdit target, IZeroMapperContext ctx)
|
||||
{
|
||||
Map(source, (MediaEdit)target, ctx);
|
||||
}
|
||||
|
||||
|
||||
protected virtual void Map(zero.Media.Media source, MediaFileEdit target, IZeroMapperContext ctx)
|
||||
{
|
||||
Map(source, (MediaEdit)target, ctx);
|
||||
target.AlternativeText = source.ImageMeta?.AlternativeText;
|
||||
target.Caption = source.Caption;
|
||||
target.Path = source.Path;
|
||||
target.Thumbnails = source.ImageMeta?.Thumbnails;
|
||||
target.Size = source.Size;
|
||||
target.ImageMeta = source.ImageMeta;
|
||||
target.FocalPoint = source.ImageMeta?.FocalPoint;
|
||||
}
|
||||
|
||||
|
||||
protected virtual void Map(MediaSave source, zero.Media.Media target, IZeroMapperContext ctx)
|
||||
{
|
||||
this.MapSaveData(source, target);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class MediaSave : SaveModel<zero.Media.Media>
|
||||
{
|
||||
public bool IsFolder { get; set; }
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class MediaSourceResult
|
||||
{
|
||||
public string Path { get; set; }
|
||||
}
|
||||
@@ -1,380 +0,0 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Raven.Client.Documents;
|
||||
using Raven.Client.Documents.Linq;
|
||||
using System.IO;
|
||||
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
/// <summary>
|
||||
/// GET /empty
|
||||
/// GET /
|
||||
/// GET /{id}
|
||||
/// GET /{id}/hierarchy
|
||||
/// GET /{id}/{size}.tmp
|
||||
/// POS /
|
||||
/// PUT /{id}
|
||||
/// PUT /{id/move/{folderId}
|
||||
/// DEL /{id}
|
||||
///
|
||||
/// GET /folders/empty
|
||||
/// GET /folders/{id}
|
||||
/// GET /folders/{id}/children
|
||||
/// GET /folders/{id}/hierarchy
|
||||
/// POS /folders/
|
||||
/// PUT /folders/{id}
|
||||
/// PUT /folders/{id/move/{folderId}
|
||||
/// DEL /folders/{id}
|
||||
///
|
||||
/// GET /bulk/descendants
|
||||
/// PUT /bulk/move
|
||||
/// DEL /bulk/delete
|
||||
/// </summary>
|
||||
public class MediaController : ZeroApiTreeEntityStoreController<zero.Media.Media, IMediaStore>
|
||||
{
|
||||
IMediaManagement Media;
|
||||
|
||||
public MediaController(IMediaStore store, IMediaManagement media) : base(store)
|
||||
{
|
||||
Media = media;
|
||||
}
|
||||
|
||||
#region bulk operations
|
||||
|
||||
[HttpPut("bulk/move")]
|
||||
[ZeroAuthorize(MediaPermissions.Update)]
|
||||
public virtual async Task<ActionResult<IEnumerable<Result>>> BulkMove(MediaBulkMoveOperation operation)
|
||||
{
|
||||
List<Result<string>> results = new();
|
||||
|
||||
foreach (string id in operation.Ids)
|
||||
{
|
||||
Result<zero.Media.Media> result = await Store.Move(id, NormalizeParentId(operation.ParentId));
|
||||
results.Add(result.ConvertTo(id));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete("bulk/delete")]
|
||||
[ZeroAuthorize(MediaPermissions.Update)]
|
||||
public virtual async Task<ActionResult<IEnumerable<Result>>> BulkDelete(MediaBulkDeleteOperation operation)
|
||||
{
|
||||
List<Result<string>> results = new();
|
||||
|
||||
foreach (string id in operation.Ids)
|
||||
{
|
||||
Result<string[]> result = await Store.DeleteWithDescendants(id);
|
||||
results.Add(result.ConvertTo(id));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("bulk/descendants")]
|
||||
[ZeroAuthorize(MediaPermissions.Update)]
|
||||
public virtual async Task<ActionResult<MediaDescendantStatistics>> GetDescendantStatistics([FromQuery] string[] ids)
|
||||
{
|
||||
List<Result<string>> results = new();
|
||||
|
||||
Dictionary<string, zero.Media.Media> parents = await Store.Load(ids);
|
||||
|
||||
int folderCount = parents.Count(x => x.Value != null && x.Value.IsFolder);
|
||||
int fileCount = parents.Count(x => x.Value != null && !x.Value.IsFolder);
|
||||
|
||||
folderCount += await Store.Session.Query<MediaTreeHierarchyIndexResult, zero_Api_Media_Hierarchy>().CountAsync(x => x.Path.ContainsAny(ids) && x.IsFolder);
|
||||
fileCount += await Store.Session.Query<MediaTreeHierarchyIndexResult, zero_Api_Media_Hierarchy>().CountAsync(x => x.Path.ContainsAny(ids) && !x.IsFolder);
|
||||
|
||||
return new MediaDescendantStatistics()
|
||||
{
|
||||
Files = fileCount,
|
||||
Folders = folderCount
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region folder operations
|
||||
|
||||
[HttpGet("folders/empty")]
|
||||
[ZeroAuthorize(MediaPermissions.Create)]
|
||||
public virtual async Task<ActionResult<zero.Media.Media>> EmptyFolder(string flavor = null) => await EmptyModel(flavor, x => x.IsFolder = true);
|
||||
|
||||
|
||||
[HttpGet("folders")]
|
||||
[ZeroAuthorize(MediaPermissions.Read)]
|
||||
public virtual Task<ActionResult<Paged>> GetFoldersByQuery([FromQuery] ListQuery<zero.Media.Media> query)
|
||||
{
|
||||
query.AdditionalQuery = q => q.Where(x => x.IsFolder);
|
||||
return GetModelsByIndex<MediaBasic, zero_Api_Media_Listing>(query);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("folders/{id}")]
|
||||
[ZeroAuthorize(MediaPermissions.Read)]
|
||||
public virtual async Task<ActionResult<zero.Media.Media>> GetFolder(string id, string changeVector = null) => await GetModel(id, changeVector);
|
||||
|
||||
|
||||
[HttpGet("folders/{id}/children")]
|
||||
[ZeroAuthorize(MediaPermissions.Read)]
|
||||
public virtual async Task<ActionResult<Paged>> GetFolderChildren(string id, [FromQuery] ListQuery<zero.Media.Media> query, [FromQuery] bool files = true)
|
||||
{
|
||||
id = NormalizeParentId(id);
|
||||
|
||||
zero.Media.Media parent = null;
|
||||
|
||||
if (id.HasValue())
|
||||
{
|
||||
parent = await Store.Load(id);
|
||||
|
||||
if (parent == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
|
||||
query.OrderQuery = q => q.OrderByDescending(x => x.IsFolder).ThenByDescending(x => x.CreatedDate);
|
||||
Paged<zero.Media.Media> result = await Store.LoadChildren<zero_Api_Media_Listing>(id, query.Page, query.PageSize, q => q.WhereIf(x => x.IsFolder, !files).Filter(query));
|
||||
Paged<MediaBasic> mappedResult = Mapper.Map<zero.Media.Media, MediaBasic>(result);
|
||||
|
||||
// get children for all folders
|
||||
string[] folderIds = mappedResult.Items.Where(x => x.IsFolder).Select(x => x.Id).ToArray();
|
||||
IList<zero_Api_Media_ChildCounts.Result> children = await Store.Session.Query<zero_Api_Media_ChildCounts.Result, zero_Api_Media_ChildCounts>()
|
||||
.ProjectInto<zero_Api_Media_ChildCounts.Result>()
|
||||
.Where(x => x.Id.In(folderIds))
|
||||
.ToListAsync();
|
||||
|
||||
foreach (MediaBasic item in mappedResult.Items)
|
||||
{
|
||||
if (item.IsFolder)
|
||||
{
|
||||
zero_Api_Media_ChildCounts.Result childCounts = children.FirstOrDefault(x => x.Id == item.Id);
|
||||
|
||||
if (childCounts != null)
|
||||
{
|
||||
item.Children = !files ? childCounts.ChildFolderCount : childCounts.ChildCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mappedResult.Properties.Add("parentId", parent?.ParentId);
|
||||
|
||||
return mappedResult;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("folders/{id}/hierarchy")]
|
||||
[ZeroAuthorize(MediaPermissions.Read)]
|
||||
public virtual async Task<ActionResult<zero.Media.Media[]>> GetFolderHierarchy(string id)
|
||||
{
|
||||
return await Store.GetHierarchy<zero_Api_Media_Hierarchy>(NormalizeParentId(id));
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("folders")]
|
||||
[ZeroAuthorize(MediaPermissions.Create)]
|
||||
public virtual Task<ActionResult<Result>> CreateFolder(zero.Media.Media saveModel)
|
||||
{
|
||||
saveModel.IsFolder = true;
|
||||
return CreateModel(saveModel);
|
||||
}
|
||||
|
||||
|
||||
[HttpPut("folders/{id}")]
|
||||
[ZeroAuthorize(MediaPermissions.Update)]
|
||||
public virtual Task<ActionResult<Result>> UpdateFolder(string id, zero.Media.Media updateModel, [FromQuery] string changeToken = null) => UpdateModel(id, updateModel, changeToken);
|
||||
|
||||
|
||||
[HttpPut("folders/{id}/move/{destinationId}")]
|
||||
[ZeroAuthorize(MediaPermissions.Read)]
|
||||
public virtual async Task<ActionResult<Result>> MoveFolder(string id, string destinationId) => await MoveModel(id, NormalizeParentId(destinationId));
|
||||
|
||||
|
||||
[HttpDelete("folders/{id}")]
|
||||
[ZeroAuthorize(MediaPermissions.Delete)]
|
||||
public virtual Task<ActionResult<Result<string[]>>> DeleteFolder(string id) => DeleteModelWithDescendants(id);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region file operations
|
||||
|
||||
[HttpGet("empty")]
|
||||
[ZeroAuthorize(MediaPermissions.Create)]
|
||||
public virtual async Task<ActionResult<zero.Media.Media>> Empty(string flavor = null) => await EmptyModel(flavor, x => x.IsFolder = false);
|
||||
|
||||
|
||||
[HttpGet("")]
|
||||
[ZeroAuthorize(MediaPermissions.Read)]
|
||||
public virtual Task<ActionResult<Paged>> GetByQuery([FromQuery] ListQuery<zero.Media.Media> query)
|
||||
{
|
||||
query.AdditionalQuery = q => q.Where(x => !x.IsFolder);
|
||||
return GetModelsByIndex<MediaBasic, zero_Api_Media_Listing>(query);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("search")]
|
||||
[ZeroAuthorize(MediaPermissions.Read)]
|
||||
public virtual async Task<ActionResult<Paged>> Search([FromQuery] ListQuery<zero.Media.Media> query, [FromQuery(Name = "q")] string searchQuery, [FromQuery] string parent = null, [FromQuery] bool includeSubfolders = true)
|
||||
{
|
||||
query.OrderQuery = q => q.OrderByScoreDescending().ThenByDescending(x => x.IsFolder).ThenByDescending(x => x.CreatedDate);
|
||||
query.Search = null;
|
||||
|
||||
if (searchQuery.IsNullOrWhiteSpace())
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (parent.HasValue())
|
||||
{
|
||||
List<string> descendantIds = await Store.Session.Query<MediaTreeHierarchyIndexResult, zero_Api_Media_Hierarchy>().Where(x => x.Path.Contains(parent) && x.IsFolder).Select(x => x.Id).ToListAsync();
|
||||
descendantIds.Add(parent);
|
||||
query.AdditionalQuery = q => q.Where(x => x.ParentId.In(descendantIds));
|
||||
}
|
||||
|
||||
Paged<zero.Media.Media> result = await Store.Load<zero_Api_Media_Listing>(query.Page, query.PageSize, q => q
|
||||
.SearchIf(x => x.Name, searchQuery, "*", "*", Raven.Client.Documents.Queries.SearchOperator.And)
|
||||
.Filter(query)
|
||||
);
|
||||
|
||||
Paged<MediaBasic> mappedResult = Mapper.Map<zero.Media.Media, MediaBasic>(result);
|
||||
|
||||
// get children for all folders
|
||||
string[] folderIds = mappedResult.Items.Where(x => x.IsFolder).Select(x => x.Id).ToArray();
|
||||
IList<zero_Api_Media_ChildCounts.Result> children = await Store.Session.Query<zero_Api_Media_ChildCounts.Result, zero_Api_Media_ChildCounts>()
|
||||
.ProjectInto<zero_Api_Media_ChildCounts.Result>()
|
||||
.Where(x => x.Id.In(folderIds))
|
||||
.ToListAsync();
|
||||
|
||||
foreach (MediaBasic item in mappedResult.Items)
|
||||
{
|
||||
if (item.IsFolder)
|
||||
{
|
||||
zero_Api_Media_ChildCounts.Result childCounts = children.FirstOrDefault(x => x.Id == item.Id);
|
||||
item.Children = childCounts?.ChildCount ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
return mappedResult;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[ZeroAuthorize(MediaPermissions.Read)]
|
||||
public virtual async Task<ActionResult<zero.Media.Media>> Get(string id, string changeVector = null) => await GetModel(id, changeVector);
|
||||
|
||||
|
||||
[HttpGet("{id}/source")]
|
||||
[ZeroAuthorize(MediaPermissions.Read)]
|
||||
public virtual async Task<ActionResult<MediaSourceResult>> GetSource(string id)
|
||||
{
|
||||
string path = await Media.GetPublicFilePath(id);
|
||||
|
||||
if (path.IsNullOrEmpty())
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return new MediaSourceResult()
|
||||
{
|
||||
Path = path
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("{id}/hierarchy")]
|
||||
[ZeroAuthorize(MediaPermissions.Read)]
|
||||
public virtual async Task<ActionResult<zero.Media.Media[]>> GetHierarchy(string id) => await Store.GetHierarchy<zero_Api_Media_Hierarchy>(NormalizeParentId(id));
|
||||
|
||||
|
||||
[HttpGet("{id}/search")]
|
||||
[ZeroAuthorize(MediaPermissions.Read)]
|
||||
public virtual async Task<ActionResult<Paged>> SearchByQueryAndParent(string id, [FromQuery] ListQuery<zero.Media.Media> query)
|
||||
{
|
||||
List<string> folderIds = await Store.Session.Query<MediaTreeHierarchyIndexResult, zero_Api_Media_Hierarchy>().Where(x => x.Path.Contains(id) && x.IsFolder).Select(x => x.Id).ToListAsync();
|
||||
folderIds.Add(id);
|
||||
|
||||
query.AdditionalQuery = q => q.Where(x => x.ParentId.In(folderIds));
|
||||
|
||||
return await GetModelsByIndex<MediaBasic, zero_Api_Media_Listing>(query);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("")]
|
||||
[ZeroAuthorize(MediaPermissions.Create)]
|
||||
public virtual async Task<ActionResult<Result>> Create([FromForm] IFormFile file, [FromForm] string folderId = null)
|
||||
{
|
||||
Result<zero.Media.Media> result = await Media.UploadFile(file, folderId);
|
||||
|
||||
bool minimalResponse = Hints.ResponsePreference == ApiResponsePreference.Minimal;
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
return Created("/", minimalResponse ? null : result.Model); // TODO correct URL
|
||||
}
|
||||
|
||||
return result.WithoutModel();
|
||||
}
|
||||
|
||||
|
||||
[HttpPut("{id}")]
|
||||
[ZeroAuthorize(MediaPermissions.Update)]
|
||||
public virtual Task<ActionResult<Result>> Update(string id, zero.Media.Media updateModel, [FromQuery] string changeToken = null) => UpdateModel(id, updateModel, changeToken);
|
||||
|
||||
|
||||
[HttpPut("{id}/move/{destinationId}")]
|
||||
[ZeroAuthorize(MediaPermissions.Read)]
|
||||
public virtual async Task<ActionResult<Result>> Move(string id, string destinationId) => await MoveModel(id, NormalizeParentId(destinationId));
|
||||
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[ZeroAuthorize(MediaPermissions.Delete)]
|
||||
public virtual Task<ActionResult<Result>> Delete(string id) => DeleteModel(id);
|
||||
|
||||
|
||||
[HttpGet("{id}/{size}.tmp")]
|
||||
public async Task<IActionResult> GetThumbnail(string id, string size)
|
||||
{
|
||||
zero.Media.Media media = await Media.GetFile(id);
|
||||
|
||||
if (media == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
string path = Media.GetPublicFilePath(media);
|
||||
|
||||
if (path == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (path.StartsWith("url://"))
|
||||
{
|
||||
path = path.Substring(6);
|
||||
}
|
||||
|
||||
FileExtensionContentTypeProvider provider = new();
|
||||
string contentType;
|
||||
if (!provider.TryGetContentType(Path.GetFileName(path), out contentType))
|
||||
{
|
||||
contentType = "application/octet-stream";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return File(await Media.GetFileStream(media), contentType, DateTimeOffset.Now, EntityTagHeaderValue.Any);
|
||||
}
|
||||
catch (FileSystemException)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class MediaModule : ZeroModule
|
||||
{
|
||||
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddSingleton<IPermissionProvider, MediaPermissions>();
|
||||
services.AddSingleton<IMapperProfile, MediaMapperProfile>();
|
||||
|
||||
services.Configure<RavenOptions>(opts =>
|
||||
{
|
||||
opts.Indexes.Add<zero_Api_Media_Listing>();
|
||||
opts.Indexes.Add<zero_Api_Media_ChildCounts>();
|
||||
opts.Indexes.Add<zero_Api_Media_Hierarchy>();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Media;
|
||||
|
||||
public class MediaPermissions : PermissionProvider
|
||||
{
|
||||
public const string Group = "zero.media";
|
||||
|
||||
public const string Create = "zero.settings.media.create";
|
||||
public const string Read = "zero.settings.media.read";
|
||||
public const string Update = "zero.settings.media.update";
|
||||
public const string Delete = "zero.settings.media.delete";
|
||||
|
||||
|
||||
public override Task Configure(IPermissionContext context)
|
||||
{
|
||||
PermissionGroup group = new(Group, "@media.list");
|
||||
group.Permissions.Add(new Permission("zero.media.defaults", "Default permissions")
|
||||
{
|
||||
Children = new()
|
||||
{
|
||||
new(Create, "@permission.states.create"),
|
||||
new(Read, "@permission.states.read"),
|
||||
new(Update, "@permission.states.update"),
|
||||
new(Delete, "@permission.states.delete")
|
||||
}
|
||||
});
|
||||
|
||||
context.AddGroup(group);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
//using Microsoft.AspNetCore.Http;
|
||||
//using Microsoft.AspNetCore.Mvc;
|
||||
//using Microsoft.AspNetCore.StaticFiles;
|
||||
//using Microsoft.Net.Http.Headers;
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.IO;
|
||||
//using System.Net.Http;
|
||||
//using System.Threading.Tasks;
|
||||
//using zero.Core;
|
||||
//using zero.Core.Collections;
|
||||
//using zero.Core.Entities;
|
||||
//using zero.Core.Identity;
|
||||
//using zero.Web.Models;
|
||||
|
||||
//namespace zero.Web.Controllers
|
||||
//{
|
||||
// [ZeroAuthorize(Permissions.Sections.Media, PermissionsValue.True)]
|
||||
// public class MediaController : ZeroBackofficeCollectionController<Media, IMediaCollection>
|
||||
// {
|
||||
// IPaths Paths;
|
||||
|
||||
// public MediaController(IMediaCollection collection, IPaths paths) : base(collection)
|
||||
// {
|
||||
// Paths = paths;
|
||||
// PreviewTransform = (item, model) => model.Icon = "fth-globe";
|
||||
// }
|
||||
|
||||
|
||||
// public async Task<Paged<MediaListItem>> GetListByQuery([FromQuery] MediaListItemQuery query)
|
||||
// {
|
||||
// query.IncludeInactive = true;
|
||||
// return await Collection.Load(query);
|
||||
// }
|
||||
|
||||
|
||||
// [HttpPost]
|
||||
// public async Task<Result<Media>> Upload(IFormFile file, [FromForm] string folderId) => await Collection.Save(await Collection.Upload(file, folderId));
|
||||
|
||||
// [HttpPost]
|
||||
// public async Task<Media> UploadTemporary(IFormFile file, [FromForm] string folderId) => await Collection.Upload(file, folderId);
|
||||
|
||||
// [HttpPost]
|
||||
// public async Task<Result<Media>> Move([FromBody] ActionCopyModel model) => await Collection.Move(model.Id, model.DestinationId);
|
||||
|
||||
|
||||
// public async Task<MediaListResultModel> GetAll([FromQuery] MediaListQuery query)
|
||||
// {
|
||||
// query.IncludeInactive = true;
|
||||
// Paged<MediaListModel> items = (await Collection.Load(query)).MapTo(x => new MediaListModel()
|
||||
// {
|
||||
// Id = x.Id,
|
||||
// IsFolder = false,
|
||||
// Name = x.Name,
|
||||
// Size = x.Size,
|
||||
// Source = x.PreviewSource ?? x.Source,
|
||||
// Type = x.Type
|
||||
// });
|
||||
|
||||
// IList<MediaFolder> hierarchy = null;
|
||||
// MediaFolder folder = null;
|
||||
|
||||
// if (!String.IsNullOrEmpty(query.FolderId))
|
||||
// {
|
||||
// folder = await Collection.Folders.Load(query.FolderId);
|
||||
// hierarchy = await Collection.Folders.GetHierarchy(query.FolderId);
|
||||
// }
|
||||
|
||||
// return new MediaListResultModel(items, null, folder, hierarchy);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -1,26 +0,0 @@
|
||||
//using Microsoft.AspNetCore.Mvc;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Threading.Tasks;
|
||||
//using zero.Core.Collections;
|
||||
//using zero.Core.Entities;
|
||||
//using zero.Core.Identity;
|
||||
//using zero.Web.Models;
|
||||
|
||||
//namespace zero.Web.Controllers
|
||||
//{
|
||||
// [ZeroAuthorize(Permissions.Sections.Media, PermissionsValue.True)]
|
||||
// public class MediaFolderController : ZeroBackofficeCollectionController<MediaFolder, IMediaFolderCollection>
|
||||
// {
|
||||
// public MediaFolderController(IMediaFolderCollection collection) : base(collection) { }
|
||||
|
||||
|
||||
// public async Task<IList<MediaFolder>> GetHierarchy([FromQuery] string id) => await Collection.GetHierarchy(id);
|
||||
|
||||
|
||||
// public async Task<IList<TreeItem>> GetAllAsTree([FromQuery] string parent = null, [FromQuery] string active = null) => await Collection.LoadAsTree(parent, active);
|
||||
|
||||
|
||||
// [HttpPost]
|
||||
// public async Task<Result<MediaFolder>> Move([FromBody] ActionCopyModel model) => await Collection.Move(model.Id, model.DestinationId);
|
||||
// }
|
||||
//}
|
||||
@@ -1,250 +0,0 @@
|
||||
//using Raven.Client.Documents;
|
||||
//using Raven.Client.Documents.Linq;
|
||||
//using Raven.Client.Documents.Session;
|
||||
|
||||
//namespace zero.Backoffice.Modules;
|
||||
|
||||
//public class MediaTreeService : IMediaTreeService
|
||||
//{
|
||||
// protected IMediaStore Media { get; private set; }
|
||||
|
||||
// protected PageOptions PageOptions { get; set; }
|
||||
|
||||
|
||||
// public PageTreeService(IPagesStore pages, IZeroOptions options, IRoutes routes)
|
||||
// {
|
||||
// Media = pages;
|
||||
// Routes = routes;
|
||||
// PageOptions = options.For<PageOptions>();
|
||||
// }
|
||||
|
||||
|
||||
// /// <inheritdoc />
|
||||
// /// FOR MEDIA
|
||||
// public virtual async Task<Paged<MediaListItem>> Load(MediaListItemQuery query)
|
||||
// {
|
||||
// bool hasSearch = !query.Search.IsNullOrWhiteSpace();
|
||||
// bool isRoot = query.FolderId.IsNullOrWhiteSpace();
|
||||
|
||||
// query.SearchFor(entity => entity.Name);
|
||||
|
||||
// query.OrderQuery = q => q
|
||||
// .OrderByDescending(x => x.IsFolder)
|
||||
// .ThenBy(query.OrderBy, query.OrderIsDescending, query.OrderType == ListQueryOrderType.String ? OrderingType.String : OrderingType.Double);
|
||||
|
||||
// IRavenQueryable<MediaListItem> dbQuery = Session.Query<MediaListItem, Media_ByParent>().ProjectInto<MediaListItem>();
|
||||
|
||||
// if (!hasSearch || !query.SearchIsGlobal)
|
||||
// {
|
||||
// dbQuery = dbQuery.WhereIf(x => x.ParentId == query.FolderId, !query.FolderId.IsNullOrEmpty(), x => x.ParentId == null);
|
||||
// }
|
||||
|
||||
// Paged<MediaListItem> result = await dbQuery.ToQueriedListAsyncX(query);
|
||||
|
||||
// string[] ids = result.Items.Where(x => x.IsFolder).Select(x => x.Id).ToArray();
|
||||
|
||||
// List<Media_ByChildren.Result> children = await Session.Query<Media_ByChildren.Result, Media_ByChildren>()
|
||||
// .Where(x => x.ParentId.In(ids))
|
||||
// .ToListAsync();
|
||||
|
||||
// foreach (MediaListItem item in result.Items)
|
||||
// {
|
||||
// item.Children = children.FirstOrDefault(x => x.ParentId == item.Id)?.ChildrenCount ?? 0;
|
||||
// }
|
||||
|
||||
// return result;
|
||||
// }
|
||||
|
||||
|
||||
// /// <inheritdoc />
|
||||
// /// FOR MEDIA FOLDER
|
||||
// public async Task<List<TreeItem>> LoadAsTree(string parentId = null, string activeId = null)
|
||||
// {
|
||||
// List<TreeItem> items = new();
|
||||
// string[] openIds = Array.Empty<string>();
|
||||
|
||||
// IList<MediaFolder> folders = await Session.Query<MediaFolder>()
|
||||
// .WhereIf(x => x.ParentId == parentId, !parentId.IsNullOrEmpty(), x => x.ParentId == null)
|
||||
// .OrderByDescending(x => x.CreatedDate).ThenBy(x => x.Name)
|
||||
// .ToListAsync();
|
||||
|
||||
|
||||
// // get hierarchy so we know if we should set the folder to open
|
||||
// if (!activeId.IsNullOrEmpty())
|
||||
// {
|
||||
// MediaFolder_ByHierarchy.Result result = await Session.Query<MediaFolder_ByHierarchy.Result, MediaFolder_ByHierarchy>()
|
||||
// .ProjectInto<MediaFolder_ByHierarchy.Result>()
|
||||
// .Include<MediaFolder_ByHierarchy.Result, MediaFolder>(x => x.Path.Select(p => p.Id))
|
||||
// .FirstOrDefaultAsync(x => x.Id == activeId);
|
||||
|
||||
// if (result != null)
|
||||
// {
|
||||
// openIds = result.Path.Select(x => x.Id).ToArray();
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// // get children for all folders
|
||||
// string[] folderIds = folders.Select(x => x.Id).ToArray();
|
||||
|
||||
// IList<MediaFolders_WithChildren.Result> children = await Session.Query<MediaFolders_WithChildren.Result, MediaFolders_WithChildren>()
|
||||
// .ProjectInto<MediaFolders_WithChildren.Result>()
|
||||
// .Where(x => x.Id.In(folderIds))
|
||||
// .ToListAsync();
|
||||
|
||||
|
||||
// foreach (MediaFolder folder in folders)
|
||||
// {
|
||||
// int childCount = children.Count(x => x.Id == folder.Id);
|
||||
|
||||
// items.Add(new TreeItem()
|
||||
// {
|
||||
// Id = folder.Id,
|
||||
// Name = folder.Name,
|
||||
// HasChildren = childCount > 0,
|
||||
// ChildCount = childCount,
|
||||
// ParentId = folder.ParentId,
|
||||
// Sort = folder.Sort,
|
||||
// Icon = "fth-folder",
|
||||
// IsOpen = openIds.Contains(folder.Id),
|
||||
// IsInactive = !folder.IsActive,
|
||||
// HasActions = true,
|
||||
// Modifier = !folder.IsActive ? new TreeItemModifier()
|
||||
// {
|
||||
// Icon = "fth-minus-circle color-yellow",
|
||||
// Name = "Inactive"
|
||||
// } : null
|
||||
// });
|
||||
// }
|
||||
|
||||
// return items;
|
||||
// }
|
||||
|
||||
|
||||
// /// <inheritdoc />
|
||||
// public async Task<IList<TreeItem>> GetChildren(string parentId = null, string activeId = null, string search = null)
|
||||
// {
|
||||
// IList<TreeItem> items = new List<TreeItem>();
|
||||
// IReadOnlyCollection<PageType> pageTypes = PageOptions.GetAllItems();
|
||||
// string[] openIds = new string[0] { };
|
||||
// Paged<Page> pages = null;
|
||||
// IList<Pages_WithChildren.Result> children = null;
|
||||
// bool isSearch = !search.IsNullOrWhiteSpace();
|
||||
|
||||
// if (isSearch)
|
||||
// {
|
||||
// pages = await Media.Load(1, Int32.MaxValue, q => q.SearchIf(x => x.Name, search, "*").OrderBy(x => x.Sort, OrderingType.Long));
|
||||
|
||||
// var urls = await Routes.GetUrls(pages.Items.ToArray());
|
||||
|
||||
// foreach (Page page in pages.Items)
|
||||
// {
|
||||
// if (urls.TryGetValue(page, out string url))
|
||||
// {
|
||||
// page.Url = url;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// pages = await Media.Load(1, Int32.MaxValue, q => q
|
||||
// .WhereIf(x => x.ParentId == parentId, !parentId.IsNullOrEmpty(), x => x.ParentId == null)
|
||||
// .OrderBy(x => x.Sort, OrderingType.Long));
|
||||
|
||||
|
||||
// // get hierarchy so we know if we should set the page to open
|
||||
// if (!activeId.IsNullOrEmpty())
|
||||
// {
|
||||
// Pages_ByHierarchy.Result result = await Media.Session.Query<Pages_ByHierarchy.Result, Pages_ByHierarchy>()
|
||||
// .ProjectInto<Pages_ByHierarchy.Result>()
|
||||
// .Include<Pages_ByHierarchy.Result, Page>(x => x.Path.Select(p => p.Id))
|
||||
// .FirstOrDefaultAsync(x => x.Id == activeId);
|
||||
|
||||
// if (result != null)
|
||||
// {
|
||||
// openIds = result.Path.Select(x => x.Id).ToArray(); // .Union(new string[1] { activeId })
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// // get children for all pages
|
||||
// string[] pageIds = pages.Items.Select(x => x.Id).ToArray();
|
||||
|
||||
// children = await Media.Session.Query<Pages_WithChildren.Result, Pages_WithChildren>()
|
||||
// .ProjectInto<Pages_WithChildren.Result>()
|
||||
// .Where(x => x.Id.In(pageIds))
|
||||
// .ToListAsync();
|
||||
// }
|
||||
|
||||
|
||||
// // function to get modifier icon
|
||||
// TreeItemModifier GetModifier(Page page)
|
||||
// {
|
||||
// if (page.PublishDate > DateTimeOffset.Now || page.UnpublishDate > DateTimeOffset.Now)
|
||||
// {
|
||||
// return new TreeItemModifier("@page.schedule.scheduled", "fth-clock");
|
||||
// }
|
||||
// if (!page.IsActive)
|
||||
// {
|
||||
// return new TreeItemModifier("@ui.inactive", "fth-minus-circle color-red");
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
|
||||
// // build tree
|
||||
// foreach (Page page in pages.Items)
|
||||
// {
|
||||
// PageType pageType = pageTypes.FirstOrDefault(x => x.Alias == page.PageTypeAlias);
|
||||
|
||||
// if (pageType == null)
|
||||
// {
|
||||
// continue;
|
||||
// // TODO the page type does not exist anymore
|
||||
// }
|
||||
|
||||
// int childCount = isSearch ? 0 : children.Count(x => x.Id == page.Id);
|
||||
|
||||
// items.Add(new TreeItem()
|
||||
// {
|
||||
// Id = page.Id,
|
||||
// Name = page.Name,
|
||||
// HasChildren = childCount > 0,
|
||||
// ChildCount = childCount,
|
||||
// ParentId = page.ParentId,
|
||||
// Sort = page.Sort,
|
||||
// Icon = pageType.Icon,
|
||||
// IsOpen = openIds.Contains(page.Id),
|
||||
// IsInactive = !page.IsActive,
|
||||
// HasActions = true,
|
||||
// Modifier = GetModifier(page),
|
||||
// Description = isSearch ? page.Url : null
|
||||
// });
|
||||
// }
|
||||
|
||||
// if (parentId.IsNullOrEmpty())
|
||||
// {
|
||||
// items.Add(new TreeItem()
|
||||
// {
|
||||
// Id = "recyclebin",
|
||||
// ParentId = null,
|
||||
// Sort = 99999,
|
||||
// Name = "@recyclebin.name",
|
||||
// Icon = "fth-trash",
|
||||
// HasChildren = false,
|
||||
// HasActions = true
|
||||
// });
|
||||
// }
|
||||
|
||||
// return items;
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
//public interface IMediaTreeService
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// Get media children as tree items
|
||||
// /// </summary>
|
||||
// Task<IList<TreeItem>> GetChildren(string parentId = null, string activeId = null, string search = null);
|
||||
//}
|
||||
@@ -1,11 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace zero.Api.Endpoints.NotFound;
|
||||
|
||||
public class NotFoundZeroApiController : Controller
|
||||
{
|
||||
public virtual ActionResult Index()
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace zero.Api.Endpoints.PageModules;
|
||||
|
||||
public class PageModuleModule : ZeroModule
|
||||
{
|
||||
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddSingleton<IPermissionProvider, PageModulePermissions>();
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
namespace zero.Api.Endpoints.PageModules;
|
||||
|
||||
public class PageModulePermissions : PermissionProvider
|
||||
{
|
||||
public const string Group = "zero.pagemodules";
|
||||
|
||||
public const string Create = "zero.pagemodules.create";
|
||||
public const string Read = "zero.pagemodules.read";
|
||||
public const string Update = "zero.pagemodules.update";
|
||||
public const string Delete = "zero.pagemodules.delete";
|
||||
|
||||
|
||||
public override Task Configure(IPermissionContext context)
|
||||
{
|
||||
PermissionGroup group = new(Group, "@module.list");
|
||||
group.Permissions.Add(new Permission("zero.pagemodules.defaults", "Default permissions")
|
||||
{
|
||||
Children = new()
|
||||
{
|
||||
new(Create, "@permission.states.create"),
|
||||
new(Read, "@permission.states.read"),
|
||||
new(Update, "@permission.states.update"),
|
||||
new(Delete, "@permission.states.delete")
|
||||
}
|
||||
});
|
||||
|
||||
context.AddGroup(group);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace zero.Api.Endpoints.PageModules;
|
||||
|
||||
public class PageModulesController : ZeroApiController
|
||||
{
|
||||
readonly IPageModuleTypeService ModuleTypeService;
|
||||
|
||||
public PageModulesController(IPageModuleTypeService moduleTypeService)
|
||||
{
|
||||
ModuleTypeService = moduleTypeService;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("")]
|
||||
[ZeroAuthorize(PageModulePermissions.Read)]
|
||||
public async Task<ActionResult<IList<PageModuleType>>> GetModuleTypes([FromQuery] string[] tags = default, [FromQuery] string pageId = default) => Ok(await ModuleTypeService.GetModuleTypes(tags, pageId));
|
||||
|
||||
|
||||
[HttpGet("{alias}")]
|
||||
[ZeroAuthorize(PageModulePermissions.Read)]
|
||||
public ActionResult<PageModuleType> GetModuleType(string alias) => Ok(ModuleTypeService.GetModuleType(alias));
|
||||
|
||||
|
||||
[HttpGet("{alias}/empty")]
|
||||
[ZeroAuthorize(PageModulePermissions.Read)]
|
||||
public ActionResult<PageModule> GetEmpty(string alias)
|
||||
{
|
||||
PageModule module = ModuleTypeService.GetEmpty(alias);
|
||||
|
||||
if (module == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Endpoints.Pages;
|
||||
|
||||
public class zero_Api_Pages_ChildCounts : ZeroIndex<Page, zero_Api_Pages_ChildCounts.Result>
|
||||
{
|
||||
public class Result : ZeroIdEntity
|
||||
{
|
||||
public int ChildCount { get; set; }
|
||||
}
|
||||
|
||||
protected override void Create()
|
||||
{
|
||||
Map = items => items.Where(x => x.ParentId != null).Select(item => new Result
|
||||
{
|
||||
Id = item.ParentId,
|
||||
ChildCount = 1
|
||||
});
|
||||
|
||||
Reduce = results => results.GroupBy(x => new { x.Id }).Select(group => new Result()
|
||||
{
|
||||
Id = group.Key.Id,
|
||||
ChildCount = group.Sum(x => x.ChildCount)
|
||||
});
|
||||
|
||||
StoreAllFields(FieldStorage.Yes);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Endpoints.Pages;
|
||||
|
||||
public class zero_Api_Pages_Listing : ZeroIndex<Page>
|
||||
{
|
||||
protected override void Create()
|
||||
{
|
||||
Map = items => items.Select(item => new
|
||||
{
|
||||
Name = item.Name,
|
||||
ParentId = item.ParentId,
|
||||
CreatedDate = item.CreatedDate,
|
||||
Sort = item.Sort
|
||||
});
|
||||
|
||||
Index(x => x.Name, FieldIndexing.Search);
|
||||
Index(x => x.ParentId, FieldIndexing.Exact);
|
||||
Index(x => x.CreatedDate, FieldIndexing.Exact);
|
||||
Index(x => x.Sort, FieldIndexing.Exact);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Pages;
|
||||
|
||||
public class PageBasic : ZeroIdEntity
|
||||
{
|
||||
public string ParentId { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public int Children { get; set; }
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Pages;
|
||||
|
||||
public class PageEdit : ZeroIdEntity
|
||||
{
|
||||
// we can't use Page as property type here
|
||||
// cause that would serialize flavors to Page and remove additional properties.
|
||||
// according to the System.Text.Json docs using "object" will serialize to the implementing type
|
||||
public object Page { get; set; }
|
||||
|
||||
public FlavorConfig PageType { get; set; }
|
||||
|
||||
public List<string> Urls { get; set; } = new();
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Pages;
|
||||
|
||||
public class PageMapperProfile : ZeroMapperProfile
|
||||
{
|
||||
public override void Configure(IZeroMapper mapper)
|
||||
{
|
||||
mapper.Define<Page, PageBasic>((source, ctx) => new(), Map);
|
||||
// mapper.Define<CountrySave, Country>((source, ctx) => new(), Map);
|
||||
}
|
||||
|
||||
|
||||
protected virtual void Map(Page source, PageBasic target, IZeroMapperContext ctx)
|
||||
{
|
||||
//this.MapBasicData(source, target);
|
||||
}
|
||||
|
||||
//protected virtual void Map(CountrySave source, Country target, IZeroMapperContext ctx)
|
||||
//{
|
||||
// this.MapSaveData(source, target);
|
||||
// target.Code = source.Code;
|
||||
// target.IsPreferred = source.IsPreferred;
|
||||
//}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
//using Microsoft.AspNetCore.Mvc;
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Threading.Tasks;
|
||||
//using zero.Core.Api;
|
||||
//using zero.Core.Entities;
|
||||
//using zero.Core.Utils;
|
||||
//using zero.Web.Models;
|
||||
|
||||
//namespace zero.Web.Controllers
|
||||
//{
|
||||
// public class ModulesController : BackofficeController
|
||||
// {
|
||||
// IModulesApi Api;
|
||||
|
||||
// public ModulesController(IModulesApi api)
|
||||
// {
|
||||
// Api = api;
|
||||
// }
|
||||
|
||||
|
||||
// public async Task<IList<ModuleType>> GetModuleTypes([FromQuery] string[] tags = default, [FromQuery] string pageId = default) => await Api.GetModuleTypes(tags, pageId);
|
||||
|
||||
|
||||
// public ModuleType GetModuleType([FromQuery] string alias) => Api.GetModuleType(alias);
|
||||
|
||||
|
||||
// public EditModel<Module> GetEmpty(string alias)
|
||||
// {
|
||||
// ModuleType moduleType = Api.GetModuleType(alias);
|
||||
// Module module = Activator.CreateInstance(moduleType.ContentType) as Module;
|
||||
|
||||
// module.ModuleTypeAlias = moduleType.Alias;
|
||||
// module.Id = IdGenerator.Create(8);
|
||||
// module.IsActive = true;
|
||||
|
||||
// return Edit(module);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -1,19 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace zero.Api.Endpoints.Pages;
|
||||
|
||||
public class PageModule : ZeroModule
|
||||
{
|
||||
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddSingleton<IPermissionProvider, PagePermissions>();
|
||||
services.AddSingleton<IMapperProfile, PageMapperProfile>();
|
||||
|
||||
services.Configure<RavenOptions>(opts =>
|
||||
{
|
||||
opts.Indexes.Add<zero_Api_Pages_Listing>();
|
||||
opts.Indexes.Add<zero_Api_Pages_ChildCounts>();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Pages;
|
||||
|
||||
public class PagePermissions : PermissionProvider
|
||||
{
|
||||
public const string Group = "zero.page";
|
||||
|
||||
public const string Create = "zero.page.create";
|
||||
public const string Read = "zero.page.read";
|
||||
public const string Update = "zero.page.update";
|
||||
public const string Delete = "zero.page.delete";
|
||||
|
||||
|
||||
public override Task Configure(IPermissionContext context)
|
||||
{
|
||||
PermissionGroup group = new(Group, "@page.list");
|
||||
group.Permissions.Add(new Permission("zero.page.defaults", "Default permissions")
|
||||
{
|
||||
Children = new()
|
||||
{
|
||||
new(Create, "@permission.states.create"),
|
||||
new(Read, "@permission.states.read"),
|
||||
new(Update, "@permission.states.update"),
|
||||
new(Delete, "@permission.states.delete")
|
||||
}
|
||||
});
|
||||
|
||||
context.AddGroup(group);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace zero.Api.Endpoints.Pages;
|
||||
|
||||
public class PagesController : ZeroApiTreeEntityStoreController<Page, IPagesStore>
|
||||
{
|
||||
IPageTypeService PageTypeService;
|
||||
IRoutes Routes;
|
||||
|
||||
public PagesController(IPagesStore store, IPageTypeService pageTypeService, IRoutes routes) : base(store)
|
||||
{
|
||||
PageTypeService = pageTypeService;
|
||||
Routes = routes;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("empty")]
|
||||
[ZeroAuthorize(PagePermissions.Create)]
|
||||
public virtual async Task<ActionResult<object>> Empty(string flavor, string parentId = null)
|
||||
{
|
||||
Page page = await Store.Empty(flavor, parentId);
|
||||
|
||||
if (page == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (!await Store.IsAllowedAsChild(page, parentId))
|
||||
{
|
||||
return BadRequest(Result.Fail("@errors.childnotallowed"));
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("{id}/flavors")]
|
||||
[ZeroAuthorize(PagePermissions.Read)]
|
||||
public async Task<ActionResult<IEnumerable<FlavorConfig>>> GetAllowedFlavors(string id) => Ok(await PageTypeService.GetAllowedTypes(NormalizeParentId(id)));
|
||||
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[ZeroAuthorize(PagePermissions.Read)]
|
||||
public virtual Task<ActionResult<Page>> Get(string id, string changeVector = null) => GetModel(id, changeVector);
|
||||
|
||||
|
||||
[HttpGet("{id}/children")]
|
||||
[ZeroAuthorize(PagePermissions.Read)]
|
||||
public virtual async Task<ActionResult<Paged>> GetChildren(string id, [FromQuery] ListQuery<Page> query)
|
||||
{
|
||||
query.SearchFor(x => x.Name);
|
||||
query.OrderQuery = q => q.OrderByDescending(x => x.Sort).ThenByDescending(x => x.CreatedDate);
|
||||
Paged<Page> result = await Store.LoadChildren<zero_Api_Pages_Listing>(id, query.Page, query.PageSize, q => q.Filter(query));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[HttpGet("")]
|
||||
[ZeroAuthorize(PagePermissions.Read)]
|
||||
public virtual Task<ActionResult<Paged>> Get([FromQuery] ListQuery<Page> query)
|
||||
{
|
||||
query.SearchFor(x => x.Name);
|
||||
query.OrderQuery = q => q.OrderByDescending(x => x.Sort).ThenByDescending(x => x.CreatedDate);
|
||||
return GetModelsByIndex<zero_Api_Pages_Listing>(query);
|
||||
}
|
||||
|
||||
[HttpGet("{id}/url")]
|
||||
[ZeroAuthorize(PagePermissions.Read)]
|
||||
public async Task<ActionResult<UrlResult>> GetUrl(string id)
|
||||
{
|
||||
string url = await Routes.GetUrl<Page>(id);
|
||||
return new UrlResult(ZeroContext.Application.Domains.FirstOrDefault(), url);
|
||||
}
|
||||
|
||||
[HttpPost("")]
|
||||
[ZeroAuthorize(PagePermissions.Create)]
|
||||
public virtual Task<ActionResult<Result>> Create(Page saveModel) => CreateModel(saveModel);
|
||||
|
||||
|
||||
[HttpPut("{id}")]
|
||||
[ZeroAuthorize(PagePermissions.Update)]
|
||||
public virtual Task<ActionResult<Result>> Update(string id, Page updateModel, [FromQuery] string changeToken = null) => UpdateModel(id, updateModel, changeToken);
|
||||
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[ZeroAuthorize(PagePermissions.Delete)]
|
||||
public virtual Task<ActionResult<Result<string[]>>> Delete(string id) => DeleteModelWithDescendants(id);
|
||||
|
||||
|
||||
[HttpPut("{id}/move/{destinationId}")]
|
||||
[ZeroAuthorize(PagePermissions.Update)]
|
||||
public virtual Task<ActionResult<Result>> Move(string id, string destinationId) => MoveModel(id, NormalizeParentId(destinationId));
|
||||
|
||||
|
||||
[HttpPut("{id}/copy/{destinationId}")]
|
||||
[ZeroAuthorize(PagePermissions.Update)]
|
||||
public virtual Task<ActionResult<Result>> Copy(string id, string destinationId, [FromQuery] bool includeDescendants = false)
|
||||
{
|
||||
destinationId = NormalizeParentId(destinationId);
|
||||
|
||||
return includeDescendants ?
|
||||
CopyModelWithDescendants(id, destinationId)
|
||||
: CopyModel(id, destinationId);
|
||||
}
|
||||
|
||||
|
||||
[HttpPut("sort")]
|
||||
[ZeroAuthorize(PagePermissions.Update)]
|
||||
public virtual Task<ActionResult<Result>> Sort([FromBody] string[] ids) => SortModels(ids);
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
//using Microsoft.AspNetCore.Mvc;
|
||||
//using Raven.Client.Documents;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Threading.Tasks;
|
||||
//using zero.Core.Api;
|
||||
//using zero.Core.Collections;
|
||||
//using zero.Core.Entities;
|
||||
//using zero.Core.Extensions;
|
||||
//using zero.Core.Routing;
|
||||
//using zero.Web.Models;
|
||||
|
||||
//namespace zero.Web.Controllers
|
||||
//{
|
||||
// public class PagesController : BackofficeCollectionController<Page, IPageService>
|
||||
// {
|
||||
// IRoutes Routes;
|
||||
|
||||
// public PagesController(IPageService collection, IRoutes routes) : base(collection)
|
||||
// {
|
||||
// Routes = routes;
|
||||
// }
|
||||
|
||||
|
||||
// public override async Task<EditModel<Page>> GetById([FromQuery] string id, [FromQuery] string changeVector = null)
|
||||
// {
|
||||
// Page entity = changeVector.IsNullOrEmpty() ? await Collection.GetById(id) : await Collection.GetRevision(changeVector);
|
||||
|
||||
// return entity == null ? null : Edit<Page, PageEditModel<Page>>(new PageEditModel<Page>()
|
||||
// {
|
||||
// Entity = entity,
|
||||
// PageType = Collection.GetPageType(entity.PageTypeAlias),
|
||||
// Urls = new List<string>() { await Routes.GetUrl(entity) }
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
// public override async Task<IList<PickerPreviewModel>> GetPreviews([FromQuery] List<string> ids)
|
||||
// {
|
||||
// IReadOnlyCollection<PageType> pageTypes = Options.Pages.GetAllItems();
|
||||
// Dictionary<string, Page> pages = await Collection.GetByIds(ids.ToArray());
|
||||
// Dictionary<Page, Route> routes = await Routes.GetRoutes(pages.Where(x => x.Value != null).Select(x => x.Value).ToArray());
|
||||
|
||||
// return Previews(pages, item =>
|
||||
// {
|
||||
// routes.TryGetValue(item, out Route route);
|
||||
|
||||
// PickerPreviewModel model = new()
|
||||
// {
|
||||
// Id = item.Id,
|
||||
// Icon = pageTypes.FirstOrDefault(x => x.Alias == item.PageTypeAlias)?.Icon ?? "fth-folder",
|
||||
// Name = item.Name,
|
||||
// Text = route?.Url.Or("No URL found")
|
||||
// };
|
||||
|
||||
// PreviewTransform?.Invoke(item, model);
|
||||
// return model;
|
||||
// });
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// public async Task<IList<TreeItem>> GetChildren([FromQuery] string parent = null, [FromQuery] string active = null, [FromQuery] string search = null)
|
||||
// {
|
||||
// return await Collection.GetChildren(parent, active, search);
|
||||
// }
|
||||
|
||||
|
||||
// public PageType GetPageType([FromQuery] string alias) => Collection.GetPageType(alias);
|
||||
|
||||
|
||||
// public async Task<List<string>> GetUrls([FromQuery] string pageId)
|
||||
// {
|
||||
// string url = await Routes.GetUrl<Page>(pageId);
|
||||
// return url.HasValue() ? new List<string>() { url } : new List<string>();
|
||||
// }
|
||||
|
||||
|
||||
// public async Task<IList<PageType>> GetAllowedPageTypes([FromQuery] string parent = null) => await Collection.GetAllowedPageTypes(parent);
|
||||
|
||||
|
||||
// public async Task<EditModel<Page>> GetEmptyByType([FromQuery] string type, [FromQuery] string parent = null) => Edit(await Collection.GetEmpty(type, parent));
|
||||
|
||||
|
||||
// [HttpPost]
|
||||
// public async Task<Result<IList<Page>>> SaveSorting([FromBody] string[] ids) => await Collection.SaveSorting(ids);
|
||||
|
||||
|
||||
// [HttpPost]
|
||||
// public async Task<Result<Page>> Move([FromBody] ActionCopyModel model) => await Collection.Move(model.Id, model.DestinationId);
|
||||
|
||||
|
||||
// [HttpPost]
|
||||
// public async Task<Result<Page>> Copy([FromBody] ActionCopyModel model) => await Collection.Copy(model.Id, model.DestinationId, model.IncludeDescendants);
|
||||
|
||||
|
||||
// [HttpPost]
|
||||
// public async Task<Result<string[]>> Restore([FromBody] ActionCopyModel model) => await Collection.Restore(model.Id, model.IncludeDescendants);
|
||||
|
||||
|
||||
// [HttpDelete]
|
||||
// public async Task<Result<string[]>> DeleteRecursive([FromQuery] string id) => await Collection.Delete(id, recursive: true, moveToRecycleBin: true);
|
||||
// }
|
||||
//}
|
||||
@@ -1,36 +0,0 @@
|
||||
//using Microsoft.AspNetCore.Mvc;
|
||||
//using System.Threading.Tasks;
|
||||
//using zero.Core.Api;
|
||||
//using zero.Core.Entities;
|
||||
|
||||
//namespace zero.Web.Controllers
|
||||
//{
|
||||
// public class RecycleBinController : BackofficeController
|
||||
// {
|
||||
// IRecycleBinApi Api;
|
||||
|
||||
// public RecycleBinController(IRecycleBinApi api)
|
||||
// {
|
||||
// Api = api;
|
||||
// }
|
||||
|
||||
|
||||
// public async Task<Paged<RecycledEntity>> GetByQuery([FromQuery] RecycleBinListQuery query)
|
||||
// {
|
||||
// query.IncludeInactive = true;
|
||||
// return await Api.GetByQuery(query);
|
||||
// }
|
||||
|
||||
|
||||
// public async Task<int> GetCountByOperation([FromQuery] string operationId) => await Api.GetCountByOperation(operationId);
|
||||
|
||||
|
||||
// [HttpDelete]
|
||||
// public async Task<Result<RecycledEntity>> Delete([FromQuery] string id) => await Api.Delete(id);
|
||||
|
||||
|
||||
// [HttpDelete]
|
||||
// public async Task<Result<RecycledEntity>> DeleteByGroup([FromQuery] string group) => await Api.DeleteByGroup(group);
|
||||
|
||||
// }
|
||||
//}
|
||||
@@ -1,25 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using zero.Search;
|
||||
|
||||
namespace zero.Api.Endpoints.Search;
|
||||
|
||||
public class SearchController : ZeroApiController
|
||||
{
|
||||
protected ISearchService Service { get; set; }
|
||||
|
||||
public SearchController(ISearchService service)
|
||||
{
|
||||
Service = service;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("")]
|
||||
public async Task<ActionResult<Paged>> Query([FromQuery] ListQuery<SearchResult> query)
|
||||
{
|
||||
if (!query.Search.HasValue())
|
||||
{
|
||||
return new Paged<SearchResult>(new List<SearchResult>(), 0, query.Page, query.PageSize);
|
||||
}
|
||||
return await Service.Query(query.Search, query.Page, query.PageSize);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace zero.Api.Endpoints.Search;
|
||||
|
||||
public class SearchModule : ZeroModule
|
||||
{
|
||||
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddSingleton<IPermissionProvider, SearchPermissions>();
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Search;
|
||||
|
||||
public class SearchPermissions : PermissionProvider
|
||||
{
|
||||
public const string Group = "zero.search";
|
||||
|
||||
public const string Search = "zero.search.use";
|
||||
|
||||
|
||||
public override Task Configure(IPermissionContext context)
|
||||
{
|
||||
PermissionGroup group = new(Group, "@search.permissions.search_group");
|
||||
group.Permissions.Add(new Permission(Search, "@search.permissions.search"));
|
||||
|
||||
context.AddGroup(group);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Endpoints.Spaces;
|
||||
|
||||
public class zero_Api_Spaces_Listing : ZeroIndex<Space>
|
||||
{
|
||||
protected override void Create()
|
||||
{
|
||||
Map = items => items.Select(item => new
|
||||
{
|
||||
Name = item.Name,
|
||||
IsActive = item.IsActive,
|
||||
Flavor = item.Flavor,
|
||||
CreatedDate = item.CreatedDate
|
||||
});
|
||||
|
||||
Index(x => x.Name, FieldIndexing.Search);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace zero.Api.Endpoints.Spaces;
|
||||
|
||||
public class SpaceModule : ZeroModule
|
||||
{
|
||||
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddSingleton<IPermissionProvider, SpacePermissions>();
|
||||
//services.AddSingleton<IMapperProfile, LanguageMapperProfile>();
|
||||
|
||||
services.Configure<RavenOptions>(opts =>
|
||||
{
|
||||
opts.Indexes.Add<zero_Api_Spaces_Listing>();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Spaces;
|
||||
|
||||
public class SpacePermissions : PermissionProvider
|
||||
{
|
||||
public const string Group = "zero.space";
|
||||
|
||||
public const string Create = "zero.space.create";
|
||||
public const string Read = "zero.space.read";
|
||||
public const string Update = "zero.space.update";
|
||||
public const string Delete = "zero.space.delete";
|
||||
|
||||
|
||||
public override Task Configure(IPermissionContext context)
|
||||
{
|
||||
PermissionGroup group = new(Group, "@space.list");
|
||||
group.Permissions.Add(new Permission("zero.space.defaults", "Default permissions")
|
||||
{
|
||||
Children = new()
|
||||
{
|
||||
new(Create, "@permission.states.create"),
|
||||
new(Read, "@permission.states.read"),
|
||||
new(Update, "@permission.states.update"),
|
||||
new(Delete, "@permission.states.delete")
|
||||
}
|
||||
});
|
||||
|
||||
context.AddGroup(group);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections;
|
||||
|
||||
namespace zero.Api.Endpoints.Spaces;
|
||||
|
||||
public class SpacesController : ZeroApiEntityStoreController<Space, ISpaceStore>
|
||||
{
|
||||
ISpaceTypeService SpaceTypes;
|
||||
|
||||
public SpacesController(ISpaceStore store, ISpaceTypeService spaceTypes) : base(store)
|
||||
{
|
||||
SpaceTypes = spaceTypes;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("types")]
|
||||
[ZeroAuthorize(SpacePermissions.Read)]
|
||||
public virtual ActionResult<IEnumerable> GetTypes() => Ok(SpaceTypes.GetAll());
|
||||
|
||||
[HttpGet("types/{alias}")]
|
||||
[ZeroAuthorize(SpacePermissions.Read)]
|
||||
public virtual ActionResult<SpaceType> GetType(string alias) => Ok(SpaceTypes.GetByAlias(alias));
|
||||
|
||||
[HttpGet("{alias}")]
|
||||
[ZeroAuthorize(SpacePermissions.Read)]
|
||||
public virtual async Task<ActionResult<object>> Get(string alias, [FromQuery] ListQuery<Space> query = null)
|
||||
{
|
||||
SpaceType space = SpaceTypes.GetByAlias(alias);
|
||||
|
||||
if (space == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (space.View != SpaceView.Editor)
|
||||
{
|
||||
query.OrderQuery ??= q => q.OrderByDescending(x => x.CreatedDate);
|
||||
query.SearchSelector ??= x => x.Name;
|
||||
Paged<Space> result = await Store.Load<zero_Api_Spaces_Listing>(query.Page, query.PageSize, q => q.Where(x => x.Flavor == alias).Filter(query));
|
||||
return result;
|
||||
}
|
||||
|
||||
var stream = Store.Stream(q => q.Where(x => x.Flavor == alias));
|
||||
Space item = (await stream.FirstOrDefaultAsync()) ?? (await Store.Empty<Space>(alias));
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("{alias}/empty")]
|
||||
[ZeroAuthorize(SpacePermissions.Create)]
|
||||
public virtual Task<ActionResult<Space>> Empty(string alias) => EmptyModel(alias);
|
||||
|
||||
|
||||
[HttpGet("{alias}/{id}")]
|
||||
[ZeroAuthorize(SpacePermissions.Read)]
|
||||
public virtual Task<ActionResult<Space>> Get(string alias, string id, string changeVector = null) => GetModel(id, changeVector);
|
||||
|
||||
|
||||
[HttpPost("")]
|
||||
[ZeroAuthorize(SpacePermissions.Create)]
|
||||
public virtual Task<ActionResult<Result>> Create([FromBody] Space saveModel) => CreateModel(saveModel);
|
||||
|
||||
|
||||
[HttpPut("{id}")]
|
||||
[ZeroAuthorize(SpacePermissions.Update)]
|
||||
public virtual Task<ActionResult<Result>> Update(string id, [FromBody] Space updateModel, [FromQuery] string changeToken = null) => UpdateModel(id, updateModel, changeToken);
|
||||
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[ZeroAuthorize(SpacePermissions.Delete)]
|
||||
public virtual Task<ActionResult<Result>> Delete(string id) => DeleteModel(id);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Endpoints.Translations;
|
||||
|
||||
public class zero_Api_Translations_Listing : ZeroIndex<Translation>
|
||||
{
|
||||
protected override void Create()
|
||||
{
|
||||
Map = items => items.Select(item => new
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Translations;
|
||||
|
||||
public class TranslationBasic : ZeroIdEntity
|
||||
{
|
||||
public string Key { get; set; }
|
||||
|
||||
public DateTimeOffset CreatedDate { get; set; }
|
||||
|
||||
public string Flavor { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public TranslationDisplay Display { get; set; }
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Translations;
|
||||
|
||||
public class TranslationEdit : DisplayModel<Translation>
|
||||
{
|
||||
public string Value { get; set; }
|
||||
|
||||
public TranslationDisplay Display { get; set; }
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
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)
|
||||
{
|
||||
target.Id = source.Id;
|
||||
target.Key = source.Key;
|
||||
target.Flavor = source.Flavor;
|
||||
target.CreatedDate = source.CreatedDate;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Translations;
|
||||
|
||||
public class TranslationSave : SaveModel<Translation>
|
||||
{
|
||||
public string Value { get; set; }
|
||||
|
||||
public TranslationDisplay Display { get; set; }
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
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>();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
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<Translation>> Empty(string flavor = null) => EmptyModel(flavor);
|
||||
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[ZeroAuthorize(TranslationPermissions.Read)]
|
||||
public virtual Task<ActionResult<Translation>> Get(string id, string changeVector = null) => GetModel(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 GetModelsByIndex<TranslationBasic, zero_Api_Translations_Listing>(query);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("")]
|
||||
[ZeroAuthorize(TranslationPermissions.Create)]
|
||||
public virtual Task<ActionResult<Result>> Create(Translation saveModel) => CreateModel(saveModel);
|
||||
|
||||
|
||||
[HttpPut("{id}")]
|
||||
[ZeroAuthorize(TranslationPermissions.Update)]
|
||||
public virtual Task<ActionResult<Result>> Update(string id, Translation updateModel, [FromQuery] string changeToken = null) => UpdateModel(id, updateModel, changeToken);
|
||||
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[ZeroAuthorize(TranslationPermissions.Delete)]
|
||||
public virtual Task<ActionResult<Result>> Delete(string id) => DeleteModel(id);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using Raven.Client.Documents.Indexes;
|
||||
|
||||
namespace zero.Api.Endpoints.Users;
|
||||
|
||||
public class zero_Api_Users_Listing : ZeroIndex<ZeroUser>
|
||||
{
|
||||
protected override void Create()
|
||||
{
|
||||
Map = items => items.Select(item => new
|
||||
{
|
||||
Name = item.Name,
|
||||
CreatedDate = item.CreatedDate
|
||||
});
|
||||
|
||||
Index(x => x.Name, FieldIndexing.Search);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace zero.Api.Endpoints.Users;
|
||||
|
||||
public class UserBasic : ZeroIdEntity
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
public string Email { get; set; }
|
||||
|
||||
public string AvatarId { get; set; }
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user